|
1 |
| -# Copyright (C) 2019-2022 Greenbone AG |
| 1 | +# SPDX-FileCopyrightText: 2019-2023 Greenbone AG |
2 | 2 | #
|
3 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later
|
4 | 4 | #
|
|
26 | 26 | from datetime import datetime
|
27 | 27 | from pathlib import Path
|
28 | 28 | from subprocess import CalledProcessError, run
|
29 |
| -from typing import Dict, List, Tuple, Union |
| 29 | +from typing import Dict, List, Optional, Tuple, Union |
30 | 30 |
|
31 | 31 | from pontos.terminal import Terminal
|
32 | 32 | from pontos.terminal.null import NullTerminal
|
|
53 | 53 | "GPL-2.0-or-later",
|
54 | 54 | "GPL-3.0-or-later",
|
55 | 55 | ]
|
| 56 | +OLD_LINES = [ |
| 57 | + "# \-\*\- coding: utf\-8 \-\*\-", |
| 58 | + "This program is free software: you can redistribute it and/or modify", |
| 59 | + "it under the terms of the GNU Affero General Public License as", |
| 60 | + "published by the Free Software Foundation, either version 3 of the", |
| 61 | + "License, or \(at your option\) any later version.", |
| 62 | + "This program is free software; you can redistribute it and/or", |
| 63 | + "modify it under the terms of the GNU General Public License", |
| 64 | + "version 2 as published by the Free Software Foundation.", |
| 65 | + "This program is free software: you can redistribute it and/or modify", |
| 66 | + "it under the terms of the GNU General Public License as published by", |
| 67 | + "the Free Software Foundation, either version 3 of the License, or", |
| 68 | + "\(at your option\) any later version.", |
| 69 | + "This program is distributed in the hope that it will be useful,", |
| 70 | + "but WITHOUT ANY WARRANTY; without even the implied warranty of", |
| 71 | + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", |
| 72 | + "GNU Affero General Public License for more details.", |
| 73 | + "GNU General Public License for more details.", |
| 74 | + "You should have received a copy of the GNU Affero General Public License", |
| 75 | + "along with this program. If not, see <http://www.gnu.org/licenses/>.", |
| 76 | + "along with this program; if not, write to the Free Software", |
| 77 | + "Foundation, Inc\., 51 Franklin St, Fifth Floor, Boston, MA 02110\-1301 USA\.", # noqa: E501 |
| 78 | +] |
56 | 79 |
|
57 | 80 |
|
58 | 81 | def _get_modified_year(f: Path) -> str:
|
@@ -112,11 +135,32 @@ def _add_header(
|
112 | 135 | raise ValueError
|
113 | 136 |
|
114 | 137 |
|
| 138 | +def _remove_outdated( |
| 139 | + content: str, cleanup_regexes: List[re.Pattern] |
| 140 | +) -> Optional[str]: |
| 141 | + """Remove lines that contain outdated copyright header ...""" |
| 142 | + changed = False |
| 143 | + splitted_lines = content.splitlines() |
| 144 | + i = 0 |
| 145 | + for line in splitted_lines[:20]: |
| 146 | + for regex in cleanup_regexes: |
| 147 | + if regex.match(line): |
| 148 | + changed = True |
| 149 | + splitted_lines.pop(i) |
| 150 | + i = i - 1 |
| 151 | + break |
| 152 | + i = i + 1 |
| 153 | + if changed: |
| 154 | + return "\n".join(splitted_lines) |
| 155 | + return None |
| 156 | + |
| 157 | + |
115 | 158 | def _update_file(
|
116 | 159 | file: Path,
|
117 | 160 | regex: re.Pattern,
|
118 | 161 | parsed_args: Namespace,
|
119 | 162 | term: Terminal,
|
| 163 | + cleanup_regexes: Optional[List[re.Pattern]] = None, |
120 | 164 | ) -> int:
|
121 | 165 | """Function to update the given file.
|
122 | 166 | Checks if header exists. If not it adds an
|
@@ -173,6 +217,15 @@ def _update_file(
|
173 | 217 | "is not existing."
|
174 | 218 | )
|
175 | 219 | return 1
|
| 220 | + # old header existing - cleanup? |
| 221 | + if cleanup_regexes: |
| 222 | + old_content = file.read_text(encoding="utf-8") |
| 223 | + new_content = _remove_outdated( |
| 224 | + content=old_content, cleanup_regexes=cleanup_regexes |
| 225 | + ) |
| 226 | + if new_content: |
| 227 | + file.write_text(new_content, encoding="utf-8") |
| 228 | + print(f"{file}: Cleaned up!") |
176 | 229 | # replace found header and write it to file
|
177 | 230 | if copyright_match and (
|
178 | 231 | not copyright_match["modification_year"]
|
@@ -201,10 +254,9 @@ def _update_file(
|
201 | 254 | f"{parsed_args.year}"
|
202 | 255 | )
|
203 | 256 |
|
204 |
| - return 0 |
205 | 257 | else:
|
206 | 258 | print(f"{file}: License Header is ok.")
|
207 |
| - return 0 |
| 259 | + return 0 |
208 | 260 | except FileNotFoundError as e:
|
209 | 261 | print(f"{file}: File is not existing.")
|
210 | 262 | raise e
|
@@ -335,9 +387,24 @@ def _parse_args(args=None):
|
335 | 387 | type=FileType("r"),
|
336 | 388 | )
|
337 | 389 |
|
| 390 | + parser.add_argument( |
| 391 | + "--cleanup", |
| 392 | + action="store_true", |
| 393 | + default=False, |
| 394 | + help="Do a cleanup: Remove lines from outdated header format", |
| 395 | + ) |
| 396 | + |
338 | 397 | return parser.parse_args(args)
|
339 | 398 |
|
340 | 399 |
|
| 400 | +def _compile_outdated_regex() -> List[re.Pattern]: |
| 401 | + """prepare regex patterns to remove old copyright lines""" |
| 402 | + regexes: List[re.Pattern] = [] |
| 403 | + for line in OLD_LINES: |
| 404 | + regexes.append(re.compile(rf"^(([#*]|//) ?)?{line}")) |
| 405 | + return regexes |
| 406 | + |
| 407 | + |
341 | 408 | def main() -> None:
|
342 | 409 | parsed_args = _parse_args()
|
343 | 410 | exclude_list = []
|
@@ -376,18 +443,25 @@ def main() -> None:
|
376 | 443 | term.error("Specify files to update!")
|
377 | 444 | sys.exit(1)
|
378 | 445 |
|
379 |
| - regex = re.compile( |
| 446 | + regex: re.Pattern = re.compile( |
380 | 447 | "(SPDX-FileCopyrightText:|[Cc]opyright).*?(19[0-9]{2}|20[0-9]{2}) "
|
381 | 448 | f"?-? ?(19[0-9]{{2}}|20[0-9]{{2}})? ({parsed_args.company})"
|
382 | 449 | )
|
| 450 | + cleanup_regexes: Optional[List[re.Pattern]] = None |
| 451 | + if parsed_args.cleanup: |
| 452 | + cleanup_regexes = _compile_outdated_regex() |
383 | 453 |
|
384 | 454 | for file in files:
|
385 | 455 | try:
|
386 | 456 | if file.absolute() in exclude_list:
|
387 | 457 | term.warning(f"{file}: Ignoring file from exclusion list.")
|
388 | 458 | else:
|
389 | 459 | _update_file(
|
390 |
| - file=file, regex=regex, parsed_args=parsed_args, term=term |
| 460 | + file=file, |
| 461 | + regex=regex, |
| 462 | + parsed_args=parsed_args, |
| 463 | + term=term, |
| 464 | + cleanup_regexes=cleanup_regexes, |
391 | 465 | )
|
392 | 466 | except (FileNotFoundError, UnicodeDecodeError, ValueError):
|
393 | 467 | continue
|
|
0 commit comments