gsi_util: adding subcommand framework
With this CL, new command can be easily added:
1. Add a new file: gsi/gsi_util/gsi_util/commands/hello.py
And implements a function to register parsers into gsi_util's main parser.
def setup_command_args(subparsers)
2. In gsi/gsi_util/gsi_util.py, add the new command into GsiUtil():
_COMMANDS = ['hello']
Bug: 70588453
Test: make gsi_util
Test: gsi_util --help
Test: gsi_util hello --foo
Test: gsi_util --debug hello --bar
Change-Id: I54fa6d1dea5afed724d9ac4a99f88bf78da82732
diff --git a/gsi/gsi_util/Android.bp b/gsi/gsi_util/Android.bp
new file mode 100644
index 0000000..be7b569
--- /dev/null
+++ b/gsi/gsi_util/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+python_binary_host {
+ name: "gsi_util",
+ srcs: [
+ "gsi_util.py",
+ "gsi_util/*.py",
+ "gsi_util/commands/*.py",
+ ],
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+}
diff --git a/gsi/gsi_util/gsi_util.py b/gsi/gsi_util/gsi_util.py
new file mode 100755
index 0000000..d3cab52
--- /dev/null
+++ b/gsi/gsi_util/gsi_util.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+#
+# Copyright 2017 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""gsi_util command-line utility."""
+
+import argparse
+import logging
+import sys
+
+
+class GsiUtil(object):
+ """Object for gsi_util command line tool."""
+
+ _GSI_UTIL_VERSION = '1.0'
+
+ # Adds gsi_util COMMAND here.
+ # TODO(bowgotsai): auto collect from gsi_util/commands/*.py
+ _COMMANDS = ['hello']
+
+ _LOGGING_FORMAT = '%(message)s'
+ _LOGGING_LEVEL = logging.WARNING
+
+ @staticmethod
+ def _get_module_name(command):
+ return 'gsi_util.commands.' + command
+
+ def run(self, argv):
+ """Command-line processor."""
+
+ # Sets up default logging.
+ logging.basicConfig(format=self._LOGGING_FORMAT, level=self._LOGGING_LEVEL)
+
+ # Adds top-level --version/--debug argument.
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-v', '--version', action='version',
+ version='%(prog)s {}'.format(self._GSI_UTIL_VERSION))
+ parser.add_argument(
+ '-d', '--debug', help='debug mode.', action='store_true')
+
+ # Adds subparsers for each COMMAND.
+ subparsers = parser.add_subparsers(title='COMMAND')
+ for command in self._COMMANDS:
+ module_name = self._get_module_name(command)
+ mod = __import__(module_name, globals(), locals(), ['setup_command_args'])
+ mod.setup_command_args(subparsers)
+
+ args = parser.parse_args(argv[1:])
+ if args.debug:
+ logging.getLogger().setLevel(logging.DEBUG)
+
+ try:
+ args.func(args)
+ except Exception as e:
+ logging.error('%s: %s', argv[0], e.message)
+ logging.exception(e)
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ tool = GsiUtil()
+ tool.run(sys.argv)
diff --git a/gsi/gsi_util/gsi_util/__init__.py b/gsi/gsi_util/gsi_util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gsi/gsi_util/gsi_util/__init__.py
diff --git a/gsi/gsi_util/gsi_util/commands/__init__.py b/gsi/gsi_util/gsi_util/commands/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gsi/gsi_util/gsi_util/commands/__init__.py
diff --git a/gsi/gsi_util/gsi_util/commands/hello.py b/gsi/gsi_util/gsi_util/commands/hello.py
new file mode 100644
index 0000000..ff3cdc7
--- /dev/null
+++ b/gsi/gsi_util/gsi_util/commands/hello.py
@@ -0,0 +1,32 @@
+# Copyright 2017 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation of gsi_util hello command."""
+
+import logging
+
+
+def do_hello(args):
+ if args.foo:
+ logging.info('hello foo')
+ if args.bar:
+ logging.info('hello bar')
+
+
+def setup_command_args(subparsers):
+ """Sets up command args for 'hello'."""
+ hello_parser = subparsers.add_parser('hello', help='hello help')
+ hello_parser.add_argument('--foo', action='store_true', help='foo help')
+ hello_parser.add_argument('--bar', action='store_true', help='bar help')
+ hello_parser.set_defaults(func=do_hello)