clang-format: Run license check before whitespace and tab

This commit is contained in:
Eduardo Almeida
2025-01-30 19:42:16 +00:00
parent 381101fd52
commit dffed2fa8c
2 changed files with 91 additions and 91 deletions

View File

@@ -15,9 +15,9 @@ the ".clang-format" file. This script performs the following checks / fixes:
- Check / fix local #include headers with "ns3/" prefix. Respects clang-format guards.
- Check / fix ns-3 #include headers using angle brackets <> rather than quotes "". Respects clang-format guards.
- Check / fix Doxygen tags using @ rather than \\. Respects clang-format guards.
- Check / fix SPDX licenses rather than GPL text. Respects clang-format guards.
- Check / trim trailing whitespace. Always checked.
- Check / replace tabs with spaces. Respects clang-format guards.
- Check / fix SPDX licenses rather than GPL text. Respects clang-format guards.
- Check file encoding. Always checked.
This script can be applied to all text files in a given path or to individual files.
@@ -77,9 +77,9 @@ CHECKS = [
"include_prefixes",
"include_quotes",
"doxygen_tags",
"license",
"whitespace",
"tabs",
"license",
"formatting",
"encoding",
]
@@ -115,6 +115,14 @@ FILE_EXTENSIONS_TO_CHECK["include_quotes"] = FILE_EXTENSIONS_TO_CHECK["formattin
FILE_EXTENSIONS_TO_CHECK["doxygen_tags"] = FILE_EXTENSIONS_TO_CHECK["formatting"]
FILE_EXTENSIONS_TO_CHECK["encoding"] = FILE_EXTENSIONS_TO_CHECK["formatting"]
FILE_EXTENSIONS_TO_CHECK["license"] = [
".c",
".cc",
".cmake",
".h",
".py",
]
FILE_EXTENSIONS_TO_CHECK["tabs"] = [
".c",
".cc",
@@ -150,14 +158,6 @@ FILE_EXTENSIONS_TO_CHECK["whitespace"] = FILE_EXTENSIONS_TO_CHECK["tabs"] + [
".txt",
]
FILE_EXTENSIONS_TO_CHECK["license"] = [
".c",
".cc",
".cmake",
".h",
".py",
]
# Other check parameters
TAB_SIZE = 4
FILE_ENCODING = "UTF-8"
@@ -323,9 +323,9 @@ def check_style_clang_format(
"include_prefixes": '#include headers from the same module with the "ns3/" prefix',
"include_quotes": 'ns-3 #include headers using angle brackets <> rather than quotes ""',
"doxygen_tags": "Doxygen tags using \\ rather than @",
"license": "GPL license text instead of SPDX license",
"whitespace": "trailing whitespace",
"tabs": "tabs",
"license": "GPL license text instead of SPDX license",
"formatting": "bad code formatting",
"encoding": f"bad file encoding ({FILE_ENCODING})",
}
@@ -352,6 +352,13 @@ def check_style_clang_format(
"check_style_line_function": check_doxygen_tags_line,
},
},
"license": {
"function": check_manually_file,
"kwargs": {
"respect_clang_format_guards": True,
"check_style_line_function": check_licenses_line,
},
},
"whitespace": {
"function": check_manually_file,
"kwargs": {
@@ -366,13 +373,6 @@ def check_style_clang_format(
"check_style_line_function": check_tabs_line,
},
},
"license": {
"function": check_manually_file,
"kwargs": {
"respect_clang_format_guards": True,
"check_style_line_function": check_licenses_line,
},
},
"formatting": {
"function": check_formatting_file,
"kwargs": {}, # The formatting keywords are added below
@@ -801,6 +801,70 @@ def check_doxygen_tags_line(
return (is_line_compliant, line_fixed, verbose_infos)
def check_licenses_line(
line: str,
filename: str,
line_number: int,
) -> Tuple[bool, str, List[str]]:
"""
Check / fix SPDX licenses rather than GPL text in a line.
@param line The line to check.
@param filename Name of the file to be checked.
@param line_number The number of the line checked.
@return Tuple [Whether the line is compliant with the style (before the check),
Fixed line,
Verbose information].
"""
# fmt: off
GPL_LICENSE_LINES = [
"This program is free software; you can redistribute it and/or modify",
"it under the terms of the GNU General Public License version 2 as",
"published by the Free Software Foundation;",
"This program is distributed in the hope that it will be useful,",
"but WITHOUT ANY WARRANTY; without even the implied warranty of",
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"GNU General Public License for more details.",
"You should have received a copy of the GNU General Public License",
"along with this program; if not, write to the Free Software",
"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA",
]
# fmt: on
SPDX_LICENSE = "SPDX-License-Identifier: GPL-2.0-only"
is_line_compliant = True
line_fixed = line
verbose_infos: List[str] = []
# Check if the line is a GPL license text
line_stripped = line.strip()
line_stripped_no_leading_comments = line_stripped.strip("*#/").strip()
if line_stripped_no_leading_comments in GPL_LICENSE_LINES:
is_line_compliant = False
col_index = 0
# Replace GPL text with SPDX license.
# Replace the first line of the GPL text with SPDX.
# Delete the remaining GPL text lines.
if line_stripped_no_leading_comments == GPL_LICENSE_LINES[0]:
line_fixed = line.replace(line_stripped_no_leading_comments, SPDX_LICENSE)
else:
line_fixed = ""
verbose_infos.extend(
[
f"{filename}:{line_number + 1}:{col_index}: error: GPL license text detected instead of SPDX license",
f" {line_stripped}",
f" {'':>{col_index}}^",
]
)
return (is_line_compliant, line_fixed, verbose_infos)
def check_whitespace_line(
line: str,
filename: str,
@@ -869,70 +933,6 @@ def check_tabs_line(
return (is_line_compliant, line_fixed, verbose_infos)
def check_licenses_line(
line: str,
filename: str,
line_number: int,
) -> Tuple[bool, str, List[str]]:
"""
Check / fix SPDX licenses rather than GPL text in a line.
@param line The line to check.
@param filename Name of the file to be checked.
@param line_number The number of the line checked.
@return Tuple [Whether the line is compliant with the style (before the check),
Fixed line,
Verbose information].
"""
# fmt: off
GPL_LICENSE_LINES = [
"This program is free software; you can redistribute it and/or modify",
"it under the terms of the GNU General Public License version 2 as",
"published by the Free Software Foundation;",
"This program is distributed in the hope that it will be useful,",
"but WITHOUT ANY WARRANTY; without even the implied warranty of",
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"GNU General Public License for more details.",
"You should have received a copy of the GNU General Public License",
"along with this program; if not, write to the Free Software",
"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA",
]
# fmt: on
SPDX_LICENSE = "SPDX-License-Identifier: GPL-2.0-only"
is_line_compliant = True
line_fixed = line
verbose_infos: List[str] = []
# Check if the line is a GPL license text
line_stripped = line.strip()
line_stripped_no_leading_comments = line_stripped.strip("*#/").strip()
if line_stripped_no_leading_comments in GPL_LICENSE_LINES:
is_line_compliant = False
col_index = 0
# Replace GPL text with SPDX license.
# Replace the first line of the GPL text with SPDX.
# Delete the remaining GPL text lines.
if line_stripped_no_leading_comments == GPL_LICENSE_LINES[0]:
line_fixed = line.replace(line_stripped_no_leading_comments, SPDX_LICENSE)
else:
line_fixed = ""
verbose_infos.extend(
[
f"{filename}:{line_number + 1}:{col_index}: error: GPL license text detected instead of SPDX license",
f" {line_stripped}",
f" {'':>{col_index}}^",
]
)
return (is_line_compliant, line_fixed, verbose_infos)
###########################################################
# MAIN
###########################################################
@@ -974,6 +974,12 @@ if __name__ == "__main__":
help="Do not check / fix Doxygen tags using @ rather than \\ (respects clang-format guards)",
)
parser.add_argument(
"--no-licenses",
action="store_true",
help="Do not check / fix SPDX licenses rather than GPL text (respects clang-format guards)",
)
parser.add_argument(
"--no-whitespace",
action="store_true",
@@ -986,12 +992,6 @@ if __name__ == "__main__":
help="Do not check / fix tabs (respects clang-format guards)",
)
parser.add_argument(
"--no-licenses",
action="store_true",
help="Do not check / fix SPDX licenses rather than GPL text (respects clang-format guards)",
)
parser.add_argument(
"--no-formatting",
action="store_true",
@@ -1034,9 +1034,9 @@ if __name__ == "__main__":
"include_prefixes": not args.no_include_prefixes,
"include_quotes": not args.no_include_quotes,
"doxygen_tags": not args.no_doxygen_tags,
"license": not args.no_licenses,
"whitespace": not args.no_whitespace,
"tabs": not args.no_tabs,
"license": not args.no_licenses,
"formatting": not args.no_formatting,
"encoding": not args.no_encoding,
},