Skip to content

Commit 37d574b

Browse files
authored
Merge pull request #2765 from nexB/omnibus-fall3-license-improvements
Add new licenses and new detection rules
2 parents 9ed2cb4 + fd628e6 commit 37d574b

22,826 files changed

Lines changed: 42066 additions & 55632 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.rst

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55
-----------------------
66

77

8+
89
Important API changes:
910
~~~~~~~~~~~~~~~~~~~~~~~~
1011

@@ -36,7 +37,9 @@ Copyright detection:
3637

3738
- The data structure in the JSON is now using consistently named attributes as
3839
opposed to a plain value.
39-
- Several copyright detection bugs have been fixed.
40+
- Several copyright detection bugs have been fixed.
41+
- French and German copyright detection is improved.
42+
- Some spurious trailing dots in holders are not stripped.
4043

4144

4245
License detection:
@@ -53,6 +56,27 @@ License detection:
5356
`{{` and `}}`. When defined a RULE will only match when the key phrases match
5457
exactly.
5558

59+
- The rule attribute "only_known_words" has been renamed to "is_continuous" and its
60+
meaning has been updated and expanded. A rule tagged as "is_continuous" can only
61+
be matched if there are no gaps between matched words, be they stopwords, extra
62+
unknown or known words. This improves several false positive license detections.
63+
64+
- When scanning binary files, the detection of single word rules is filtered when
65+
surrounded by gibberish or is using mixed case. For instance $#%$GpL$ is a false
66+
positive and is no longer reported.
67+
68+
- Several rules we tagged as is_license_notice incorrectly but were references
69+
and have been requalified as is_license_reference. All rules made of a single
70+
ord have been requalified as is_license_reference if they were not qualified
71+
this way.
72+
73+
- Matches to small license rules (with small defined as under 15 words)
74+
that are scattered on too many lines are now filtered as false matches.
75+
76+
- Small, two-words matches that overlap the previous or next match by
77+
by the word "license" and assimilated are now filtered as false matches.
78+
79+
5680
Package detection:
5781
~~~~~~~~~~~~~~~~~~
5882

conftest.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,6 @@ def pytest_addoption(parser):
5757
"""
5858
group = parser.getgroup('scancode', 'Test suite options for ScanCode')
5959

60-
group.addoption(
61-
'--force-py3',
62-
dest='force_py3',
63-
action='store_true',
64-
default=False,
65-
help='[DEPRECATED and ignored] Python 3 port is completed.',
66-
)
67-
6860
group.addoption(
6961
'--test-suite',
7062
action='store',

etc/scripts/licenses/buildrules.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def cli(licenses_file):
227227
rulerec = models.Rule(**rd)
228228

229229
# force recomputing relevance to remove junk stored relevance for long rules
230-
rulerec.compute_relevance(_threshold=18.0)
230+
rulerec.set_relevance()
231231

232232
rulerec.data_file = base_loc + '.yml'
233233
rulerec.text_file = base_loc + '.RULE'
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (c) nexB Inc. and others. All rights reserved.
4+
# ScanCode is a trademark of nexB Inc.
5+
# SPDX-License-Identifier: Apache-2.0
6+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
7+
# See https://github.com/nexB/scancode-toolkit for support or download.
8+
# See https://aboutcode.org for more information about nexB OSS projects.
9+
#
10+
11+
import click
12+
13+
from licensedcode.cache import get_licenses_by_spdx_key
14+
15+
import synclic
16+
17+
"""
18+
A script to generate license detection rules from lists of SPDX
19+
licenses for their name or id/name combos.
20+
21+
It is common to see SPDX license names and ids used for licensing documentation.
22+
23+
Here we fetch the latest SPDX licenses list and generate rules for each
24+
license id/name, name and a few other related combinations.
25+
"""
26+
27+
TRACE = False
28+
29+
template = '''----------------------------------------
30+
license_expression: {key}
31+
relevance: 100
32+
{is_license}: yes
33+
minimum_coverage: 100
34+
is_continuous: yes
35+
notes: Rule based on an SPDX license identifier and name
36+
---
37+
{text}
38+
'''
39+
40+
41+
@click.command()
42+
@click.argument(
43+
# 'A buildrules-formatted file used to generate new licenses rules.')
44+
'output', type=click.Path(), metavar='FILE')
45+
46+
@click.help_option('-h', '--help')
47+
def cli(output):
48+
"""
49+
Generate ScanCode license detection rules from a list of SPDX
50+
license. Save these in FILE for use with buildrules.
51+
52+
The `spdx` directory is used as a temp store for fetched SPDX licenses.
53+
"""
54+
55+
licenses_by_spdx_key = get_licenses_by_spdx_key(
56+
licenses=None,
57+
include_deprecated=False,
58+
lowercase_keys=False,
59+
include_other_spdx_license_keys=True,
60+
)
61+
62+
spdx_source = synclic.SpdxSource(external_base_dir=None)
63+
spdx_data = list(spdx_source.fetch_spdx_licenses())
64+
65+
messages = []
66+
with open(output, 'w') as o:
67+
for spdx in spdx_data:
68+
is_exception = 'licenseExceptionId' in spdx
69+
spdx_key = spdx.get('licenseId') or spdx.get('licenseExceptionId')
70+
name = spdx['name']
71+
lic = licenses_by_spdx_key.get(spdx_key)
72+
if not lic:
73+
print('--> Skipping SPDX license unknown in ScanCode:', spdx_key,)
74+
continue
75+
for rule in build_rules(lic.key, spdx_key, name, is_exception):
76+
o.write(rule)
77+
78+
o.write('----------------------------------------\n')
79+
80+
for msg in messages:
81+
print(*msg)
82+
83+
84+
def build_rules(key, spdx_key, name, is_exception=False):
85+
yield template.format(
86+
key=key,
87+
is_license='is_license_reference',
88+
text=name,
89+
)
90+
91+
yield template.format(
92+
key=key,
93+
is_license='is_license_reference',
94+
text=f'name: {name}',
95+
)
96+
97+
yield template.format(
98+
key=key,
99+
is_license='is_license_reference',
100+
text=f'{spdx_key} {name}',
101+
)
102+
103+
yield template.format(
104+
key=key,
105+
is_license='is_license_reference',
106+
text=f'{name} {spdx_key}',
107+
)
108+
109+
yield template.format(
110+
key=key,
111+
is_license='is_license_tag',
112+
text=f'{spdx_key} {name}',
113+
)
114+
115+
yield template.format(
116+
key=key,
117+
is_license='is_license_tag',
118+
text=f'license: {spdx_key}',
119+
)
120+
121+
yield template.format(
122+
key=key,
123+
is_license='is_license_tag',
124+
text=f'license: {name}',
125+
)
126+
127+
if is_exception:
128+
yield template.format(
129+
key=key,
130+
is_license='is_license_tag',
131+
text=f'licenseExceptionId: {spdx_key}',
132+
)
133+
else:
134+
yield template.format(
135+
key=key,
136+
is_license='is_license_tag',
137+
text=f'licenseId: {spdx_key}',
138+
)
139+
140+
141+
if __name__ == '__main__':
142+
cli()

etc/scripts/licenses/gen_spdx_lists_fp.py

Lines changed: 0 additions & 172 deletions
This file was deleted.

etc/scripts/licenses/genrulevariants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def cli(source, replacement):
6464
rulerec = models.Rule(**rd)
6565

6666
# force recomputing relevance to remove junk stored relevance for long rules
67-
rulerec.compute_relevance(_threshold=18.0)
67+
rulerec.set_relevance()
6868

6969
rulerec.data_file = base_loc + '.yml'
7070
rulerec.text_file = base_loc + '.RULE'

0 commit comments

Comments
 (0)