-
Notifications
You must be signed in to change notification settings - Fork 1
/
ghw
executable file
·168 lines (135 loc) · 4.13 KB
/
ghw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python3
"""Get to GitHub really fast!
A simple command line interface to open GitHub repositories in a
web browser without ever leaving the terminal.
"""
import argparse
import subprocess
import sys
from pathlib import Path
from typing import Optional
DOTFILES_DIR = Path(Path.home(), ".dotfiles", "zfunc")
sys.path.insert(0, str(DOTFILES_DIR))
from gitUtils import get_git_username
VERSION = "0.1.0"
GITHUB_USERNAME = get_git_username()
# Templates for URL completion
URL_TEMPLATE = "https://github.com/{username}/{repo}/tree/{branch}"
GH_BASE = "https://github.com/{path}"
def open_url(url: str) -> None:
"""Use xdg-open to open a URL in the default browser."""
subprocess.Popen(
["xdg-open", f"{url}"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
def ssh_to_https(ssh_url: str) -> str:
"""Convert ssh remote scheme to https."""
if "@" not in ssh_url:
return ssh_url
url = ssh_url.split("@")[1]
url = url.replace(":", "/")
url = f"https://{url}"
return url
def get_current_branch() -> Optional[str]:
"""Get the branch of the current git repo.
Uses a external call to a subprocess to grab the
branch of the current git repository.
Returns:
branch: str name of branch
None: failed to get a branch name
"""
branch_name = subprocess.run(
["git", "branch", "--show-current"],
capture_output=True,
)
if branch_name.stderr:
return None
return branch_name.stdout.decode().strip()
def get_remote_url(name: Optional[str] = None, branch_name: Optional[str] = None):
"""Convert name of repo to URL
Converts either, the name of the repo, or the remote URL to a GitHub URL.
Args:
name: Optionally, get the URL of a GitHub repo from its name
branch_name: Optionally, get the URL to the specific branch of a repo
Returns:
str: URL to repository
Raises:
None
"""
# Get the right branch name, default to master.
if not name:
# Try and grab current git repo.
# If there isn't one, just open profile.
url = (
subprocess.run(
["git", "config", "--get", "remote.origin.url"],
capture_output=True,
)
.stdout.decode()
.strip()
)
# Cleanup output
if url == "":
return GH_BASE.format(path=GITHUB_USERNAME)
elif url.endswith(".git"):
url = url[:-4]
# Ensure URL is in proper HTTPS schema.
url = ssh_to_https(url)
branch_name = branch_name or get_current_branch()
else:
url = GH_BASE.format(path=f"{GITHUB_USERNAME}/{name}")
if branch_name:
url = f"{url}/tree/{branch_name}"
return url
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=__doc__,
)
group = parser.add_mutually_exclusive_group()
parser.add_argument(
"-v",
"--version",
action="version",
version=f"%(prog)s {VERSION}",
)
parser.add_argument(
"-d",
"--dry-run",
action="store_true",
help="Just print the external URL.",
)
# Ensure you can't provide a qualified name and repo name simultaneously.
group.add_argument(
"repo",
nargs="?",
action="store",
metavar="NAME",
help="Name of repository to navigate to.",
)
group.add_argument(
"-q",
"--qualified",
action="store",
metavar="USER/REPO",
help="Qualified name to navigate to",
)
parser.add_argument(
"-b",
"--branch",
action="store",
metavar="BRANCH",
help="Branch of repository to navigate to.",
)
args = vars(parser.parse_args())
if args["qualified"]:
url = GH_BASE.format(path=args["qualified"])
if args["branch"]:
url = f"{url}/tree/{args['branch']}"
else:
url = get_remote_url(args["repo"], args["branch"])
if args["dry_run"]:
print(url)
else:
open_url(url)