Support Sourcehut & Codeberg in permalinks (#8616)
Updates #5110 Release Notes: - Added support for repositories hosted on `git.sr.ht` (Sourcehut) and `codeberg.org` to the `editor: copy permalink to line` and `editor: open permalink to line` actions ([#5110](https://github.com/zed-industries/zed/issues/5110)). --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
parent
faa6f979be
commit
db9cc42245
1 changed files with 227 additions and 3 deletions
|
@ -9,6 +9,8 @@ enum GitHostingProvider {
|
||||||
Gitlab,
|
Gitlab,
|
||||||
Gitee,
|
Gitee,
|
||||||
Bitbucket,
|
Bitbucket,
|
||||||
|
Sourcehut,
|
||||||
|
Codeberg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GitHostingProvider {
|
impl GitHostingProvider {
|
||||||
|
@ -18,6 +20,8 @@ impl GitHostingProvider {
|
||||||
Self::Gitlab => "https://gitlab.com",
|
Self::Gitlab => "https://gitlab.com",
|
||||||
Self::Gitee => "https://gitee.com",
|
Self::Gitee => "https://gitee.com",
|
||||||
Self::Bitbucket => "https://bitbucket.org",
|
Self::Bitbucket => "https://bitbucket.org",
|
||||||
|
Self::Sourcehut => "https://git.sr.ht",
|
||||||
|
Self::Codeberg => "https://codeberg.org",
|
||||||
};
|
};
|
||||||
|
|
||||||
Url::parse(&base_url).unwrap()
|
Url::parse(&base_url).unwrap()
|
||||||
|
@ -30,7 +34,9 @@ impl GitHostingProvider {
|
||||||
let line = selection.start.row + 1;
|
let line = selection.start.row + 1;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Github | Self::Gitlab | Self::Gitee => format!("L{}", line),
|
Self::Github | Self::Gitlab | Self::Gitee | Self::Sourcehut | Self::Codeberg => {
|
||||||
|
format!("L{}", line)
|
||||||
|
}
|
||||||
Self::Bitbucket => format!("lines-{}", line),
|
Self::Bitbucket => format!("lines-{}", line),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,8 +44,10 @@ impl GitHostingProvider {
|
||||||
let end_line = selection.end.row + 1;
|
let end_line = selection.end.row + 1;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Github => format!("L{}-L{}", start_line, end_line),
|
Self::Github | Self::Codeberg => format!("L{}-L{}", start_line, end_line),
|
||||||
Self::Gitlab | Self::Gitee => format!("L{}-{}", start_line, end_line),
|
Self::Gitlab | Self::Gitee | Self::Sourcehut => {
|
||||||
|
format!("L{}-{}", start_line, end_line)
|
||||||
|
}
|
||||||
Self::Bitbucket => format!("lines-{}:{}", start_line, end_line),
|
Self::Bitbucket => format!("lines-{}:{}", start_line, end_line),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +81,8 @@ pub fn build_permalink(params: BuildPermalinkParams) -> Result<Url> {
|
||||||
GitHostingProvider::Gitlab => format!("{owner}/{repo}/-/blob/{sha}/{path}"),
|
GitHostingProvider::Gitlab => format!("{owner}/{repo}/-/blob/{sha}/{path}"),
|
||||||
GitHostingProvider::Gitee => format!("{owner}/{repo}/blob/{sha}/{path}"),
|
GitHostingProvider::Gitee => format!("{owner}/{repo}/blob/{sha}/{path}"),
|
||||||
GitHostingProvider::Bitbucket => format!("{owner}/{repo}/src/{sha}/{path}"),
|
GitHostingProvider::Bitbucket => format!("{owner}/{repo}/src/{sha}/{path}"),
|
||||||
|
GitHostingProvider::Sourcehut => format!("~{owner}/{repo}/tree/{sha}/item/{path}"),
|
||||||
|
GitHostingProvider::Codeberg => format!("{owner}/{repo}/src/commit/{sha}/{path}"),
|
||||||
};
|
};
|
||||||
let line_fragment = selection.map(|selection| provider.line_fragment(&selection));
|
let line_fragment = selection.map(|selection| provider.line_fragment(&selection));
|
||||||
|
|
||||||
|
@ -148,6 +158,38 @@ fn parse_git_remote_url(url: &str) -> Option<ParsedGitRemote> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if url.starts_with("git@git.sr.ht:") || url.starts_with("https://git.sr.ht/") {
|
||||||
|
// sourcehut indicates a repo with '.git' suffix as a separate repo.
|
||||||
|
// For example, "git@git.sr.ht:~username/repo" and "git@git.sr.ht:~username/repo.git"
|
||||||
|
// are two distinct repositories.
|
||||||
|
let repo_with_owner = url
|
||||||
|
.trim_start_matches("git@git.sr.ht:~")
|
||||||
|
.trim_start_matches("https://git.sr.ht/~");
|
||||||
|
|
||||||
|
let (owner, repo) = repo_with_owner.split_once("/")?;
|
||||||
|
|
||||||
|
return Some(ParsedGitRemote {
|
||||||
|
provider: GitHostingProvider::Sourcehut,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if url.starts_with("git@codeberg.org:") || url.starts_with("https://codeberg.org/") {
|
||||||
|
let repo_with_owner = url
|
||||||
|
.trim_start_matches("git@codeberg.org:")
|
||||||
|
.trim_start_matches("https://codeberg.org/")
|
||||||
|
.trim_end_matches(".git");
|
||||||
|
|
||||||
|
let (owner, repo) = repo_with_owner.split_once("/")?;
|
||||||
|
|
||||||
|
return Some(ParsedGitRemote {
|
||||||
|
provider: GitHostingProvider::Codeberg,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,4 +518,186 @@ mod tests {
|
||||||
"https://bitbucket.org/thorstenzed/testingrepo/src/f00b4r/main.rs#lines-24:48";
|
"https://bitbucket.org/thorstenzed/testingrepo/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_build_sourcehut_permalink_from_ssh_url() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@git.sr.ht:~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_ssh_url_with_git_prefix() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@git.sr.ht:~rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed.git/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_ssh_url_single_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@git.sr.ht:~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: Some(Point::new(6, 1)..Point::new(6, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs#L7";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_ssh_url_multi_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@git.sr.ht:~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: Some(Point::new(23, 1)..Point::new(47, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs#L24-48";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_https_url() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://git.sr.ht/~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_https_url_single_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://git.sr.ht/~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: Some(Point::new(6, 1)..Point::new(6, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs#L7";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_sourcehut_permalink_from_https_url_multi_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://git.sr.ht/~rajveermalviya/zed",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: Some(Point::new(23, 1)..Point::new(47, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs#L24-48";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_ssh_url() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@codeberg.org:rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/editor/src/git/permalink.rs";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_ssh_url_single_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@codeberg.org:rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: Some(Point::new(6, 1)..Point::new(6, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/editor/src/git/permalink.rs#L7";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_ssh_url_multi_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "git@codeberg.org:rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/editor/src/git/permalink.rs",
|
||||||
|
selection: Some(Point::new(23, 1)..Point::new(47, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/editor/src/git/permalink.rs#L24-L48";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_https_url() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://codeberg.org/rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/zed/src/main.rs";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_https_url_single_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://codeberg.org/rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: Some(Point::new(6, 1)..Point::new(6, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/zed/src/main.rs#L7";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_codeberg_permalink_from_https_url_multi_line_selection() {
|
||||||
|
let permalink = build_permalink(BuildPermalinkParams {
|
||||||
|
remote_url: "https://codeberg.org/rajveermalviya/zed.git",
|
||||||
|
sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
|
||||||
|
path: "crates/zed/src/main.rs",
|
||||||
|
selection: Some(Point::new(23, 1)..Point::new(47, 10)),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_url = "https://codeberg.org/rajveermalviya/zed/src/commit/faa6f979be417239b2e070dbbf6392b909224e0b/crates/zed/src/main.rs#L24-L48";
|
||||||
|
assert_eq!(permalink.to_string(), expected_url.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue