Skip to content

Commit 18de61a

Browse files
committed
Remove link if no file and optimize rendered link api calls
1 parent cb766af commit 18de61a

File tree

1 file changed

+68
-49
lines changed

1 file changed

+68
-49
lines changed

src/handlers/rendered_link.rs

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::borrow::Cow;
2+
13
use anyhow::bail;
24

35
use crate::{
@@ -38,62 +40,79 @@ async fn add_rendered_link(ctx: &Context, e: &IssuesEvent, prefix: &str) -> anyh
3840
{
3941
let files = e.issue.files(&ctx.github).await?;
4042

41-
if let Some(file) = files.iter().find(|f| f.filename.starts_with(prefix)) {
42-
let head = e.issue.head.as_ref().unwrap();
43-
let base = e.issue.base.as_ref().unwrap();
43+
let rendered_link = files
44+
.iter()
45+
.find(|f| f.filename.starts_with(prefix))
46+
.map(|file| {
47+
let head = e.issue.head.as_ref().unwrap();
48+
let base = e.issue.base.as_ref().unwrap();
4449

45-
// This URL should be stable while the PR is open, even if the
46-
// user pushes new commits.
47-
//
48-
// It will go away if the user deletes their branch, or if
49-
// they reset it (such as if they created a PR from master).
50-
// That should usually only happen after the PR is closed
51-
// a which point we switch to a SHA-based url.
52-
//
53-
// If the PR is merged we use a URL that points to the actual
54-
// repository, as to be resilient to branch deletion, as well
55-
// be in sync with current "master" branch.
56-
//
57-
// For a PR "octocat:master" <- "Bob:patch-1", we generate,
58-
// - if merged: `https://github.com/octocat/REPO/blob/master/FILEPATH`
59-
// - if open: `https://github.com/Bob/REPO/blob/patch-1/FILEPATH`
60-
// - if closed: `https://github.com/octocat/REPO/blob/SHA/FILEPATH`
61-
let rendered_link = format!(
62-
"[Rendered](https://github.com/{}/blob/{}/{})",
63-
if e.issue.merged || e.action == IssuesAction::Closed {
64-
&e.repository.full_name
65-
} else {
66-
&head.repo.full_name
67-
},
68-
if e.issue.merged {
69-
&base.git_ref
70-
} else if e.action == IssuesAction::Closed {
71-
&head.sha
72-
} else {
73-
&head.git_ref
74-
},
75-
file.filename
76-
);
50+
// This URL should be stable while the PR is open, even if the
51+
// user pushes new commits.
52+
//
53+
// It will go away if the user deletes their branch, or if
54+
// they reset it (such as if they created a PR from master).
55+
// That should usually only happen after the PR is closed
56+
// a which point we switch to a SHA-based url.
57+
//
58+
// If the PR is merged we use a URL that points to the actual
59+
// repository, as to be resilient to branch deletion, as well
60+
// be in sync with current "master" branch.
61+
//
62+
// For a PR "octocat:master" <- "Bob:patch-1", we generate,
63+
// - if merged: `https://github.com/octocat/REPO/blob/master/FILEPATH`
64+
// - if open: `https://github.com/Bob/REPO/blob/patch-1/FILEPATH`
65+
// - if closed: `https://github.com/octocat/REPO/blob/SHA/FILEPATH`
66+
format!(
67+
"[Rendered](https://github.com/{}/blob/{}/{})",
68+
if e.issue.merged || e.action == IssuesAction::Closed {
69+
&e.repository.full_name
70+
} else {
71+
&head.repo.full_name
72+
},
73+
if e.issue.merged {
74+
&base.git_ref
75+
} else if e.action == IssuesAction::Closed {
76+
&head.sha
77+
} else {
78+
&head.git_ref
79+
},
80+
file.filename
81+
)
82+
});
7783

78-
let new_body = if !e.issue.body.contains("[Rendered]") {
84+
let new_body: Cow<'_, str> = if !e.issue.body.contains("[Rendered]") {
85+
if let Some(rendered_link) = rendered_link {
7986
// add rendered link to the end of the body
80-
format!("{}\n\n{rendered_link}", e.issue.body)
81-
} else if let Some(start_pos) = e.issue.body.find("[Rendered](") {
82-
let Some(end_offset) = &e.issue.body[start_pos..].find(')') else {
83-
bail!("no `)` after `[Rendered]` found")
84-
};
87+
format!("{}\n\n{rendered_link}", e.issue.body).into()
88+
} else {
89+
// or return the original body since we don't have
90+
// a rendered link to add
91+
e.issue.body.as_str().into()
92+
}
93+
} else if let Some(start_pos) = e.issue.body.find("[Rendered](") {
94+
let Some(end_offset) = &e.issue.body[start_pos..].find(')') else {
95+
bail!("no `)` after `[Rendered]` found")
96+
};
8597

86-
// replace the current rendered link with the new one
87-
e.issue.body.replace(
98+
// replace the current rendered link with the new one or replace
99+
// it with an empty string if we don't have one
100+
e.issue
101+
.body
102+
.replace(
88103
&e.issue.body[start_pos..=(start_pos + end_offset)],
89-
&rendered_link,
104+
rendered_link.as_deref().unwrap_or(""),
90105
)
91-
} else {
92-
bail!(
93-
"found `[Rendered]` but not it's associated link, can't replace it, bailing out"
94-
)
95-
};
106+
.into()
107+
} else {
108+
bail!(
109+
"found `[Rendered]` but not it's associated link, can't replace it or remove it, bailing out"
110+
)
111+
};
96112

113+
// avoid an expensive GitHub api call by first checking if we actually
114+
// edited the pull request body
115+
if e.issue.body != new_body {
97116
e.issue.edit_body(&ctx.github, &new_body).await?;
98117
}
99118
}

0 commit comments

Comments
 (0)