Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/gittools/pre_commit_copyright.py
6351 views
1
#!/usr/bin/env python3
2
3
# CAUTION: The first docstring in this file will be the copyright notice that will be
4
# looked for in all file paths that the pre-commit hook passes in. If all files
5
# contain the __doc__ text below, the commit will be allowed to proceed.
6
7
"""ArduPilot.org.
8
#
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
"""
22
23
# --- Do not merges these two docstrings. See CAUTION above. ---
24
25
from argparse import ArgumentParser
26
from pathlib import Path
27
28
r"""
29
A pre-commit hook that will use the content of __doc__ and then ensure all files
30
processed contain that same copyright information. This is useful to ensure that all
31
those files consistent copyright notices, which is important for legal and compliance
32
reasons. If any files does not contain the expected copyright information, the commit
33
will be aborted and an error message will be displayed with the file paths of all files
34
that do not match.
35
36
Place an entry into the local `.pre-commit-config.yaml` file to run this job.
37
```yaml
38
- repo: local
39
hooks:
40
- id: check-copyright
41
name: check copyright notice in files
42
entry: Tools/gittools/pre_commit_copyright.py
43
language: python
44
files: |
45
(?x)^(
46
Tools/ros2/.*\.py
47
)$
48
args: [
49
--ignore=excluded_file.py,
50
--ignore=another_excluded.py,
51
]
52
```
53
54
Usage:
55
1. Place this script in the `Tools/gittools/pre_commit_copyright.py` file.
56
2. Ensure the docstring of this file is set to the expected copyright notice.
57
3. Add the entry to your `.pre-commit-config.yaml` file as shown above.
58
4. Run `pre-commit install` to set up the pre-commit hooks.
59
5. Now, when you try to commit changes, this hook will check for the copyright notice.
60
6. If any files do not contain the expected copyright notice, the commit will be aborted.
61
7. The error message will list all files that do not match the expected copyright notice.
62
8. Use --ignore=file_path to exclude specific files from copyright checking.
63
64
Command line usage:
65
python pre_commit_copyright.py file1.py file2.py --ignore=excluded_file.py \
66
--ignore=another_excluded.py
67
"""
68
69
70
def get_file_paths() -> list[str]:
71
"""Parse command line arguments and return a sorted list of file paths excluding
72
ignored files."""
73
parser = ArgumentParser(description="Check copyright notice in files")
74
parser.add_argument("files", nargs="+", help="File paths to check")
75
parser.add_argument(
76
"--ignore",
77
action="append",
78
default=[],
79
help="File paths to ignore (can be used multiple times)",
80
)
81
args = parser.parse_args()
82
return sorted(set(args.files) - set(args.ignore))
83
84
85
def check_copyright(file_path: Path) -> bool:
86
"""Check if the file contains the expected copyright notice."""
87
try:
88
return __doc__ in file_path.read_text()
89
except Exception as e: # noqa: BLE001 Path.read_text() can raise many exceptions
90
print(f"Error reading {file_path}: {e}")
91
return False
92
93
94
def main():
95
"""Main function to check all file paths from command line arguments.
96
97
pre-commit will repeatedly call this function and each time it will pass ~four file
98
paths to be checked.
99
100
Supports --ignore flags to exclude specific files from copyright checking.
101
"""
102
if failed_files := [
103
path for path in get_file_paths() if not check_copyright(Path(path))
104
]:
105
raise SystemExit(f"Copyright not found in: {', '.join(failed_files)}")
106
107
108
if __name__ == "__main__":
109
main()
110
111