Path: blob/master/Tools/gittools/pre_commit_copyright.py
6351 views
#!/usr/bin/env python312# CAUTION: The first docstring in this file will be the copyright notice that will be3# looked for in all file paths that the pre-commit hook passes in. If all files4# contain the __doc__ text below, the commit will be allowed to proceed.56"""ArduPilot.org.7#8# This program is free software: you can redistribute it and/or modify9# it under the terms of the GNU General Public License as published by10# the Free Software Foundation, either version 3 of the License, or11# (at your option) any later version.12#13# This program is distributed in the hope that it will be useful,14# but WITHOUT ANY WARRANTY; without even the implied warranty of15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16# GNU General Public License for more details.17#18# You should have received a copy of the GNU General Public License19# along with this program. If not, see <https://www.gnu.org/licenses/>.20"""2122# --- Do not merges these two docstrings. See CAUTION above. ---2324from argparse import ArgumentParser25from pathlib import Path2627r"""28A pre-commit hook that will use the content of __doc__ and then ensure all files29processed contain that same copyright information. This is useful to ensure that all30those files consistent copyright notices, which is important for legal and compliance31reasons. If any files does not contain the expected copyright information, the commit32will be aborted and an error message will be displayed with the file paths of all files33that do not match.3435Place an entry into the local `.pre-commit-config.yaml` file to run this job.36```yaml37- repo: local38hooks:39- id: check-copyright40name: check copyright notice in files41entry: Tools/gittools/pre_commit_copyright.py42language: python43files: |44(?x)^(45Tools/ros2/.*\.py46)$47args: [48--ignore=excluded_file.py,49--ignore=another_excluded.py,50]51```5253Usage:541. Place this script in the `Tools/gittools/pre_commit_copyright.py` file.552. Ensure the docstring of this file is set to the expected copyright notice.563. Add the entry to your `.pre-commit-config.yaml` file as shown above.574. Run `pre-commit install` to set up the pre-commit hooks.585. Now, when you try to commit changes, this hook will check for the copyright notice.596. If any files do not contain the expected copyright notice, the commit will be aborted.607. The error message will list all files that do not match the expected copyright notice.618. Use --ignore=file_path to exclude specific files from copyright checking.6263Command line usage:64python pre_commit_copyright.py file1.py file2.py --ignore=excluded_file.py \65--ignore=another_excluded.py66"""676869def get_file_paths() -> list[str]:70"""Parse command line arguments and return a sorted list of file paths excluding71ignored files."""72parser = ArgumentParser(description="Check copyright notice in files")73parser.add_argument("files", nargs="+", help="File paths to check")74parser.add_argument(75"--ignore",76action="append",77default=[],78help="File paths to ignore (can be used multiple times)",79)80args = parser.parse_args()81return sorted(set(args.files) - set(args.ignore))828384def check_copyright(file_path: Path) -> bool:85"""Check if the file contains the expected copyright notice."""86try:87return __doc__ in file_path.read_text()88except Exception as e: # noqa: BLE001 Path.read_text() can raise many exceptions89print(f"Error reading {file_path}: {e}")90return False919293def main():94"""Main function to check all file paths from command line arguments.9596pre-commit will repeatedly call this function and each time it will pass ~four file97paths to be checked.9899Supports --ignore flags to exclude specific files from copyright checking.100"""101if failed_files := [102path for path in get_file_paths() if not check_copyright(Path(path))103]:104raise SystemExit(f"Copyright not found in: {', '.join(failed_files)}")105106107if __name__ == "__main__":108main()109110111