Add a helper function to build_api to list services

It wasn't immediately obvious to me how to specify
the service name for manual invocation so I've added
a helper which will list registered services.

BUG=chromium:1000894
TEST=Manual and ../api/compile_build_api_proto

Change-Id: I4f1a0e04d245f3eb66dbe9eb5b542f8ed60a924d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1785684
Reviewed-by: Alex Klein <saklein@chromium.org>
Commit-Queue: George Engelbrecht <engeg@google.com>
Tested-by: George Engelbrecht <engeg@google.com>
diff --git a/scripts/build_api.py b/scripts/build_api.py
index d2fdaa8..4983198 100644
--- a/scripts/build_api.py
+++ b/scripts/build_api.py
@@ -8,6 +8,7 @@
 from __future__ import print_function
 
 import os
+import sys
 
 from chromite.api import api_config as api_config_lib
 from chromite.api import router as router_lib
@@ -20,22 +21,23 @@
   """Build the argument parser."""
   parser = commandline.ArgumentParser(description=__doc__)
 
-  parser.add_argument('service_method',
+  parser.add_argument('service_method', nargs='?',
                       help='The "chromite.api.Service/Method" that is being '
                            'called.')
-
   parser.add_argument(
-      '--input-json', type='path', required=True,
+      '--input-json', type='path',
       help='Path to the JSON serialized input argument protobuf message.')
   parser.add_argument(
-      '--output-json', type='path', required=True,
+      '--output-json', type='path',
       help='The path to which the result protobuf message should be written.')
-  # Run configuration options.
   parser.add_argument(
       '--validate-only', action='store_true', default=False,
       help='When set, only runs the argument validation logic. Calls produce'
            'a return code of 0 iff the arguments comprise a valid call to the'
            'endpoint, or 1 otherwise.')
+  parser.add_argument(
+      '--list-services', action='store_true',
+      help='List the names of the registered services.')
 
   return parser
 
@@ -46,6 +48,23 @@
   opts = parser.parse_args(argv)
 
   methods = router.ListMethods()
+
+  if opts.list_services:
+    for method in methods:
+      print(method)
+    sys.exit(0)
+
+  if not opts.service_method:
+    parser.error('Must pass "Service/Method".')
+
+  parts = opts.service_method.split('/')
+  if len(parts) != 2:
+    parser.error(
+        'Must pass the correct format: (i.e. chromite.api.SdkService/Create)')
+
+  if not opts.input_json or not opts.output_json:
+    parser.error('--input-json and --output-json are both required.')
+
   if opts.service_method not in methods:
     # Unknown method, try to match against known methods and make a suggestion.
     # This is just for developer sanity, e.g. misspellings when testing.
@@ -56,11 +75,6 @@
       error += '\nDid you mean: \n%s' % '\n'.join(matched)
     parser.error(error)
 
-  parts = opts.service_method.split('/')
-
-  if len(parts) != 2:
-    parser.error('Must pass "Service/Method".')
-
   opts.service = parts[0]
   opts.method = parts[1]