Skip to content

Commit

Permalink
Merge pull request eclipse-score#164 from nradakovic/nira_bug_161
Browse files Browse the repository at this point in the history
fix: Support configurable year in cr_checker
  • Loading branch information
ltekieli authored Jan 16, 2025
2 parents 6991a3e + 17f2016 commit 9482827
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
9 changes: 8 additions & 1 deletion tools/cr_checker/cr_checker.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def copyright_checker(
srcs,
visibility,
template = "//tools/cr_checker/resources:templates",
config = "//tools/cr_checker/resources:config",
extensions = [],
offset = 0,
debug = False,
Expand All @@ -34,6 +35,8 @@ def copyright_checker(
targets can use this rule.
template (str, optional): Path to the template resource used for validation.
Defaults to "//tools/cr_checker/resources:templates".
config (str, optional): Path to the config resource used for project variables.
Defaults to "//tools/cr_checker/resources:config".
extensions (list, optional): A list of file extensions to filter the source files.
Defaults to an empty list, meaning all files are checked.
offset (int, optional): The line offset for applying checks or modifications.
Expand All @@ -53,7 +56,10 @@ def copyright_checker(
"{}.fix".format(name),
]

args = ["-t $(location {})".format(template)]
args = [
"-t $(location {})".format(template),
"-c $(location {})".format(config),
]
data = []
if len(extensions):
args.append("-e {exts}".format(
Expand Down Expand Up @@ -85,6 +91,7 @@ def copyright_checker(
args = args,
data = srcs + [
template,
config,
],
visibility = visibility,
)
10 changes: 9 additions & 1 deletion tools/cr_checker/resources/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# *******************************************************************************
# Copyright (c) 2024 Contributors to the Eclipse Foundation
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
Expand All @@ -18,3 +18,11 @@ filegroup(
],
visibility = ["//visibility:public"],
)

filegroup(
name = "config",
srcs = [
"config.json",
],
visibility = ["//visibility:public"],
)
3 changes: 3 additions & 0 deletions tools/cr_checker/resources/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"years": [2024, 2025]
}
6 changes: 3 additions & 3 deletions tools/cr_checker/resources/templates.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# *******************************************************************************
[cpp,c,h,hpp]
/********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
* Copyright (c) {year} Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -25,7 +25,7 @@
********************************************************************************/
[py,sh,bzl,ini,yml,BUILD,bazel]
# *******************************************************************************
# Copyright (c) 2024 Contributors to the Eclipse Foundation
# Copyright (c) {year} Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
Expand All @@ -39,7 +39,7 @@
[rst]
..
# *******************************************************************************
# Copyright (c) 2024 Contributors to the Eclipse Foundation
# Copyright (c) {year} Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
Expand Down
59 changes: 50 additions & 9 deletions tools/cr_checker/tool/cr_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import sys
import tempfile
import mmap
import json
from datetime import datetime
from pathlib import Path

LOGGER = logging.getLogger()
Expand Down Expand Up @@ -98,6 +100,21 @@ def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)


def get_years_from_config(config_path):
"""
Reads the years from a JSON configuration file.
Args:
config_path (Path): Path to the configuration JSON file.
Returns:
list: List of years from the configuration file.
"""
with config_path.open("r") as file:
config = json.load(file)
return config.get("years", [])


def load_templates(path):
"""
Loads the copyright templates from a configuration file.
Expand Down Expand Up @@ -228,7 +245,7 @@ def load_text_from_file_with_mmap(path, header_length, encoding, offset):
return fmap[:header_length].decode(encoding)


def has_copyright(path, copyright_text, use_mmap, encoding, offset):
def has_copyright(path, copyright_text, use_mmap, encoding, offset, config):
"""
Checks if the specified copyright text is present in the beginning of a file.
Expand All @@ -242,6 +259,8 @@ def has_copyright(path, copyright_text, use_mmap, encoding, offset):
offset (int): Additional number of characters to read beyond the length
of `copyright_text`, used to account for extra content
(such as a shebang) before the copyright text.
config (Path): Path to the config JSON file where configuration
variables are stored (e.g. years for copyright headers).
Returns:
bool: True if the file contains the copyright text, False if it is missing.
Expand All @@ -254,10 +273,14 @@ def has_copyright(path, copyright_text, use_mmap, encoding, offset):
if use_mmap:
load_text = load_text_from_file_with_mmap

if copyright_text not in load_text(path, len(copyright_text), encoding, offset):
return False
LOGGER.debug("File %s has copyright.", path)
return True
for year in get_years_from_config(config):
formated_cr = copyright_text.format(year=year)
if formated_cr in load_text(path, len(formated_cr), encoding, offset):
LOGGER.debug("File %s has copyright.", path)
return True

LOGGER.debug("File %s doesn't have copyright.", path)
return False


def get_files_from_dir(directory, exts=None):
Expand Down Expand Up @@ -361,15 +384,17 @@ def fix_copyright(path, copyright_text, encoding, offset):
with open(path, "w", encoding=encoding) as handle:
if offset > 0:
handle.write(first_line + "\n")
handle.write(copyright_text)
handle.write(copyright_text.format(year=datetime.now().year))
# Reset the file pointer to the beginning of the temporary file
temp.seek(0)
for chunk in iter(lambda: temp.read(4096), ""):
handle.write(chunk)
LOGGER.info("Fixed missing header in: %s", path)


def process_files(files, templates, fix, use_mmap=False, encoding="utf-8", offset=0): # pylint: disable=too-many-arguments
def process_files(
files, templates, fix, config, use_mmap=False, encoding="utf-8", offset=0
): # pylint: disable=too-many-arguments
"""
Processes a list of files to check for the presence of copyright text.
Expand All @@ -378,6 +403,8 @@ def process_files(files, templates, fix, use_mmap=False, encoding="utf-8", offse
templates (dict): A dictionary where keys are file extensions
(e.g., '.py', '.txt') and values are strings or patterns
representing the required copyright text.
config (Path): Path to the config JSON file where configuration
variables are stored (e.g. years for copyright headers).
use_mmap (bool): Flag for using mmap function for reading files
(instead of standard option).
encoding (str): Encoding type to use when reading the file.
Expand All @@ -397,7 +424,7 @@ def process_files(files, templates, fix, use_mmap=False, encoding="utf-8", offse
"Skipped (no configuration for selected file extension): %s", item
)
continue
if not has_copyright(item, templates[key], use_mmap, encoding, offset):
if not has_copyright(item, templates[key], use_mmap, encoding, offset, config):
if fix:
fix_copyright(item, templates[key], encoding, offset)
results["no_copyright"] += 1
Expand Down Expand Up @@ -433,6 +460,14 @@ def parse_arguments(argv):
help="Path to the template file",
)

parser.add_argument(
"-c",
"--config-file",
type=Path,
required=True,
help="Path to the config file",
)

parser.add_argument(
"-v", "--verbose", action="store_true", help="Enable debug logging level"
)
Expand Down Expand Up @@ -524,7 +559,13 @@ def main(argv=None):
LOGGER.debug("Running check on files: %s", files)

results = process_files(
files, templates, args.fix, args.use_memory_map, args.encoding, args.offset
files,
templates,
args.fix,
args.config_file,
args.use_memory_map,
args.encoding,
args.offset,
)
total_no = results["no_copyright"]
total_fixes = results["fixed"]
Expand Down

0 comments on commit 9482827

Please sign in to comment.