| #!/usr/bin/env python3 | |
| # Copyright 2016 The Android Open Source Project | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """Helper script to quickly update the bundled cpplint.py script.""" | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| import re | |
| import sys | |
| import urllib.request | |
| # Since this is manually run by repohooks developers, we can safely require more | |
| # recent versions of Python. | |
| assert sys.version_info >= (3, 9), f"Python 3.9+ required; found {sys.version}" | |
| THIS_FILE = Path(__file__).resolve() | |
| SCRIPT_NAME = THIS_FILE.name | |
| THIS_DIR = THIS_FILE.parent | |
| CPPLINT_PY = THIS_DIR / "cpplint.py" | |
| # The cpplint project. | |
| GITHUB_URL = "https://github.com/cpplint/cpplint/raw" | |
| def find_latest_tag() -> str: | |
| """Figure out the latest tag/release and return its commit.""" | |
| url = "https://api.github.com/repos/cpplint/cpplint/tags" | |
| with urllib.request.urlopen(url, timeout=60) as fp: | |
| data = fp.read() | |
| # This will have the format: | |
| # [ | |
| # {"name": "0.0.7", "commit": {"sha": "<sha1>", ...}, ...}, | |
| # {"name": "0.0.6", "commit": {"sha": "<sha1>", ...}, ...}, | |
| # ... | |
| # ] | |
| resp = json.loads(data) | |
| # Filter out random named tags. | |
| tags = [x for x in resp if re.match(r"^[0-9.]+$", x["name"])] | |
| tags = sorted( | |
| tags, | |
| key=lambda x: tuple(int(v) for v in x["name"].split(".")), | |
| reverse=True, | |
| ) | |
| latest = tags[0] | |
| print(f"{SCRIPT_NAME}: found latest tag {latest['name']}") | |
| return latest["commit"]["sha"] | |
| def download(commit: str) -> str: | |
| """Download latest cpplint version.""" | |
| url = f"{GITHUB_URL}/{commit}/cpplint.py" | |
| with urllib.request.urlopen(url, timeout=60) as fp: | |
| return fp.read() | |
| def munge_content(data: str) -> str: | |
| """Make changes to |data| for local script usage.""" | |
| lines = data.splitlines() | |
| if lines[0].endswith(b"python"): | |
| lines[0] += b"3" | |
| lines.insert(1, b"# pylint: skip-file") | |
| return b"\n".join(lines).rstrip() + b"\n" | |
| def update_script(data: str) -> None: | |
| """Update the cpplint script.""" | |
| CPPLINT_PY.write_bytes(data) | |
| CPPLINT_PY.chmod(0o755) | |
| def get_parser() -> argparse.ArgumentParser: | |
| """Return a command line parser.""" | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument( | |
| "--rev", | |
| help="What git commit or ref to fetch (default: latest)", | |
| ) | |
| return parser | |
| def main(argv: list[str]) -> int: | |
| parser = get_parser() | |
| opts = parser.parse_args(argv) | |
| ret = 0 | |
| commit = opts.rev | |
| if not commit: | |
| commit = find_latest_tag() | |
| data = download(commit) | |
| data = munge_content(data) | |
| update_script(data) | |
| return ret | |
| if __name__ == "__main__": | |
| sys.exit(main(sys.argv[1:])) |