main/repo: add support for subcommand aliases
This supports [alias] sections with repo subcommands just like git.
Change-Id: Ie9235b5d4449414e6a745814f0110bd6af74ea93
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/255833
Reviewed-by: David Pursehouse <dpursehouse@collab.net>
Tested-by: Mike Frysinger <vapier@google.com>
diff --git a/main.py b/main.py
index 2422e8b..06cd110 100755
--- a/main.py
+++ b/main.py
@@ -26,6 +26,7 @@
import netrc
import optparse
import os
+import shlex
import sys
import textwrap
import time
@@ -48,7 +49,7 @@
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 @@
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 @@
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 77e8028..77a3f8d 100755
--- a/repo
+++ b/repo
@@ -13,6 +13,7 @@
import datetime
import os
import platform
+import shlex
import subprocess
import sys
@@ -693,6 +694,24 @@
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 @@
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 @@
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':