From bb930461cee056de210816e58c36a8d6dfd122be Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 25 Feb 2020 15:18:31 -0500 Subject: [PATCH] subcmds: stop instantiating at import time The current subcmds design has singletons in all_commands. This isn't exactly unusual, but the fact that our main & help subcommand will then attach members to the classes before invoking them is. This makes it hard to keep track of what members a command has access to, and the two code paths (main & help) attach different members depending on what APIs they then invoke. Lets pull this back a step by storing classes in all_commands and leave the instantiation step to when they're used. This doesn't fully clean up the confusion, but gets us closer. Change-Id: I6a768ff97fe541e6f3228358dba04ed66c4b070a Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/259154 Tested-by: Mike Frysinger Reviewed-by: David Pursehouse --- main.py | 2 +- subcmds/__init__.py | 3 ++- subcmds/help.py | 6 +++--- subcmds/version.py | 6 +++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index b309fad3..1393b400 100755 --- a/main.py +++ b/main.py @@ -204,7 +204,7 @@ class _Repo(object): SetDefaultColoring(gopts.color) try: - cmd = self.commands[name] + cmd = self.commands[name]() except KeyError: print("repo: '%s' is not a repo command. See 'repo help'." % name, file=sys.stderr) diff --git a/subcmds/__init__.py b/subcmds/__init__.py index a49e7bd3..c3de9d1e 100644 --- a/subcmds/__init__.py +++ b/subcmds/__init__.py @@ -16,6 +16,7 @@ import os +# A mapping of the subcommand name to the class that implements it. all_commands = {} my_dir = os.path.dirname(__file__) @@ -37,7 +38,7 @@ for py in os.listdir(my_dir): ['%s' % name]) mod = getattr(mod, name) try: - cmd = getattr(mod, clsn)() + cmd = getattr(mod, clsn) except AttributeError: raise SyntaxError('%s/%s does not define class %s' % ( __name__, py, clsn)) diff --git a/subcmds/help.py b/subcmds/help.py index 5e24ed0b..1e16019a 100644 --- a/subcmds/help.py +++ b/subcmds/help.py @@ -43,7 +43,7 @@ Displays detailed usage information about a command. fmt = ' %%-%ds %%s' % maxlen for name in commandNames: - command = all_commands[name] + command = all_commands[name]() try: summary = command.helpSummary.strip() except AttributeError: @@ -134,7 +134,7 @@ Displays detailed usage information about a command. def _PrintAllCommandHelp(self): for name in sorted(all_commands): - cmd = all_commands[name] + cmd = all_commands[name]() cmd.manifest = self.manifest self._PrintCommandHelp(cmd, header_prefix='[%s] ' % (name,)) @@ -159,7 +159,7 @@ Displays detailed usage information about a command. name = args[0] try: - cmd = all_commands[name] + cmd = all_commands[name]() except KeyError: print("repo: '%s' is not a repo command." % name, file=sys.stderr) sys.exit(1) diff --git a/subcmds/version.py b/subcmds/version.py index 91dbe68f..8721bf49 100644 --- a/subcmds/version.py +++ b/subcmds/version.py @@ -44,9 +44,9 @@ class Version(Command, MirrorSafeCommand): print('repo version %s' % rp_ver) print(' (from %s)' % rem.url) - if Version.wrapper_path is not None: - print('repo launcher version %s' % Version.wrapper_version) - print(' (from %s)' % Version.wrapper_path) + if self.wrapper_path is not None: + print('repo launcher version %s' % self.wrapper_version) + print(' (from %s)' % self.wrapper_path) if src_ver != rp_ver: print(' (currently at %s)' % src_ver)