summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChinmay Dalal <dalal.chinmay.0101@gmail.com>2022-09-15 01:09:23 +0530
committerGitHub <noreply@github.com>2022-09-14 15:39:23 -0400
commitd16ed23e73b396353e85104ed2122a90940e515d (patch)
tree3afe3e1df70b6cc5842b3e3a3ecc4832085cbc78
parentcc0f1dd9681d497fff1e12b5b94eabe0cf68b19f (diff)
Add sourcehut link parsing (#1190)
* Add sourcehut link parsing * refactor: GitRemoteRepo::GitHubRepo -> ..::GitHub, repo_slug -> slug https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names * readme.md: change bitbucket to sourcehut
-rw-r--r--README.md4
-rw-r--r--src/git_config/git_config_entry.rs97
2 files changed, 80 insertions, 21 deletions
diff --git a/README.md b/README.md
index 6ac1a819..07160e4a 100644
--- a/README.md
+++ b/README.md
@@ -47,12 +47,12 @@ Delta has many features and is very customizable; please see the [user manual](h
- Line numbering
- `n` and `N` keybindings to move between files in large diffs, and between diffs in `log -p` views (`--navigate`)
- Improved merge conflict display
-- Improved `git blame` display (syntax highlighting; `--hyperlinks` formats commits as links to GitHub/GitLab/Bitbucket etc)
+- Improved `git blame` display (syntax highlighting; `--hyperlinks` formats commits as links to GitHub/GitLab/SourceHut etc)
- Syntax-highlights grep output from `rg`, `git grep`, `grep`, etc
- Support for Git's `--color-moved` feature.
- Code can be copied directly from the diff (`-/+` markers are removed by default).
- `diff-highlight` and `diff-so-fancy` emulation modes
-- Commit hashes can be formatted as terminal [hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) to the GitHub/GitLab/Bitbucket page (`--hyperlinks`).
+- Commit hashes can be formatted as terminal [hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) to the GitHub/GitLab/SourceHut page (`--hyperlinks`).
File paths can also be formatted as hyperlinks for opening in your OS.
- Stylable box/line decorations to draw attention to commit, file and hunk header sections.
- Style strings (foreground color, background color, font attributes) are supported for >20 stylable elements, using the same color/style language as git
diff --git a/src/git_config/git_config_entry.rs b/src/git_config/git_config_entry.rs
index 66a9f840..56dcc1c2 100644
--- a/src/git_config/git_config_entry.rs
+++ b/src/git_config/git_config_entry.rs
@@ -14,18 +14,22 @@ pub enum GitConfigEntry {
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GitRemoteRepo {
- GitHubRepo { repo_slug: String },
- GitLabRepo { repo_slug: String },
+ GitHub { slug: String },
+ GitLab { slug: String },
+ SourceHut { slug: String },
}
impl GitRemoteRepo {
pub fn format_commit_url(&self, commit: &str) -> String {
match self {
- Self::GitHubRepo { repo_slug } => {
- format!("https://github.com/{}/commit/{}", repo_slug, commit)
+ Self::GitHub { slug } => {
+ format!("https://github.com/{}/commit/{}", slug, commit)
}
- Self::GitLabRepo { repo_slug } => {
- format!("https://gitlab.com/{}/-/commit/{}", repo_slug, commit)
+ Self::GitLab { slug } => {
+ format!("https://gitlab.com/{}/-/commit/{}", slug, commit)
+ }
+ Self::SourceHut { slug } => {
+ format!("https://git.sr.ht/{}/commit/{}", slug, commit)
}
}
}
@@ -61,30 +65,51 @@ lazy_static! {
"
)
.unwrap();
+ static ref SOURCEHUT_REMOTE_URL: Regex = Regex::new(
+ r"(?x)
+ ^
+ (?:https://|git@)? # Support both HTTPS and SSH URLs, SSH URLs optionally omitting the git@
+ git\.sr\.ht
+ [:/] # This separator differs between SSH and HTTPS URLs
+ ~([^/]+) # Capture the username
+ /
+ (.+) # Capture the repo name
+ $
+ "
+ )
+ .unwrap();
}
impl FromStr for GitRemoteRepo {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(caps) = GITHUB_REMOTE_URL.captures(s) {
- Ok(Self::GitHubRepo {
- repo_slug: format!(
+ Ok(Self::GitHub {
+ slug: format!(
"{user}/{repo}",
user = caps.get(1).unwrap().as_str(),
repo = caps.get(2).unwrap().as_str()
),
})
} else if let Some(caps) = GITLAB_REMOTE_URL.captures(s) {
- Ok(Self::GitLabRepo {
- repo_slug: format!(
+ Ok(Self::GitLab {
+ slug: format!(
"{user}{groups}/{repo}",
user = caps.get(1).unwrap().as_str(),
groups = caps.get(2).map(|x| x.as_str()).unwrap_or_default(),
repo = caps.get(3).unwrap().as_str()
),
})
+ } else if let Some(caps) = SOURCEHUT_REMOTE_URL.captures(s) {
+ Ok(Self::SourceHut {
+ slug: format!(
+ "~{user}/{repo}",
+ user = caps.get(1).unwrap().as_str(),
+ repo = caps.get(2).unwrap().as_str()
+ ),
+ })
} else {
- Err("Not a GitHub or GitLab repo.".into())
+ Err("Not a GitHub, GitLab or SourceHut repo.".into())
}
}
}
@@ -108,8 +133,8 @@ mod tests {
assert!(parsed.is_ok());
assert_eq!(
parsed.unwrap(),
- GitRemoteRepo::GitHubRepo {
- repo_slug: "dandavison/delta".to_string()
+ GitRemoteRepo::GitHub {
+ slug: "dandavison/delta".to_string()
}
);
}
@@ -117,8 +142,8 @@ mod tests {
#[test]
fn test_format_github_commit_link() {
- let repo = GitRemoteRepo::GitHubRepo {
- repo_slug: "dandavison/delta".to_string(),
+ let repo = GitRemoteRepo::GitHub {
+ slug: "dandavison/delta".to_string(),
};
let commit_hash = "d3b07384d113edec49eaa6238ad5ff00";
assert_eq!(
@@ -153,8 +178,8 @@ mod tests {
assert!(parsed.is_ok());
assert_eq!(
parsed.unwrap(),
- GitRemoteRepo::GitLabRepo {
- repo_slug: expected.to_string()
+ GitRemoteRepo::GitLab {
+ slug: expected.to_string()
}
);
}
@@ -162,8 +187,8 @@ mod tests {
#[test]
fn test_format_gitlab_commit_link() {
- let repo = GitRemoteRepo::GitLabRepo {
- repo_slug: "proj/grp/repo".to_string(),
+ let repo = GitRemoteRepo::GitLab {
+ slug: "proj/grp/repo".to_string(),
};
let commit_hash = "d3b07384d113edec49eaa6238ad5ff00";
assert_eq!(
@@ -171,4 +196,38 @@ mod tests {
format!("https://gitlab.com/proj/grp/repo/-/commit/{}", commit_hash)
)
}
+
+ #[test]
+ fn test_parse_sourcehut_urls() {
+ let urls = &[
+ "https://git.sr.ht/~someuser/somerepo",
+ "git@git.sr.ht:~someuser/somerepo",
+ "git.sr.ht:~someuser/somerepo",
+ ];
+ for url in urls {
+ let parsed = GitRemoteRepo::from_str(url);
+ assert!(parsed.is_ok());
+ assert_eq!(
+ parsed.unwrap(),
+ GitRemoteRepo::SourceHut {
+ slug: "~someuser/somerepo".to_string()
+ }
+ );
+ }
+ }
+
+ #[test]
+ fn test_format_sourcehut_commit_link() {
+ let repo = GitRemoteRepo::SourceHut {
+ slug: "~someuser/somerepo".to_string(),
+ };
+ let commit_hash = "df41ac86f08a40e64c76062fd67e238522c14990";
+ assert_eq!(
+ repo.format_commit_url(commit_hash),
+ format!(
+ "https://git.sr.ht/~someuser/somerepo/commit/{}",
+ commit_hash
+ )
+ )
+ }
}