Skip to content

Commit

Permalink
Improve rendered link handler with proper edit and sha-based link
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Oct 26, 2024
1 parent f563bc9 commit 8f211e0
Showing 1 changed file with 66 additions and 23 deletions.
89 changes: 66 additions & 23 deletions src/handlers/rendered_link.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use anyhow::bail;

use crate::{
github::{Event, IssuesAction, IssuesEvent},
handlers::Context,
Expand All @@ -10,6 +12,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/",
Expand All @@ -25,32 +31,69 @@ 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 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 head = e.issue.head.as_ref().unwrap();
let base = e.issue.base.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.
//
// If the PR is merged we use a URL that points to the actual
// repository, as to be resilient to branch deletion, as well
// be in sync with current "master" branch.
//
// For a PR "octocat:master" <- "Bob:patch-1", we generate,
// - if merged: `https://github.com/octocat/REPO/blob/master/FILEPATH`
// - if open: `https://github.com/Bob/REPO/blob/patch-1/FILEPATH`
// - if closed: `https://github.com/octocat/REPO/blob/SHA/FILEPATH`
let rendered_link = format!(
"[Rendered](https://github.com/{}/blob/{}/{})",
if e.issue.merged || e.action == IssuesAction::Closed {
&e.repository.full_name
} else {
&head.repo.full_name
},
if e.issue.merged {
&base.git_ref
} else if e.action == IssuesAction::Closed {
&head.sha
} else {
&head.git_ref
},
file.filename
);

let new_body = if !e.issue.body.contains("[Rendered]") {
// add rendered link to the end of the body
format!("{}\n\n{rendered_link}", e.issue.body)
} else if let Some(start_pos) = e.issue.body.find("[Rendered](") {
let Some(end_offset) = &e.issue.body[start_pos..].find(')') else {
bail!("no `)` after `[Rendered]` found")
};

// replace the current rendered link with the new one
e.issue.body.replace(
&e.issue.body[start_pos..=(start_pos + end_offset)],
&rendered_link,
)
} else {
bail!(
"found `[Rendered]` but not it's associated link, can't replace it, bailing out"
)
};

e.issue.edit_body(&ctx.github, &new_body).await?;
}
}

Expand Down

0 comments on commit 8f211e0

Please sign in to comment.