| #!/usr/bin/env python3 | |
| # Copyright 2018 The Chromium OS Authors. All rights reserved. | |
| # 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 | |
| from typing import List | |
| 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:])) |