Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: recipe_engine/common_args.py

Issue 2839423002: [recipes.py] move common arg parsing to separate module. (Closed)
Patch Set: put back missing arg Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | recipes.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2017 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file.
4
5 """Common arguments to the various recipes.py subcommands.
6
7 This is in a separate file for recipes.py for testing purposes.
8 """
9
10 import json
11 import logging
12 import os
13
14 from . import package_io
15
16 from . import env
17
18 import argparse # this is vendored
19
20 from . import arguments_pb2
21
22 from google.protobuf import json_format as jsonpb
23
24
25 def add_common_args(parser):
26 class ProjectOverrideAction(argparse.Action):
27 def __call__(self, parser, namespace, values, option_string=None):
28 p = values.split('=', 2)
29 if len(p) != 2:
30 raise ValueError('Override must have the form: repo=path')
31 project_id, path = p
32
33 v = getattr(namespace, self.dest, None)
34 if v is None:
35 v = {}
36 setattr(namespace, self.dest, v)
37
38 if v.get(project_id):
39 raise ValueError('An override is already defined for [%s] (%s)' % (
40 project_id, v[project_id]))
41 path = os.path.abspath(os.path.expanduser(path))
42 if not os.path.isdir(path):
43 raise ValueError('Override path [%s] is not a directory' % (path,))
44 v[project_id] = path
45
46 def package_type(value):
47 if not os.path.isfile(value):
48 raise argparse.ArgumentTypeError(
49 'Given recipes config file %r does not exist.' % (value,))
50 return package_io.PackageFile(value)
51
52 parser.add_argument(
53 '--package',
54 type=package_type,
55 help='Path to recipes.cfg of the recipe package to operate on'
56 ', usually in infra/config/recipes.cfg')
57 parser.add_argument(
58 '--deps-path',
59 type=os.path.abspath,
60 help='Path where recipe engine dependencies will be extracted. Specify '
61 '"-" to use a temporary directory for deps, which will be cleaned '
62 'up on exit.')
63 parser.add_argument(
64 '--verbose', '-v', action='count',
65 help='Increase logging verboisty')
66 # TODO(phajdan.jr): Figure out if we need --no-fetch; remove if not.
67 parser.add_argument(
68 '--no-fetch', action='store_true',
69 help='Disable automatic fetching')
70 parser.add_argument('-O', '--project-override', metavar='ID=PATH',
71 action=ProjectOverrideAction,
72 help='Override a project repository path with a local one.')
73 parser.add_argument(
74 # Use 'None' as default so that we can recognize when none of the
75 # bootstrap options were passed.
76 '--use-bootstrap', action='store_true', default=None,
77 help='Use bootstrap/bootstrap.py to create a isolated python virtualenv'
78 ' with required python dependencies.')
79 parser.add_argument(
80 '--bootstrap-vpython-path', metavar='PATH',
81 help='Specify the `vpython` executable path to use when bootstrapping ('
82 'requires --use-bootstrap).')
83 parser.add_argument(
84 '--disable-bootstrap', action='store_false', dest='use_bootstrap',
85 help='Disables bootstrap (see --use-bootstrap)')
86
87 def operational_args_type(value):
88 with open(value) as fd:
89 return jsonpb.ParseDict(json.load(fd), arguments_pb2.Arguments())
90
91 parser.set_defaults(
92 operational_args=arguments_pb2.Arguments(),
93 bare_command=False, # don't call postprocess_func, don't use package_deps
94 postprocess_func=lambda parser, args: None,
95 )
96
97 parser.add_argument(
98 '--operational-args-path',
99 dest='operational_args',
100 type=operational_args_type,
101 help='The path to an operational Arguments file. If provided, this file '
102 'must contain a JSONPB-encoded Arguments protobuf message, and will '
103 'be integrated into the runtime parameters.')
104
105 def post_process_args(parser, args):
106 # TODO(iannucci): We should always do logging.basicConfig() (probably with
107 # logging.WARNING), even if no verbose is passed. However we need to be
108 # careful as this could cause issues with spurious/unexpected output.
109 # I think it's risky enough to do in a different CL.
110
111 if args.verbose > 0:
112 logging.basicConfig()
113 logging.getLogger().setLevel(logging.INFO)
114 if args.verbose > 1:
115 logging.getLogger().setLevel(logging.DEBUG)
116
117 if args.bare_command:
118 # TODO(iannucci): this is gross, and only for the remote subcommand;
119 # remote doesn't behave like ANY other commands. A way to solve this will
120 # be to allow --package to take a remote repo and then simply remove the
121 # remote subcommand entirely.
122 if args.package is not None:
123 parser.error('%s forbids --package' % args.command)
124 else:
125 if not args.package:
126 parser.error('%s requires --package' % args.command)
127
128 return post_process_args
OLDNEW
« no previous file with comments | « no previous file | recipes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698