From dffed2fa8cd9e6cdee9676792c91e7f5e6413c2e Mon Sep 17 00:00:00 2001 From: Eduardo Almeida Date: Thu, 30 Jan 2025 19:42:16 +0000 Subject: [PATCH] clang-format: Run license check before whitespace and tab --- doc/contributing/source/coding-style.rst | 4 +- utils/check-style-clang-format.py | 178 +++++++++++------------ 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/doc/contributing/source/coding-style.rst b/doc/contributing/source/coding-style.rst index 35f8cf612..e54ab8c16 100644 --- a/doc/contributing/source/coding-style.rst +++ b/doc/contributing/source/coding-style.rst @@ -155,9 +155,9 @@ The script performs multiple style checks. By default, the script runs the follo * Check if local ``#include`` headers do not use the "ns3/" prefix. Respects clang-format guards. * Check if ns-3 ``#include`` headers use quotes (``""``) instead of angle brackets (``<>``). Respects clang-format guards. * Check if Doxygen tags use ``@`` rather than ``\\``. Respects clang-format guards. +* Check if source code use SPDX licenses rather than GPL license text. Respects clang-format guards. * Check if there are no trailing whitespace. Always checked. * Check if there are no tabs. Respects clang-format guards. -* Check if source code files use SPDX licenses rather than GPL license text. Respects clang-format guards. * Check if files have the correct encoding (UTF-8). Always checked. The process returns a zero exit code if all files adhere to these rules. @@ -171,9 +171,9 @@ flags: * ``--no-include-prefixes`` * ``--no-include-quotes`` * ``--no-doxygen-tags`` +* ``--no-licenses`` * ``--no-whitespace`` * ``--no-tabs`` -* ``--no-licenses`` * ``--no-encoding`` Additional information about the formatting issues detected by the script can be enabled diff --git a/utils/check-style-clang-format.py b/utils/check-style-clang-format.py index 616e8805e..664a5bfb7 100755 --- a/utils/check-style-clang-format.py +++ b/utils/check-style-clang-format.py @@ -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, },