xref: /aosp_15_r20/external/pigweed/pw_presubmit/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_presubmit:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker============
4*61c4878aSAndroid Build Coastguard Workerpw_presubmit
5*61c4878aSAndroid Build Coastguard Worker============
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_presubmit
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard WorkerThe presubmit module provides Python tools for running presubmit checks and
10*61c4878aSAndroid Build Coastguard Workerchecking and fixing code format. It also includes the presubmit check script for
11*61c4878aSAndroid Build Coastguard Workerthe Pigweed repository, ``pigweed_presubmit.py``.
12*61c4878aSAndroid Build Coastguard Worker
13*61c4878aSAndroid Build Coastguard WorkerPresubmit checks are essential tools, but they take work to set up, and
14*61c4878aSAndroid Build Coastguard Workerprojects don’t always get around to it. The ``pw_presubmit`` module provides
15*61c4878aSAndroid Build Coastguard Workertools for setting up high quality presubmit checks for any project. We use this
16*61c4878aSAndroid Build Coastguard Workerframework to run Pigweed’s presubmit on our workstations and in our automated
17*61c4878aSAndroid Build Coastguard Workerbuilding tools.
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard WorkerThe ``pw_presubmit`` module also includes ``pw format``, a tool that provides a
20*61c4878aSAndroid Build Coastguard Workerunified interface for automatically formatting code in a variety of languages.
21*61c4878aSAndroid Build Coastguard WorkerWith ``pw format``, you can format Bazel, C, C++, Python, GN, and Go code
22*61c4878aSAndroid Build Coastguard Workeraccording to configurations defined by your project. ``pw format`` leverages
23*61c4878aSAndroid Build Coastguard Workerexisting tools like ``clang-format``, and it’s simple to add support for new
24*61c4878aSAndroid Build Coastguard Workerlanguages. (Note: Bazel formatting requires ``buildifier`` to be present on your
25*61c4878aSAndroid Build Coastguard Workersystem. If it's not Bazel formatting passes without checking.)
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker.. image:: docs/pw_presubmit_demo.gif
28*61c4878aSAndroid Build Coastguard Worker   :alt: ``pw format`` demo
29*61c4878aSAndroid Build Coastguard Worker   :align: left
30*61c4878aSAndroid Build Coastguard Worker
31*61c4878aSAndroid Build Coastguard WorkerThe ``pw_presubmit`` package includes presubmit checks that can be used with any
32*61c4878aSAndroid Build Coastguard Workerproject. These checks include:
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard Worker.. todo-check: disable
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard Worker* Check code format of several languages including C, C++, and Python
37*61c4878aSAndroid Build Coastguard Worker* Initialize a Python environment
38*61c4878aSAndroid Build Coastguard Worker* Run all Python tests
39*61c4878aSAndroid Build Coastguard Worker* Run pylint
40*61c4878aSAndroid Build Coastguard Worker* Run mypy
41*61c4878aSAndroid Build Coastguard Worker* Ensure source files are included in the GN and Bazel builds
42*61c4878aSAndroid Build Coastguard Worker* Build and run all tests with GN
43*61c4878aSAndroid Build Coastguard Worker* Build and run all tests with Bazel
44*61c4878aSAndroid Build Coastguard Worker* Ensure all header files contain ``#pragma once`` (or, that they have matching
45*61c4878aSAndroid Build Coastguard Worker  ``#ifndef``/``#define`` lines)
46*61c4878aSAndroid Build Coastguard Worker* Ensure lists are kept in alphabetical order
47*61c4878aSAndroid Build Coastguard Worker* Forbid non-inclusive language
48*61c4878aSAndroid Build Coastguard Worker* Check format of TODO lines
49*61c4878aSAndroid Build Coastguard Worker* Apply various rules to ``.gitmodules`` or ``OWNERS`` files
50*61c4878aSAndroid Build Coastguard Worker* Ensure all source files are in the build
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker.. todo-check: enable
53*61c4878aSAndroid Build Coastguard Worker
54*61c4878aSAndroid Build Coastguard Worker-------------
55*61c4878aSAndroid Build Coastguard WorkerCompatibility
56*61c4878aSAndroid Build Coastguard Worker-------------
57*61c4878aSAndroid Build Coastguard WorkerPython 3
58*61c4878aSAndroid Build Coastguard Worker
59*61c4878aSAndroid Build Coastguard Worker-------------------------------------------
60*61c4878aSAndroid Build Coastguard WorkerCreating a presubmit check for your project
61*61c4878aSAndroid Build Coastguard Worker-------------------------------------------
62*61c4878aSAndroid Build Coastguard WorkerCreating a presubmit check for a project using ``pw_presubmit`` is simple, but
63*61c4878aSAndroid Build Coastguard Workerrequires some customization. Projects must define their own presubmit check
64*61c4878aSAndroid Build Coastguard WorkerPython script that uses the ``pw_presubmit`` package.
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard WorkerA project's presubmit script can be registered as a
67*61c4878aSAndroid Build Coastguard Worker:ref:`pw_cli <module-pw_cli>` plugin, so that it can be run as ``pw
68*61c4878aSAndroid Build Coastguard Workerpresubmit``.
69*61c4878aSAndroid Build Coastguard Worker
70*61c4878aSAndroid Build Coastguard WorkerSetting up the command-line interface
71*61c4878aSAndroid Build Coastguard Worker=====================================
72*61c4878aSAndroid Build Coastguard WorkerThe ``pw_presubmit.cli`` module sets up the command-line interface for a
73*61c4878aSAndroid Build Coastguard Workerpresubmit script. This defines a standard set of arguments for invoking
74*61c4878aSAndroid Build Coastguard Workerpresubmit checks. Its use is optional, but recommended.
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard WorkerCommon ``pw presubmit`` command line arguments
77*61c4878aSAndroid Build Coastguard Worker----------------------------------------------
78*61c4878aSAndroid Build Coastguard Worker.. argparse::
79*61c4878aSAndroid Build Coastguard Worker   :module: pw_presubmit.cli
80*61c4878aSAndroid Build Coastguard Worker   :func: _get_default_parser
81*61c4878aSAndroid Build Coastguard Worker   :prog: pw presubmit
82*61c4878aSAndroid Build Coastguard Worker   :nodefaultconst:
83*61c4878aSAndroid Build Coastguard Worker   :nodescription:
84*61c4878aSAndroid Build Coastguard Worker   :noepilog:
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker``pw_presubmit.cli`` Python API
88*61c4878aSAndroid Build Coastguard Worker-------------------------------
89*61c4878aSAndroid Build Coastguard Worker.. automodule:: pw_presubmit.cli
90*61c4878aSAndroid Build Coastguard Worker   :members: add_arguments, run
91*61c4878aSAndroid Build Coastguard Worker
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard WorkerPresubmit output directory
94*61c4878aSAndroid Build Coastguard Worker--------------------------
95*61c4878aSAndroid Build Coastguard WorkerThe ``pw_presubmit`` command line interface includes an ``--output-directory``
96*61c4878aSAndroid Build Coastguard Workeroption that specifies the working directory to use for presubmits. The default
97*61c4878aSAndroid Build Coastguard Workerpath is ``out/presubmit``.  A subdirectory is created for each presubmit step.
98*61c4878aSAndroid Build Coastguard WorkerThis directory persists between presubmit runs and can be cleaned by deleting it
99*61c4878aSAndroid Build Coastguard Workeror running ``pw presubmit --clean``.
100*61c4878aSAndroid Build Coastguard Worker
101*61c4878aSAndroid Build Coastguard Worker.. _module-pw_presubmit-presubmit-checks:
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard WorkerPresubmit checks
104*61c4878aSAndroid Build Coastguard Worker================
105*61c4878aSAndroid Build Coastguard WorkerA presubmit check is defined as a function or other callable. The function must
106*61c4878aSAndroid Build Coastguard Workeraccept one argument: a ``PresubmitContext``, which provides the paths on which
107*61c4878aSAndroid Build Coastguard Workerto run. Presubmit checks communicate failure by raising an exception.
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard WorkerPresubmit checks may use the ``filter_paths`` decorator to automatically filter
110*61c4878aSAndroid Build Coastguard Workerthe paths list for file types they care about.
111*61c4878aSAndroid Build Coastguard Worker
112*61c4878aSAndroid Build Coastguard WorkerEither of these functions could be used as presubmit checks:
113*61c4878aSAndroid Build Coastguard Worker
114*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
115*61c4878aSAndroid Build Coastguard Worker
116*61c4878aSAndroid Build Coastguard Worker   @pw_presubmit.filter_paths(endswith='.py')
117*61c4878aSAndroid Build Coastguard Worker   def file_contains_ni(ctx: PresubmitContext):
118*61c4878aSAndroid Build Coastguard Worker       for path in ctx.paths:
119*61c4878aSAndroid Build Coastguard Worker           with open(path) as file:
120*61c4878aSAndroid Build Coastguard Worker               contents = file.read()
121*61c4878aSAndroid Build Coastguard Worker               if 'ni' not in contents and 'nee' not in contents:
122*61c4878aSAndroid Build Coastguard Worker                   raise PresumitFailure('Files must say "ni"!', path=path)
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker   def run_the_build(_):
125*61c4878aSAndroid Build Coastguard Worker       subprocess.run(['make', 'release'], check=True)
126*61c4878aSAndroid Build Coastguard Worker
127*61c4878aSAndroid Build Coastguard WorkerPresubmit checks functions are grouped into "programs" -- a named series of
128*61c4878aSAndroid Build Coastguard Workerchecks. Projects may find it helpful to have programs for different purposes,
129*61c4878aSAndroid Build Coastguard Workersuch as a quick program for local use and a full program for automated use. The
130*61c4878aSAndroid Build Coastguard Worker:ref:`example script <example-script>` uses ``pw_presubmit.Programs`` to define
131*61c4878aSAndroid Build Coastguard Worker``quick`` and ``full`` programs.
132*61c4878aSAndroid Build Coastguard Worker
133*61c4878aSAndroid Build Coastguard WorkerBy default, presubmit steps are only run on files changed since ``@{upstream}``.
134*61c4878aSAndroid Build Coastguard WorkerIf all such files are filtered out by ``filter_paths``, then that step will be
135*61c4878aSAndroid Build Coastguard Workerskipped. This can be overridden with the ``--base`` and ``--full`` arguments to
136*61c4878aSAndroid Build Coastguard Worker``pw presubmit``. In automated testing ``--full`` is recommended, except for
137*61c4878aSAndroid Build Coastguard Workerlint/format checks where ``--base HEAD~1`` is recommended.
138*61c4878aSAndroid Build Coastguard Worker
139*61c4878aSAndroid Build Coastguard Worker.. autoclass:: pw_presubmit.presubmit_context.PresubmitContext
140*61c4878aSAndroid Build Coastguard Worker   :members:
141*61c4878aSAndroid Build Coastguard Worker   :noindex:
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard WorkerAdditional members can be added by subclassing ``PresubmitContext`` and
144*61c4878aSAndroid Build Coastguard Worker``Presubmit``. Then override ``Presubmit._create_presubmit_context()`` to
145*61c4878aSAndroid Build Coastguard Workerreturn the subclass of ``PresubmitContext``. Finally, add
146*61c4878aSAndroid Build Coastguard Worker``presubmit_class=PresubmitSubClass`` when calling ``cli.run()``.
147*61c4878aSAndroid Build Coastguard Worker
148*61c4878aSAndroid Build Coastguard Worker.. autoclass:: pw_presubmit.presubmit_context.LuciContext
149*61c4878aSAndroid Build Coastguard Worker   :members:
150*61c4878aSAndroid Build Coastguard Worker   :noindex:
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker.. autoclass:: pw_presubmit.presubmit_context.LuciPipeline
153*61c4878aSAndroid Build Coastguard Worker   :members:
154*61c4878aSAndroid Build Coastguard Worker   :noindex:
155*61c4878aSAndroid Build Coastguard Worker
156*61c4878aSAndroid Build Coastguard Worker.. autoclass:: pw_presubmit.presubmit_context.LuciTrigger
157*61c4878aSAndroid Build Coastguard Worker   :members:
158*61c4878aSAndroid Build Coastguard Worker   :noindex:
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard WorkerSubsteps
161*61c4878aSAndroid Build Coastguard Worker--------
162*61c4878aSAndroid Build Coastguard WorkerPresubmit steps can define substeps that can run independently in other tooling.
163*61c4878aSAndroid Build Coastguard WorkerThese steps should subclass ``SubStepCheck`` and must define a ``substeps()``
164*61c4878aSAndroid Build Coastguard Workermethod that yields ``SubStep`` objects. ``SubStep`` objects have the following
165*61c4878aSAndroid Build Coastguard Workermembers:
166*61c4878aSAndroid Build Coastguard Worker
167*61c4878aSAndroid Build Coastguard Worker* ``name``: Name of the substep
168*61c4878aSAndroid Build Coastguard Worker* ``_func``: Substep code
169*61c4878aSAndroid Build Coastguard Worker* ``args``: Positional arguments for ``_func``
170*61c4878aSAndroid Build Coastguard Worker* ``kwargs``: Keyword arguments for ``_func``
171*61c4878aSAndroid Build Coastguard Worker
172*61c4878aSAndroid Build Coastguard Worker``SubStep`` objects must have unique names. For a detailed example of a
173*61c4878aSAndroid Build Coastguard Worker``SubStepCheck`` subclass see ``GnGenNinja`` in ``build.py``.
174*61c4878aSAndroid Build Coastguard Worker
175*61c4878aSAndroid Build Coastguard WorkerExisting Presubmit Checks
176*61c4878aSAndroid Build Coastguard Worker-------------------------
177*61c4878aSAndroid Build Coastguard WorkerA small number of presubmit checks are made available through ``pw_presubmit``
178*61c4878aSAndroid Build Coastguard Workermodules.
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard WorkerCode Formatting
181*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^
182*61c4878aSAndroid Build Coastguard WorkerFormatting checks for a variety of languages are available from
183*61c4878aSAndroid Build Coastguard Worker``pw_presubmit.format_code``. These include C/C++, Java, Go, Python, GN, and
184*61c4878aSAndroid Build Coastguard Workerothers. All of these checks can be included by adding
185*61c4878aSAndroid Build Coastguard Worker``pw_presubmit.format_code.presubmit_checks()`` to a presubmit program. These
186*61c4878aSAndroid Build Coastguard Workerall use language-specific formatters like clang-format or black.
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard WorkerExample changes demonstrating how to add formatters:
189*61c4878aSAndroid Build Coastguard Worker
190*61c4878aSAndroid Build Coastguard Worker* `CSS <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/178810>`_
191*61c4878aSAndroid Build Coastguard Worker* `JSON <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/171991>`_
192*61c4878aSAndroid Build Coastguard Worker* `reStructuredText <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168541>`_
193*61c4878aSAndroid Build Coastguard Worker* `TypeScript <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/164825>`_
194*61c4878aSAndroid Build Coastguard Worker
195*61c4878aSAndroid Build Coastguard WorkerThese will suggest fixes using ``pw format --fix``.
196*61c4878aSAndroid Build Coastguard Worker
197*61c4878aSAndroid Build Coastguard WorkerOptions for code formatting can be specified in the ``pigweed.json`` file
198*61c4878aSAndroid Build Coastguard Worker(see also :ref:`SEED-0101 <seed-0101>`). These apply to both ``pw presubmit``
199*61c4878aSAndroid Build Coastguard Workersteps that check code formatting and ``pw format`` commands that either check
200*61c4878aSAndroid Build Coastguard Workeror fix code formatting.
201*61c4878aSAndroid Build Coastguard Worker
202*61c4878aSAndroid Build Coastguard Worker* ``python_formatter``: Choice of Python formatter. Options are ``black``
203*61c4878aSAndroid Build Coastguard Worker  (default, used by Pigweed itself) and ``yapf``.
204*61c4878aSAndroid Build Coastguard Worker* ``black_path``: If ``python_formatter`` is ``black``, use this as the
205*61c4878aSAndroid Build Coastguard Worker  executable instead of ``black``.
206*61c4878aSAndroid Build Coastguard Worker* ``black_config_file``: Set the config file for the black formatter.
207*61c4878aSAndroid Build Coastguard Worker* ``exclude``: List of path regular expressions to ignore. Will be evaluated
208*61c4878aSAndroid Build Coastguard Worker  against paths relative to the checkout root using ``re.search``.
209*61c4878aSAndroid Build Coastguard Worker
210*61c4878aSAndroid Build Coastguard WorkerExample section from a ``pigweed.json`` file:
211*61c4878aSAndroid Build Coastguard Worker
212*61c4878aSAndroid Build Coastguard Worker.. code-block:: json
213*61c4878aSAndroid Build Coastguard Worker
214*61c4878aSAndroid Build Coastguard Worker   {
215*61c4878aSAndroid Build Coastguard Worker     "pw": {
216*61c4878aSAndroid Build Coastguard Worker       "pw_presubmit": {
217*61c4878aSAndroid Build Coastguard Worker         "format": {
218*61c4878aSAndroid Build Coastguard Worker           "python_formatter": "black",
219*61c4878aSAndroid Build Coastguard Worker           "black_config_file": "$pw_env{PW_PROJECT_ROOT}/config/.black.toml"
220*61c4878aSAndroid Build Coastguard Worker           "black_path": "black",
221*61c4878aSAndroid Build Coastguard Worker           "exclude": [
222*61c4878aSAndroid Build Coastguard Worker             "\\bthird_party/foo/src"
223*61c4878aSAndroid Build Coastguard Worker           ]
224*61c4878aSAndroid Build Coastguard Worker         }
225*61c4878aSAndroid Build Coastguard Worker       }
226*61c4878aSAndroid Build Coastguard Worker     }
227*61c4878aSAndroid Build Coastguard Worker   }
228*61c4878aSAndroid Build Coastguard Worker
229*61c4878aSAndroid Build Coastguard WorkerSorted Blocks
230*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^
231*61c4878aSAndroid Build Coastguard WorkerBlocks of code can be required to be kept in sorted order using comments like
232*61c4878aSAndroid Build Coastguard Workerthe following:
233*61c4878aSAndroid Build Coastguard Worker
234*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: start
237*61c4878aSAndroid Build Coastguard Worker   bar
238*61c4878aSAndroid Build Coastguard Worker   baz
239*61c4878aSAndroid Build Coastguard Worker   foo
240*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: end
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard WorkerThis can be included by adding ``pw_presubmit.keep_sorted.presubmit_check`` to a
243*61c4878aSAndroid Build Coastguard Workerpresubmit program. Adding ``ignore-case`` to the start line will use
244*61c4878aSAndroid Build Coastguard Workercase-insensitive sorting.
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard WorkerBy default, duplicates will be removed. Lines that are identical except in case
247*61c4878aSAndroid Build Coastguard Workerare preserved, even with ``ignore-case``. To allow duplicates, add
248*61c4878aSAndroid Build Coastguard Worker``allow-dupes`` to the start line.
249*61c4878aSAndroid Build Coastguard Worker
250*61c4878aSAndroid Build Coastguard WorkerPrefixes can be ignored by adding ``ignore-prefix=`` followed by a
251*61c4878aSAndroid Build Coastguard Workercomma-separated list of prefixes. The list below will be kept in this order.
252*61c4878aSAndroid Build Coastguard WorkerNeither commas nor whitespace are supported in prefixes.
253*61c4878aSAndroid Build Coastguard Worker
254*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
255*61c4878aSAndroid Build Coastguard Worker
256*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: start ignore-prefix=',"
257*61c4878aSAndroid Build Coastguard Worker   'bar',
258*61c4878aSAndroid Build Coastguard Worker   "baz",
259*61c4878aSAndroid Build Coastguard Worker   'foo',
260*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: end
261*61c4878aSAndroid Build Coastguard Worker
262*61c4878aSAndroid Build Coastguard WorkerInline comments are assumed to be associated with the following line. For
263*61c4878aSAndroid Build Coastguard Workerexample, the following is already sorted. This can be disabled with
264*61c4878aSAndroid Build Coastguard Worker``sticky-comments=no``.
265*61c4878aSAndroid Build Coastguard Worker
266*61c4878aSAndroid Build Coastguard Worker.. todo-check: disable
267*61c4878aSAndroid Build Coastguard Worker
268*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
269*61c4878aSAndroid Build Coastguard Worker
270*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: start
271*61c4878aSAndroid Build Coastguard Worker   # TODO: b/1234 - Fix this.
272*61c4878aSAndroid Build Coastguard Worker   bar,
273*61c4878aSAndroid Build Coastguard Worker   # TODO: b/5678 - Also fix this.
274*61c4878aSAndroid Build Coastguard Worker   foo,
275*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: end
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker.. todo-check: enable
278*61c4878aSAndroid Build Coastguard Worker
279*61c4878aSAndroid Build Coastguard WorkerBy default, the prefix of the keep-sorted line is assumed to be the comment
280*61c4878aSAndroid Build Coastguard Workermarker used by any inline comments. This can be overridden by adding lines like
281*61c4878aSAndroid Build Coastguard Worker``sticky-comments=%,#`` to the start line.
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard WorkerLines indented more than the preceding line are assumed to be continuations.
284*61c4878aSAndroid Build Coastguard WorkerThus, the following block is already sorted. keep-sorted blocks can not be
285*61c4878aSAndroid Build Coastguard Workernested, so there's no ability to add a keep-sorted block for the sub-items.
286*61c4878aSAndroid Build Coastguard Worker
287*61c4878aSAndroid Build Coastguard Worker.. code-block::
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: start
290*61c4878aSAndroid Build Coastguard Worker   * abc
291*61c4878aSAndroid Build Coastguard Worker     * xyz
292*61c4878aSAndroid Build Coastguard Worker     * uvw
293*61c4878aSAndroid Build Coastguard Worker   * def
294*61c4878aSAndroid Build Coastguard Worker   # keep-sorted: end
295*61c4878aSAndroid Build Coastguard Worker
296*61c4878aSAndroid Build Coastguard WorkerThe presubmit check will suggest fixes using ``pw keep-sorted --fix``.
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard WorkerFuture versions may support additional multiline list items.
299*61c4878aSAndroid Build Coastguard Worker
300*61c4878aSAndroid Build Coastguard Worker.gitmodules
301*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^
302*61c4878aSAndroid Build Coastguard WorkerVarious rules can be applied to .gitmodules files. This check can be included
303*61c4878aSAndroid Build Coastguard Workerby adding ``pw_presubmit.gitmodules.create()`` to a presubmit program. This
304*61c4878aSAndroid Build Coastguard Workerfunction takes an optional argument of type ``pw_presubmit.gitmodules.Config``.
305*61c4878aSAndroid Build Coastguard Worker``Config`` objects have several properties.
306*61c4878aSAndroid Build Coastguard Worker
307*61c4878aSAndroid Build Coastguard Worker* ``allow_submodules: bool = True`` — If false, don't allow any submodules.
308*61c4878aSAndroid Build Coastguard Worker* ``allow_non_googlesource_hosts: bool = False`` — If false, all submodule URLs
309*61c4878aSAndroid Build Coastguard Worker  must be on a Google-managed Gerrit server.
310*61c4878aSAndroid Build Coastguard Worker* ``allowed_googlesource_hosts: Sequence[str] = ()`` — If set, any
311*61c4878aSAndroid Build Coastguard Worker  Google-managed Gerrit URLs for submodules most be in this list. Entries
312*61c4878aSAndroid Build Coastguard Worker  should be like ``pigweed`` for ``pigweed-review.googlesource.com``.
313*61c4878aSAndroid Build Coastguard Worker* ``require_relative_urls: bool = False`` — If true, all submodules must be
314*61c4878aSAndroid Build Coastguard Worker  relative to the superproject remote.
315*61c4878aSAndroid Build Coastguard Worker* ``allow_sso: bool = True`` — If false, ``sso://`` and ``rpc://`` submodule
316*61c4878aSAndroid Build Coastguard Worker  URLs are prohibited.
317*61c4878aSAndroid Build Coastguard Worker* ``allow_git_corp_google_com: bool = True`` — If false, ``git.corp.google.com``
318*61c4878aSAndroid Build Coastguard Worker  submodule URLs are prohibited.
319*61c4878aSAndroid Build Coastguard Worker* ``require_branch: bool = False`` — If true, all submodules must reference a
320*61c4878aSAndroid Build Coastguard Worker  branch.
321*61c4878aSAndroid Build Coastguard Worker* ``validator: Callable[[PresubmitContext, Path, str, dict[str, str]], None] = None``
322*61c4878aSAndroid Build Coastguard Worker  — A function that can be used for arbitrary submodule validation. It's called
323*61c4878aSAndroid Build Coastguard Worker  with the ``PresubmitContext``, the path to the ``.gitmodules`` file, the name
324*61c4878aSAndroid Build Coastguard Worker  of the current submodule, and the properties of the current submodule.
325*61c4878aSAndroid Build Coastguard Worker
326*61c4878aSAndroid Build Coastguard Worker#pragma once
327*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^
328*61c4878aSAndroid Build Coastguard WorkerThere's a ``pragma_once`` check that confirms the first non-comment line of
329*61c4878aSAndroid Build Coastguard WorkerC/C++ headers is ``#pragma once``. This is enabled by adding
330*61c4878aSAndroid Build Coastguard Worker``pw_presubmit.cpp_checks.pragma_once`` to a presubmit program.
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker#ifndef/#define
333*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^
334*61c4878aSAndroid Build Coastguard WorkerThere's an ``ifndef_guard`` check that confirms the first two non-comment lines
335*61c4878aSAndroid Build Coastguard Workerof C/C++ headers are ``#ifndef HEADER_H`` and ``#define HEADER_H``. This is
336*61c4878aSAndroid Build Coastguard Workerenabled by adding ``pw_presubmit.cpp_checks.include_guard_check()`` to a
337*61c4878aSAndroid Build Coastguard Workerpresubmit program. ``include_guard_check()`` has options for specifying what the
338*61c4878aSAndroid Build Coastguard Workerheader guard should be based on the path.
339*61c4878aSAndroid Build Coastguard Worker
340*61c4878aSAndroid Build Coastguard WorkerThis check is not used in Pigweed itself but is available to projects using
341*61c4878aSAndroid Build Coastguard WorkerPigweed.
342*61c4878aSAndroid Build Coastguard Worker
343*61c4878aSAndroid Build Coastguard Worker.. todo-check: disable
344*61c4878aSAndroid Build Coastguard Worker
345*61c4878aSAndroid Build Coastguard WorkerTODO(b/###) Formatting
346*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^
347*61c4878aSAndroid Build Coastguard WorkerThere's a check that confirms ``TODO`` lines match a given format. Upstream
348*61c4878aSAndroid Build Coastguard WorkerPigweed expects these to look like ``TODO: https://pwbug.dev/### -
349*61c4878aSAndroid Build Coastguard WorkerExplanation``, but projects may define their own patterns instead.
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard WorkerFor information on supported TODO expressions, see Pigweed's
352*61c4878aSAndroid Build Coastguard Worker:ref:`docs-pw-todo-style`.
353*61c4878aSAndroid Build Coastguard Worker
354*61c4878aSAndroid Build Coastguard Worker.. todo-check: enable
355*61c4878aSAndroid Build Coastguard Worker
356*61c4878aSAndroid Build Coastguard WorkerPython Checks
357*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^
358*61c4878aSAndroid Build Coastguard WorkerThere are two checks in the ``pw_presubmit.python_checks`` module, ``gn_pylint``
359*61c4878aSAndroid Build Coastguard Workerand ``gn_python_check``. They assume there's a top-level ``python`` GN target.
360*61c4878aSAndroid Build Coastguard Worker``gn_pylint`` runs Pylint and Mypy checks and ``gn_python_check`` runs Pylint,
361*61c4878aSAndroid Build Coastguard WorkerMypy, and all Python tests.
362*61c4878aSAndroid Build Coastguard Worker
363*61c4878aSAndroid Build Coastguard WorkerBazel Checks
364*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^
365*61c4878aSAndroid Build Coastguard WorkerThere is one Bazel-related check: the ``includes_presubmit_check`` verifies
366*61c4878aSAndroid Build Coastguard Workerthat ``cc_library`` Bazel targets don't use the ``includes`` attribute.  See
367*61c4878aSAndroid Build Coastguard Worker:bug:`378564135` for a discussion of why this attribute should be avoided.
368*61c4878aSAndroid Build Coastguard Worker
369*61c4878aSAndroid Build Coastguard WorkerInclusive Language
370*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^
371*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: disable
372*61c4878aSAndroid Build Coastguard Worker
373*61c4878aSAndroid Build Coastguard WorkerThe inclusive language check looks for words that are typical of non-inclusive
374*61c4878aSAndroid Build Coastguard Workercode, like using "master" and "slave" in place of "primary" and "secondary" or
375*61c4878aSAndroid Build Coastguard Worker"sanity check" in place of "consistency check".
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: enable
378*61c4878aSAndroid Build Coastguard Worker
379*61c4878aSAndroid Build Coastguard WorkerThese checks can be disabled for individual lines with
380*61c4878aSAndroid Build Coastguard Worker"inclusive-language: ignore" on the line in question or the line above it, or
381*61c4878aSAndroid Build Coastguard Workerfor entire blocks by using "inclusive-language: disable" before the block and
382*61c4878aSAndroid Build Coastguard Worker"inclusive-language: enable" after the block.
383*61c4878aSAndroid Build Coastguard Worker
384*61c4878aSAndroid Build Coastguard Worker.. In case things get moved around in the previous paragraphs the enable line
385*61c4878aSAndroid Build Coastguard Worker.. is repeated here: inclusive-language: enable.
386*61c4878aSAndroid Build Coastguard Worker
387*61c4878aSAndroid Build Coastguard WorkerOWNERS
388*61c4878aSAndroid Build Coastguard Worker^^^^^^
389*61c4878aSAndroid Build Coastguard WorkerThere's a check that requires folders matching specific patterns contain
390*61c4878aSAndroid Build Coastguard Worker``OWNERS`` files. It can be included by adding
391*61c4878aSAndroid Build Coastguard Worker``module_owners.presubmit_check()`` to a presubmit program. This function takes
392*61c4878aSAndroid Build Coastguard Workera callable as an argument that indicates, for a given file, where a controlling
393*61c4878aSAndroid Build Coastguard Worker``OWNERS`` file should be, or returns None if no ``OWNERS`` file is necessary.
394*61c4878aSAndroid Build Coastguard WorkerFormatting of ``OWNERS`` files is handled similary to formatting of other
395*61c4878aSAndroid Build Coastguard Workersource files and is discussed in `Code Formatting`.
396*61c4878aSAndroid Build Coastguard Worker
397*61c4878aSAndroid Build Coastguard WorkerJSON
398*61c4878aSAndroid Build Coastguard Worker^^^^
399*61c4878aSAndroid Build Coastguard WorkerThe JSON check requires all ``*.json`` files to be valid JSON files. It can be
400*61c4878aSAndroid Build Coastguard Workerincluded by adding ``json_check.presubmit_check()`` to a presubmit program.
401*61c4878aSAndroid Build Coastguard Worker
402*61c4878aSAndroid Build Coastguard WorkerSource in Build
403*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^
404*61c4878aSAndroid Build Coastguard WorkerPigweed provides checks that source files are configured as part of the build
405*61c4878aSAndroid Build Coastguard Workerfor GN, Bazel, CMake, and Soong. These can be included by adding
406*61c4878aSAndroid Build Coastguard Worker``source_in_build.gn(filter)`` and similar functions to a presubmit check. The
407*61c4878aSAndroid Build Coastguard WorkerCMake check additionally requires a callable that invokes CMake with appropriate
408*61c4878aSAndroid Build Coastguard Workeroptions.
409*61c4878aSAndroid Build Coastguard Worker
410*61c4878aSAndroid Build Coastguard Workerpw_presubmit
411*61c4878aSAndroid Build Coastguard Worker------------
412*61c4878aSAndroid Build Coastguard Worker.. automodule:: pw_presubmit
413*61c4878aSAndroid Build Coastguard Worker   :members: filter_paths, call, PresubmitFailure, Programs
414*61c4878aSAndroid Build Coastguard Worker
415*61c4878aSAndroid Build Coastguard Worker.. _example-script:
416*61c4878aSAndroid Build Coastguard Worker
417*61c4878aSAndroid Build Coastguard Worker
418*61c4878aSAndroid Build Coastguard WorkerGit hook
419*61c4878aSAndroid Build Coastguard Worker--------
420*61c4878aSAndroid Build Coastguard WorkerYou can run a presubmit program or step as a `git hook
421*61c4878aSAndroid Build Coastguard Worker<https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks>`_ using
422*61c4878aSAndroid Build Coastguard Worker``pw_presubmit.install_hook``.  This can be used to run certain presubmit
423*61c4878aSAndroid Build Coastguard Workerchecks before a change is pushed to a remote.
424*61c4878aSAndroid Build Coastguard Worker
425*61c4878aSAndroid Build Coastguard WorkerWe strongly recommend that you only run fast (< 15 seconds) and trivial checks
426*61c4878aSAndroid Build Coastguard Workeras push hooks, and perform slower or more complex ones in CI. This is because,
427*61c4878aSAndroid Build Coastguard Worker
428*61c4878aSAndroid Build Coastguard Worker* Running slow checks in the push hook will force you to wait longer for
429*61c4878aSAndroid Build Coastguard Worker  ``git push`` to complete, and
430*61c4878aSAndroid Build Coastguard Worker* If your change fails one of the checks at this stage, it will not yet be
431*61c4878aSAndroid Build Coastguard Worker  uploaded to the remote, so you'll have a harder time debugging any failures
432*61c4878aSAndroid Build Coastguard Worker  (sharing the change with your colleagues, linking to it from an issue
433*61c4878aSAndroid Build Coastguard Worker  tracker, etc).
434*61c4878aSAndroid Build Coastguard Worker
435*61c4878aSAndroid Build Coastguard WorkerExample
436*61c4878aSAndroid Build Coastguard Worker=======
437*61c4878aSAndroid Build Coastguard WorkerA simple example presubmit check script follows. This can be copied-and-pasted
438*61c4878aSAndroid Build Coastguard Workerto serve as a starting point for a project's presubmit check script.
439*61c4878aSAndroid Build Coastguard Worker
440*61c4878aSAndroid Build Coastguard WorkerSee ``pigweed_presubmit.py`` for a more complex presubmit check script example.
441*61c4878aSAndroid Build Coastguard Worker
442*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
443*61c4878aSAndroid Build Coastguard Worker
444*61c4878aSAndroid Build Coastguard Worker   """Example presubmit check script."""
445*61c4878aSAndroid Build Coastguard Worker
446*61c4878aSAndroid Build Coastguard Worker   import argparse
447*61c4878aSAndroid Build Coastguard Worker   import logging
448*61c4878aSAndroid Build Coastguard Worker   import os
449*61c4878aSAndroid Build Coastguard Worker   from pathlib import Path
450*61c4878aSAndroid Build Coastguard Worker   import re
451*61c4878aSAndroid Build Coastguard Worker   import sys
452*61c4878aSAndroid Build Coastguard Worker
453*61c4878aSAndroid Build Coastguard Worker   try:
454*61c4878aSAndroid Build Coastguard Worker       import pw_cli.log
455*61c4878aSAndroid Build Coastguard Worker   except ImportError:
456*61c4878aSAndroid Build Coastguard Worker       print("ERROR: Activate the environment before running presubmits!", file=sys.stderr)
457*61c4878aSAndroid Build Coastguard Worker       sys.exit(2)
458*61c4878aSAndroid Build Coastguard Worker
459*61c4878aSAndroid Build Coastguard Worker   import pw_presubmit
460*61c4878aSAndroid Build Coastguard Worker   from pw_presubmit import (
461*61c4878aSAndroid Build Coastguard Worker       build,
462*61c4878aSAndroid Build Coastguard Worker       cli,
463*61c4878aSAndroid Build Coastguard Worker       cpp_checks,
464*61c4878aSAndroid Build Coastguard Worker       format_code,
465*61c4878aSAndroid Build Coastguard Worker       inclusive_language,
466*61c4878aSAndroid Build Coastguard Worker       python_checks,
467*61c4878aSAndroid Build Coastguard Worker   )
468*61c4878aSAndroid Build Coastguard Worker   from pw_presubmit.presubmit import filter_paths
469*61c4878aSAndroid Build Coastguard Worker   from pw_presubmit.presubmit_context import PresubmitContext
470*61c4878aSAndroid Build Coastguard Worker   from pw_presubmit.install_hook import install_git_hook
471*61c4878aSAndroid Build Coastguard Worker
472*61c4878aSAndroid Build Coastguard Worker   # Set up variables for key project paths.
473*61c4878aSAndroid Build Coastguard Worker   PROJECT_ROOT = Path(os.environ["MY_PROJECT_ROOT"])
474*61c4878aSAndroid Build Coastguard Worker   PIGWEED_ROOT = PROJECT_ROOT / "pigweed"
475*61c4878aSAndroid Build Coastguard Worker
476*61c4878aSAndroid Build Coastguard Worker   # Rerun the build if files with these extensions change.
477*61c4878aSAndroid Build Coastguard Worker   _BUILD_EXTENSIONS = frozenset(
478*61c4878aSAndroid Build Coastguard Worker       [".rst", ".gn", ".gni", *format_code.C_FORMAT.extensions]
479*61c4878aSAndroid Build Coastguard Worker   )
480*61c4878aSAndroid Build Coastguard Worker
481*61c4878aSAndroid Build Coastguard Worker
482*61c4878aSAndroid Build Coastguard Worker   #
483*61c4878aSAndroid Build Coastguard Worker   # Presubmit checks
484*61c4878aSAndroid Build Coastguard Worker   #
485*61c4878aSAndroid Build Coastguard Worker   def release_build(ctx: PresubmitContext):
486*61c4878aSAndroid Build Coastguard Worker       build.gn_gen(ctx, build_type="release")
487*61c4878aSAndroid Build Coastguard Worker       build.ninja(ctx)
488*61c4878aSAndroid Build Coastguard Worker       build.gn_check(ctx)  # Run after building to check generated files.
489*61c4878aSAndroid Build Coastguard Worker
490*61c4878aSAndroid Build Coastguard Worker
491*61c4878aSAndroid Build Coastguard Worker   def host_tests(ctx: PresubmitContext):
492*61c4878aSAndroid Build Coastguard Worker       build.gn_gen(ctx, run_host_tests="true")
493*61c4878aSAndroid Build Coastguard Worker       build.ninja(ctx)
494*61c4878aSAndroid Build Coastguard Worker       build.gn_check(ctx)
495*61c4878aSAndroid Build Coastguard Worker
496*61c4878aSAndroid Build Coastguard Worker
497*61c4878aSAndroid Build Coastguard Worker   # Avoid running some checks on certain paths.
498*61c4878aSAndroid Build Coastguard Worker   PATH_EXCLUSIONS = (
499*61c4878aSAndroid Build Coastguard Worker       re.compile(r"^external/"),
500*61c4878aSAndroid Build Coastguard Worker       re.compile(r"^vendor/"),
501*61c4878aSAndroid Build Coastguard Worker   )
502*61c4878aSAndroid Build Coastguard Worker
503*61c4878aSAndroid Build Coastguard Worker
504*61c4878aSAndroid Build Coastguard Worker   # Use the upstream pragma_once check, but apply a different set of path
505*61c4878aSAndroid Build Coastguard Worker   # filters with @filter_paths.
506*61c4878aSAndroid Build Coastguard Worker   @filter_paths(endswith=".h", exclude=PATH_EXCLUSIONS)
507*61c4878aSAndroid Build Coastguard Worker   def pragma_once(ctx: PresubmitContext):
508*61c4878aSAndroid Build Coastguard Worker       cpp_checks.pragma_once(ctx)
509*61c4878aSAndroid Build Coastguard Worker
510*61c4878aSAndroid Build Coastguard Worker
511*61c4878aSAndroid Build Coastguard Worker   #
512*61c4878aSAndroid Build Coastguard Worker   # Presubmit check programs
513*61c4878aSAndroid Build Coastguard Worker   #
514*61c4878aSAndroid Build Coastguard Worker   OTHER = (
515*61c4878aSAndroid Build Coastguard Worker       # Checks not ran by default but that should be available. These might
516*61c4878aSAndroid Build Coastguard Worker       # include tests that are expensive to run or that don't yet pass.
517*61c4878aSAndroid Build Coastguard Worker       build.gn_gen_check,
518*61c4878aSAndroid Build Coastguard Worker   )
519*61c4878aSAndroid Build Coastguard Worker
520*61c4878aSAndroid Build Coastguard Worker   QUICK = (
521*61c4878aSAndroid Build Coastguard Worker       # List some presubmit checks to run
522*61c4878aSAndroid Build Coastguard Worker       pragma_once,
523*61c4878aSAndroid Build Coastguard Worker       host_tests,
524*61c4878aSAndroid Build Coastguard Worker       # Use the upstream formatting checks, with custom path filters applied.
525*61c4878aSAndroid Build Coastguard Worker       format_code.presubmit_checks(exclude=PATH_EXCLUSIONS),
526*61c4878aSAndroid Build Coastguard Worker       # Include the upstream inclusive language check.
527*61c4878aSAndroid Build Coastguard Worker       inclusive_language.presubmit_check,
528*61c4878aSAndroid Build Coastguard Worker       # Include just the lint-related Python checks.
529*61c4878aSAndroid Build Coastguard Worker       python_checks.gn_python_lint.with_filter(exclude=PATH_EXCLUSIONS),
530*61c4878aSAndroid Build Coastguard Worker   )
531*61c4878aSAndroid Build Coastguard Worker
532*61c4878aSAndroid Build Coastguard Worker   FULL = (
533*61c4878aSAndroid Build Coastguard Worker       QUICK,  # Add all checks from the 'quick' program
534*61c4878aSAndroid Build Coastguard Worker       release_build,
535*61c4878aSAndroid Build Coastguard Worker       # Use the upstream Python checks, with custom path filters applied.
536*61c4878aSAndroid Build Coastguard Worker       # Checks listed multiple times are only run once.
537*61c4878aSAndroid Build Coastguard Worker       python_checks.gn_python_check.with_filter(exclude=PATH_EXCLUSIONS),
538*61c4878aSAndroid Build Coastguard Worker   )
539*61c4878aSAndroid Build Coastguard Worker
540*61c4878aSAndroid Build Coastguard Worker   PROGRAMS = pw_presubmit.Programs(other=OTHER, quick=QUICK, full=FULL)
541*61c4878aSAndroid Build Coastguard Worker
542*61c4878aSAndroid Build Coastguard Worker
543*61c4878aSAndroid Build Coastguard Worker   #
544*61c4878aSAndroid Build Coastguard Worker   # Allowlist of remote refs for presubmit. If the remote ref being pushed to
545*61c4878aSAndroid Build Coastguard Worker   # matches any of these values (with regex matching), then the presubmits
546*61c4878aSAndroid Build Coastguard Worker   # checks will be run before pushing.
547*61c4878aSAndroid Build Coastguard Worker   #
548*61c4878aSAndroid Build Coastguard Worker   PRE_PUSH_REMOTE_REF_ALLOWLIST = ("refs/for/main",)
549*61c4878aSAndroid Build Coastguard Worker
550*61c4878aSAndroid Build Coastguard Worker
551*61c4878aSAndroid Build Coastguard Worker   def run(install: bool, remote_ref: str | None, **presubmit_args) -> int:
552*61c4878aSAndroid Build Coastguard Worker       """Process the --install argument then invoke pw_presubmit."""
553*61c4878aSAndroid Build Coastguard Worker
554*61c4878aSAndroid Build Coastguard Worker       # Install the presubmit Git pre-push hook, if requested.
555*61c4878aSAndroid Build Coastguard Worker       if install:
556*61c4878aSAndroid Build Coastguard Worker           # '$remote_ref' will be replaced by the actual value of the remote ref
557*61c4878aSAndroid Build Coastguard Worker           # at runtime.
558*61c4878aSAndroid Build Coastguard Worker           install_git_hook(
559*61c4878aSAndroid Build Coastguard Worker               "pre-push",
560*61c4878aSAndroid Build Coastguard Worker               [
561*61c4878aSAndroid Build Coastguard Worker                   "python",
562*61c4878aSAndroid Build Coastguard Worker                   "-m",
563*61c4878aSAndroid Build Coastguard Worker                   "tools.presubmit_check",
564*61c4878aSAndroid Build Coastguard Worker                   "--base",
565*61c4878aSAndroid Build Coastguard Worker                   "HEAD~",
566*61c4878aSAndroid Build Coastguard Worker                   "--remote-ref",
567*61c4878aSAndroid Build Coastguard Worker                   "$remote_ref",
568*61c4878aSAndroid Build Coastguard Worker               ],
569*61c4878aSAndroid Build Coastguard Worker           )
570*61c4878aSAndroid Build Coastguard Worker           return 0
571*61c4878aSAndroid Build Coastguard Worker
572*61c4878aSAndroid Build Coastguard Worker       # Run the checks if either no remote_ref was passed, or if the remote ref
573*61c4878aSAndroid Build Coastguard Worker       # matches anything in the allowlist.
574*61c4878aSAndroid Build Coastguard Worker       if remote_ref is None or any(
575*61c4878aSAndroid Build Coastguard Worker           re.search(pattern, remote_ref)
576*61c4878aSAndroid Build Coastguard Worker           for pattern in PRE_PUSH_REMOTE_REF_ALLOWLIST
577*61c4878aSAndroid Build Coastguard Worker       ):
578*61c4878aSAndroid Build Coastguard Worker           return cli.run(root=PROJECT_ROOT, **presubmit_args)
579*61c4878aSAndroid Build Coastguard Worker       return 0
580*61c4878aSAndroid Build Coastguard Worker
581*61c4878aSAndroid Build Coastguard Worker
582*61c4878aSAndroid Build Coastguard Worker   def main() -> int:
583*61c4878aSAndroid Build Coastguard Worker       """Run the presubmit checks for this repository."""
584*61c4878aSAndroid Build Coastguard Worker       parser = argparse.ArgumentParser(description=__doc__)
585*61c4878aSAndroid Build Coastguard Worker       cli.add_arguments(parser, PROGRAMS, "quick")
586*61c4878aSAndroid Build Coastguard Worker
587*61c4878aSAndroid Build Coastguard Worker       # Define an option for installing a Git pre-push hook for this script.
588*61c4878aSAndroid Build Coastguard Worker       parser.add_argument(
589*61c4878aSAndroid Build Coastguard Worker           "--install",
590*61c4878aSAndroid Build Coastguard Worker           action="store_true",
591*61c4878aSAndroid Build Coastguard Worker           help="Install the presubmit as a Git pre-push hook and exit.",
592*61c4878aSAndroid Build Coastguard Worker       )
593*61c4878aSAndroid Build Coastguard Worker
594*61c4878aSAndroid Build Coastguard Worker       # Define an optional flag to pass the remote ref into this script, if it
595*61c4878aSAndroid Build Coastguard Worker       # is run as a pre-push hook. The destination variable in the parsed args
596*61c4878aSAndroid Build Coastguard Worker       # will be `remote_ref`, as dashes are replaced with underscores to make
597*61c4878aSAndroid Build Coastguard Worker       # valid variable names.
598*61c4878aSAndroid Build Coastguard Worker       parser.add_argument(
599*61c4878aSAndroid Build Coastguard Worker           "--remote-ref",
600*61c4878aSAndroid Build Coastguard Worker           default=None,
601*61c4878aSAndroid Build Coastguard Worker           nargs="?",  # Make optional.
602*61c4878aSAndroid Build Coastguard Worker           help="Remote ref of the push command, for use by the pre-push hook.",
603*61c4878aSAndroid Build Coastguard Worker       )
604*61c4878aSAndroid Build Coastguard Worker
605*61c4878aSAndroid Build Coastguard Worker       return run(**vars(parser.parse_args()))
606*61c4878aSAndroid Build Coastguard Worker
607*61c4878aSAndroid Build Coastguard Worker
608*61c4878aSAndroid Build Coastguard Worker   if __name__ == "__main__":
609*61c4878aSAndroid Build Coastguard Worker       pw_cli.log.install(logging.INFO)
610*61c4878aSAndroid Build Coastguard Worker       sys.exit(main())
611*61c4878aSAndroid Build Coastguard Worker
612*61c4878aSAndroid Build Coastguard Worker---------------------
613*61c4878aSAndroid Build Coastguard WorkerCode formatting tools
614*61c4878aSAndroid Build Coastguard Worker---------------------
615*61c4878aSAndroid Build Coastguard WorkerThe ``pw_presubmit.format_code`` module formats supported source files using
616*61c4878aSAndroid Build Coastguard Workerexternal code format tools. The file ``format_code.py`` can be invoked directly
617*61c4878aSAndroid Build Coastguard Workerfrom the command line or from ``pw`` as ``pw format``.
618*61c4878aSAndroid Build Coastguard Worker
619*61c4878aSAndroid Build Coastguard WorkerExample
620*61c4878aSAndroid Build Coastguard Worker=======
621*61c4878aSAndroid Build Coastguard WorkerA simple example of adding support for a custom format. This code wraps the
622*61c4878aSAndroid Build Coastguard Workerbuilt in formatter to add a new format. It could also be used to replace
623*61c4878aSAndroid Build Coastguard Workera formatter or remove/disable a PigWeed supplied one.
624*61c4878aSAndroid Build Coastguard Worker
625*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
626*61c4878aSAndroid Build Coastguard Worker
627*61c4878aSAndroid Build Coastguard Worker   #!/usr/bin/env python
628*61c4878aSAndroid Build Coastguard Worker   """Formats files in repository. """
629*61c4878aSAndroid Build Coastguard Worker
630*61c4878aSAndroid Build Coastguard Worker   import logging
631*61c4878aSAndroid Build Coastguard Worker   import sys
632*61c4878aSAndroid Build Coastguard Worker
633*61c4878aSAndroid Build Coastguard Worker   import pw_cli.log
634*61c4878aSAndroid Build Coastguard Worker   from pw_presubmit import format_code
635*61c4878aSAndroid Build Coastguard Worker   from your_project import presubmit_checks
636*61c4878aSAndroid Build Coastguard Worker   from your_project import your_check
637*61c4878aSAndroid Build Coastguard Worker
638*61c4878aSAndroid Build Coastguard Worker   YOUR_CODE_FORMAT = CodeFormat('YourFormat',
639*61c4878aSAndroid Build Coastguard Worker                                 filter=FileFilter(suffix=('.your', )),
640*61c4878aSAndroid Build Coastguard Worker                                 check=your_check.check,
641*61c4878aSAndroid Build Coastguard Worker                                 fix=your_check.fix)
642*61c4878aSAndroid Build Coastguard Worker
643*61c4878aSAndroid Build Coastguard Worker   CODE_FORMATS = (*format_code.CODE_FORMATS, YOUR_CODE_FORMAT)
644*61c4878aSAndroid Build Coastguard Worker
645*61c4878aSAndroid Build Coastguard Worker   def _run(exclude, **kwargs) -> int:
646*61c4878aSAndroid Build Coastguard Worker       """Check and fix formatting for source files in the repo."""
647*61c4878aSAndroid Build Coastguard Worker       return format_code.format_paths_in_repo(exclude=exclude,
648*61c4878aSAndroid Build Coastguard Worker                                               code_formats=CODE_FORMATS,
649*61c4878aSAndroid Build Coastguard Worker                                               **kwargs)
650*61c4878aSAndroid Build Coastguard Worker
651*61c4878aSAndroid Build Coastguard Worker
652*61c4878aSAndroid Build Coastguard Worker   def main():
653*61c4878aSAndroid Build Coastguard Worker       return _run(**vars(format_code.arguments(git_paths=True).parse_args()))
654*61c4878aSAndroid Build Coastguard Worker
655*61c4878aSAndroid Build Coastguard Worker
656*61c4878aSAndroid Build Coastguard Worker   if __name__ == '__main__':
657*61c4878aSAndroid Build Coastguard Worker       pw_cli.log.install(logging.INFO)
658*61c4878aSAndroid Build Coastguard Worker       sys.exit(main())
659*61c4878aSAndroid Build Coastguard Worker
660*61c4878aSAndroid Build Coastguard Worker.. pw_presubmit-nav-end
661*61c4878aSAndroid Build Coastguard Worker
662*61c4878aSAndroid Build Coastguard Worker.. toctree::
663*61c4878aSAndroid Build Coastguard Worker   :maxdepth: 1
664*61c4878aSAndroid Build Coastguard Worker   :hidden:
665*61c4878aSAndroid Build Coastguard Worker
666*61c4878aSAndroid Build Coastguard Worker   format
667