note.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //! Allow users to add summary comments in Issues & Pull Requests.
  2. //!
  3. //! Users can make a new summary entry by commenting the following:
  4. //!
  5. //! ```md
  6. //! @rustbot note summary-title
  7. //! ```
  8. //!
  9. //! If this is the first summary entry, rustbot will amend the original post (the top-level comment) to add a "Notes" section. The section should **not** be edited by hand.
  10. //!
  11. //! ```md
  12. //! <!-- TRIAGEBOT_SUMMARY_START -->
  13. //!
  14. //! ### Summary Notes
  15. //!
  16. //! - ["summary-title" by @username](link-to-comment)
  17. //!
  18. //! Generated by triagebot, see [help](https://github.com/rust-lang/triagebot/wiki/Note) for how to add more
  19. //! <!-- TRIAGEBOT_SUMMARY_END -->
  20. //! ```
  21. //!
  22. //! If this is *not* the first summary entry, rustbot will simply append the new entry to the existing notes section:
  23. //!
  24. //! ```md
  25. //! <!-- TRIAGEBOT_SUMMARY_START -->
  26. //!
  27. //! ### Summary Notes
  28. //!
  29. //! - ["first-note" by @username](link-to-comment)
  30. //! - ["second-note" by @username](link-to-comment)
  31. //! - ["summary-title" by @username](link-to-comment)
  32. //!
  33. //! <!-- TRIAGEBOT_SUMMARY_END -->
  34. //! ```
  35. //!
  36. use crate::{config::NoteConfig, github::Event, handlers::Context, interactions::EditIssueBody};
  37. use anyhow::Context as _;
  38. use parser::command::note::NoteCommand;
  39. use tracing as log;
  40. #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
  41. struct NoteDataEntry {
  42. title: String,
  43. comment_url: String,
  44. author: String,
  45. }
  46. impl NoteDataEntry {
  47. pub fn to_markdown(&self) -> String {
  48. format!(
  49. "\n- [\"{title}\" by @{author}]({comment_url})",
  50. title = self.title,
  51. author = self.author,
  52. comment_url = self.comment_url
  53. )
  54. }
  55. }
  56. #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
  57. struct NoteData {
  58. entries: Vec<NoteDataEntry>,
  59. }
  60. impl NoteData {
  61. pub fn remove(&mut self, title: &str) -> anyhow::Result<()> {
  62. let idx = self
  63. .entries
  64. .iter()
  65. .position(|x| x.title == title)
  66. .context("Summary with title does not exist")?;
  67. log::debug!(
  68. "Removing summary {:?} from index {}",
  69. self.entries[idx],
  70. idx
  71. );
  72. self.entries.remove(idx);
  73. Ok(())
  74. }
  75. pub fn to_markdown(&self) -> String {
  76. if self.entries.is_empty() {
  77. return String::new();
  78. }
  79. let mut text = String::from("\n### Summary Notes\n");
  80. for entry in &self.entries {
  81. text.push_str(&entry.to_markdown());
  82. }
  83. text.push_str("\n\nGenerated by triagebot, see [help](https://github.com/rust-lang/triagebot/wiki/Note) for how to add more");
  84. text
  85. }
  86. }
  87. pub(super) async fn handle_command(
  88. ctx: &Context,
  89. _config: &NoteConfig,
  90. event: &Event,
  91. cmd: NoteCommand,
  92. ) -> anyhow::Result<()> {
  93. let issue = event.issue().unwrap();
  94. let e = EditIssueBody::new(&issue, "SUMMARY");
  95. let mut current: NoteData = e.current_data().unwrap_or_default();
  96. let comment_url = String::from(event.html_url().unwrap());
  97. let author = event.user().login.to_owned();
  98. match &cmd {
  99. NoteCommand::Summary { title } => {
  100. let new_entry = NoteDataEntry {
  101. title: title.to_owned(),
  102. comment_url,
  103. author,
  104. };
  105. log::debug!("New Note Entry: {:#?}", new_entry);
  106. current.entries.push(new_entry);
  107. }
  108. NoteCommand::Remove { title } => {
  109. current.remove(title)?;
  110. }
  111. }
  112. let new_markdown = current.to_markdown();
  113. log::debug!("New MD: {:#?}", new_markdown);
  114. e.apply(&ctx.github, new_markdown, current).await?;
  115. Ok(())
  116. }