Skip to content

Commit 6eb5a25

Browse files
authored
Merge pull request #2469 from nexB/release-21.3.3x-prep
Release 21.3.30 Signed-off-by: Philippe Ombredanne <[email protected]>
2 parents ef99832 + 23811cd commit 6eb5a25

File tree

4,816 files changed

+64232
-4549
lines changed

Some content is hidden

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

4,816 files changed

+64232
-4549
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,6 @@ tcl
8585

8686
*.orig
8787
/release*
88+
/00-*.txt
89+
/z-todo-licenses-*
90+

CHANGELOG.rst

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,109 @@
11
Changelog
22
=========
33

4+
v21.4.x (next)
5+
--------------
46

5-
v21.3.x (next)
6-
------------
7+
Breaking API changes:
78

9+
- The data structure of the JSON output has changed for copyrights, authors
10+
and holders: we now use proper name for attributes and not a generic "value".
811

9-
Misc.:
12+
- The data structure of the JSON output has changed for licenses: we now
13+
return match details once for each matched license expression rather than
14+
once for each license in a matched expression. There is a new top-level
15+
"licenses" attributes that contains the data details for each detected
16+
licenses only once. This data can contain the reference license text
17+
as an option.
18+
19+
- The data structure of the JSON output has changed for packages: we now
20+
return "package_manifests" package information at the manifest file-level
21+
rather than "packages". There is a a new top-level "packages" attribute
22+
that contains each package instace that can be aggregating data from
23+
multiple manifests for a single package instance.
24+
25+
26+
Ouputs:
27+
28+
- Add new YAML-formatted output. This is exactly the same data structure as for
29+
the JSON output
30+
31+
32+
License scanning:
33+
34+
- Add new command line option to filter ignorable copyrights when included
35+
in licenses.
36+
37+
38+
39+
v21.3.30
40+
--------
41+
42+
This is a mjor version with no breaking API changes. Heads-up: the next version
43+
will bring up some significant API changes.
44+
45+
46+
Security:
47+
48+
- Update dependency versions for security.
49+
50+
51+
License scanning:
52+
53+
- Add 22 new and update 71 existing reference licenses
54+
55+
- Update licenses to include the SPDX license list 3.12
56+
57+
- Improve license detection accuracy with over 2300 new and improved license
58+
detection rules
59+
60+
- Undeprecate the regexp license and deprecate the hs-regexp-orig license
61+
62+
- Improve license db initial load time with caching for faster scancode
63+
start time
64+
65+
- Ensure that license short names are no more than 50 characters long
66+
67+
- Thank you to Chin-Yeung Li @chinyeungli, Armijn Hemmel @jelmer
68+
69+
70+
Copyright scanning:
71+
72+
- Detect SPDX-FileCopyrightText as defined by the FSFE Reuse project
1073

1174
- Fix bug when using the --filter-clues command line option
1275
Thank you to Van Lindberg @VanL
1376

77+
- Allow calling copyright detection from text lines to ease integration
78+
Thank you to Jelmer Vernooij @jelmer
79+
80+
81+
Package scanning:
82+
83+
- Add support for installed RPMs detection internally (not wired to scans)
84+
Thank you to Chin-Yeung Li @chinyeungli
85+
86+
- Improve handling of Debian copyright files with faster and more
87+
accurate license detection
88+
Thank you to Thomas Druez @tdruez
89+
90+
- Add new built-in support for installed_files report. Only available when
91+
used as a library.
92+
93+
- Improve support for RPM, npm, Debian, build scripts (Bazel) and Go packages
94+
95+
- Add new support to collect information from semi-structured Readme files
96+
97+
98+
Ouputs:
99+
100+
- Add new Debian copyright-formatted output.
101+
Thank you to Jelmer Vernooij @jelmer
102+
103+
- Fix bug in --ignore where directories where not skipped correctly
104+
Thank you to Pierre Tardy @tardyp
105+
106+
14107

15108
v21.2.25
16109
--------

NOTICE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ including:
3434
- https://github.com/nexB/thirdparty-packages/pypi/
3535
- https://github.com/nexB/scancode-plugins/
3636
- https://github.com/nexB/scancode-thirdparty-src/
37+
- https://github.com/nexB/thirdparty-packages/
3738

3839
You may also contact us to request the source code by email at [email protected] or
3940
by postal mail at:

configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export THIRDPARTY_LINKS="https://thirdparty.aboutcode.org/pypi"
5252
# requirements used by default or with --dev.
5353
# note the use of constraints with -c
5454
REQUIREMENTS="--editable . --constraint requirements.txt"
55-
DEV_REQUIREMENTS="--editable .[dev] --constraint requirements.txt --constraint requirements-dev.txt"
55+
DEV_REQUIREMENTS="--editable .[dev] --editable .[packages] --constraint requirements.txt --constraint requirements-dev.txt"
5656

5757
# default supported Python version
5858
if [[ "$CONFIGURE_SUPPORTED_PYTHON" == "" ]]; then

etc/release/utils_thirdparty.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,7 +1745,13 @@ def get_remote_repo(remote_links_url=REMOTE_LINKS_URL):
17451745

17461746

17471747
def get_remote_package(name, version, remote_links_url=REMOTE_LINKS_URL):
1748-
return get_remote_repo(remote_links_url).get_package(name, version)
1748+
"""
1749+
Return a PypiPackage or None.
1750+
"""
1751+
try:
1752+
return get_remote_repo(remote_links_url).get_package(name, version)
1753+
except RemoteNotFetchedException as e:
1754+
print(f'Failed to fetch remote package info: {e}')
17491755

17501756

17511757
_PYPI_REPO = None
@@ -1759,7 +1765,13 @@ def get_pypi_repo(pypi_simple_url=PYPI_SIMPLE_URL):
17591765

17601766

17611767
def get_pypi_package(name, version, pypi_simple_url=PYPI_SIMPLE_URL):
1762-
return get_pypi_repo(pypi_simple_url).get_package(name, version)
1768+
"""
1769+
Return a PypiPackage or None.
1770+
"""
1771+
try:
1772+
return get_pypi_repo(pypi_simple_url).get_package(name, version)
1773+
except RemoteNotFetchedException as e:
1774+
print(f'Failed to fetch remote package info: {e}')
17631775

17641776
################################################################################
17651777
#
@@ -2003,20 +2015,25 @@ def fetch_missing_sources(dest_dir=THIRDPARTY_DIR):
20032015
for package in local_packages:
20042016
if not package.sdist:
20052017
print(f'Finding sources for: {package.name}=={package.version}: ', end='')
2006-
pypi_package = pypi_repo.get_package(
2007-
name=package.name, version=package.version)
2008-
2009-
if pypi_package and pypi_package.sdist:
2010-
print(f'Fetching sources from Pypi')
2011-
pypi_package.fetch_sdist(dest_dir=dest_dir)
2012-
else:
2013-
remote_package = remote_repo.get_package(
2018+
try:
2019+
pypi_package = pypi_repo.get_package(
20142020
name=package.name, version=package.version)
20152021

2016-
if remote_package and remote_package.sdist:
2017-
print(f'Fetching sources from Remote')
2018-
remote_package.fetch_sdist(dest_dir=dest_dir)
2022+
if pypi_package and pypi_package.sdist:
2023+
print(f'Fetching sources from Pypi')
2024+
pypi_package.fetch_sdist(dest_dir=dest_dir)
20192025
continue
2026+
else:
2027+
remote_package = remote_repo.get_package(
2028+
name=package.name, version=package.version)
2029+
2030+
if remote_package and remote_package.sdist:
2031+
print(f'Fetching sources from Remote')
2032+
remote_package.fetch_sdist(dest_dir=dest_dir)
2033+
continue
2034+
2035+
except RemoteNotFetchedException as e:
2036+
print(f'Failed to fetch remote package info: {e}')
20202037

20212038
print(f'No sources found')
20222039
not_found.append((package.name, package.version,))
@@ -2542,7 +2559,6 @@ def add_or_upgrade_built_wheels(
25422559
name=name, version=version, environment=environment, dest_dir=dest_dir)
25432560
if wheel_filename:
25442561
wheel_filenames.append(wheel_filename)
2545-
continue
25462562

25472563
# the wheel is not available locally, remotely or in Pypi
25482564
# we need to build binary from sources

etc/scripts/licenses/buildrules.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def rule_exists(text):
139139
if len(matches) > 1:
140140
return False
141141
match = matches[0]
142-
if match.matcher == match_hash.MATCH_HASH:
142+
if match.matcher == match_hash.MATCH_HASH and match.score() == 100:
143143
return match.rule.identifier
144144

145145

etc/scripts/licenses/synclic.py

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,11 @@
3737
Run python synclic.py -h for help.
3838
"""
3939

40-
4140
TRACE = True
4241
TRACE_ADD = True
4342
TRACE_FETCH = True
4443
TRACE_DEEP = False
4544

46-
4745
# may be useful to change for testing
4846
SPDX_DEFAULT_REPO = 'spdx/license-list-data'
4947

@@ -164,15 +162,15 @@ def __init__(self, external_base_dir):
164162
if not exists(self.new_dir):
165163
mkdir(self.new_dir)
166164

167-
def get_licenses(self, scancode_licenses):
165+
def get_licenses(self, scancode_licenses, **kwargs):
168166
"""
169167
Return a mapping of key -> ScanCode License objects either fetched
170168
externally or loaded from the existing `self.original_dir`
171169
"""
172170
print('Fetching and storing external licenses in:', self.original_dir)
173171

174172
licenses = []
175-
for lic, text in self.fetch_licenses(scancode_licenses):
173+
for lic, text in self.fetch_licenses(scancode_licenses, **kwargs):
176174
try:
177175
with io.open(lic.text_file, 'w', encoding='utf-8')as tf:
178176
tf.write(text)
@@ -193,7 +191,7 @@ def get_licenses(self, scancode_licenses):
193191

194192
return load_licenses(self.update_dir, with_deprecated=True)
195193

196-
def fetch_licenses(self, scancode_licenses):
194+
def fetch_licenses(self, scancode_licenses, **kwargs):
197195
"""
198196
Yield tuples of (License object, license text) fetched from this external source.
199197
"""
@@ -338,14 +336,18 @@ class SpdxSource(ExternalLicensesSource):
338336
'notes',
339337
)
340338

341-
def fetch_licenses(self, scancode_licenses, from_repo=SPDX_DEFAULT_REPO):
339+
def fetch_licenses(self, scancode_licenses, commitish=None, from_repo=SPDX_DEFAULT_REPO):
342340
"""
343341
Yield License objects fetched from the latest SPDX license list.
342+
Use the latest tagged version or the `commitish` is provided.
344343
"""
345-
# get latest tag
346-
tags_url = 'https://api.github.com/repos/{from_repo}/tags'.format(**locals())
347-
tags = get_response(tags_url, headers={}, params={})
348-
tag = tags[0]['name']
344+
if not commitish:
345+
# get latest tag
346+
tags_url = 'https://api.github.com/repos/{from_repo}/tags'.format(**locals())
347+
tags = get_response(tags_url, headers={}, params={})
348+
tag = tags[0]['name']
349+
else:
350+
tag = commitish
349351

350352
# fetch licenses and exceptions
351353
# note that exceptions data have -- weirdly enough -- a different schema
@@ -385,11 +387,15 @@ def build_license(self, mapping, scancode_licenses):
385387

386388
# these keys have a complicated history
387389
if key in set([
388-
'gpl-1.0', 'gpl-2.0', 'gpl-3.0',
389-
'lgpl-2.0', 'lgpl-2.1', 'lgpl-3.0',
390-
'agpl-1.0', 'agpl-2.0', 'agpl-3.0',
391-
'gfdl-1.1', 'gfdl-1.2', 'gfdl-1.3',
392-
'nokia-qt-exception-1.1', 'bzip2-1.0.5']):
390+
'gpl-1.0', 'gpl-2.0', 'gpl-3.0',
391+
'lgpl-2.0', 'lgpl-2.1', 'lgpl-3.0',
392+
'agpl-1.0', 'agpl-2.0', 'agpl-3.0',
393+
'gfdl-1.1', 'gfdl-1.2', 'gfdl-1.3',
394+
'nokia-qt-exception-1.1',
395+
'bzip2-1.0.5',
396+
'bsd-2-clause-freebsd',
397+
'bsd-2-clause-netbsd',
398+
]):
393399
return
394400

395401
deprecated = mapping.get('isDeprecatedLicenseId', False)
@@ -484,7 +490,7 @@ def __init__(self, external_base_dir, api_base_url=None, api_key=None):
484490

485491
super(DejaSource, self).__init__(external_base_dir)
486492

487-
def fetch_licenses(self, scancode_licenses):
493+
def fetch_licenses(self, scancode_licenses, **kwargs):
488494
api_url = '/'.join([self.api_base_url.rstrip('/'), 'licenses/'])
489495
for licenses in call_deja_api(api_url, self.api_key, paginate=100):
490496
for lic in licenses:
@@ -815,7 +821,9 @@ def update_external(_attrib, _sc_val, _ext_val):
815821
scancode_key = scancode_license.spdx_license_key
816822
external_key = external_license.spdx_license_key
817823
if scancode_key != external_key:
818-
raise Exception('Non mergeable licenses with different SPDX keys: %(scancode_key)s <> %(external_key)s' % locals())
824+
raise Exception(
825+
f'Non mergeable licenses with different SPDX keys: scancode_license.spdx_license_key {scancode_key} <> external_license.spdx_license_key {external_key}'
826+
)
819827
else:
820828
scancode_key = scancode_license.key
821829
external_key = external_license.key
@@ -914,7 +922,7 @@ def update_external(_attrib, _sc_val, _ext_val):
914922

915923

916924
def synchronize_licenses(scancode_licenses, external_source, use_spdx_key=False,
917-
match_text=False, match_approx=False):
925+
match_text=False, match_approx=False, commitish=None):
918926
"""
919927
Update the `scancode_licenses` ScanCodeLicenses licenses and texts in-place
920928
(e.g. in their current storage directory) from an `external_source`
@@ -949,7 +957,7 @@ def synchronize_licenses(scancode_licenses, external_source, use_spdx_key=False,
949957

950958
# mappings of key -> License
951959
scancodes_by_key = scancode_licenses.by_key
952-
externals_by_key = external_source.get_licenses(scancode_licenses)
960+
externals_by_key = external_source.get_licenses(scancode_licenses, commitish=commitish)
953961

954962
if use_spdx_key:
955963
scancodes_by_key = scancode_licenses.by_spdx_key
@@ -1123,8 +1131,9 @@ def synchronize_licenses(scancode_licenses, external_source, use_spdx_key=False,
11231131
@click.option('-a', '--match-approx', is_flag=True, default=False, help='Include approximate license detection matches when matching ScanCode license.')
11241132
@click.option('-t', '--trace', is_flag=True, default=False, help='Print execution trace.')
11251133
@click.option('--create-ext', is_flag=True, default=False, help='Create new external licenses in the external source if possible.')
1134+
@click.option('--commitish', type=str, default=None, help='An optional commitish to use for SPDX license data instead of the latest release.')
11261135
@click.help_option('-h', '--help')
1127-
def cli(license_dir, source, match_text, match_approx, trace, create_ext):
1136+
def cli(license_dir, source, match_text, match_approx, trace, create_ext, commitish=None):
11281137
"""
11291138
Synchronize ScanCode licenses with an external license source.
11301139
@@ -1143,10 +1152,13 @@ def cli(license_dir, source, match_text, match_approx, trace, create_ext):
11431152
scancode_licenses = ScanCodeLicenses()
11441153

11451154
use_spdx_key = source == 'spdx'
1146-
added_to_external = synchronize_licenses(scancode_licenses, external_source,
1147-
use_spdx_key=use_spdx_key,
1148-
match_text=match_text,
1149-
match_approx=match_approx)
1155+
added_to_external = synchronize_licenses(
1156+
scancode_licenses, external_source,
1157+
use_spdx_key=use_spdx_key,
1158+
match_text=match_text,
1159+
match_approx=match_approx,
1160+
commitish=commitish,
1161+
)
11501162
print()
11511163
if create_ext and isinstance(external_source, DejaSource):
11521164
api_url = external_source.api_base_url

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
aboutcode-toolkit==5.1.0
1+
aboutcode-toolkit==6.0.0
22
apipkg==1.5
33
codecov==2.1.11
44
coverage==5.3.1

0 commit comments

Comments
 (0)