Skip to content

Commit 80ef05d

Browse files
committed
fix: support https repo uri not ending with .git
1 parent a7d078e commit 80ef05d

4 files changed

Lines changed: 120 additions & 75 deletions

File tree

src/run/ci_provider/buildkite/provider.rs

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use std::env;
22

3-
use lazy_static::lazy_static;
4-
use regex::Regex;
53
use simplelog::SharedLogger;
64

75
use crate::prelude::*;
6+
use crate::run::helpers::{parse_git_remote, GitRemote};
87
use crate::run::{
98
ci_provider::{
109
interfaces::{CIProviderMetadata, RepositoryProvider, RunEvent},
@@ -27,16 +26,6 @@ pub struct BuildkiteProvider {
2726
repository_root_path: String,
2827
}
2928

30-
lazy_static! {
31-
static ref GITHUB_URL_REGEX: Regex = Regex::new(
32-
r"(?x)
33-
(?:https://github.com/|git@github.com:)
34-
(?P<owner>[^/]+)/(?P<repository>[^/.]+)\.git
35-
"
36-
)
37-
.expect("Failed to compile GitHub URL regex");
38-
}
39-
4029
pub fn get_pr_number() -> Result<Option<u64>> {
4130
Ok(get_env_variable("BUILDKITE_PULL_REQUEST")?.parse().ok())
4231
}
@@ -64,24 +53,6 @@ pub fn get_ref() -> Result<String> {
6453
}
6554
}
6655

67-
pub fn get_owner_and_repository() -> Result<(String, String)> {
68-
let repository_url = get_env_variable("BUILDKITE_REPO")?;
69-
let captures = GITHUB_URL_REGEX
70-
.captures(&repository_url)
71-
.context("Failed to parse the GitHub repository URL")?;
72-
73-
let owner = captures
74-
.name("owner")
75-
.context("Failed to parse the GitHub repository URL")?
76-
.as_str();
77-
let repository = captures
78-
.name("repository")
79-
.context("Failed to parse the GitHub repository URL")?
80-
.as_str();
81-
82-
Ok((owner.into(), repository.into()))
83-
}
84-
8556
impl TryFrom<&Config> for BuildkiteProvider {
8657
type Error = Error;
8758
fn try_from(config: &Config) -> Result<Self> {
@@ -90,7 +61,18 @@ impl TryFrom<&Config> for BuildkiteProvider {
9061
}
9162

9263
let is_pr = get_pr_number()?.is_some();
93-
let (owner, repository) = get_owner_and_repository()?;
64+
let repository_url = get_env_variable("BUILDKITE_REPO")?;
65+
let GitRemote {
66+
owner,
67+
repository,
68+
domain,
69+
} = parse_git_remote(&repository_url)?;
70+
71+
if domain != "github.com" {
72+
bail!(
73+
"Only GitHub repositories are supported by CodSpeed BuildKite integration for now."
74+
);
75+
}
9476

9577
let repository_root_path = match find_repository_root(&std::env::current_dir()?) {
9678
Some(mut path) => {
@@ -181,29 +163,6 @@ mod tests {
181163
});
182164
}
183165

184-
#[test]
185-
fn test_get_owner_and_repository() {
186-
with_var(
187-
"BUILDKITE_REPO",
188-
Some("https://github.com/my-org/adrien-python-test.git"),
189-
|| {
190-
let (owner, repository) = get_owner_and_repository().unwrap();
191-
assert_eq!(owner, "my-org");
192-
assert_eq!(repository, "adrien-python-test");
193-
},
194-
);
195-
196-
with_var(
197-
"BUILDKITE_REPO",
198-
Some("git@github.com:my-org/adrien-python-test.git"),
199-
|| {
200-
let (owner, repository) = get_owner_and_repository().unwrap();
201-
assert_eq!(owner, "my-org");
202-
assert_eq!(repository, "adrien-python-test");
203-
},
204-
);
205-
}
206-
207166
#[test]
208167
fn test_try_from_push_main() {
209168
with_vars(

src/run/ci_provider/local/provider.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use git2::Repository;
2-
use lazy_static::lazy_static;
32
use simplelog::SharedLogger;
43

54
use crate::local_logger::get_local_logger;
65
use crate::prelude::*;
6+
use crate::run::helpers::{parse_git_remote, GitRemote};
77
use crate::run::{
88
ci_provider::{
99
interfaces::{CIProviderMetadata, RepositoryProvider, RunEvent},
@@ -27,31 +27,22 @@ pub struct LocalProvider {
2727

2828
impl LocalProvider {}
2929

30-
lazy_static! {
31-
static ref REMOTE_REGEX: regex::Regex = regex::Regex::new(
32-
r"(?P<domain>[^/@\.]+)\.\w+[:/](?P<owner>[^/]+)/(?P<repository>[^/]+)\.git"
33-
)
34-
.unwrap();
35-
}
36-
3730
fn extract_provider_owner_and_repository_from_remote_url(
3831
remote_url: &str,
3932
) -> Result<(RepositoryProvider, String, String)> {
40-
let captures = REMOTE_REGEX.captures(remote_url).ok_or_else(|| {
41-
anyhow!(
42-
"Could not extract owner and repository from remote url: {}",
43-
remote_url
44-
)
45-
})?;
46-
47-
let domain = captures.name("domain").unwrap().as_str();
48-
let repository_provider = serde_json::from_str(&format!("\"{}\"", domain.to_uppercase()))
49-
.context(format!(
33+
let GitRemote {
34+
domain,
35+
owner,
36+
repository,
37+
} = parse_git_remote(remote_url)?;
38+
let repository_provider = match domain.as_str() {
39+
"github.com" => RepositoryProvider::GitHub,
40+
"gitlab.com" => RepositoryProvider::GitLab,
41+
domain => bail!(
5042
"Repository provider {} is not supported by CodSpeed",
5143
domain
52-
))?;
53-
let owner = captures.name("owner").unwrap().as_str();
54-
let repository = captures.name("repository").unwrap().as_str();
44+
),
45+
};
5546

5647
Ok((
5748
repository_provider,

src/run/helpers/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mod find_repository_root;
22
mod get_env_var;
3+
mod parse_git_remote;
34

45
pub use find_repository_root::find_repository_root;
56
pub use get_env_var::get_env_variable;
7+
pub use parse_git_remote::*;
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use anyhow::{anyhow, Result};
2+
use lazy_static::lazy_static;
3+
4+
lazy_static! {
5+
static ref REMOTE_REGEX: regex::Regex = regex::Regex::new(
6+
r"(?P<domain>[^/@\.]+\.\w+)[:/](?P<owner>[^/]+)/(?P<repository>[^/]+?)(\.git)?$"
7+
)
8+
.unwrap();
9+
}
10+
11+
#[derive(Debug)]
12+
pub struct GitRemote {
13+
pub domain: String,
14+
pub owner: String,
15+
pub repository: String,
16+
}
17+
18+
pub fn parse_git_remote(remote: &str) -> Result<GitRemote> {
19+
let captures = REMOTE_REGEX.captures(remote).ok_or_else(|| {
20+
anyhow!(
21+
"Could not extract owner and repository from remote url: {}",
22+
remote
23+
)
24+
})?;
25+
26+
let domain = captures.name("domain").unwrap().as_str();
27+
let owner = captures.name("owner").unwrap().as_str();
28+
let repository = captures.name("repository").unwrap().as_str();
29+
30+
Ok(GitRemote {
31+
domain: domain.to_string(),
32+
owner: owner.to_string(),
33+
repository: repository.to_string(),
34+
})
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::*;
40+
41+
#[test]
42+
fn test_parse_git_remote() {
43+
let remote = "git@github.com:CodSpeedHQ/runner.git";
44+
let git_remote = parse_git_remote(remote).unwrap();
45+
insta::assert_debug_snapshot!(git_remote, @r###"
46+
GitRemote {
47+
domain: "github.com",
48+
owner: "CodSpeedHQ",
49+
repository: "runner",
50+
}
51+
"###);
52+
53+
let remote = "https://github.com/CodSpeedHQ/runner.git";
54+
let git_remote = parse_git_remote(remote).unwrap();
55+
insta::assert_debug_snapshot!(git_remote, @r###"
56+
GitRemote {
57+
domain: "github.com",
58+
owner: "CodSpeedHQ",
59+
repository: "runner",
60+
}
61+
"###);
62+
63+
let remote = "https://github.com/CodSpeedHQ/runner";
64+
let git_remote = parse_git_remote(remote).unwrap();
65+
insta::assert_debug_snapshot!(git_remote, @r###"
66+
GitRemote {
67+
domain: "github.com",
68+
owner: "CodSpeedHQ",
69+
repository: "runner",
70+
}
71+
"###);
72+
73+
let remote = "git@gitlab.com:codspeed/runner.git";
74+
let git_remote = parse_git_remote(remote).unwrap();
75+
insta::assert_debug_snapshot!(git_remote, @r###"
76+
GitRemote {
77+
domain: "gitlab.com",
78+
owner: "codspeed",
79+
repository: "runner",
80+
}
81+
"###);
82+
83+
let remote = "https://gitlab.com/codspeed/runner.git";
84+
let git_remote = parse_git_remote(remote).unwrap();
85+
insta::assert_debug_snapshot!(git_remote, @r###"
86+
GitRemote {
87+
domain: "gitlab.com",
88+
owner: "codspeed",
89+
repository: "runner",
90+
}
91+
"###);
92+
}
93+
}

0 commit comments

Comments
 (0)