diff --git a/main.py b/main.py index 2422e8be..06cd1108 100755 --- a/main.py +++ b/main.py @@ -26,6 +26,7 @@ import getpass import netrc import optparse import os +import shlex import sys import textwrap import time @@ -48,7 +49,7 @@ from color import SetDefaultColoring import event_log from repo_trace import SetTrace from git_command import user_agent -from git_config import init_ssh, close_ssh +from git_config import init_ssh, close_ssh, RepoConfig from command import InteractiveCommand from command import MirrorSafeCommand from command import GitcAvailableCommand, GitcClientCommand @@ -155,6 +156,9 @@ class _Repo(object): argv = [] gopts, _gargs = global_options.parse_args(glob) + name, alias_args = self._ExpandAlias(name) + argv = alias_args + argv + if gopts.help: global_options.print_help() commands = ' '.join(sorted(self.commands)) @@ -165,6 +169,27 @@ class _Repo(object): return (name, gopts, argv) + def _ExpandAlias(self, name): + """Look up user registered aliases.""" + # We don't resolve aliases for existing subcommands. This matches git. + if name in self.commands: + return name, [] + + key = 'alias.%s' % (name,) + alias = RepoConfig.ForRepository(self.repodir).GetString(key) + if alias is None: + alias = RepoConfig.ForUser().GetString(key) + if alias is None: + return name, [] + + args = alias.strip().split(' ', 1) + name = args[0] + if len(args) == 2: + args = shlex.split(args[1]) + else: + args = [] + return name, args + def _Run(self, name, gopts, argv): """Execute the requested subcommand.""" result = 0 diff --git a/repo b/repo index 77e80284..77a3f8d3 100755 --- a/repo +++ b/repo @@ -13,6 +13,7 @@ from __future__ import print_function import datetime import os import platform +import shlex import subprocess import sys @@ -693,6 +694,24 @@ def _SetConfig(cwd, name, value): run_git('config', name, value, cwd=cwd) +def _GetRepoConfig(name): + """Read a repo configuration option.""" + config = os.path.join(home_dot_repo, 'config') + if not os.path.exists(config): + return None + + cmd = ['config', '--file', config, '--get', name] + ret = run_git(*cmd, check=False) + if ret.returncode == 0: + return ret.stdout + elif ret.returncode == 1: + return None + else: + print('repo: error: git %s failed:\n%s' % (' '.join(cmd), ret.stderr), + file=sys.stderr) + raise RunError() + + def _InitHttp(): handlers = [] @@ -876,6 +895,25 @@ class _Options(object): version = False +def _ExpandAlias(name): + """Look up user registered aliases.""" + # We don't resolve aliases for existing subcommands. This matches git. + if name in {'gitc-init', 'help', 'init'}: + return name, [] + + alias = _GetRepoConfig('alias.%s' % (name,)) + if alias is None: + return name, [] + + args = alias.strip().split(' ', 1) + name = args[0] + if len(args) == 2: + args = shlex.split(args[1]) + else: + args = [] + return name, args + + def _ParseArguments(args): cmd = None opt = _Options() @@ -1004,6 +1042,11 @@ def main(orig_args): file=sys.stderr) sys.exit(1) if not repo_main: + # Only expand aliases here since we'll be parsing the CLI ourselves. + # If we had repo_main, alias expansion would happen in main.py. + cmd, alias_args = _ExpandAlias(cmd) + args = alias_args + args + if opt.help: _Usage() if cmd == 'help':