| #!/usr/bin/env python3 |
| # Copyright 2018 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Run cpplint with the right settings.""" |
| |
| from pathlib import Path |
| import sys |
| |
| import libdot |
| |
| |
| # The set of file extensions we support as cpplint needs to be told explicitly. |
| EXTENSIONS = {"c", "cc", "cpp", "h", "hpp"} |
| |
| |
| # The commit in depot_tools that we're pinned to. |
| CHROMIUM_REF = "c4fb1974191f0d09fcb932f76ae7b5abce1f0ce5" |
| |
| # Full path to Chromium's fork of the cpplint.py script. |
| CPPLINT_URL = ( |
| "https://chromium.googlesource.com/chromium/tools/depot_tools/+/" |
| f"{CHROMIUM_REF}/cpplint.py" |
| ) |
| |
| # Our local cache of the script. |
| CPPLINT = libdot.BIN_DIR / f".cpplint.{CHROMIUM_REF}" |
| |
| |
| def filter_known_files(paths: list[Path]) -> list[Path]: |
| """Figure out what files this linter supports.""" |
| ret = [] |
| for path in paths: |
| path = Path(path) |
| |
| if "third_party" in path.parts: |
| # Ignore code we didn't author. |
| continue |
| elif path.suffix[1:] in EXTENSIONS: |
| ret += [path] |
| |
| return [str(x) for x in ret] |
| |
| |
| def setup(): |
| """Initialize the tool settings.""" |
| if CPPLINT.exists(): |
| return |
| |
| for path in libdot.BIN_DIR.glob(".cpplint.*"): |
| path.unlink() |
| |
| libdot.fetch(f"{CPPLINT_URL}?format=TEXT", CPPLINT, b64=True) |
| CPPLINT.chmod(0o755) |
| |
| |
| def run(argv=(), **kwargs): |
| """Run the tool directly.""" |
| setup() |
| |
| cmd = [CPPLINT, f'--extensions={",".join(EXTENSIONS)}'] + list(argv) |
| return libdot.run(cmd, **kwargs) |
| |
| |
| def perform( |
| argv=(), paths=(), fix=False, gerrit_comments_file=None |
| ): # pylint: disable=unused-argument |
| """Run high level tool logic.""" |
| ret = True |
| argv = list(argv) |
| paths = list(paths) |
| |
| # Cpplint doesn't have any automatic fixing logic. |
| if fix: |
| return ret |
| |
| # TODO(vapier): Add support for Gerrit comments. |
| |
| result = run(argv + paths, check=False) |
| return result.returncode == 0 |
| |
| |
| def get_parser(): |
| """Get a command line parser.""" |
| parser = libdot.ArgumentParser(description=__doc__, short_options=False) |
| parser.add_argument( |
| "--gerrit-comments-file", |
| help="Save errors for posting files to Gerrit.", |
| ) |
| parser.add_argument("paths", nargs="*", help="Paths to lint.") |
| return parser |
| |
| |
| def main(argv): |
| """The main func!""" |
| parser = get_parser() |
| opts, args = parser.parse_known_args(argv) |
| |
| return ( |
| 0 |
| if perform( |
| argv=args, |
| paths=opts.paths, |
| gerrit_comments_file=opts.gerrit_comments_file, |
| ) |
| else 1 |
| ) |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main(sys.argv[1:])) |