xref: /aosp_15_r20/external/open-dice/tools/open_dice_tools/presubmit.py (revision 60b67249c2e226f42f35cc6cfe66c6048e0bae6b)
1*60b67249SAndroid Build Coastguard Worker# Copyright 2023 Google LLC
2*60b67249SAndroid Build Coastguard Worker#
3*60b67249SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker# the License at
6*60b67249SAndroid Build Coastguard Worker#
7*60b67249SAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker#
9*60b67249SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker# the License.
14*60b67249SAndroid Build Coastguard Worker"""Presubmit script."""
15*60b67249SAndroid Build Coastguard Worker
16*60b67249SAndroid Build Coastguard Workerimport argparse
17*60b67249SAndroid Build Coastguard Workerimport logging
18*60b67249SAndroid Build Coastguard Workerimport os
19*60b67249SAndroid Build Coastguard Workerfrom pathlib import Path
20*60b67249SAndroid Build Coastguard Workerimport re
21*60b67249SAndroid Build Coastguard Workerimport sys
22*60b67249SAndroid Build Coastguard Worker
23*60b67249SAndroid Build Coastguard Workerimport pw_cli.log
24*60b67249SAndroid Build Coastguard Workerimport pw_presubmit
25*60b67249SAndroid Build Coastguard Workerfrom pw_presubmit import (
26*60b67249SAndroid Build Coastguard Worker    build,
27*60b67249SAndroid Build Coastguard Worker    cli,
28*60b67249SAndroid Build Coastguard Worker    cpp_checks,
29*60b67249SAndroid Build Coastguard Worker    format_code,
30*60b67249SAndroid Build Coastguard Worker    git_repo,
31*60b67249SAndroid Build Coastguard Worker    inclusive_language,
32*60b67249SAndroid Build Coastguard Worker    install_hook,
33*60b67249SAndroid Build Coastguard Worker    keep_sorted,
34*60b67249SAndroid Build Coastguard Worker    presubmit_context,
35*60b67249SAndroid Build Coastguard Worker    python_checks,
36*60b67249SAndroid Build Coastguard Worker)
37*60b67249SAndroid Build Coastguard Worker
38*60b67249SAndroid Build Coastguard Worker_LOG = logging.getLogger(__name__)
39*60b67249SAndroid Build Coastguard Worker
40*60b67249SAndroid Build Coastguard Worker# Set up variables for key project paths.
41*60b67249SAndroid Build Coastguard Workertry:
42*60b67249SAndroid Build Coastguard Worker    PROJECT_ROOT = Path(os.environ["PW_PROJECT_ROOT"])
43*60b67249SAndroid Build Coastguard Workerexcept KeyError:
44*60b67249SAndroid Build Coastguard Worker    print(
45*60b67249SAndroid Build Coastguard Worker        "ERROR: The presubmit checks must be run in the Open Dice project's "
46*60b67249SAndroid Build Coastguard Worker        "root directory",
47*60b67249SAndroid Build Coastguard Worker        file=sys.stderr,
48*60b67249SAndroid Build Coastguard Worker    )
49*60b67249SAndroid Build Coastguard Worker    sys.exit(2)
50*60b67249SAndroid Build Coastguard Worker
51*60b67249SAndroid Build Coastguard WorkerPIGWEED_ROOT = PROJECT_ROOT / "third_party" / "pigweed" / "src"
52*60b67249SAndroid Build Coastguard Worker
53*60b67249SAndroid Build Coastguard Worker# Rerun the build if files with these extensions change.
54*60b67249SAndroid Build Coastguard Worker_BUILD_EXTENSIONS = frozenset(
55*60b67249SAndroid Build Coastguard Worker    [".rst", ".gn", ".gni", *format_code.C_FORMAT.extensions]
56*60b67249SAndroid Build Coastguard Worker)
57*60b67249SAndroid Build Coastguard Worker
58*60b67249SAndroid Build Coastguard Workerdefault_build = build.GnGenNinja(name="default_build")
59*60b67249SAndroid Build Coastguard Worker
60*60b67249SAndroid Build Coastguard WorkerEXCLUSIONS = presubmit_context.FormatOptions.load().exclude
61*60b67249SAndroid Build Coastguard Worker
62*60b67249SAndroid Build Coastguard WorkerOTHER_CHECKS = (build.gn_gen_check,)
63*60b67249SAndroid Build Coastguard Worker
64*60b67249SAndroid Build Coastguard Worker_FORMAT = (format_code.presubmit_checks(exclude=EXCLUSIONS),)
65*60b67249SAndroid Build Coastguard Worker
66*60b67249SAndroid Build Coastguard WorkerQUICK = (
67*60b67249SAndroid Build Coastguard Worker    default_build,
68*60b67249SAndroid Build Coastguard Worker    _FORMAT,
69*60b67249SAndroid Build Coastguard Worker)
70*60b67249SAndroid Build Coastguard Worker
71*60b67249SAndroid Build Coastguard Worker
72*60b67249SAndroid Build Coastguard Workerdef include_guard(path: Path) -> str:
73*60b67249SAndroid Build Coastguard Worker    path = path.relative_to(PROJECT_ROOT)
74*60b67249SAndroid Build Coastguard Worker    exclude = ("include",)
75*60b67249SAndroid Build Coastguard Worker    transform = {"ulib": "lib"}
76*60b67249SAndroid Build Coastguard Worker    parts = [transform.get(x, x) for x in path.parts if x not in exclude]
77*60b67249SAndroid Build Coastguard Worker    return re.sub(r"[.-]", "_", "".join(f"{x}_" for x in parts).upper())
78*60b67249SAndroid Build Coastguard Worker
79*60b67249SAndroid Build Coastguard Worker
80*60b67249SAndroid Build Coastguard WorkerLINTFORMAT = (
81*60b67249SAndroid Build Coastguard Worker    _FORMAT,
82*60b67249SAndroid Build Coastguard Worker    cpp_checks.include_guard_check(include_guard).with_filter(
83*60b67249SAndroid Build Coastguard Worker        exclude=EXCLUSIONS
84*60b67249SAndroid Build Coastguard Worker    ),
85*60b67249SAndroid Build Coastguard Worker    inclusive_language.presubmit_check.with_filter(exclude=EXCLUSIONS),
86*60b67249SAndroid Build Coastguard Worker    keep_sorted.presubmit_check.with_filter(exclude=EXCLUSIONS),
87*60b67249SAndroid Build Coastguard Worker    python_checks.gn_python_lint,
88*60b67249SAndroid Build Coastguard Worker)
89*60b67249SAndroid Build Coastguard Worker
90*60b67249SAndroid Build Coastguard WorkerFULL = (
91*60b67249SAndroid Build Coastguard Worker    QUICK,  # Add all checks from the 'quick' program
92*60b67249SAndroid Build Coastguard Worker    LINTFORMAT,
93*60b67249SAndroid Build Coastguard Worker    # Use the upstream Python checks, with custom path filters applied.
94*60b67249SAndroid Build Coastguard Worker    python_checks.gn_python_check,
95*60b67249SAndroid Build Coastguard Worker)
96*60b67249SAndroid Build Coastguard Worker
97*60b67249SAndroid Build Coastguard WorkerPROGRAMS = pw_presubmit.Programs(
98*60b67249SAndroid Build Coastguard Worker    # keep-sorted: start
99*60b67249SAndroid Build Coastguard Worker    full=FULL,
100*60b67249SAndroid Build Coastguard Worker    lintformat=LINTFORMAT,
101*60b67249SAndroid Build Coastguard Worker    other_checks=OTHER_CHECKS,
102*60b67249SAndroid Build Coastguard Worker    quick=QUICK,
103*60b67249SAndroid Build Coastguard Worker    # keep-sorted: end
104*60b67249SAndroid Build Coastguard Worker)
105*60b67249SAndroid Build Coastguard Worker
106*60b67249SAndroid Build Coastguard Worker
107*60b67249SAndroid Build Coastguard Workerdef run(install: bool, exclude: list, **presubmit_args) -> int:
108*60b67249SAndroid Build Coastguard Worker    """Process the --install argument then invoke pw_presubmit."""
109*60b67249SAndroid Build Coastguard Worker
110*60b67249SAndroid Build Coastguard Worker    # Install the presubmit Git pre-push hook, if requested.
111*60b67249SAndroid Build Coastguard Worker    if install:
112*60b67249SAndroid Build Coastguard Worker        install_hook.install_git_hook(
113*60b67249SAndroid Build Coastguard Worker            "pre-push",
114*60b67249SAndroid Build Coastguard Worker            [
115*60b67249SAndroid Build Coastguard Worker                "python",
116*60b67249SAndroid Build Coastguard Worker                "-m",
117*60b67249SAndroid Build Coastguard Worker                "open_dice_tools.presubmit",
118*60b67249SAndroid Build Coastguard Worker                "--base",
119*60b67249SAndroid Build Coastguard Worker                "origin/main..HEAD",
120*60b67249SAndroid Build Coastguard Worker                "--program",
121*60b67249SAndroid Build Coastguard Worker                "quick",
122*60b67249SAndroid Build Coastguard Worker            ],
123*60b67249SAndroid Build Coastguard Worker        )
124*60b67249SAndroid Build Coastguard Worker        return 0
125*60b67249SAndroid Build Coastguard Worker
126*60b67249SAndroid Build Coastguard Worker    repos = git_repo.discover_submodules(superproject_dir=PROJECT_ROOT)
127*60b67249SAndroid Build Coastguard Worker    return cli.run(
128*60b67249SAndroid Build Coastguard Worker        root=PROJECT_ROOT, repositories=repos, exclude=exclude, **presubmit_args
129*60b67249SAndroid Build Coastguard Worker    )
130*60b67249SAndroid Build Coastguard Worker
131*60b67249SAndroid Build Coastguard Worker
132*60b67249SAndroid Build Coastguard Workerdef main() -> int:
133*60b67249SAndroid Build Coastguard Worker    """Run the presubmit checks for this repository."""
134*60b67249SAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(description=__doc__)
135*60b67249SAndroid Build Coastguard Worker    cli.add_arguments(parser, PROGRAMS, "quick")
136*60b67249SAndroid Build Coastguard Worker
137*60b67249SAndroid Build Coastguard Worker    # Define an option for installing a Git pre-push hook for this script.
138*60b67249SAndroid Build Coastguard Worker    parser.add_argument(
139*60b67249SAndroid Build Coastguard Worker        "--install",
140*60b67249SAndroid Build Coastguard Worker        action="store_true",
141*60b67249SAndroid Build Coastguard Worker        help="Install the presubmit as a Git pre-push hook and exit.",
142*60b67249SAndroid Build Coastguard Worker    )
143*60b67249SAndroid Build Coastguard Worker
144*60b67249SAndroid Build Coastguard Worker    return run(**vars(parser.parse_args()))
145*60b67249SAndroid Build Coastguard Worker
146*60b67249SAndroid Build Coastguard Worker
147*60b67249SAndroid Build Coastguard Workerif __name__ == "__main__":
148*60b67249SAndroid Build Coastguard Worker    pw_cli.log.install(logging.INFO)
149*60b67249SAndroid Build Coastguard Worker    sys.exit(main())
150