diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:13:15 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:15:24 +0100 |
commit | 55f00c88619dc25dd6d37c0428cded856704f841 (patch) | |
tree | 9db2e27a0650675e67f1b501715a71d32ab8e50d /rtemsspec | |
parent | 48058608c263970f310837ae0787d1f2ef490529 (diff) |
content: Improve copyright support
Diffstat (limited to 'rtemsspec')
-rw-r--r-- | rtemsspec/content.py | 108 | ||||
-rw-r--r-- | rtemsspec/tests/test_content_copyrights.py | 7 |
2 files changed, 66 insertions, 49 deletions
diff --git a/rtemsspec/content.py b/rtemsspec/content.py index 75b4958d..c91e6ccf 100644 --- a/rtemsspec/content.py +++ b/rtemsspec/content.py @@ -45,33 +45,63 @@ GenericContentIterable = Union[Iterable[str], Iterable[List[str]], Iterable[GenericContent]] +def split_copyright_statement(statement: str) -> Tuple[str, Set[int]]: + """ Splits the copyright statement into the holder and year set. """ + match = re.search( + r"^\s*Copyright\s+\(C\)\s+([0-9]+),\s*([0-9]+)\s+(.+)\s*$", + statement, + flags=re.I, + ) + if match: + return match.group(3), set((int(match.group(1)), int(match.group(2)))) + match = re.search( + r"^\s*Copyright\s+\(C\)\s+([0-9]+)\s+(.+)\s*$", + statement, + flags=re.I, + ) + if match: + return match.group(2), set((int(match.group(1)), )) + raise ValueError(statement) + + +def make_copyright_statement(holder: str, + years: Set[int], + line: str = "Copyright (C)") -> str: + """ Makes the copyright statement from the holder and year set. """ + year_count = len(years) + line += f" {min(years)}" + if year_count > 1: + line += f", {max(years)}" + line += f" {holder}" + return line + + class Copyright: """ This class represents a copyright holder with its years of substantial contributions. """ - def __init__(self, holder: str): + @classmethod + def from_statement(cls, statement: str) -> "Copyright": + """ Makes a copyright from the statement. """ + holder, years = split_copyright_statement(statement) + return Copyright(holder, years) + + def __init__(self, holder: str, years: Optional[Set[int]] = None): self.holder = holder - self.years: Set[int] = set() + self.years = years if years is not None else set() def add_year(self, year: int): """ - Adds a year to the set of substantial contributions of this copyright + Adds the year to the set of substantial contributions of this copyright holder. """ self.years.add(year) - def get_statement(self) -> str: - """ Returns a copyright statement. """ - line = "Copyright (C)" - year_count = len(self.years) - if year_count == 1: - line += f" {min(self.years)}" - else: - line += f" {min(self.years)}, {max(self.years)}" - line += f" {self.holder}" - return line + def get_statement(self, line: str = "Copyright (C)") -> str: + """ Returns the associated copyright statement. """ + return make_copyright_statement(self.holder, self.years, line) def __lt__(self, other: "Copyright") -> bool: return (min(self.years), max(self.years), @@ -79,45 +109,27 @@ class Copyright: self.holder) -class Copyrights: +def _copyright_key(holder_years): + return (-min(holder_years[1]), -max(holder_years[1]), holder_years[0]) + + +class Copyrights(dict): """ This class represents a set of copyright holders. """ - def __init__(self): - self.copyrights = {} - - def register(self, statement): - """ Registers a copyright statement. """ - match = re.search( - r"^\s*Copyright\s+\(C\)\s+([0-9]+),\s*([0-9]+)\s+(.+)\s*$", - statement, - flags=re.I, - ) - if match: - holder = match.group(3) - the_copyright = self.copyrights.setdefault(holder, - Copyright(holder)) - the_copyright.add_year(int(match.group(1))) - the_copyright.add_year(int(match.group(2))) - return - match = re.search( - r"^\s*Copyright\s+\(C\)\s+([0-9]+)\s+(.+)\s*$", - statement, - flags=re.I, - ) - if match: - holder = match.group(2) - the_copyright = self.copyrights.setdefault(holder, - Copyright(holder)) - the_copyright.add_year(int(match.group(1))) - return - raise ValueError(statement) + def register(self, statements: Union[str, Iterable[str]]) -> None: + """ Registers the copyright statement. """ + if isinstance(statements, str): + statements = [statements] + for statement in statements: + holder, years = split_copyright_statement(statement) + self.setdefault(holder, set()).update(years) - def get_statements(self): + def get_statements(self, line: str = "Copyright (C)") -> List[str]: """ Returns all registered copyright statements as a sorted list. """ - statements = [] - for the_copyright in sorted(self.copyrights.values(), reverse=True): - statements.append(the_copyright.get_statement()) - return statements + return [ + make_copyright_statement(holder, years, line) + for holder, years in sorted(self.items(), key=_copyright_key) + ] def make_lines(content: GenericContent) -> List[str]: diff --git a/rtemsspec/tests/test_content_copyrights.py b/rtemsspec/tests/test_content_copyrights.py index d33bcf0c..fdcc9db4 100644 --- a/rtemsspec/tests/test_content_copyrights.py +++ b/rtemsspec/tests/test_content_copyrights.py @@ -30,6 +30,11 @@ from rtemsspec.content import Copyright from rtemsspec.content import Copyrights +def test_copyright_from_statement(): + c = Copyright.from_statement("Copyright (C) 42 John Doe") + assert "Copyright (C) 42 John Doe" == c.get_statement() + + def test_copyright_get_statement(): c = Copyright("John Doe") c.add_year(3) @@ -64,7 +69,7 @@ def test_copyrights_register(): c = Copyrights() with pytest.raises(ValueError): c.register("abc") - c.register("Copyright (C) 2 A") + c.register(["Copyright (C) 2 A"]) c.register("Copyright (C) 2, 3 A") c.register("Copyright (C) 2, 4 C") c.register("Copyright (C) 3 E") |