note.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. //! ...details details details...
  9. //! ```
  10. //!
  11. //! 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.
  12. //!
  13. //! ```md
  14. //! <!-- TRIAGEBOT_SUMMARY_START -->
  15. //!
  16. //! ### Summary Notes
  17. //!
  18. //! - ["summary-title" by @username](link-to-comment)
  19. //!
  20. //! <!-- TRIAGEBOT_SUMMARY_END -->
  21. //! ```
  22. //!
  23. //! If this is *not* the first summary entry, rustbot will simply append the new entry to the existing notes section:
  24. //!
  25. //! ```md
  26. //! <!-- TRIAGEBOT_SUMMARY_START -->
  27. //!
  28. //! ### Summary Notes
  29. //!
  30. //! - ["first-note" by @username](link-to-comment)
  31. //! - ["second-note" by @username](link-to-comment)
  32. //! - ["summary-title" by @username](link-to-comment)
  33. //!
  34. //! <!-- TRIAGEBOT_SUMMARY_END -->
  35. //! ```
  36. //!
  37. use crate::{config::NoteConfig, github::Event, handlers::Context, interactions::EditIssueBody};
  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.to_owned(),
  51. author = self.author.to_owned(),
  52. comment_url = self.comment_url.to_owned()
  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 to_markdown(&self) -> String {
  62. if self.entries.is_empty() {
  63. return String::new();
  64. }
  65. let mut text = String::from("\n### Summary Notes\n");
  66. for entry in &self.entries {
  67. text.push_str(&entry.to_markdown());
  68. }
  69. text
  70. }
  71. }
  72. pub(super) async fn handle_command(
  73. ctx: &Context,
  74. _config: &NoteConfig,
  75. event: &Event,
  76. cmd: NoteCommand,
  77. ) -> anyhow::Result<()> {
  78. let issue = event.issue().unwrap();
  79. let e = EditIssueBody::new(&issue, "SUMMARY");
  80. let mut current: NoteData = e.current_data().unwrap_or_default();
  81. let comment_url = String::from(event.html_url().unwrap());
  82. let author = event.user().login.to_owned();
  83. let NoteCommand::Summary { title } = &cmd;
  84. let new_entry = NoteDataEntry {
  85. title: title.to_owned(),
  86. comment_url,
  87. author,
  88. };
  89. log::debug!("New Note Entry: {:#?}", new_entry);
  90. current.entries.push(new_entry);
  91. let new_markdown = current.to_markdown();
  92. log::debug!("New MD: {:#?}", new_markdown);
  93. e.apply(&ctx.github, new_markdown, current).await?;
  94. Ok(())
  95. }