note.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 parser::command::note::NoteCommand;
  38. use tracing as log;
  39. #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
  40. struct NoteDataEntry {
  41. title: String,
  42. comment_url: String,
  43. author: String,
  44. }
  45. impl NoteDataEntry {
  46. pub fn to_markdown(&self) -> String {
  47. format!(
  48. "\n- [\"{title}\" by @{author}]({comment_url})",
  49. title = self.title,
  50. author = self.author,
  51. comment_url = self.comment_url
  52. )
  53. }
  54. }
  55. #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
  56. struct NoteData {
  57. entries: Vec<NoteDataEntry>,
  58. }
  59. impl NoteData {
  60. pub fn remove(&mut self, title: &str) -> () {
  61. let idx = self.entries.iter().position(|x| x.title == title).unwrap();
  62. log::debug!(
  63. "Removing element {:#?} from index {}",
  64. self.entries[idx],
  65. idx
  66. );
  67. self.entries.remove(idx);
  68. }
  69. pub fn to_markdown(&self) -> String {
  70. if self.entries.is_empty() {
  71. return String::new();
  72. }
  73. let mut text = String::from("\n### Summary Notes\n");
  74. for entry in &self.entries {
  75. text.push_str(&entry.to_markdown());
  76. }
  77. text.push_str("\n\nGenerated by triagebot, see [help](https://github.com/rust-lang/triagebot/wiki/Note) for how to add more");
  78. text
  79. }
  80. }
  81. pub(super) async fn handle_command(
  82. ctx: &Context,
  83. _config: &NoteConfig,
  84. event: &Event,
  85. cmd: NoteCommand,
  86. ) -> anyhow::Result<()> {
  87. let issue = event.issue().unwrap();
  88. let e = EditIssueBody::new(&issue, "SUMMARY");
  89. let mut current: NoteData = e.current_data().unwrap_or_default();
  90. let comment_url = String::from(event.html_url().unwrap());
  91. let author = event.user().login.to_owned();
  92. match &cmd {
  93. NoteCommand::Summary { title } => {
  94. let new_entry = NoteDataEntry {
  95. title: title.to_owned(),
  96. comment_url,
  97. author,
  98. };
  99. log::debug!("New Note Entry: {:#?}", new_entry);
  100. current.entries.push(new_entry);
  101. }
  102. NoteCommand::Remove { title } => {
  103. current.remove(title);
  104. }
  105. }
  106. let new_markdown = current.to_markdown();
  107. log::debug!("New MD: {:#?}", new_markdown);
  108. e.apply(&ctx.github, new_markdown, current).await?;
  109. Ok(())
  110. }