diff --git a/src/handlers/rendered_link.rs b/src/handlers/rendered_link.rs index 81547701..270753a8 100644 --- a/src/handlers/rendered_link.rs +++ b/src/handlers/rendered_link.rs @@ -1,8 +1,14 @@ use crate::{ github::{Event, IssuesAction, IssuesEvent}, handlers::Context, + interactions::EditIssueBody, }; +#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)] +struct RenderedLinkData { + rendered_link: String, +} + pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { let e = if let Event::Issue(e) = event { e @@ -10,6 +16,10 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { return Ok(()); }; + if !e.issue.is_pr() { + return Ok(()); + } + let repo = e.issue.repository(); let prefix = match (&*repo.organization, &*repo.repository) { ("rust-lang", "rfcs") => "text/", @@ -25,32 +35,47 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { } async fn add_rendered_link(ctx: &Context, e: &IssuesEvent, prefix: &str) -> anyhow::Result<()> { - if e.action == IssuesAction::Opened { + if e.action == IssuesAction::Opened + || e.action == IssuesAction::Closed + || e.action == IssuesAction::Reopened + { + let edit = EditIssueBody::new(&e.issue, "RENDERED_LINK"); + let current_data: Option = edit.current_data(); + let files = e.issue.files(&ctx.github).await?; if let Some(file) = files.iter().find(|f| f.filename.starts_with(prefix)) { - if !e.issue.body.contains("[Rendered]") { - // This URL should be stable while the PR is open, even if the - // user pushes new commits. - // - // It will go away if the user deletes their branch, or if - // they reset it (such as if they created a PR from master). - // That should usually only happen after the PR is closed. - // During the closing process, the closer should update the - // Rendered link to the new location (which we should - // automate!). - let head = e.issue.head.as_ref().unwrap(); - let url = format!( - "https://github.com/{}/blob/{}/{}", - head.repo.full_name, head.git_ref, file.filename - ); - e.issue - .edit_body( - &ctx.github, - &format!("{}\n\n[Rendered]({})", e.issue.body, url), - ) - .await?; - } + let mut current_data = current_data.unwrap_or_default(); + let head = e.issue.head.as_ref().unwrap(); + + // This URL should be stable while the PR is open, even if the + // user pushes new commits. + // + // It will go away if the user deletes their branch, or if + // they reset it (such as if they created a PR from master). + // That should usually only happen after the PR is closed + // a which point we switch to a SHA-based url. + current_data.rendered_link = format!( + "https://github.com/{}/blob/{}/{}", + head.repo.full_name, + if e.action == IssuesAction::Closed { + &head.sha + } else { + &head.git_ref + }, + file.filename + ); + + edit.apply( + &ctx.github, + format!("[Rendered]({})", ¤t_data.rendered_link), + current_data, + ) + .await?; + } else if let Some(mut current_data) = current_data { + // No render link to show, but one previously, so remove it + current_data.rendered_link = String::new(); + edit.apply(&ctx.github, String::new(), current_data).await?; } }