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