98 lines
2.6 KiB
Python
Executable File
98 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
from dataclasses import dataclass
|
|
import re
|
|
import subprocess
|
|
|
|
REMOTE_TYPES = [
|
|
{
|
|
# github
|
|
"match": re.compile(r'git@github.com:(?P<username>[\w\.-]+)/(?P<project>[\w\.-]+).git'),
|
|
"format-branch": lambda g: f"https://github.com/{g.username}/{g.project}/tree/{g.branch}/",
|
|
"format-commit": lambda g: f"https://github.com/{g.username}/{g.project}/commit/{g.commit}/",
|
|
},
|
|
{
|
|
# gitea
|
|
"match": re.compile(r'(?P<gituser>[\w\.-]+)@(?P<host>[\w\.-]+):(?P<username>[\w\.-]+)/(?P<project>[\w\.-]+).git'),
|
|
"format-branch": lambda g: f"https://{g.host}/{g.username}/{g.project}/src/branch/{g.branch}/",
|
|
"format-commit": lambda g: f"https://{g.host}/{g.username}/{g.project}/commit/{g.commit}/",
|
|
},
|
|
]
|
|
|
|
@dataclass
|
|
class FormatArgs:
|
|
gituser: str = None
|
|
host: str = None
|
|
username: str = None
|
|
project: str = None
|
|
commit: str = None
|
|
branch: str = None
|
|
|
|
def get_remote_branch():
|
|
s = subprocess.run(["git", "status", "--porcelain", "-uno", "-b", "--no-ahead-behind"], capture_output=True, text=True)
|
|
|
|
git_status_branch_info = s.stdout.splitlines()[0][3:].split()[0]
|
|
|
|
branches = git_status_branch_info.split("...")
|
|
|
|
if len(branches) != 2:
|
|
raise Exception("no branch name found")
|
|
|
|
local_branch, remote_branch = branches
|
|
|
|
remote, branch = remote_branch.split("/")
|
|
|
|
return {
|
|
"remote": remote,
|
|
"branch": branch,
|
|
}
|
|
|
|
def get_remote_url(remote):
|
|
s = subprocess.run(["git", "remote", "get-url", remote], capture_output=True, text=True)
|
|
|
|
remote_url = s.stdout.strip()
|
|
|
|
return remote_url
|
|
|
|
def get_last_commit():
|
|
s = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True)
|
|
|
|
commit = s.stdout.strip()
|
|
|
|
return commit
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
prog='git-show-link',
|
|
)
|
|
|
|
parser.add_argument("--branch", dest="display_branch", action='store_true', help="Display link to branch, instead to commit")
|
|
|
|
args = parser.parse_args()
|
|
|
|
r = get_remote_branch()
|
|
|
|
remote_url = get_remote_url(r["remote"])
|
|
|
|
for remote_type in REMOTE_TYPES:
|
|
m = remote_type["match"].match(remote_url)
|
|
|
|
if m is None:
|
|
continue
|
|
|
|
g = FormatArgs(**m.groupdict())
|
|
|
|
if args.display_branch:
|
|
g.branch = r["branch"]
|
|
print(remote_type["format-branch"](g))
|
|
else:
|
|
commit = get_last_commit()
|
|
g.commit = commit
|
|
print(remote_type["format-commit"](g))
|
|
break
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|