command: make --verbose/--quiet available to all subcommands
Add new CommonOptions entry points to move the existing --jobs to,
and relocate all --verbose/--quiet options to that. This provides
both a consistent interface for users as well as for code.
Change-Id: Ifaf83b88872421f4749b073c472b4a67ca6c0437
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/303224
Reviewed-by: Raman Tenneti <rtenneti@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
diff --git a/command.py b/command.py
index f708832..be2d6a6 100644
--- a/command.py
+++ b/command.py
@@ -84,18 +84,34 @@
usage = 'repo %s' % self.NAME
epilog = 'Run `repo help %s` to view the detailed manual.' % self.NAME
self._optparse = optparse.OptionParser(usage=usage, epilog=epilog)
+ self._CommonOptions(self._optparse)
self._Options(self._optparse)
return self._optparse
- def _Options(self, p):
- """Initialize the option parser.
+ def _CommonOptions(self, p, opt_v=True):
+ """Initialize the option parser with common options.
+
+ These will show up for *all* subcommands, so use sparingly.
+ NB: Keep in sync with repo:InitParser().
"""
+ g = p.add_option_group('Logging options')
+ opts = ['-v'] if opt_v else []
+ g.add_option(*opts, '--verbose',
+ dest='output_mode', action='store_true',
+ help='show all output')
+ g.add_option('-q', '--quiet',
+ dest='output_mode', action='store_false',
+ help='only show errors')
+
if self.PARALLEL_JOBS is not None:
p.add_option(
'-j', '--jobs',
type=int, default=self.PARALLEL_JOBS,
help='number of jobs to run in parallel (default: %s)' % self.PARALLEL_JOBS)
+ def _Options(self, p):
+ """Initialize the option parser with subcommand-specific options."""
+
def _RegisteredEnvironmentOptions(self):
"""Get options that can be set from environment variables.
@@ -120,6 +136,11 @@
self.OptionParser.print_usage()
sys.exit(1)
+ def CommonValidateOptions(self, opt, args):
+ """Validate common options."""
+ opt.quiet = opt.output_mode is False
+ opt.verbose = opt.output_mode is True
+
def ValidateOptions(self, opt, args):
"""Validate the user options & arguments before executing.
diff --git a/main.py b/main.py
index 9abda6a..8aba2ec 100755
--- a/main.py
+++ b/main.py
@@ -257,6 +257,7 @@
git_trace2_event_log.CommandEvent(name='repo', subcommands=[name])
try:
+ cmd.CommonValidateOptions(copts, cargs)
cmd.ValidateOptions(copts, cargs)
result = cmd.Execute(copts, cargs)
except (DownloadError, ManifestInvalidRevisionError,
diff --git a/repo b/repo
index 604f800..cf9f186 100755
--- a/repo
+++ b/repo
@@ -281,6 +281,8 @@
def InitParser(parser, gitc_init=False):
"""Setup the CLI parser."""
+ # NB: Keep in sync with command.py:_CommonOptions().
+
# Logging.
group = parser.add_option_group('Logging options')
group.add_option('-v', '--verbose',
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index b82a2db..ea3f4ed 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -37,10 +37,6 @@
PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
def _Options(self, p):
- super()._Options(p)
- p.add_option('-q', '--quiet',
- action='store_true', default=False,
- help='be quiet')
p.add_option('--all',
dest='all', action='store_true',
help='delete all branches in all projects')
diff --git a/subcmds/cherry_pick.py b/subcmds/cherry_pick.py
index 4b7f141..fc4998c 100644
--- a/subcmds/cherry_pick.py
+++ b/subcmds/cherry_pick.py
@@ -32,9 +32,6 @@
change id will be added.
"""
- def _Options(self, p):
- pass
-
def ValidateOptions(self, opt, args):
if len(args) != 1:
self.Usage()
diff --git a/subcmds/diff.py b/subcmds/diff.py
index 8186817..cdc262e 100644
--- a/subcmds/diff.py
+++ b/subcmds/diff.py
@@ -32,7 +32,6 @@
PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
def _Options(self, p):
- super()._Options(p)
p.add_option('-u', '--absolute',
dest='absolute', action='store_true',
help='Paths are relative to the repository root')
diff --git a/subcmds/forall.py b/subcmds/forall.py
index f0ce97c..4a631fb 100644
--- a/subcmds/forall.py
+++ b/subcmds/forall.py
@@ -129,8 +129,6 @@
del parser.rargs[0]
def _Options(self, p):
- super()._Options(p)
-
p.add_option('-r', '--regex',
dest='regex', action='store_true',
help="Execute the command only on projects matching regex or wildcard expression")
@@ -153,13 +151,10 @@
help='Silently skip & do not exit non-zero due missing '
'checkouts')
- g = p.add_option_group('Output')
+ g = p.get_option_group('--quiet')
g.add_option('-p',
dest='project_header', action='store_true',
help='Show project headers before output')
- g.add_option('-v', '--verbose',
- dest='verbose', action='store_true',
- help='Show command error messages')
p.add_option('--interactive',
action='store_true',
help='force interactive usage')
diff --git a/subcmds/grep.py b/subcmds/grep.py
index 49feaf6..9a4a8a3 100644
--- a/subcmds/grep.py
+++ b/subcmds/grep.py
@@ -82,8 +82,11 @@
if value is not None:
pt.append(value)
+ def _CommonOptions(self, p):
+ """Override common options slightly."""
+ super()._CommonOptions(p, opt_v=False)
+
def _Options(self, p):
- super()._Options(p)
g = p.add_option_group('Sources')
g.add_option('--cached',
action='callback', callback=self._carry_option,
diff --git a/subcmds/init.py b/subcmds/init.py
index a23e529..4182262 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -79,6 +79,9 @@
to update the working directory files.
"""
+ def _CommonOptions(self, p):
+ """Disable due to re-use of Wrapper()."""
+
def _Options(self, p, gitc_init=False):
Wrapper().InitParser(p, gitc_init=gitc_init)
@@ -436,9 +439,6 @@
% ('.'.join(str(x) for x in MIN_GIT_VERSION_SOFT),),
file=sys.stderr)
- opt.quiet = opt.output_mode is False
- opt.verbose = opt.output_mode is True
-
rp = self.manifest.repoProject
# Handle new --repo-url requests.
diff --git a/subcmds/rebase.py b/subcmds/rebase.py
index cf536e9..e0186d4 100644
--- a/subcmds/rebase.py
+++ b/subcmds/rebase.py
@@ -39,7 +39,8 @@
"""
def _Options(self, p):
- p.add_option('-i', '--interactive',
+ g = p.get_option_group('--quiet')
+ g.add_option('-i', '--interactive',
dest="interactive", action="store_true",
help="interactive rebase (single project only)")
@@ -52,9 +53,6 @@
p.add_option('--no-ff',
dest='ff', default=True, action='store_false',
help='Pass --no-ff to git rebase')
- p.add_option('-q', '--quiet',
- dest='quiet', action='store_true',
- help='Pass --quiet to git rebase')
p.add_option('--autosquash',
dest='autosquash', action='store_true',
help='Pass --autosquash to git rebase')
diff --git a/subcmds/stage.py b/subcmds/stage.py
index 98b3022..ff0f173 100644
--- a/subcmds/stage.py
+++ b/subcmds/stage.py
@@ -38,7 +38,8 @@
"""
def _Options(self, p):
- p.add_option('-i', '--interactive',
+ g = p.get_option_group('--quiet')
+ g.add_option('-i', '--interactive',
dest='interactive', action='store_true',
help='use interactive staging')
diff --git a/subcmds/start.py b/subcmds/start.py
index 04589fb..2593ace 100644
--- a/subcmds/start.py
+++ b/subcmds/start.py
@@ -38,7 +38,6 @@
PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
def _Options(self, p):
- super()._Options(p)
p.add_option('--all',
dest='all', action='store_true',
help='begin branch in all projects')
diff --git a/subcmds/status.py b/subcmds/status.py
index 6c8e22e..dc223a0 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -80,12 +80,9 @@
PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
def _Options(self, p):
- super()._Options(p)
p.add_option('-o', '--orphans',
dest='orphans', action='store_true',
help="include objects in working directory outside of repo projects")
- p.add_option('-q', '--quiet', action='store_true',
- help="only print the name of modified projects")
def _StatusHelper(self, quiet, project):
"""Obtains the status for a specific project.
diff --git a/subcmds/sync.py b/subcmds/sync.py
index b8abb1a..e707987 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -167,13 +167,14 @@
"""
PARALLEL_JOBS = 1
- def _Options(self, p, show_smart=True):
+ def _CommonOptions(self, p):
try:
self.PARALLEL_JOBS = self.manifest.default.sync_j
except ManifestParseError:
pass
- super()._Options(p)
+ super()._CommonOptions(p)
+ def _Options(self, p, show_smart=True):
p.add_option('--jobs-network', default=None, type=int, metavar='JOBS',
help='number of network jobs to run in parallel (defaults to --jobs)')
p.add_option('--jobs-checkout', default=None, type=int, metavar='JOBS',
@@ -211,12 +212,6 @@
p.add_option('-c', '--current-branch',
dest='current_branch_only', action='store_true',
help='fetch only current branch from server')
- p.add_option('-v', '--verbose',
- dest='output_mode', action='store_true',
- help='show all sync output')
- p.add_option('-q', '--quiet',
- dest='output_mode', action='store_false',
- help='only show errors')
p.add_option('-m', '--manifest-name',
dest='manifest_name',
help='temporary manifest to use for this sync', metavar='NAME.xml')
@@ -770,9 +765,6 @@
soft_limit, _ = _rlimit_nofile()
self.jobs = min(self.jobs, (soft_limit - 5) // 3)
- opt.quiet = opt.output_mode is False
- opt.verbose = opt.output_mode is True
-
if opt.manifest_name:
self.manifest.Override(opt.manifest_name)