pull_request.rs

 1use lazy_static::lazy_static;
 2use url::Url;
 3
 4use crate::{hosting_provider::HostingProvider, permalink::ParsedGitRemote};
 5
 6lazy_static! {
 7    static ref GITHUB_PULL_REQUEST_NUMBER: regex::Regex =
 8        regex::Regex::new(r"\(#(\d+)\)$").unwrap();
 9}
10
11#[derive(Clone, Debug)]
12pub struct PullRequest {
13    pub number: u32,
14    pub url: Url,
15}
16
17pub fn extract_pull_request(remote: &ParsedGitRemote, message: &str) -> Option<PullRequest> {
18    match remote.provider {
19        HostingProvider::Github => {
20            let line = message.lines().next()?;
21            let capture = GITHUB_PULL_REQUEST_NUMBER.captures(line)?;
22            let number = capture.get(1)?.as_str().parse::<u32>().ok()?;
23
24            let mut url = remote.provider.base_url();
25            let path = format!("/{}/{}/pull/{}", remote.owner, remote.repo, number);
26            url.set_path(&path);
27
28            Some(PullRequest { number, url })
29        }
30        _ => None,
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use unindent::Unindent;
37
38    use crate::{
39        hosting_provider::HostingProvider, permalink::ParsedGitRemote,
40        pull_request::extract_pull_request,
41    };
42
43    #[test]
44    fn test_github_pull_requests() {
45        let remote = ParsedGitRemote {
46            provider: HostingProvider::Github,
47            owner: "zed-industries",
48            repo: "zed",
49        };
50
51        let message = "This does not contain a pull request";
52        assert!(extract_pull_request(&remote, message).is_none());
53
54        // Pull request number at end of first line
55        let message = r#"
56            project panel: do not expand collapsed worktrees on "collapse all entries" (#10687)
57
58            Fixes #10597
59
60            Release Notes:
61
62            - Fixed "project panel: collapse all entries" expanding collapsed worktrees.
63            "#
64        .unindent();
65
66        assert_eq!(
67            extract_pull_request(&remote, &message)
68                .unwrap()
69                .url
70                .as_str(),
71            "https://github.com/zed-industries/zed/pull/10687"
72        );
73
74        // Pull request number in middle of line, which we want to ignore
75        let message = r#"
76            Follow-up to #10687 to fix problems
77
78            See the original PR, this is a fix.
79            "#
80        .unindent();
81        assert!(extract_pull_request(&remote, &message).is_none());
82    }
83}