cros: speed up basic commandline parsing
Our current design imports all subcommand modules before doing anything.
As we add more modules, and the modules themselves get larger, this does
not scale well at all. As it stands now, doing nothing or just passing
in --help takes over 500msec.
The reason for this design was to enable flexibility: the name of the
module implementing a subcommand did not have to match the subcommand,
and we could put more than one subcommand in a module using decorators.
In practice, we've never used this functionality -- we've always had a
one-to-one matching between the module name & the subcommand it held.
Lets make this a hard requirement to regain performance. We no longer
have to import every single subcommand every time (and all their unique
but unused modules), we only have to import & execute the specific one
the user has requested.
This cuts the no-op time by half for `cros`, and shaves 300msec off all
`cros` command users run.
BUG=chromium:868820, chromium:1022507
TEST=`cros --help` is faster
TEST=`cros lint ...` still works
Change-Id: Icc1cc9493c12dae94f5459a027fca37cecfa0aef
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1903449
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Chris McDonald <cjmcdonald@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/cros_unittest.py b/scripts/cros_unittest.py
index 47f8d2a..85098e1 100644
--- a/scripts/cros_unittest.py
+++ b/scripts/cros_unittest.py
@@ -22,5 +22,12 @@
"""Test that the default log level is set to notice."""
arg_parser = self.PatchObject(commandline, 'ArgumentParser',
return_value=commandline.ArgumentParser())
- cros.GetOptions({})
- arg_parser.assert_called_with(caching=True, default_log_level='notice')
+ cros.GetOptions()
+ arg_parser.assert_called_with(caching=True, default_log_level='notice',
+ add_help=False)
+
+ def testSubcommand(self):
+ """Test parser when given a subcommand."""
+ parser = cros.GetOptions('lint')
+ opts = parser.parse_args(['lint'])
+ self.assertEqual(opts.subcommand, 'lint')