diff --git a/changelog.d/added/new-prefixes.md b/changelog.d/added/new-prefixes.md new file mode 100644 index 00000000..7ff626c7 --- /dev/null +++ b/changelog.d/added/new-prefixes.md @@ -0,0 +1,2 @@ +- Added new copyright prefixes `spdx-string`, `spdx-string-c`, and + `spdx-string-symbol`. (#979) diff --git a/changelog.d/fixed/prefix-merge.md b/changelog.d/fixed/prefix-merge.md new file mode 100644 index 00000000..3a5e3ca6 --- /dev/null +++ b/changelog.d/fixed/prefix-merge.md @@ -0,0 +1,2 @@ +- `reuse annotate --merge-copyrights` now works more reliably with copyright + prefixes. This still needs some work, though. (#979) diff --git a/docs/man/reuse-annotate.rst b/docs/man/reuse-annotate.rst index a3929089..ae01e0af 100644 --- a/docs/man/reuse-annotate.rst +++ b/docs/man/reuse-annotate.rst @@ -84,13 +84,16 @@ Other options .. code-block:: - spdx: SPDX-FileCopyrightText: - spdx-c: SPDX-FileCopyrightText: (C) - spdx-symbol: SPDX-FileCopyrightText: © - string: Copyright - string-c: Copyright (C) - string-symbol: Copyright © - symbol: © + spdx: SPDX-FileCopyrightText: + spdx-c: SPDX-FileCopyrightText: (C) + spdx-symbol: SPDX-FileCopyrightText: © + spdx-string: SPDX-FileCopyrightText: Copyright + spdx-string-c: SPDX-FileCopyrightText: Copyright (C) + spdx-string-symbol: SPDX-FileCopyrightText: Copyright © + string: Copyright + string-c: Copyright (C) + string-symbol: Copyright © + symbol: © .. option:: -t, --template TEMPLATE diff --git a/src/reuse/_util.py b/src/reuse/_util.py index d10044ce..d5cf1666 100644 --- a/src/reuse/_util.py +++ b/src/reuse/_util.py @@ -116,12 +116,13 @@ _COPYRIGHT_PATTERNS = [ re.compile( - r"(?P(?PSPDX-(File|Snippet)CopyrightText:)\s+" + r"(?P(?PSPDX-(File|Snippet)CopyrightText:" + r"(\s(\([Cc]\)|©|Copyright(\s(©|\([Cc]\)))?))?)\s+" r"((?P\d{4} ?- ?\d{4}|\d{4}),?\s+)?" r"(?P.*?))" + _END_PATTERN ), re.compile( - r"(?P(?PCopyright(\s?\([cC]\))?)\s+" + r"(?P(?PCopyright(\s(\([Cc]\)|©))?)\s+" r"((?P\d{4} ?- ?\d{4}|\d{4}),?\s+)?" r"(?P.*?))" + _END_PATTERN ), @@ -134,6 +135,9 @@ _COPYRIGHT_PREFIXES = { "spdx": "SPDX-FileCopyrightText:", "spdx-c": "SPDX-FileCopyrightText: (C)", + "spdx-string-c": "SPDX-FileCopyrightText: Copyright (C)", + "spdx-string": "SPDX-FileCopyrightText: Copyright", + "spdx-string-symbol": "SPDX-FileCopyrightText: Copyright ©", "spdx-symbol": "SPDX-FileCopyrightText: ©", "string": "Copyright", "string-c": "Copyright (C)", @@ -313,6 +317,7 @@ def merge_copyright_lines(copyright_lines: Set[str]) -> Set[str]: "prefix": match.groupdict()["prefix"], } ) + break copyright_out = set() for line_info in copyright_in: diff --git a/tests/test_main_annotate_merge.py b/tests/test_main_annotate_merge.py index 7889bfcd..9f60de08 100644 --- a/tests/test_main_annotate_merge.py +++ b/tests/test_main_annotate_merge.py @@ -8,6 +8,7 @@ from inspect import cleandoc from reuse._main import main +from reuse._util import _COPYRIGHT_PREFIXES # pylint: disable=unused-argument @@ -191,4 +192,69 @@ def test_annotate_merge_copyrights_no_year_in_existing( ) +def test_annotate_merge_copyrights_all_prefixes( + fake_repository, stringio, mock_date_today +): + """Test that merging works for all copyright prefixes.""" + # TODO: there should probably also be a test for mixing copyright prefixes, + # but this behaviour is really unpredictable to me at the moment, and the + # whole copyright-line-as-string thing needs overhauling. + simple_file = fake_repository / "foo.py" + for copyright_prefix, copyright_string in _COPYRIGHT_PREFIXES.items(): + simple_file.write_text("pass") + result = main( + [ + "annotate", + "--year", + "2016", + "--license", + "GPL-3.0-or-later", + "--copyright", + "Jane Doe", + "--copyright-style", + copyright_prefix, + "--merge-copyrights", + "foo.py", + ], + out=stringio, + ) + assert result == 0 + assert simple_file.read_text(encoding="utf-8") == cleandoc( + f""" + # {copyright_string} 2016 Jane Doe + # + # SPDX-License-Identifier: GPL-3.0-or-later + + pass + """ + ) + + result = main( + [ + "annotate", + "--year", + "2018", + "--license", + "GPL-3.0-or-later", + "--copyright", + "Jane Doe", + "--copyright-style", + copyright_prefix, + "--merge-copyrights", + "foo.py", + ], + out=stringio, + ) + assert result == 0 + assert simple_file.read_text(encoding="utf-8") == cleandoc( + f""" + # {copyright_string} 2016 - 2018 Jane Doe + # + # SPDX-License-Identifier: GPL-3.0-or-later + + pass + """ + ) + + # REUSE-IgnoreEnd diff --git a/tests/test_util.py b/tests/test_util.py index ab00bd21..a081b3d0 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -124,12 +124,15 @@ def test_extract_copyright_variations(): """There are multiple ways to declare copyright. All should be detected.""" text = cleandoc( """ - SPDX-FileCopyrightText: 2019 Jane Doe - SPDX-FileCopyrightText: © 2019 Jane Doe - © 2019 Jane Doe - Copyright © 2019 Jane Doe - Copyright 2019 Jane Doe - Copyright (C) 2019 Jane Doe + SPDX-FileCopyrightText: 2019 spdx + SPDX-FileCopyrightText: (C) 2019 spdx-c + SPDX-FileCopyrightText: © 2019 spdx-symbol + SPDX-FileCopyrightText: Copyright (C) 2019 spdx-string-c + SPDX-FileCopyrightText: Copyright © 2019 spdx-string-symbol + Copyright 2019 string + Copyright (C) 2019 string-c + Copyright © 2019 string-symbol + © 2019 symbol """ ) @@ -428,6 +431,30 @@ def test_make_copyright_line_prefix_string_c_year(): assert statement == "Copyright (C) 2019 hello" +def test_make_copyright_line_prefix_spdx_string_c_year(): + """Given a simple statement, prefix and a year, make it a copyright line.""" + statement = _util.make_copyright_line( + "hello", year=2019, copyright_prefix="spdx-string-c" + ) + assert statement == "SPDX-FileCopyrightText: Copyright (C) 2019 hello" + + +def test_make_copyright_line_prefix_spdx_string_year(): + """Given a simple statement, prefix and a year, make it a copyright line.""" + statement = _util.make_copyright_line( + "hello", year=2019, copyright_prefix="spdx-string" + ) + assert statement == "SPDX-FileCopyrightText: Copyright 2019 hello" + + +def test_make_copyright_line_prefix_spdx_string_symbol_year(): + """Given a simple statement, prefix and a year, make it a copyright line.""" + statement = _util.make_copyright_line( + "hello", year=2019, copyright_prefix="spdx-string-symbol" + ) + assert statement == "SPDX-FileCopyrightText: Copyright © 2019 hello" + + def test_make_copyright_line_prefix_string_symbol_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line(