Skip to content

Commit 46f3037

Browse files
authored
Merge pull request #212 from fosslight/dev_copyright_from_text
Remove copyright info for license text file of GPL family
2 parents 4b5777c + dee7703 commit 46f3037

File tree

2 files changed

+119
-12
lines changed

2 files changed

+119
-12
lines changed

src/fosslight_source/_parsing_scancode_file_item.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,27 @@
3030
SPDX_REPLACE_WORDS = ["(", ")"]
3131
KEY_AND = r"(?<=\s)and(?=\s)"
3232
KEY_OR = r"(?<=\s)or(?=\s)"
33+
GPL_LICENSE_PATTERN = r'((a|l)?gpl|gfdl)' # GPL, LGPL, AGPL, GFDL
34+
35+
36+
def is_gpl_family_license(licenses: list) -> bool:
37+
if not licenses:
38+
return False
39+
40+
for license_name in licenses:
41+
if not license_name:
42+
continue
43+
44+
license_lower = license_name.lower()
45+
if re.search(GPL_LICENSE_PATTERN, license_lower):
46+
logger.debug(f"GPL family license detected: {license_name}")
47+
return True
48+
49+
return False
50+
51+
52+
def should_remove_copyright_for_gpl_license_text(licenses: list, is_license_text: bool) -> bool:
53+
return is_license_text and is_gpl_family_license(licenses)
3354

3455

3556
def get_error_from_header(header_item: list) -> Tuple[bool, str]:
@@ -100,8 +121,6 @@ def parsing_scancode_32_earlier(scancode_file_list: list, has_error: bool = Fals
100121
pass
101122
copyright_value_list.append(copyright_data)
102123

103-
result_item.copyright = copyright_value_list
104-
105124
# Set the license value
106125
license_detected = []
107126
if licenses is None or licenses == "":
@@ -165,14 +184,21 @@ def parsing_scancode_32_earlier(scancode_file_list: list, has_error: bool = Fals
165184
if len(license_detected) > 0:
166185
result_item.licenses = license_detected
167186

187+
if is_manifest_file(file_path):
188+
result_item.is_license_text = True
189+
190+
# Remove copyright info for license text file of GPL family
191+
if should_remove_copyright_for_gpl_license_text(license_detected, result_item.is_license_text):
192+
logger.debug(f"Removing copyright for GPL family license text file: {file_path}")
193+
result_item.copyright = []
194+
else:
195+
result_item.copyright = copyright_value_list
196+
168197
if len(license_expression_list) > 0:
169198
license_expression_list = list(
170199
set(license_expression_list))
171200
result_item.comment = ','.join(license_expression_list)
172201

173-
if is_manifest_file(file_path):
174-
result_item.is_license_text = True
175-
176202
if is_exclude_file(file_path, prev_dir, prev_dir_value):
177203
result_item.exclude = True
178204
scancode_file_item.append(result_item)
@@ -227,7 +253,6 @@ def parsing_scancode_32_later(
227253
except Exception:
228254
pass
229255
copyright_value_list.append(copyright_data)
230-
result_item.copyright = copyright_value_list
231256

232257
license_detected = []
233258
licenses = file.get("license_detections", [])
@@ -263,6 +288,20 @@ def parsing_scancode_32_later(
263288
license_list[lic_matched_key] = lic_info
264289
license_detected.append(found_lic)
265290
result_item.licenses = license_detected
291+
292+
result_item.exclude = is_exclude_file(file_path)
293+
result_item.is_license_text = file.get("percentage_of_license_text", 0) > 90 or is_notice_file(file_path)
294+
295+
if is_manifest_file(file_path) and len(license_detected) > 0:
296+
result_item.is_license_text = True
297+
298+
# Remove copyright info for license text file of GPL family
299+
if should_remove_copyright_for_gpl_license_text(license_detected, result_item.is_license_text):
300+
logger.debug(f"Removing copyright for GPL family license text file: {file_path}")
301+
result_item.copyright = []
302+
else:
303+
result_item.copyright = copyright_value_list
304+
266305
if len(license_detected) > 1:
267306
license_expression_spdx = file.get("detected_license_expression_spdx", "")
268307
license_expression = file.get("detected_license_expression", "")
@@ -271,12 +310,6 @@ def parsing_scancode_32_later(
271310
if license_expression:
272311
result_item.comment = license_expression
273312

274-
result_item.exclude = is_exclude_file(file_path)
275-
result_item.is_license_text = file.get("percentage_of_license_text", 0) > 90 or is_notice_file(file_path)
276-
277-
if is_manifest_file(file_path) and len(license_detected) > 0:
278-
result_item.is_license_text = True
279-
280313
scancode_file_item.append(result_item)
281314
except Exception as ex:
282315
msg.append(f"Error Parsing item: {ex}")

tests/test_tox.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
import subprocess
77
import pytest
88
import shutil
9+
import sys
10+
11+
# Add project root to sys.path for importing FL Source modules
12+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
13+
14+
# Import after sys.path modification to access our custom GPL license functions
15+
# flake8: noqa E402
16+
from fosslight_source._parsing_scancode_file_item import (
17+
is_gpl_family_license, should_remove_copyright_for_gpl_license_text
18+
)
919

1020
remove_directories = ["test_scan", "test_scan2", "test_scan3"]
1121

@@ -26,6 +36,70 @@ def run_command(command):
2636
return success, process.stdout if success else process.stderr
2737

2838

39+
def test_is_gpl_family_license():
40+
gpl_licenses = [
41+
["gpl-2.0"],
42+
["gpl-3.0"],
43+
["lgpl-2.1"],
44+
["lgpl-3.0"],
45+
["agpl-3.0"],
46+
["GPL-2.0"],
47+
["LGPL-2.1"],
48+
["AGPL-3.0"],
49+
["gpl-2.0-only"],
50+
["lgpl-2.1-only"],
51+
["agpl-3.0-only"],
52+
["gfdl-1.3"],
53+
["gpl-2.0", "mit"],
54+
["mit", "lgpl-3.0"]
55+
]
56+
57+
non_gpl_licenses = [
58+
["mit"],
59+
["apache-2.0"],
60+
["bsd-3-clause"],
61+
["mozilla-2.0"],
62+
["isc"],
63+
[],
64+
["mit", "apache-2.0"]
65+
]
66+
67+
for licenses in gpl_licenses:
68+
assert is_gpl_family_license(licenses), \
69+
f"Should detect GPL family license: {licenses}"
70+
71+
for licenses in non_gpl_licenses:
72+
assert not is_gpl_family_license(licenses), \
73+
f"Should not detect GPL family license: {licenses}"
74+
75+
76+
def test_should_remove_copyright_for_gpl_license_text():
77+
assert should_remove_copyright_for_gpl_license_text(["gpl-2.0"], True), \
78+
"Should remove copyright for GPL license text file"
79+
assert should_remove_copyright_for_gpl_license_text(["lgpl-3.0"], True), \
80+
"Should remove copyright for LGPL license text file"
81+
assert should_remove_copyright_for_gpl_license_text(["agpl-3.0"], True), \
82+
"Should remove copyright for AGPL license text file"
83+
84+
assert not should_remove_copyright_for_gpl_license_text(["gpl-2.0"], False), \
85+
"Should NOT remove copyright for GPL source file"
86+
assert not should_remove_copyright_for_gpl_license_text(["lgpl-3.0"], False), \
87+
"Should NOT remove copyright for LGPL source file"
88+
89+
assert not should_remove_copyright_for_gpl_license_text(["mit"], True), \
90+
"Should NOT remove copyright for MIT license text file"
91+
assert not should_remove_copyright_for_gpl_license_text(["apache-2.0"], True), \
92+
"Should NOT remove copyright for Apache license text file"
93+
94+
assert not should_remove_copyright_for_gpl_license_text(["mit"], False), \
95+
"Should NOT remove copyright for MIT source file"
96+
97+
assert not should_remove_copyright_for_gpl_license_text([], True), \
98+
"Should NOT remove copyright for empty license list"
99+
assert not should_remove_copyright_for_gpl_license_text([], False), \
100+
"Should NOT remove copyright for empty license list"
101+
102+
29103
def test_run():
30104
scan_success, _ = run_command("fosslight_source -p tests/test_files -j -m -o test_scan")
31105
scan_exclude_success, _ = run_command("fosslight_source -p tests -e test_files/test cli_test.py -j -m -o test_scan2")

0 commit comments

Comments
 (0)