• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 The ChromiumOS Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Collection of helper functions that can be used to compose presubmit
6# checks. For cross repo usage import and compose into presubmit hooks
7# as follows:
8#
9#   import sys
10#   sys.path.insert(1, 'config/presubmit')
11#
12#   import presubmits
13#
14#   def CheckChangeOnUpload(input_api, output_api):
15#     results = []
16#     results.extend(presubmits.CheckGenerated(input_api, output_api))
17#     # ... other checks
18#     return results
19#
20# Note that this expects a config symlink to exist that points at this repo.
21#
22# For more details on the depot tools provided presubmit API see:
23# http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
24
25def CheckScript(input_api, output_api, script, msg=None):
26  """Invokes a script with the result per unix error codes.
27
28  Invokes a shell script with the result following the unix error
29  code result of the script.
30
31  Args:
32    input_api: InputApi, provides information about the change.
33    output_api: OutputApi, provides the mechanism for returning a response.
34    script: str, script to invoke.
35    msg: str, message to use when failure.
36
37  Returns:
38    list of PresubmitError, or empty list if no errors.
39  """
40  results = []
41  if input_api.subprocess.call(script, shell=True):
42    if not msg:
43      msg = 'Error: {} failed. Please fix and try again.'.format(script)
44    results.append(output_api.PresubmitError(msg))
45  return results
46
47
48def CheckChecker(input_api, output_api,
49                 checker_cmd='./config/payload_utils/checker.py',
50                 program='./program/generated/config.jsonproto',
51                 project='./generated/config.jsonproto',
52                 factory_dir='./factory'):
53  """Runs the checker.py script as a presubmit check.
54
55  Runs the checker script as a presubmit check checking for successful
56  exit.
57
58  Args:
59    input_api: InputApi, provides information about the change.
60    output_api: OutputApi, provides the mechanism for returning a response.
61    program: str, path to the program config json proto.
62    project: str, path to the project config json proto.
63    factory_dir: str, path to the project factory config dir.
64
65  Returns:
66    list of PresubmitError, or empty list if no errors.
67  """
68  results = []
69
70  cmd = [checker_cmd]
71  cmd.extend(['--program', program])
72  cmd.extend(['--project', project])
73  cmd.extend(['--factory_dir', factory_dir])
74  if input_api.subprocess.call(cmd):
75    msg = 'Error: config checker checker.py failed. Please fix and try again.'
76    results.append(output_api.PresubmitError(msg))
77
78  return results
79
80
81def CheckGenerated(input_api, output_api, cmd='./generate.sh'):
82  """Runs a script as a presubmit check.
83
84  Runs a script as a presubmit check checking for successful exit and no
85  diff generated.
86
87  Args:
88    input_api: InputApi, provides information about the change.
89    output_api: OutputApi, provides the mechanism for returning a response.
90    cmd: String, command to run as the "generate" script.
91
92  Returns:
93    list of PresubmitError, or empty list if no errors.
94  """
95  results = []
96
97  if input_api.subprocess.call(
98      cmd,
99      shell=True):
100    msg = 'Error: {} failed. Please fix and try again.'.format(cmd)
101    results.append(output_api.PresubmitError(msg))
102  elif input_api.subprocess.call(
103      'git diff --exit-code',
104      shell=True,
105      stdout=input_api.subprocess.PIPE,
106      stderr=input_api.subprocess.PIPE):
107    msg = ('Error: Running {} produced a diff. Please run the script, amend '
108           'your changes, and try again.'.format(cmd))
109    results.append(output_api.PresubmitError(msg))
110
111  return results
112
113
114_DEFAULT_FAILURE_MESSAGE=(
115    'Error: Running gen_config produced a diff. Please '
116    'resync your chromiumos checkout, run the gen_config '
117    'script, amend your changes, and try again. Repos '
118    'needing resyncing could include: '
119    'chromiumos/config, '
120    'chromeos/program/<your program>, '
121    'chromeos/project/<your program>/<your project>'
122)
123
124def CheckGenConfig(input_api, output_api,
125                   config_file='config.star',
126                   gen_config_cmd='./config/bin/gen_config',
127                   failure_message=_DEFAULT_FAILURE_MESSAGE):
128  """Runs a gen_config as a presubmit check.
129
130  Runs the gen_config script as a presubmit check checking for successful
131  exit and no diff generated.
132
133  Args:
134    input_api: InputApi, provides information about the change.
135    output_api: OutputApi, provides the mechanism for returning a response.
136    config_file: str, file to generate from, defaults to config.star.
137    gen_config_cmd: str, location of gen_config script
138    failure_message: str, message to use when gen_config produces a diff.
139
140  Returns:
141    list of PresubmitError, or empty list if no errors.
142  """
143  results = []
144
145  # TODO: get on path for recipes, for now expect to find at
146  # config/bin/gen_config
147  if input_api.subprocess.call([gen_config_cmd, config_file]):
148    msg = 'Error: gen_config failed. Please fix and try again.'
149    results.append(output_api.PresubmitError(msg))
150  elif input_api.subprocess.call(['git', 'diff', '--exit-code']):
151    results.append(output_api.PresubmitError(failure_message))
152
153  return results
154
155
156def CheckUntracked(input_api, output_api):
157  """Looks for untracked files in the repo and fails if found.
158
159  Args:
160    input_api: InputApi, provides information about the change.
161    output_api: OutputApi, provides the mechanism for returning a response.
162
163  Returns:
164    list of PresubmitError, or empty list if no errors.
165  """
166  results = []
167  cmd = ['git', 'ls-files', '--others', '--exclude-standard']
168  out = input_api.subprocess.capture(cmd)
169  if out:
170    msg = 'Found untracked files:\n{}'.format(out)
171    results.append(output_api.PresubmitPromptWarning(msg))
172
173  return results
174