diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f99366c..76e9eff4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,13 +16,13 @@ repos: hooks: - id: check-yaml - id: end-of-file-fixer - exclude: requirements_lock.txt + exclude: requirements_lock.txt|\.svg$ - id: trailing-whitespace - id: check-shebang-scripts-are-executable - id: check-executables-have-shebangs - id: check-added-large-files args: [--maxkb=100, --enforce-all] # increase or add git lfs if too strict - exclude: org.eclipse.dash.licenses-1.1.0.jar|blanket_index.html + exclude: org.eclipse.dash.licenses-1.1.0.jar|blanket_index.html$ - repo: https://github.com/google/yamlfmt rev: 21ca5323a9c87ee37a434e0ca908efc0a89daa07 # v0.21.0 hooks: @@ -31,11 +31,13 @@ repos: rev: a1bb792acda6fd0724936b4ebbdbc8eceb9c0459 # v6.2.0 hooks: - id: reuse-lint-file + exclude: \.svg$ - repo: local hooks: - id: copyright name: Check and fix copyright headers with cr_checker entry: cr_checker/tool/pre-commit_wrapper --extensions h hpp c cpp rs rst py sh bzl ini yml yaml BUILD bazel --fix + exclude: \.svg$ # this would be the better language implementation, but struggle with python tooling # language: python language: script diff --git a/BUILD b/BUILD index d1490afb..8146d9b8 100644 --- a/BUILD +++ b/BUILD @@ -28,8 +28,11 @@ copyright_checker( "python_basics", "starpls", "tools", - "plantuml", "lobster_bazel", + "bazel", + "manual_analysis", + "plantuml", + "validation", # Add other directories/files you want to check ], diff --git a/bazel/rules/rules_score/README.md b/bazel/rules/rules_score/README.md index 490245e9..3e51029d 100644 --- a/bazel/rules/rules_score/README.md +++ b/bazel/rules/rules_score/README.md @@ -1,3 +1,16 @@ + + # Rules Score Starlark rules implementing the **S-CORE** functional-safety development process diff --git a/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/fta_example.puml b/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/fta_example.puml index be185b82..67a186f7 100644 --- a/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/fta_example.puml +++ b/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/fta_example.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + @startuml !include ../../../../../../../plantuml/fta_metamodel.puml diff --git a/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/safety_analysis.puml b/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/safety_analysis.puml index bff22765..624aba5e 100644 --- a/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/safety_analysis.puml +++ b/bazel/rules/rules_score/examples/seooc/safety_analysis/assets/safety_analysis.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + ' ******************************************************************************* ' Copyright (c) {year} Contributors to the Eclipse Foundation ' diff --git a/bazel/rules/rules_score/examples/seooc/safety_analysis/safety_analysis.md b/bazel/rules/rules_score/examples/seooc/safety_analysis/safety_analysis.md index 63686cd0..fa8c248d 100644 --- a/bazel/rules/rules_score/examples/seooc/safety_analysis/safety_analysis.md +++ b/bazel/rules/rules_score/examples/seooc/safety_analysis/safety_analysis.md @@ -1,3 +1,16 @@ + + # Safety Analysis This document shows the workflow and the interrelation on how to document an FMEA in TRLC / PlantUml / Lobster. diff --git a/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_class_diagram.puml b/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_class_diagram.puml index fafab979..6170a9c9 100644 --- a/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_class_diagram.puml +++ b/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_class_diagram.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + @startuml unit_1_class_diagram namespace unit_1 { diff --git a/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_class_diagram.puml b/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_class_diagram.puml index dd0d77b6..4d8e2780 100644 --- a/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_class_diagram.puml +++ b/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_class_diagram.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + @startuml unit_2_class_diagram namespace unit_1 { diff --git a/bazel/rules/rules_score/private/sphinx_module.bzl b/bazel/rules/rules_score/private/sphinx_module.bzl index d4baa109..57438e1b 100644 --- a/bazel/rules/rules_score/private/sphinx_module.bzl +++ b/bazel/rules/rules_score/private/sphinx_module.bzl @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + load("//bazel/rules/rules_score:providers.bzl", "SphinxModuleInfo", "SphinxNeedsInfo") # ====================================================================================== diff --git a/bazel/rules/rules_score/rules_score.bzl b/bazel/rules/rules_score/rules_score.bzl index 8296c9f7..be2fe9c3 100644 --- a/bazel/rules/rules_score/rules_score.bzl +++ b/bazel/rules/rules_score/rules_score.bzl @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + load( "//bazel/rules/rules_score:providers.bzl", _ComponentInfo = "ComponentInfo", diff --git a/bazel/rules/rules_score/sphinx_toolchain.bzl b/bazel/rules/rules_score/sphinx_toolchain.bzl index dfb2d20e..1b679066 100644 --- a/bazel/rules/rules_score/sphinx_toolchain.bzl +++ b/bazel/rules/rules_score/sphinx_toolchain.bzl @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + SphinxInfo = provider( doc = "Provider for Sphinx Toolchain", fields = { diff --git a/bazel/rules/rules_score/src/sphinx_html_merge.py b/bazel/rules/rules_score/src/sphinx_html_merge.py index 60dfaa43..901034a9 100755 --- a/bazel/rules/rules_score/src/sphinx_html_merge.py +++ b/bazel/rules/rules_score/src/sphinx_html_merge.py @@ -1,4 +1,17 @@ #!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Merge multiple Sphinx HTML output directories. This script merges Sphinx HTML documentation from multiple modules into a single diff --git a/bazel/rules/rules_score/templates/dependable_element_index.template.rst b/bazel/rules/rules_score/templates/dependable_element_index.template.rst index 70d86b43..ef56ce40 100644 --- a/bazel/rules/rules_score/templates/dependable_element_index.template.rst +++ b/bazel/rules/rules_score/templates/dependable_element_index.template.rst @@ -1,15 +1,16 @@ -.. ******************************************************************************* -.. Copyright (c) 2025 Contributors to the Eclipse Foundation .. -.. See the NOTICE file(s) distributed with this work for additional -.. information regarding copyright ownership. -.. -.. This program and the accompanying materials are made available under the -.. terms of the Apache License Version 2.0 which is available at -.. https://www.apache.org/licenses/LICENSE-2.0 -.. -.. SPDX-License-Identifier: Apache-2.0 -.. ******************************************************************************* + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* Dependable element: {title} ===================={underline} diff --git a/bazel/rules/rules_score/templates/fmea.template.rst b/bazel/rules/rules_score/templates/fmea.template.rst index 3dfb889c..5d51ef8f 100644 --- a/bazel/rules/rules_score/templates/fmea.template.rst +++ b/bazel/rules/rules_score/templates/fmea.template.rst @@ -1,3 +1,17 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + {title} {underline} diff --git a/cli_helper/README.md b/cli_helper/README.md index 19daf88b..943a3eae 100644 --- a/cli_helper/README.md +++ b/cli_helper/README.md @@ -1,8 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> # CLI Helper diff --git a/cr_checker/README.md b/cr_checker/README.md index 1ba934af..e9d98334 100644 --- a/cr_checker/README.md +++ b/cr_checker/README.md @@ -1,8 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> # CopyRight Checker diff --git a/cr_checker/resources/templates.ini b/cr_checker/resources/templates.ini index aee1b930..d9f1220e 100644 --- a/cr_checker/resources/templates.ini +++ b/cr_checker/resources/templates.ini @@ -10,7 +10,7 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -[cpp,c,h,hpp] +[cpp,c,h,hpp,trlc,rsl] /******************************************************************************** * Copyright (c) {year} {author} * @@ -63,3 +63,29 @@ // // SPDX-License-Identifier: Apache-2.0 // ******************************************************************************* +[puml] +' ******************************************************************************* +' Copyright (c) {year} Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* +[md] + diff --git a/cr_checker/tests/test_cr_checker.py b/cr_checker/tests/test_cr_checker.py index 7e66c4f7..7cfac352 100644 --- a/cr_checker/tests/test_cr_checker.py +++ b/cr_checker/tests/test_cr_checker.py @@ -251,7 +251,7 @@ def test_process_files_fix_inserts_header_after_shebang(tmp_path): assert results["no_copyright"] == 1 expected_header = header_template.format(year=current_year, author=author) assert script.read_text(encoding="utf-8") == ( - "#!/usr/bin/env python3\n" + expected_header + "print('hi')\n" + "#!/usr/bin/env python3\n" + expected_header + "\n" + "print('hi')\n" ) @@ -301,4 +301,144 @@ def test_process_files_fix_inserts_header_without_shebang(tmp_path): assert results["fixed"] == 1 assert results["no_copyright"] == 1 expected_header = header_template.format(year=current_year, author=author) - assert script.read_text(encoding="utf-8") == expected_header + "print('hi')\n" + assert ( + script.read_text(encoding="utf-8") == expected_header + "\n" + "print('hi')\n" + ) + + +# test that border lines with different fill characters are accepted (flexible matching) +def test_process_files_accepts_flexible_border(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.cpp" + current_year = datetime.now().year + # Use '/' fill chars instead of '*' for border lines + header = ( + "/////////////////////////////////////////////////////////////////////////////////////\n" + f" * Copyright (c) {current_year} Author\n" + " *\n" + " * See the NOTICE file(s) distributed with this work for additional\n" + " * information regarding copyright ownership.\n" + " *\n" + " * This program and the accompanying materials are made available under the\n" + " * terms of the Apache License Version 2.0 which is available at\n" + " * https://www.apache.org/licenses/LICENSE-2.0\n" + " *\n" + " * SPDX-License-Identifier: Apache-2.0\n" + " /////////////////////////////////////////////////////////////////////////////////////\n" + ) + test_file.write_text(header + "int main() {}\n", encoding="utf-8") + header_template = load_template("cpp") + + results = cr_checker.process_files( + [test_file], + {"cpp": header_template}, + False, + use_mmap=False, + encoding="utf-8", + offset=0, + remove_offset=0, + ) + + assert results["no_copyright"] == 0 + + +# test that a blank line after the header does not cause a check failure +def test_process_files_accepts_header_with_trailing_blank_line(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.py" + header_template = load_template("py") + current_year = datetime.now().year + header = header_template.format(year=current_year, author="Author") + test_file.write_text(header + "\nsome content\n", encoding="utf-8") + + results = cr_checker.process_files( + [test_file], + {"py": header_template}, + False, + use_mmap=False, + encoding="utf-8", + offset=0, + remove_offset=0, + ) + + assert results["no_copyright"] == 0 + + +# test that fix_copyright inserts a blank line after the header +def test_process_files_fix_inserts_trailing_blank_line(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.py" + test_file.write_text("some content\n", encoding="utf-8") + header_template = load_template("py") + current_year = datetime.now().year + author = "Author" + config = write_config(tmp_path, author) + + cr_checker.process_files( + [test_file], + {"py": header_template}, + True, + config=config, + use_mmap=False, + encoding="utf-8", + offset=0, + remove_offset=0, + ) + + expected_header = header_template.format(year=current_year, author=author) + assert test_file.read_text(encoding="utf-8").startswith(expected_header + "\n") + + +# test that has_duplicate_copyright detects a header that appears twice +def test_has_duplicate_copyright_detects_duplicate(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.py" + header_template = load_template("py") + current_year = datetime.now().year + header = header_template.format(year=current_year, author="Author") + test_file.write_text(header + header + "some content\n", encoding="utf-8") + + result = cr_checker.has_duplicate_copyright( + test_file, header_template, False, "utf-8", 0 + ) + + assert result is True + + +# test that has_duplicate_copyright returns False for a single header +def test_has_duplicate_copyright_single_header(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.py" + header_template = load_template("py") + current_year = datetime.now().year + header = header_template.format(year=current_year, author="Author") + test_file.write_text(header + "some content\n", encoding="utf-8") + + result = cr_checker.has_duplicate_copyright( + test_file, header_template, False, "utf-8", 0 + ) + + assert result is False + + +# test that process_files counts duplicate headers separately from missing headers +def test_process_files_detects_duplicate_header(tmp_path): + cr_checker = load_cr_checker_module() + test_file = tmp_path / "file.py" + header_template = load_template("py") + current_year = datetime.now().year + header = header_template.format(year=current_year, author="Author") + test_file.write_text(header + header + "some content\n", encoding="utf-8") + + results = cr_checker.process_files( + [test_file], + {"py": header_template}, + False, + use_mmap=False, + encoding="utf-8", + offset=0, + remove_offset=0, + ) + + assert results["duplicate_copyright"] == 1 + assert results["no_copyright"] == 0 diff --git a/cr_checker/tool/cr_checker.py b/cr_checker/tool/cr_checker.py index 9d492e35..3da01cae 100755 --- a/cr_checker/tool/cr_checker.py +++ b/cr_checker/tool/cr_checker.py @@ -29,6 +29,9 @@ BYTES_TO_READ = 4 * 1024 DEFAULT_AUTHOR = "Contributors to the Eclipse Foundation" +BORDER_FILL_PATTERN = re.compile(r"([/*#'\-=+])\1{4,}") +FILL_CHARS_REGEX = r"[/*#'\-=+]+" + LOGGER = logging.getLogger() COLORS = { @@ -139,6 +142,28 @@ def convert_bre_to_regex(template: str) -> str: return escaped +def line_to_flexible_regex(line: str) -> str: + """ + Convert a border line to a regex that accepts any fill characters. + + Runs of 5+ identical fill characters (e.g. ``****``) are replaced with + ``[/*#'\\-=+]+`` so that alternative styles (e.g. ``////``) are also + accepted. + """ + stripped = line.rstrip("\n") + has_newline = line.endswith("\n") + result = [] + last_end = 0 + for m in BORDER_FILL_PATTERN.finditer(stripped): + result.append(re.escape(stripped[last_end : m.start()])) + result.append(FILL_CHARS_REGEX) + last_end = m.end() + result.append(re.escape(stripped[last_end:])) + if has_newline: + result.append("\n") + return "".join(result) + + def load_templates(path): """ Loads the copyright templates from a configuration file. @@ -196,7 +221,7 @@ def load_exclusion(path): path (str): Path to the exclusion file. Returns: - tuple(list, bool): a list of files that are excluded from the coypright check and a boolean indicating whether + tuple(list, bool): a list of files that are excluded from the copyright check and a boolean indicating whether all paths listed in the exclusion file exist and are files. """ @@ -362,13 +387,18 @@ def has_copyright(path, template, use_mmap, encoding, offset, config=None): IOError: If there is an error opening or reading the file. """ - load_text = load_text_from_file - if use_mmap: - load_text = load_text_from_file_with_mmap + load_text = load_text_from_file_with_mmap if use_mmap else load_text_from_file - template_regex = convert_bre_to_regex( - template.format(year=r"\\d\{4\}", author=r"\.\*") - ) + lines = template.splitlines(keepends=True) + regex_parts = [] + for line in lines: + stripped_line = line.rstrip("\n") + if BORDER_FILL_PATTERN.search(stripped_line): + regex_parts.append(line_to_flexible_regex(line)) + else: + formatted = line.format(year=r"\\d\{4\}", author=r"\.\*") + regex_parts.append(convert_bre_to_regex(formatted)) + template_regex = "".join(regex_parts) + "\n?" if re.match(template_regex, load_text(path, BYTES_TO_READ, encoding, offset)): LOGGER.debug("File %s has copyright.", path) @@ -378,6 +408,41 @@ def has_copyright(path, template, use_mmap, encoding, offset, config=None): return False +def has_duplicate_copyright(path, template, use_mmap, encoding, offset): + """ + Checks if the copyright header appears more than once in the file. + + Args: + path (Path): A `pathlib.Path` object pointing to the file to check. + template (str): The copyright template to search for. + use_mmap (bool): If True, uses memory-mapped file reading. + encoding (str): Encoding type to use when reading the file. + offset (int): Byte offset to skip (e.g. shebang line). + + Returns: + bool: True if the copyright header appears more than once, False otherwise. + """ + load_text = load_text_from_file_with_mmap if use_mmap else load_text_from_file + + lines = template.splitlines(keepends=True) + regex_parts = [] + for line in lines: + stripped_line = line.rstrip("\n") + if BORDER_FILL_PATTERN.search(stripped_line): + regex_parts.append(line_to_flexible_regex(line)) + else: + formatted = line.format(year=r"\\d\{4\}", author=r"\.\*") + regex_parts.append(convert_bre_to_regex(formatted)) + template_regex = "\n?".join(regex_parts) + + content = load_text(path, 2 * BYTES_TO_READ, encoding, offset) + matches = list(re.finditer(template_regex, content)) + if len(matches) > 1: + LOGGER.debug("File %s has %d copyright headers.", path, len(matches)) + return True + return False + + def get_files_from_dir(directory, exts=None): """ Finds files in the specified directories. Filters by extensions if provided. @@ -520,6 +585,7 @@ def fix_copyright(path, copyright_text, encoding, offset, config=None) -> bool: copyright_text.format( year=datetime.now().year, author=get_author_from_config(config) ) + + "\n" ) for chunk in iter(lambda: temp.read(4096), ""): handle.write(chunk) @@ -562,7 +628,7 @@ def process_files( Returns: int: The number of files that do not contain the required copyright text. """ - results = {"no_copyright": 0, "fixed": 0} + results = {"no_copyright": 0, "fixed": 0, "duplicate_copyright": 0} for item in files: name = Path(item).name key = name if name == "BUILD" else Path(item).suffix[1:] @@ -584,7 +650,12 @@ def process_files( shebang_offset = detect_shebang_offset(item, encoding) effective_offset = offset + shebang_offset if offset == 0 else offset - if not has_copyright( + if has_duplicate_copyright( + item, templates[key], use_mmap, encoding, effective_offset + ): + LOGGER.error("Duplicate copyright header in: %s", item) + results["duplicate_copyright"] += 1 + elif not has_copyright( item, templates[key], use_mmap, encoding, effective_offset, config ): if fix: @@ -771,6 +842,7 @@ def main(argv=None): ) total_no = results["no_copyright"] total_fixes = results["fixed"] + total_duplicates = results["duplicate_copyright"] LOGGER.info("=" * 64) LOGGER.info("Process completed.") @@ -780,6 +852,12 @@ def main(argv=None): total_no, COLORS["ENDC"], ) + LOGGER.info( + "Total files with duplicate copyright: %s%d%s", + COLORS["RED"] if total_duplicates > 0 else COLORS["GREEN"], + total_duplicates, + COLORS["ENDC"], + ) if not exclusion_valid: LOGGER.info("The exclusion file contains paths that do not exist.") if args.fix: @@ -798,7 +876,7 @@ def main(argv=None): ) LOGGER.info("=" * 64) - return 0 if (total_no == 0 and exclusion_valid) else 1 + return 0 if (total_no == 0 and total_duplicates == 0 and exclusion_valid) else 1 if __name__ == "__main__": diff --git a/dash/README.md b/dash/README.md index 0add86ea..c6ba09d9 100644 --- a/dash/README.md +++ b/dash/README.md @@ -1,8 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> # DASH License Checker Bazel Integration diff --git a/format_checker/README.md b/format_checker/README.md index 069ab8fb..b69e249f 100644 --- a/format_checker/README.md +++ b/format_checker/README.md @@ -1,20 +1,16 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. -# Source Format Targets for Bazel Projects + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 -This module provides reusable Bazel macros for formatting **Starlark**, **Python**, **YAML**, and **Rust** files using [`aspect-build/rules_lint`](https://github.com/aspect-build/rules_lint) and `buildifier`. Rust formatting uses the shared S-CORE policies via `@score_tooling//format_checker:rustfmt_with_policies`. + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> ---- - -## Features - -- ✅ Supports Python (`ruff`), YAML (`yamlfmt`), Starlark (`buildifier`) and Rust (policy-backed `rustfmt` by default) -- ✅ Provides `format.fix` and `format.check` targets -- ✅ Simple macro-based usage for local formatting scope - ✅ Centralized logic without Bazel module extensions --- diff --git a/lobster_bazel/README.md b/lobster_bazel/README.md index 4e8cb6ee..1d4c5024 100644 --- a/lobster_bazel/README.md +++ b/lobster_bazel/README.md @@ -1,14 +1,16 @@ -# Tracing to Source Files (Bazel / Source Code Linker) + -Supported file types (automatically detected by extension): | Extension | Language | Comment sign | |----------------------|-----------|--------------| diff --git a/lobster_bazel/test/data/source_with_tags.cpp b/lobster_bazel/test/data/source_with_tags.cpp index 1fdcbb7e..230765c9 100644 --- a/lobster_bazel/test/data/source_with_tags.cpp +++ b/lobster_bazel/test/data/source_with_tags.cpp @@ -1,16 +1,3 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - /******************************************************************************** * Copyright (c) 2025 Contributors to the Eclipse Foundation * diff --git a/manual_analysis/README.md b/manual_analysis/README.md index 4b44ebb3..4ad0ee59 100644 --- a/manual_analysis/README.md +++ b/manual_analysis/README.md @@ -1,43 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. -# Manual Analysis + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 -This directory provides Bazel rules and tooling for defining and executing -**manual verification analyses**. A manual analysis captures a structured, -interactive review of a piece of implementation (the *context*) against a set -of requirements. A lock file ensures the analysis is re-done whenever the -context changes. - -## Overview - -A manual analysis consists of: - -- **Context** – the implementation under review (source files, headers, or - entire `cc_library` dependency graphs). -- **Analysis YAML** – a structured, step-by-step description of the - verification procedure (`action`, `automated_action`, `decision`, - `assertion`, `repeat`). -- **Results file** – a JSON file capturing the outcomes recorded during an - interactive run. -- **Lock file** – a SHA-256 digest file that ties the results to a specific - snapshot of the context. If the context changes, the test fails and the - analysis must be re-executed. - -The tooling also produces a **LOBSTER traceability artifact** (`.lobster` file) -so that coverage of requirements can be tracked across the project. - -For the Bazel-focused architectural design and runtime views of this tooling, -see [`docs/README.md`](docs/README.md). - -## Bazel Rules - -### `manual_analysis` (macro) - -The primary entry point. It instantiates two targets: + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> | Target | Kind | Purpose | |-----------------|--------|--------------------------------------------------------------------------| diff --git a/manual_analysis/docs/README.md b/manual_analysis/docs/README.md index f6628321..22f5af62 100644 --- a/manual_analysis/docs/README.md +++ b/manual_analysis/docs/README.md @@ -1,4 +1,4 @@ - - -# Manual Analysis Tooling - -### Processing Phases - -The manual-analysis tooling is organized around two Bazel-driven runtime flows: - -- **Update flow** — re-run the interactive analysis and refresh the committed - lock file. -- **Test flow** — recompute the lock in the Bazel action sandbox, validate the - committed artifacts, and emit a `.lobster` traceability artifact. +----------------------------------------------------------------------------- --> The following sequence diagrams show both flows separately so the Bazel rule composition stays visible. diff --git a/manual_analysis/example/requirements.rsl b/manual_analysis/example/requirements.rsl index c73ebc27..6217f04d 100644 --- a/manual_analysis/example/requirements.rsl +++ b/manual_analysis/example/requirements.rsl @@ -1,3 +1,16 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + package manual_analysis_example type Requirement diff --git a/manual_analysis/example/requirements.trlc b/manual_analysis/example/requirements.trlc index 496494c8..489e8495 100644 --- a/manual_analysis/example/requirements.trlc +++ b/manual_analysis/example/requirements.trlc @@ -1,3 +1,16 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + package manual_analysis_example Requirement no_cat_killing diff --git a/plantuml/linker/README.md b/plantuml/linker/README.md index 1ff65aa9..710adbc9 100644 --- a/plantuml/linker/README.md +++ b/plantuml/linker/README.md @@ -1,4 +1,4 @@ - - -# PlantUML Linker - -Reads `.fbs.bin` files produced by the [PlantUML parser](../parser/README.md) and generates a -`plantuml_links.json` file consumed by the `clickable_plantuml` Sphinx extension. - -## What it does - -When an architecture is described across multiple PlantUML component diagrams, the linker -correlates components between them: if a component alias in diagram **A** matches a top-level -component alias in diagram **B**, the linker emits a link from A → B. This lets the Sphinx -documentation render clickable diagrams where high-level overview components link through to -their detailed sub-diagrams. - -## Usage - -``` -linker --fbs-files [ ...] --output plantuml_links.json -``` - -The tool is invoked automatically by the `architectural_design()` Bazel rule — there is -normally no need to call it manually. - -## Build - -```bash -bazel build //plantuml/linker:linker -``` +----------------------------------------------------------------------------- --> diff --git a/plantuml/parser/README.md b/plantuml/parser/README.md index 0235e88e..31a0480c 100644 --- a/plantuml/parser/README.md +++ b/plantuml/parser/README.md @@ -1,4 +1,4 @@ - +----------------------------------------------------------------------------- --> # PlantUML Parser diff --git a/plantuml/parser/docs/README.md b/plantuml/parser/docs/README.md index 6e764fc5..8d882d03 100644 --- a/plantuml/parser/docs/README.md +++ b/plantuml/parser/docs/README.md @@ -1,4 +1,4 @@ - - +----------------------------------------------------------------------------- --> # PlantUML Parser ### Processing Phases diff --git a/plantuml/sphinx/clickable_plantuml/README.md b/plantuml/sphinx/clickable_plantuml/README.md index 5d024236..ec3e28f3 100644 --- a/plantuml/sphinx/clickable_plantuml/README.md +++ b/plantuml/sphinx/clickable_plantuml/README.md @@ -1,4 +1,4 @@ - +----------------------------------------------------------------------------- --> # clickable_plantuml Sphinx extension that makes PlantUML diagrams clickable by injecting hyperlinks into rendered SVG/PNG diagrams. diff --git a/python_basics/README.md b/python_basics/README.md index d4b990c4..f341c9c4 100644 --- a/python_basics/README.md +++ b/python_basics/README.md @@ -1,9 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> # S-CORE Python Basics * ✅ Makes development of Python code easier inside Bazel diff --git a/python_basics/score_pytest/README.md b/python_basics/score_pytest/README.md index 559fcbc9..cdc8df4c 100644 --- a/python_basics/score_pytest/README.md +++ b/python_basics/score_pytest/README.md @@ -1,8 +1,15 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> # Score pytest wrapper & plugin diff --git a/starpls/README.md b/starpls/README.md index e8a66239..ea35f164 100644 --- a/starpls/README.md +++ b/starpls/README.md @@ -1,77 +1,78 @@ - - -# StarPLS Bazel Module - -This Bazel module provides a convenient way to integrate the pre-built `starpls` Starlark language server into your Bazel workspace. - -## Features - -* Downloads a specific version of the `starpls` binary. -* Provides a simple Bazel macro (`setup_starpls`) to create a `genrule` target that downloads and makes the language server executable. - -## Prerequisites - -* An operating system compatible with the downloaded binary (currently hardcoded to `linux-amd64`). -* The `rules_shell` Bazel module must be added as a dependency in your workspace's `MODULE.bazel` file. - -## Usage - -1. **Add dependencies to your `MODULE.bazel` file:** - - ```bazel - # Needed by the score_starpls_lsp module internally - bazel_dep(name = "rules_shell", version = "0.4.0") # Or newer - - # The score_starpls_lsp module itself - bazel_dep(name = "score_starpls_lsp", version = "0.1.0") - # If using a local path override for testing: - # local_path_override( - # module_name = "score_starpls_lsp", - # path = "/path/to/your/local/score_starpls_lsp" - # ) - ``` - -2. **Load the setup macro and invoke it in your `BUILD` file:** - - ```bazel - load("@score_starpls_lsp//:starpls.bzl", "setup_starpls") - - setup_starpls( - name = "starpls_server", - visibility = ["//visibility:public"], - ) - ``` - -3. **Run the language server:** - - You can now run the language server directly using Bazel: - ```bash - bazel run //starpls_server-- [arguments_for_starpls...] - ``` - -4. **Configure your IDE (e.g., VS Code):** - - Point your IDE's Starlark/Bazel language server setting to the executable `genrule` target you created (e.g., `//starpls_server`). For VSCode, configure it to execute the `bazel run` command: - ```json - "bazel.lsp.command": "bazel", - "bazel.lsp.args": [ - "run", - "//:starpls_server" - ], - ``` - -## Current Limitations - -* **Platform:** Downloads only the `linux-amd64` binary. -* **Version:** Downloads a fixed version (`0.1.21`) of `starpls`. - -## Running Integration Tests - -To run the `starpls_test` integration test suite after cleaning the Bazel cache and outputs, execute the following command from the root directory of the `starpls` module: - -```bash -bazel clean --expunge && bazel test //integration_tests:starpls_test + + +* Downloads a specific version of the `starpls` binary. +* Provides a simple Bazel macro (`setup_starpls`) to create a `genrule` target that downloads and makes the language server executable. + +## Prerequisites + +* An operating system compatible with the downloaded binary (currently hardcoded to `linux-amd64`). +* The `rules_shell` Bazel module must be added as a dependency in your workspace's `MODULE.bazel` file. + +## Usage + +1. **Add dependencies to your `MODULE.bazel` file:** + + ```bazel + # Needed by the score_starpls_lsp module internally + bazel_dep(name = "rules_shell", version = "0.4.0") # Or newer + + # The score_starpls_lsp module itself + bazel_dep(name = "score_starpls_lsp", version = "0.1.0") + # If using a local path override for testing: + # local_path_override( + # module_name = "score_starpls_lsp", + # path = "/path/to/your/local/score_starpls_lsp" + # ) + ``` + +2. **Load the setup macro and invoke it in your `BUILD` file:** + + ```bazel + load("@score_starpls_lsp//:starpls.bzl", "setup_starpls") + + setup_starpls( + name = "starpls_server", + visibility = ["//visibility:public"], + ) + ``` + +3. **Run the language server:** + + You can now run the language server directly using Bazel: + ```bash + bazel run //starpls_server-- [arguments_for_starpls...] + ``` + +4. **Configure your IDE (e.g., VS Code):** + + Point your IDE's Starlark/Bazel language server setting to the executable `genrule` target you created (e.g., `//starpls_server`). For VSCode, configure it to execute the `bazel run` command: + ```json + "bazel.lsp.command": "bazel", + "bazel.lsp.args": [ + "run", + "//:starpls_server" + ], + ``` + +## Current Limitations + +* **Platform:** Downloads only the `linux-amd64` binary. +* **Version:** Downloads a fixed version (`0.1.21`) of `starpls`. + +## Running Integration Tests + +To run the `starpls_test` integration test suite after cleaning the Bazel cache and outputs, execute the following command from the root directory of the `starpls` module: + +```bash +bazel clean --expunge && bazel test //integration_tests:starpls_test diff --git a/tools/README.md b/tools/README.md index 022205f8..d4c374a3 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,20 +1,16 @@ - + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. -# S-CORE tooling binaries + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 -This bazel module provides centrally managed binaries for developer tools used in S-CORE, including linters -and formatters. + SPDX-License-Identifier: Apache-2.0 +----------------------------------------------------------------------------- --> -For Rust coverage reporting, see [coverage/README.md](../coverage/README.md). - -It provides a template script `sample.sh` that can be adapted to run the tools you need. - -## Current tools: -Currently binaries / executables for the following tools are provided - **Ruff**: A super-fast Python linter. - **basedpyright**: A type checker for Python. - **Actionlint**: A linter for your GitHub Actions workflows. diff --git a/validation/ai_checker/README.md b/validation/ai_checker/README.md index f500bebb..25a36bbb 100644 --- a/validation/ai_checker/README.md +++ b/validation/ai_checker/README.md @@ -1,3 +1,16 @@ + + # AI Checker AI-powered analysis tool for engineering artefacts against guidelines. diff --git a/validation/ai_checker/_assets/class_diagram.puml b/validation/ai_checker/_assets/class_diagram.puml index c080daa0..4011e9f5 100644 --- a/validation/ai_checker/_assets/class_diagram.puml +++ b/validation/ai_checker/_assets/class_diagram.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + @startuml class RequirementAnalysis <> { diff --git a/validation/ai_checker/_assets/deployment_diagram.puml b/validation/ai_checker/_assets/deployment_diagram.puml index 2a0424e8..c6f25c3c 100644 --- a/validation/ai_checker/_assets/deployment_diagram.puml +++ b/validation/ai_checker/_assets/deployment_diagram.puml @@ -1,3 +1,16 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + @startuml skinparam packageStyle rectangle diff --git a/validation/ai_checker/guidelines/general.md b/validation/ai_checker/guidelines/general.md index e2c44c47..2918e7c6 100644 --- a/validation/ai_checker/guidelines/general.md +++ b/validation/ai_checker/guidelines/general.md @@ -1,14 +1,16 @@ -# General + -Accept following points as fully defined and don´t list it in the findings or suggestions: -- General: - - "S-Core" is the Name of the Platform project -- Bazel commands - - Link: "@//:target" - - public visible - - expose target - Markdown Expressions (Link: "[label](http://example.com)") - RST Expressions (Link: ".. _a link: https://domain.invalid/" or `a link`_ ) - Expression which are provided as comment or via `` as fully defined. diff --git a/validation/ai_checker/guidelines/requirements_guidelines.md b/validation/ai_checker/guidelines/requirements_guidelines.md index 50d56d4e..b2b431a4 100644 --- a/validation/ai_checker/guidelines/requirements_guidelines.md +++ b/validation/ai_checker/guidelines/requirements_guidelines.md @@ -1,3 +1,16 @@ + + # Requirements Writing Guidelines Guidelines for creating and formulating requirements, derived from the SCORE Requirements Engineering Process. diff --git a/validation/archver/README.md b/validation/archver/README.md index fb8b0eb0..52e0d1d5 100644 --- a/validation/archver/README.md +++ b/validation/archver/README.md @@ -1,4 +1,4 @@ - +----------------------------------------------------------------------------- --> # Architecture Verifier (archver)