From 6c20343b9a8e63918ebee7a17f190426df7e3548 Mon Sep 17 00:00:00 2001 From: Leszek Lugin Date: Wed, 10 Jul 2024 16:43:13 +0200 Subject: [PATCH] Add: single-year flag to command pontos-update-header To enable using only creation year for header license. --- pontos/updateheader/_parser.py | 11 +++++++ pontos/updateheader/updateheader.py | 7 ++++ tests/updateheader/test_header.py | 51 +++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/pontos/updateheader/_parser.py b/pontos/updateheader/_parser.py index a14bc5869..7315ae646 100644 --- a/pontos/updateheader/_parser.py +++ b/pontos/updateheader/_parser.py @@ -109,4 +109,15 @@ def parse_args(args: Optional[Sequence[str]] = None) -> Namespace: help="Do a cleanup: Remove lines from outdated header format", ) + parser.add_argument( + "--single-year", + action="store_true", + default=False, + help=( + "If set, will not update license with from-to years format " + "(YYYY-YYYY) if it has single (only creation) year format (YYYY). " + "Default is %(default)s." + ), + ) + return parser.parse_args(args) diff --git a/pontos/updateheader/updateheader.py b/pontos/updateheader/updateheader.py index 8ccbd71a2..d385b6838 100644 --- a/pontos/updateheader/updateheader.py +++ b/pontos/updateheader/updateheader.py @@ -152,6 +152,7 @@ def update_file( company: str, *, cleanup: bool = False, + single_year: bool = False, ) -> None: """Function to update the header of the given file @@ -211,6 +212,10 @@ def update_file( or copyright_match.modification_year and copyright_match.modification_year < year ): + if single_year: + # In case of single year updating the license with modification date doesn't make sense. + # Changing the existing license header with created-modified years to single year is not supported. + return copyright_term = ( f"SPDX-FileCopyrightText: " f"{copyright_match.creation_year}" @@ -312,6 +317,7 @@ def main(args: Optional[Sequence[str]] = None) -> None: changed: bool = parsed_args.changed quiet: bool = parsed_args.quiet cleanup: bool = parsed_args.cleanup + single_year: bool = parsed_args.single_year if quiet: term: Union[NullTerminal, RichTerminal] = NullTerminal() @@ -368,6 +374,7 @@ def main(args: Optional[Sequence[str]] = None) -> None: license_id, company, cleanup=cleanup, + single_year=single_year, ) except (FileNotFoundError, UnicodeDecodeError, ValueError): continue diff --git a/tests/updateheader/test_header.py b/tests/updateheader/test_header.py index 560fda065..3e00ed667 100644 --- a/tests/updateheader/test_header.py +++ b/tests/updateheader/test_header.py @@ -291,6 +291,32 @@ def test_update_create_header(self, mock_stdout): expected_header, test_file.read_text(encoding="utf-8") ) + @patch("sys.stdout", new_callable=StringIO) + def test_update_create_header_single_year(self, mock_stdout): + year = "1995" + license_id = "AGPL-3.0-or-later" + + expected_header = HEADER.format(date="1995") + "\n\n" + + with temp_file(name="test.py", change_into=True) as test_file: + update_file( + test_file, + year, + license_id, + self.company, + single_year=True + ) + + ret = mock_stdout.getvalue() + self.assertEqual( + f"{test_file}: Added license header.\n", + ret, + ) + self.assertEqual( + expected_header, test_file.read_text(encoding="utf-8") + ) + + @patch("sys.stdout", new_callable=StringIO) def test_update_header_in_file(self, mock_stdout): year = "2021" @@ -318,6 +344,29 @@ def test_update_header_in_file(self, mock_stdout): test_file.read_text(encoding="utf-8"), ) + @patch("sys.stdout", new_callable=StringIO) + def test_update_header_in_file_single_year(self, mock_stdout): + year = "2021" + license_id = "AGPL-3.0-or-later" + + header = HEADER.format(date="2020") + with temp_file( + content=header, name="test.py", change_into=True + ) as test_file: + update_file( + test_file, + year, + license_id, + self.company, + single_year=True, + ) + + ret = mock_stdout.getvalue() + self.assertIn( + "# SPDX-FileCopyrightText: 2020 Greenbone AG", + test_file.read_text(encoding="utf-8"), + ) + @patch("sys.stdout", new_callable=StringIO) def test_update_header_ok_in_file(self, mock_stdout): year = "2021" @@ -510,6 +559,7 @@ def test_defaults(self): self.assertEqual(args.files, ["foo.txt"]) self.assertIsNone(args.directories) self.assertIsNone(args.exclude_file) + self.assertFalse(args.single_year) self.assertFalse(args.cleanup) def test_files_and_directories_mutual_exclusive(self): @@ -569,6 +619,7 @@ def test_main_never_happen(self, argparser_mock, mock_stdout): self.args.log_file = None self.args.quiet = False self.args.cleanup = False + self.args.single_year = False argparser_mock.return_value = self.args