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