blob: 498319889fe165edd69f2a1cd3add1c46c395bba [file] [log] [blame]
Alex Kleinf4dc4f52018-12-05 13:55:12 -07001# -*- coding: utf-8 -*-
2# Copyright 2018 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""The build API entry point."""
7
8from __future__ import print_function
9
Alex Klein5bcb4d22019-03-21 13:51:54 -060010import os
George Engelbrechtd3de8df2019-09-04 18:15:05 -060011import sys
Alex Kleinf4dc4f52018-12-05 13:55:12 -070012
Alex Klein69339cc2019-07-22 14:08:35 -060013from chromite.api import api_config as api_config_lib
Alex Klein146d4772019-06-20 13:48:25 -060014from chromite.api import router as router_lib
Alex Kleinf4dc4f52018-12-05 13:55:12 -070015from chromite.lib import commandline
Alex Klein2bfacb22019-02-04 11:42:17 -070016from chromite.lib import cros_build_lib
Alex Klein00b1f1e2019-02-08 13:53:42 -070017from chromite.utils import matching
Alex Kleinf4dc4f52018-12-05 13:55:12 -070018
19
Alex Kleinf4dc4f52018-12-05 13:55:12 -070020def GetParser():
Alex Klein00b1f1e2019-02-08 13:53:42 -070021 """Build the argument parser."""
Alex Kleinf4dc4f52018-12-05 13:55:12 -070022 parser = commandline.ArgumentParser(description=__doc__)
23
George Engelbrechtd3de8df2019-09-04 18:15:05 -060024 parser.add_argument('service_method', nargs='?',
Alex Kleinf4dc4f52018-12-05 13:55:12 -070025 help='The "chromite.api.Service/Method" that is being '
26 'called.')
Alex Kleinf4dc4f52018-12-05 13:55:12 -070027 parser.add_argument(
George Engelbrechtd3de8df2019-09-04 18:15:05 -060028 '--input-json', type='path',
Alex Kleinf4dc4f52018-12-05 13:55:12 -070029 help='Path to the JSON serialized input argument protobuf message.')
30 parser.add_argument(
George Engelbrechtd3de8df2019-09-04 18:15:05 -060031 '--output-json', type='path',
Alex Kleinf4dc4f52018-12-05 13:55:12 -070032 help='The path to which the result protobuf message should be written.')
Alex Klein69339cc2019-07-22 14:08:35 -060033 parser.add_argument(
34 '--validate-only', action='store_true', default=False,
35 help='When set, only runs the argument validation logic. Calls produce'
36 'a return code of 0 iff the arguments comprise a valid call to the'
37 'endpoint, or 1 otherwise.')
George Engelbrechtd3de8df2019-09-04 18:15:05 -060038 parser.add_argument(
39 '--list-services', action='store_true',
40 help='List the names of the registered services.')
Alex Kleinf4dc4f52018-12-05 13:55:12 -070041
42 return parser
43
44
Alex Klein00b1f1e2019-02-08 13:53:42 -070045def _ParseArgs(argv, router):
Alex Kleinf4dc4f52018-12-05 13:55:12 -070046 """Parse and validate arguments."""
47 parser = GetParser()
48 opts = parser.parse_args(argv)
49
Alex Klein00b1f1e2019-02-08 13:53:42 -070050 methods = router.ListMethods()
George Engelbrechtd3de8df2019-09-04 18:15:05 -060051
52 if opts.list_services:
53 for method in methods:
54 print(method)
55 sys.exit(0)
56
57 if not opts.service_method:
58 parser.error('Must pass "Service/Method".')
59
60 parts = opts.service_method.split('/')
61 if len(parts) != 2:
62 parser.error(
63 'Must pass the correct format: (i.e. chromite.api.SdkService/Create)')
64
65 if not opts.input_json or not opts.output_json:
66 parser.error('--input-json and --output-json are both required.')
67
Alex Klein00b1f1e2019-02-08 13:53:42 -070068 if opts.service_method not in methods:
Alex Klein00aa8072019-04-15 16:36:00 -060069 # Unknown method, try to match against known methods and make a suggestion.
70 # This is just for developer sanity, e.g. misspellings when testing.
Alex Klein00b1f1e2019-02-08 13:53:42 -070071 matched = matching.GetMostLikelyMatchedObject(methods, opts.service_method,
72 matched_score_threshold=0.6)
73 error = 'Unrecognized service name.'
74 if matched:
75 error += '\nDid you mean: \n%s' % '\n'.join(matched)
76 parser.error(error)
77
Alex Kleinf4dc4f52018-12-05 13:55:12 -070078 opts.service = parts[0]
79 opts.method = parts[1]
80
Alex Klein5bcb4d22019-03-21 13:51:54 -060081 if not os.path.exists(opts.input_json):
82 parser.error('Input file does not exist.')
83
Alex Klein69339cc2019-07-22 14:08:35 -060084 opts.config = api_config_lib.ApiConfig(validate_only=opts.validate_only)
85
Alex Kleinf4dc4f52018-12-05 13:55:12 -070086 opts.Freeze()
87 return opts
88
89
Alex Kleinf4dc4f52018-12-05 13:55:12 -070090def main(argv):
Alex Klein146d4772019-06-20 13:48:25 -060091 router = router_lib.GetRouter()
Alex Kleinf4dc4f52018-12-05 13:55:12 -070092
Alex Klein00b1f1e2019-02-08 13:53:42 -070093 opts = _ParseArgs(argv, router)
94
Alex Klein7a115172019-02-08 14:14:20 -070095 try:
Alex Klein5bcb4d22019-03-21 13:51:54 -060096 return router.Route(opts.service, opts.method, opts.input_json,
Alex Klein69339cc2019-07-22 14:08:35 -060097 opts.output_json, opts.config)
Amin Hassani1e2dfd22019-06-24 10:34:17 -070098 except router_lib.Error as e:
99 # Handle router_lib.Error derivatives nicely, but let anything else bubble
100 # up.
Alex Klein7a115172019-02-08 14:14:20 -0700101 cros_build_lib.Die(e.message)