git_hosting_providers: Extract Bitbucket pull request number (#34584)
git: Extract Bitbucket pull request number Release Notes: - git: Extract Bitbucket pull request number --------- Co-authored-by: Peter Tripp <peter@zed.dev>
This commit is contained in:
parent
cdfb3348ea
commit
00701b5e99
1 changed files with 57 additions and 1 deletions
|
@ -1,12 +1,22 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use git::{
|
use git::{
|
||||||
BuildCommitPermalinkParams, BuildPermalinkParams, GitHostingProvider, ParsedGitRemote,
|
BuildCommitPermalinkParams, BuildPermalinkParams, GitHostingProvider, ParsedGitRemote,
|
||||||
RemoteUrl,
|
PullRequest, RemoteUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn pull_request_regex() -> &'static Regex {
|
||||||
|
static PULL_REQUEST_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
|
// This matches Bitbucket PR reference pattern: (pull request #xxx)
|
||||||
|
Regex::new(r"\(pull request #(\d+)\)").unwrap()
|
||||||
|
});
|
||||||
|
&PULL_REQUEST_REGEX
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Bitbucket {
|
pub struct Bitbucket {
|
||||||
name: String,
|
name: String,
|
||||||
base_url: Url,
|
base_url: Url,
|
||||||
|
@ -96,6 +106,22 @@ impl GitHostingProvider for Bitbucket {
|
||||||
);
|
);
|
||||||
permalink
|
permalink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_pull_request(&self, remote: &ParsedGitRemote, message: &str) -> Option<PullRequest> {
|
||||||
|
// Check first line of commit message for PR references
|
||||||
|
let first_line = message.lines().next()?;
|
||||||
|
|
||||||
|
// Try to match against our PR patterns
|
||||||
|
let capture = pull_request_regex().captures(first_line)?;
|
||||||
|
let number = capture.get(1)?.as_str().parse::<u32>().ok()?;
|
||||||
|
|
||||||
|
// Construct the PR URL in Bitbucket format
|
||||||
|
let mut url = self.base_url();
|
||||||
|
let path = format!("/{}/{}/pull-requests/{}", remote.owner, remote.repo, number);
|
||||||
|
url.set_path(&path);
|
||||||
|
|
||||||
|
Some(PullRequest { number, url })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -203,4 +229,34 @@ mod tests {
|
||||||
"https://bitbucket.org/zed-industries/zed/src/f00b4r/main.rs#lines-24:48";
|
"https://bitbucket.org/zed-industries/zed/src/f00b4r/main.rs#lines-24:48";
|
||||||
assert_eq!(permalink.to_string(), expected_url.to_string())
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bitbucket_pull_requests() {
|
||||||
|
use indoc::indoc;
|
||||||
|
|
||||||
|
let remote = ParsedGitRemote {
|
||||||
|
owner: "zed-industries".into(),
|
||||||
|
repo: "zed".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let bitbucket = Bitbucket::public_instance();
|
||||||
|
|
||||||
|
// Test message without PR reference
|
||||||
|
let message = "This does not contain a pull request";
|
||||||
|
assert!(bitbucket.extract_pull_request(&remote, message).is_none());
|
||||||
|
|
||||||
|
// Pull request number at end of first line
|
||||||
|
let message = indoc! {r#"
|
||||||
|
Merged in feature-branch (pull request #123)
|
||||||
|
|
||||||
|
Some detailed description of the changes.
|
||||||
|
"#};
|
||||||
|
|
||||||
|
let pr = bitbucket.extract_pull_request(&remote, message).unwrap();
|
||||||
|
assert_eq!(pr.number, 123);
|
||||||
|
assert_eq!(
|
||||||
|
pr.url.as_str(),
|
||||||
|
"https://bitbucket.org/zed-industries/zed/pull-requests/123"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue