.. _module-pw_presubmit:

============
pw_presubmit
============
The presubmit module provides Python tools for running presubmit checks and
checking and fixing code format. It also includes the presubmit check script for
the Pigweed repository, ``pigweed_presubmit.py``.

Presubmit checks are essential tools, but they take work to set up, and
projects don’t always get around to it. The ``pw_presubmit`` module provides
tools for setting up high quality presubmit checks for any project. We use this
framework to run Pigweed’s presubmit on our workstations and in our automated
building tools.

The ``pw_presubmit`` module also includes ``pw format``, a tool that provides a
unified interface for automatically formatting code in a variety of languages.
With ``pw format``, you can format Bazel, C, C++, Python, GN, and Go code
according to configurations defined by your project. ``pw format`` leverages
existing tools like ``clang-format``, and it’s simple to add support for new
languages. (Note: Bazel formatting requires ``buildifier`` to be present on your
system. If it's not Bazel formatting passes without checking.)

.. image:: docs/pw_presubmit_demo.gif
   :alt: ``pw format`` demo
   :align: left

The ``pw_presubmit`` package includes presubmit checks that can be used with any
project. These checks include:

* Check code format of several languages including C, C++, and Python
* Initialize a Python environment
* Run all Python tests
* Run pylint
* Run mypy
* Ensure source files are included in the GN and Bazel builds
* Build and run all tests with GN
* Build and run all tests with Bazel
* Ensure all header files contain ``#pragma once``

-------------
Compatibility
-------------
Python 3

-------------------------------------------
Creating a presubmit check for your project
-------------------------------------------
Creating a presubmit check for a project using ``pw_presubmit`` is simple, but
requires some customization. Projects must define their own presubmit check
Python script that uses the ``pw_presubmit`` package.

A project's presubmit script can be registered as a
:ref:`pw_cli <module-pw_cli>` plugin, so that it can be run as ``pw
presubmit``.

Setting up the command-line interface
=====================================
The ``pw_presubmit.cli`` module sets up the command-line interface for a
presubmit script. This defines a standard set of arguments for invoking
presubmit checks. Its use is optional, but recommended.

pw_presubmit.cli
----------------
.. automodule:: pw_presubmit.cli
   :members: add_arguments, run

Presubmit output directory
--------------------------
The ``pw_presubmit`` command line interface includes an ``--output-directory``
option that specifies the working directory to use for presubmits. The default
path is ``out/presubmit``.  A subdirectory is created for each presubmit step.
This directory persists between presubmit runs and can be cleaned by deleting it
or running ``pw presubmit --clean``.

Presubmit checks
================
A presubmit check is defined as a function or other callable. The function must
accept one argument: a ``PresubmitContext``, which provides the paths on which
to run. Presubmit checks communicate failure by raising an exception.

Presubmit checks may use the ``filter_paths`` decorator to automatically filter
the paths list for file types they care about.

Either of these functions could be used as presubmit checks:

.. code-block:: python

  @pw_presubmit.filter_paths(endswith='.py')
  def file_contains_ni(ctx: PresubmitContext):
      for path in ctx.paths:
          with open(path) as file:
              contents = file.read()
              if 'ni' not in contents and 'nee' not in contents:
                  raise PresumitFailure('Files must say "ni"!', path=path)

  def run_the_build(_):
      subprocess.run(['make', 'release'], check=True)

Presubmit checks functions are grouped into "programs" -- a named series of
checks. Projects may find it helpful to have programs for different purposes,
such as a quick program for local use and a full program for automated use. The
:ref:`example script <example-script>` uses ``pw_presubmit.Programs`` to define
``quick`` and ``full`` programs.

``PresubmitContext`` has the following members:

* ``root``: Source checkout root directory
* ``repos``: Repositories (top-level and submodules) processed by
  ``pw presubmit``
* ``output_dir``: Output directory for the presubmit step
* ``paths``: Modified files for the presubmit step to check (often used in
  formatting steps but ignored in compile steps)
* ``package_root``: Root directory for ``pw package`` installations
* ``override_gn_args``: Additional GN args processed by ``build.gn_gen()``
* ``luci``: Information about the LUCI build or None if not running in LUCI
* ``num_jobs``: Number of jobs to run in parallel

The ``luci`` member is of type ``LuciContext`` and has the following members:

* ``buildbucket_id``: The globally-unique buildbucket id of the build
* ``build_number``: The builder-specific incrementing build number, if
  configured for this builder
* ``project``: The LUCI project under which this build is running (often
  ``pigweed`` or ``pigweed-internal``)
* ``bucket``: The LUCI bucket under which this build is running (often ends
  with ``ci`` or ``try``)
* ``builder``: The builder being run
* ``swarming_task_id``: The swarming task id of this build

Existing Presubmit Checks
-------------------------
A small number of presubmit checks are made available through ``pw_presubmit``
modules.

Code Formatting
^^^^^^^^^^^^^^^
Formatting checks for a variety of languages are available from
``pw_presubmit.format_code``. These include C/C++, Java, Go, Python, GN, and
others. All of these checks can be included by adding
``pw_presubmit.format_code.presubmit_checks()`` to a presubmit program. These
all use language-specific formatters like clang-format or yapf.

These will suggest fixes using ``pw format --fix``.

#pragma once
^^^^^^^^^^^^
There's a ``pragma_once`` check that confirms the first non-comment line of
C/C++ headers is ``#pragma once``. This is enabled by adding
``pw_presubmit.pragma_once`` to a presubmit program.

.. todo-check: disable

TODO(b/###) Formatting
^^^^^^^^^^^^^^^^^^^^^^^^^
There's a check that confirms ``TODO`` lines match a given format. Upstream
Pigweed expects these to look like ``TODO(b/###): Explanation``, but makes it
easy for projects to define their own pattern instead.

To use this check add ``todo_check.create(todo_check.BUGS_OR_USERNAMES)`` to a
presubmit program.

.. todo-check: enable

Python Checks
^^^^^^^^^^^^^
There are two checks in the ``pw_presubmit.python_checks`` module, ``gn_pylint``
and ``gn_python_check``. They assume there's a top-level ``python`` GN target.
``gn_pylint`` runs Pylint and Mypy checks and ``gn_python_check`` runs Pylint,
Mypy, and all Python tests.

Inclusive Language
^^^^^^^^^^^^^^^^^^
.. inclusive-language: disable

The inclusive language check looks for words that are typical of non-inclusive
code, like using "master" and "slave" in place of "primary" and "secondary" or
"sanity check" in place of "consistency check".

.. inclusive-language: enable

These checks can be disabled for individual lines with
"inclusive-language: ignore" on the line in question or the line above it, or
for entire blocks by using "inclusive-language: disable" before the block and
"inclusive-language: enable" after the block.

.. In case things get moved around in the previous paragraphs the enable line
.. is repeated here: inclusive-language: enable.

pw_presubmit
------------
.. automodule:: pw_presubmit
   :members: filter_paths, FileFilter, call, PresubmitFailure, Programs

.. _example-script:


Git hook
--------
You can run a presubmit program or step as a `git hook
<https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks>`_ using
``pw_presubmit.install_hook``.  This can be used to run certain presubmit
checks before a change is pushed to a remote.

We strongly recommend that you only run fast (< 15 seconds) and trivial checks
as push hooks, and perform slower or more complex ones in CI. This is because,

* Running slow checks in the push hook will force you to wait longer for
  ``git push`` to complete, and
* If your change fails one of the checks at this stage, it will not yet be
  uploaded to the remote, so you'll have a harder time debugging any failures
  (sharing the change with your colleagues, linking to it from an issue
  tracker, etc).

Example
=======
A simple example presubmit check script follows. This can be copied-and-pasted
to serve as a starting point for a project's presubmit check script.

See ``pigweed_presubmit.py`` for a more complex presubmit check script example.

.. code-block:: python

  """Example presubmit check script."""

  import argparse
  import logging
  import os
  from pathlib import Path
  import re
  import sys
  from typing import List, Optional, Pattern

  try:
      import pw_cli.log
  except ImportError:
      print('ERROR: Activate the environment before running presubmits!',
            file=sys.stderr)
      sys.exit(2)

  import pw_presubmit
  from pw_presubmit import (
      build,
      cli,
      cpp_checks,
      environment,
      format_code,
      git_repo,
      inclusive_language,
      filter_paths,
      python_checks,
      PresubmitContext,
  )
  from pw_presubmit.install_hook import install_hook

  # Set up variables for key project paths.
  PROJECT_ROOT = Path(os.environ['MY_PROJECT_ROOT'])
  PIGWEED_ROOT = PROJECT_ROOT / 'pigweed'

  # Rerun the build if files with these extensions change.
  _BUILD_EXTENSIONS = frozenset(
      ['.rst', '.gn', '.gni', *format_code.C_FORMAT.extensions])


  #
  # Presubmit checks
  #
  def release_build(ctx: PresubmitContext):
      build.gn_gen(ctx, build_type='release')
      build.ninja(ctx)


  def host_tests(ctx: PresubmitContext):
      build.gn_gen(ctx, run_host_tests='true')
      build.ninja(ctx)


  # Avoid running some checks on certain paths.
  PATH_EXCLUSIONS = (
      re.compile(r'^external/'),
      re.compile(r'^vendor/'),
  )


  # Use the upstream pragma_once check, but apply a different set of path
  # filters with @filter_paths.
  @filter_paths(endswith='.h', exclude=PATH_EXCLUSIONS)
  def pragma_once(ctx: PresubmitContext):
      cpp_checks.pragma_once(ctx)


  #
  # Presubmit check programs
  #
  OTHER = (
      # Checks not ran by default but that should be available. These might
      # include tests that are expensive to run or that don't yet pass.
      build.gn_quick_check,
  )

  QUICK = (
      # List some presubmit checks to run
      pragma_once,
      host_tests,
      # Use the upstream formatting checks, with custom path filters applied.
      format_code.presubmit_checks(exclude=PATH_EXCLUSIONS),
      # Include the upstream inclusive language check.
      inclusive_language.inclusive_language,
      # Include just the lint-related Python checks.
      python_checks.gn_pylint.with_filter(exclude=PATH_EXCLUSIONS),
  )

  FULL = (
      QUICK,  # Add all checks from the 'quick' program
      release_build,
      # Use the upstream Python checks, with custom path filters applied.
      # Checks listed multiple times are only run once.
      python_checks.gn_python_check.with_filter(exclude=PATH_EXCLUSIONS),
  )

  PROGRAMS = pw_presubmit.Programs(other=OTHER, quick=QUICK, full=FULL)


  #
  # Allowlist of remote refs for presubmit. If the remote ref being pushed to
  # matches any of these values (with regex matching), then the presubmits
  # checks will be run before pushing.
  #
  PRE_PUSH_REMOTE_REF_ALLOWLIST = (
      'refs/for/main',
  )


  def run(install: bool, remote_ref: Optional[str],  **presubmit_args) -> int:
      """Process the --install argument then invoke pw_presubmit."""

      # Install the presubmit Git pre-push hook, if requested.
      if install:
          # '$remote_ref' will be replaced by the actual value of the remote ref
          # at runtime.
          install_git_hook('pre-push', [
              'python', '-m', 'tools.presubmit_check', '--base', 'HEAD~',
              '--remote-ref', '$remote_ref'
          ])
          return 0

      # Run the checks if either no remote_ref was passed, or if the remote ref
      # matches anything in the allowlist.
      if remote_ref is None or any(
              re.search(pattern, remote_ref)
              for pattern in PRE_PUSH_REMOTE_REF_ALLOWLIST):
          return cli.run(root=PROJECT_ROOT, **presubmit_args)


  def main() -> int:
      """Run the presubmit checks for this repository."""
      parser = argparse.ArgumentParser(description=__doc__)
      cli.add_arguments(parser, PROGRAMS, 'quick')

      # Define an option for installing a Git pre-push hook for this script.
      parser.add_argument(
          '--install',
          action='store_true',
          help='Install the presubmit as a Git pre-push hook and exit.')

      # Define an optional flag to pass the remote ref into this script, if it
      # is run as a pre-push hook. The destination variable in the parsed args
      # will be `remote_ref`, as dashes are replaced with underscores to make
      # valid variable names.
      parser.add_argument(
          '--remote-ref',
          default=None,
          nargs='?',  # Make optional.
          help='Remote ref of the push command, for use by the pre-push hook.')

      return run(**vars(parser.parse_args()))

  if __name__ == '__main__':
      pw_cli.log.install(logging.INFO)
      sys.exit(main())

---------------------
Code formatting tools
---------------------
The ``pw_presubmit.format_code`` module formats supported source files using
external code format tools. The file ``format_code.py`` can be invoked directly
from the command line or from ``pw`` as ``pw format``.

Example
=======
A simple example of adding support for a custom format. This code wraps the
built in formatter to add a new format. It could also be used to replace
a formatter or remove/disable a PigWeed supplied one.

.. code-block:: python

  #!/usr/bin/env python
  """Formats files in repository. """

  import logging
  import sys

  import pw_cli.log
  from pw_presubmit import format_code
  from your_project import presubmit_checks
  from your_project import your_check

  YOUR_CODE_FORMAT = CodeFormat('YourFormat',
                                filter=FileFilter(suffix=('.your', )),
                                check=your_check.check,
                                fix=your_check.fix)

  CODE_FORMATS = (*format_code.CODE_FORMATS, YOUR_CODE_FORMAT)

  def _run(exclude, **kwargs) -> int:
      """Check and fix formatting for source files in the repo."""
      return format_code.format_paths_in_repo(exclude=exclude,
                                              code_formats=CODE_FORMATS,
                                              **kwargs)


  def main():
      return _run(**vars(format_code.arguments(git_paths=True).parse_args()))


  if __name__ == '__main__':
      pw_cli.log.install(logging.INFO)
      sys.exit(main())
