This commit is contained in:
Todd Gamblin 2025-01-13 14:56:46 -08:00
parent 37c63aa22d
commit 9ee32b060b
No known key found for this signature in database
GPG Key ID: C16729F1AACF66C6
2 changed files with 42 additions and 13 deletions

View File

@ -211,50 +211,63 @@ def _fix_path(path: str) -> List[str]:
Returns:
List of fixed lines, if a fix was possible, otherwise an empty list.
"""
lines = open(path, encoding="utf-8").read().split("\n")
comment, fixed = "#", fixed_lines
if path.endswith(".lp"):
fixed = [line.replace(comment, "%") for line in fixed_lines]
comment = "%"
# only try to fix python files / scripts
if not (path.endswith(".py") or path.endswith(".sh") or (lines and lines[0].startswith("#!"))):
try:
if path.endswith(".py") or path.endswith(".sh"):
with open(path, encoding="utf-8") as f:
lines = f.read().split("\n")
else:
with open(path, encoding="utf-8") as f:
if f.read(2) != "#!":
return []
f.seek(0)
lines = f.read().split("\n")
except UnicodeDecodeError:
return []
# easy case: license looks mostly familiar
start = next((i for i, line in enumerate(lines) if re.match(r"#\s*Copyright", line)), -1)
end = next((i for i, line in enumerate(lines) if re.match(r"#\s*SPDX-", line)), -1)
start = next(
(i for i, line in enumerate(lines) if re.match(rf"{comment}\s*Copyright", line)), -1
)
end = next((i for i, line in enumerate(lines) if re.match(rf"{comment}\s*SPDX-", line)), -1)
# here we just replace a bad license with the fixed one
if start >= 0 and end >= 0:
# filter out weird cases and make sure we mostly know what we're fixing
if (
end < start
or end - start > 6
or not all(lines[i].startswith("#") for i in range(start, end))
or not all(lines[i].startswith(comment) for i in range(start, end))
):
return []
if start < (license_lines - len(license_line_regexes)):
# replace license where it is
lines[start : end + 1] = fixed_lines
lines[start : end + 1] = fixed
else:
# move license to beginning of file
del lines[start : end + 1]
start = 0
while any(lines[start].startswith(s) for s in ("#!", "# -*-")):
while any(lines[start].startswith(s) for s in ("#!", f"{comment} -*-")):
start += 1
lines[start:start] = fixed_lines
lines[start:start] = fixed
return lines
# no license in the file yet, so we add it
if start == -1 and end == -1:
start = 0
while any(lines[start].startswith(s) for s in ("#!", "# -*-")):
while any(lines[start].startswith(s) for s in ("#!", f"{comment} -*-")):
start += 1
# add an empty line if needed
if not re.match(r"#\s*$", lines[start]):
lines[start:start] = "#"
if not re.match(rf"{comment}\s*$", lines[start]):
lines[start:start] = comment
start += 1
lines[start:start] = fixed_lines

View File

@ -91,6 +91,20 @@ def test_list_files():
GOOD_HEADER,
False,
),
(
"old_llnl.lp",
r"files not containing expected license:\s*1",
textwrap.dedent(
"""\
% Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
% Spack Project Developers. See top-level COPYRIGHT file for details.
%
% SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""
),
GOOD_HEADER.replace("#", "%"),
False,
),
("no_header.py", r"files without license in first 7 lines:\s*1", "", GOOD_HEADER, False),
(
"test-script",
@ -141,6 +155,7 @@ def test_list_files():
False,
),
("good.py", "", GOOD_HEADER, GOOD_HEADER, True),
("good.lp", "", GOOD_HEADER.replace("#", "%"), GOOD_HEADER.replace("#", "%"), True),
]
@ -185,6 +200,7 @@ def test_license_fix(self, filename, expected_txt, header, fixed_header, good, t
return
if fixed_header:
print("OUT", out)
assert f"Fixed {str(source_file)}" in out
assert license.returncode == 0