Skip to content

Commit a5f31cd

Browse files
authored
Merge pull request #1848 from Urgau/rendered_link-improvements
Improve rendered link handler with proper edit and sha-based link
2 parents 8846e4b + 8f211e0 commit a5f31cd

File tree

1 file changed

+66
-23
lines changed

1 file changed

+66
-23
lines changed

src/handlers/rendered_link.rs

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use anyhow::bail;
2+
13
use crate::{
24
github::{Event, IssuesAction, IssuesEvent},
35
handlers::Context,
@@ -10,6 +12,10 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> {
1012
return Ok(());
1113
};
1214

15+
if !e.issue.is_pr() {
16+
return Ok(());
17+
}
18+
1319
let repo = e.issue.repository();
1420
let prefix = match (&*repo.organization, &*repo.repository) {
1521
("rust-lang", "rfcs") => "text/",
@@ -25,32 +31,69 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> {
2531
}
2632

2733
async fn add_rendered_link(ctx: &Context, e: &IssuesEvent, prefix: &str) -> anyhow::Result<()> {
28-
if e.action == IssuesAction::Opened {
34+
if e.action == IssuesAction::Opened
35+
|| e.action == IssuesAction::Closed
36+
|| e.action == IssuesAction::Reopened
37+
{
2938
let files = e.issue.files(&ctx.github).await?;
3039

3140
if let Some(file) = files.iter().find(|f| f.filename.starts_with(prefix)) {
32-
if !e.issue.body.contains("[Rendered]") {
33-
// This URL should be stable while the PR is open, even if the
34-
// user pushes new commits.
35-
//
36-
// It will go away if the user deletes their branch, or if
37-
// they reset it (such as if they created a PR from master).
38-
// That should usually only happen after the PR is closed.
39-
// During the closing process, the closer should update the
40-
// Rendered link to the new location (which we should
41-
// automate!).
42-
let head = e.issue.head.as_ref().unwrap();
43-
let url = format!(
44-
"https://github.com/{}/blob/{}/{}",
45-
head.repo.full_name, head.git_ref, file.filename
46-
);
47-
e.issue
48-
.edit_body(
49-
&ctx.github,
50-
&format!("{}\n\n[Rendered]({})", e.issue.body, url),
51-
)
52-
.await?;
53-
}
41+
let head = e.issue.head.as_ref().unwrap();
42+
let base = e.issue.base.as_ref().unwrap();
43+
44+
// This URL should be stable while the PR is open, even if the
45+
// user pushes new commits.
46+
//
47+
// It will go away if the user deletes their branch, or if
48+
// they reset it (such as if they created a PR from master).
49+
// That should usually only happen after the PR is closed
50+
// a which point we switch to a SHA-based url.
51+
//
52+
// If the PR is merged we use a URL that points to the actual
53+
// repository, as to be resilient to branch deletion, as well
54+
// be in sync with current "master" branch.
55+
//
56+
// For a PR "octocat:master" <- "Bob:patch-1", we generate,
57+
// - if merged: `https://github.com/octocat/REPO/blob/master/FILEPATH`
58+
// - if open: `https://github.com/Bob/REPO/blob/patch-1/FILEPATH`
59+
// - if closed: `https://github.com/octocat/REPO/blob/SHA/FILEPATH`
60+
let rendered_link = format!(
61+
"[Rendered](https://github.com/{}/blob/{}/{})",
62+
if e.issue.merged || e.action == IssuesAction::Closed {
63+
&e.repository.full_name
64+
} else {
65+
&head.repo.full_name
66+
},
67+
if e.issue.merged {
68+
&base.git_ref
69+
} else if e.action == IssuesAction::Closed {
70+
&head.sha
71+
} else {
72+
&head.git_ref
73+
},
74+
file.filename
75+
);
76+
77+
let new_body = if !e.issue.body.contains("[Rendered]") {
78+
// add rendered link to the end of the body
79+
format!("{}\n\n{rendered_link}", e.issue.body)
80+
} else if let Some(start_pos) = e.issue.body.find("[Rendered](") {
81+
let Some(end_offset) = &e.issue.body[start_pos..].find(')') else {
82+
bail!("no `)` after `[Rendered]` found")
83+
};
84+
85+
// replace the current rendered link with the new one
86+
e.issue.body.replace(
87+
&e.issue.body[start_pos..=(start_pos + end_offset)],
88+
&rendered_link,
89+
)
90+
} else {
91+
bail!(
92+
"found `[Rendered]` but not it's associated link, can't replace it, bailing out"
93+
)
94+
};
95+
96+
e.issue.edit_body(&ctx.github, &new_body).await?;
5497
}
5598
}
5699

0 commit comments

Comments
 (0)