diff --git a/git-open b/git-open index ee5e2a1faf4b7465c348e0e9fe9bff20e3f541e8..31457e82e4caf6eaa3d7e16fb44f460380673d8f 100755 --- a/git-open +++ b/git-open @@ -3,6 +3,31 @@ import sys import subprocess import argparse +import re +import os.path +try: + # package python-pyxdg on Arch + from xdg.BaseDirectory import xdg_config_dirs +except ModuleNotFoundError: + print("xdg module not found, defaulting to $HOME/.config", file=sys.stderr) + import os + home = os.getenv("HOME") + xdg_config_dirs = [os.path.join(home, ".config")] + +can_load_configuration = False +try: + # package python-yaml on Arch + import yaml + can_load_configuration = True +except ModuleNotFoundError: + print("yaml module not found, configuration will NOT be loaded", + file=sys.stderr) + + +configuration = { + # a list of dictionaries, each containing the keys 'i' and 'o' + 'patterns': [] +} def popen(str): @@ -23,17 +48,26 @@ def remote_url(remote_name): return popen(f'git remote get-url {remote_name}').strip() def to_http(url): + for pattern in configuration['patterns']: + if match := re.match(pattern['i'], url): + rx = re.compile('[$]([0-9]+)') + on = list(pattern['o']) + for m in reversed(list(rx.finditer(pattern['o']))): + try: + on[m.start():m.end()] = match[int(m[1])] + except ValueError as e: + print('All output patterns must be numbers') + # TODO fail catastrophically instead of + # re-raising + raise e + return ''.join(on) + if url[0:4] == "http": - if "aur.archlinux.org" in url: - parts = url.split('/') - return '/'.join(parts[0:-1] + ['packages'] + [parts[-1]]) - else: - return url + return url if url[0:4] == "git@": base, path = url[4:].split(":") return "https://" + base + "/" + path raise Exception("URL doesn't start with either 'http' or 'git@'") - # return "http://www.nicememe.website" def xdg_open(item): subprocess.run(["xdg-open", item]) @@ -83,6 +117,18 @@ def main(args): else: err("All remotes failed") +def load_configuration(): + global configuration + # TODO possibly add ~/.config/git/open.yaml to list + for dir in xdg_config_dirs: + try: + with open(os.path.join(dir, 'git-open.yaml')) as f: + conf = yaml.unsafe_load(f) + configuration |= conf + break + except FileNotFoundError: + pass + if __name__ == "__main__": # Note that argparse gives `--help' and `-h', but git "eats" # `--help'. `-h' does however work. @@ -90,5 +136,9 @@ if __name__ == "__main__": parser.add_argument('-n', '--dry-run', action='store_true', dest='dry_run') parser.add_argument('remote', action='store', nargs='?') args = parser.parse_args() + + if can_load_configuration: + load_configuration() + main(args)