Skip to content

Commit 9af0855

Browse files
Add option for allrights scanning
Clean up organize imports Adapt refinement for allrights scanning Signed-off-by: Kai Hammerschmidt <kai.hammerschmidt@metaeffekt.com>
1 parent a378a21 commit 9af0855

4 files changed

Lines changed: 163 additions & 36 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ facet = "summarycode.facet:AddFacet"
272272
info = "scancode.plugin_info:InfoScanner"
273273
licenses = "licensedcode.plugin_license:LicenseScanner"
274274
copyrights = "cluecode.plugin_copyright:CopyrightScanner"
275+
allrights = "cluecode.plugin_allrights:AllrightsCopyrightScanner"
275276
packages = "packagedcode.plugin_package:PackageScanner"
276277
emails = "cluecode.plugin_email:EmailScanner"
277278
urls = "cluecode.plugin_url:UrlScanner"

src/cluecode/copyrights.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,20 +336,25 @@ def detect(self,
336336
tree_node_label = tree_node.label
337337

338338
if (include_copyrights or include_holders) and 'COPYRIGHT' in tree_node_label:
339-
copyrght = build_detection_from_node(
339+
if include_copyright_allrights:
340+
refiner = refine_allrights
341+
else:
342+
refiner = refine_copyright
343+
344+
copyright = build_detection_from_node(
340345
node=tree_node,
341346
cls=CopyrightDetection,
342347
ignored_labels=non_copyright_labels,
343348
include_copyright_allrights=include_copyright_allrights,
344-
refiner=refine_copyright,
349+
refiner=refiner,
345350
)
346351

347352
if TRACE or TRACE_DEEP:
348-
logger_debug(f'CopyrightDetector: final copyright: {copyrght}')
353+
logger_debug(f'CopyrightDetector: final copyright: {copyright}')
349354

350-
if copyrght:
355+
if copyright:
351356
if include_copyrights:
352-
yield copyrght
357+
yield copyright
353358

354359
if include_holders:
355360
# By default we strip email and urls from holders ....
@@ -3562,6 +3567,31 @@ def refine_copyright(c):
35623567
return c.strip()
35633568

35643569

3570+
def refine_allrights(c):
3571+
"""
3572+
Refine a detected copyright string.
3573+
FIXME: the grammar should not allow this to happen.
3574+
"""
3575+
if not c:
3576+
return
3577+
c = ' '.join(c.split())
3578+
c = strip_some_punct(c)
3579+
c = strip_solo_quotes(c)
3580+
# this catches trailing slashes in URL for consistency
3581+
c = c.strip('/ ~')
3582+
c = strip_all_unbalanced_parens(c)
3583+
c = remove_some_extra_words_and_punct(c)
3584+
c = ' '.join(c.split())
3585+
c = remove_dupe_copyright_words(c)
3586+
c = strip_prefixes(c, prefixes=set(['by', 'c']))
3587+
c = c.strip()
3588+
c = c.strip('+')
3589+
c = strip_balanced_edge_parens(c)
3590+
c = strip_suffixes(c, suffixes=COPYRIGHTS_SUFFIXES)
3591+
c = c.strip("'")
3592+
return c.strip()
3593+
3594+
35653595
def remove_dupe_holder(h):
35663596
"""
35673597
Remove duplicated holders

src/cluecode/plugin_allrights.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#
2+
# This code is heavily inspired by original code from ScanCode Toolkit.
3+
# The copyright header is therefore propagated. The content is primarily
4+
# taken from following packages in the ScanCode Toolkit:
5+
# - cluecode.plugin_copyright
6+
# - scancode.api
7+
#
8+
# Copyright (c) nexB Inc. and others. All rights reserved.
9+
# ScanCode is a trademark of nexB Inc.
10+
# SPDX-License-Identifier: Apache-2.0
11+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
12+
# See https://github.com/nexB/scancode-toolkit for support or download.
13+
# See https://aboutcode.org for more information about nexB OSS projects.
14+
#
15+
16+
import attr
17+
from plugincode.scan import ScanPlugin
18+
from plugincode.scan import scan_impl
19+
20+
from commoncode.cliutils import PluggableCommandLineOption
21+
from commoncode.cliutils import SCAN_GROUP
22+
23+
24+
@scan_impl
25+
class AllrightsCopyrightScanner(ScanPlugin):
26+
"""Scan a Resource for copyrights with all rights reserved. This class is an adapted version of
27+
scancodes cluecode.plugin_copyright.
28+
"""
29+
30+
resource_attributes = dict(
31+
[
32+
("copyrights", attr.ib(default=attr.Factory(list))),
33+
("holders", attr.ib(default=attr.Factory(list))),
34+
("authors", attr.ib(default=attr.Factory(list))),
35+
]
36+
)
37+
38+
run_order = 6
39+
sort_order = 6
40+
41+
options = [
42+
PluggableCommandLineOption(
43+
(
44+
"-a",
45+
"--allrights",
46+
),
47+
is_flag=True,
48+
default=False,
49+
help="Scan <input> for copyrights and all rights reserved.",
50+
help_group=SCAN_GROUP,
51+
sort_order=50,
52+
),
53+
]
54+
55+
def is_enabled(self, allrights, **kwargs): # NOQA
56+
return allrights
57+
58+
def get_scanner(self, **kwargs):
59+
from scancode.api import allrights_scanner
60+
return allrights_scanner
61+

src/scancode/api.py

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
# See https://github.com/nexB/scancode-toolkit for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9-
from itertools import islice
10-
from os.path import getsize
119
import logging
1210
import os
1311
import sys
12+
from itertools import islice
13+
from os.path import getsize
14+
15+
from typecode.contenttype import get_type
1416

1517
from commoncode.filetype import get_last_modified_date
1618
from commoncode.hash import multi_checksums
1719
from scancode import ScancodeError
18-
from typecode.contenttype import get_type
1920

2021
TRACE = os.environ.get('SCANCODE_DEBUG_API', False)
2122

@@ -30,6 +31,7 @@ def logger_debug(*args):
3031
logging.basicConfig(stream=sys.stdout)
3132
logger.setLevel(logging.DEBUG)
3233

34+
3335
def logger_debug(*args):
3436
return logger.debug(
3537
' '.join(isinstance(a, str) and a or repr(a) for a in args)
@@ -46,9 +48,9 @@ def logger_debug(*args):
4648

4749

4850
def get_copyrights(
49-
location,
50-
deadline=sys.maxsize,
51-
**kwargs,
51+
location,
52+
deadline=sys.maxsize,
53+
**kwargs,
5254
):
5355
"""
5456
Return a mapping with a single 'copyrights' key with a value that is a list
@@ -79,12 +81,45 @@ def get_copyrights(
7981
return results
8082

8183

84+
def allrights_scanner(
85+
location,
86+
deadline=sys.maxsize,
87+
**kwargs,
88+
):
89+
"""Return a mapping with a single 'copyrights' key with a value that is a list
90+
of mappings for copyright detected in the file at `location`.
91+
Adapted copy of scancodes scancode.api.get_copyrights.
92+
"""
93+
from cluecode.copyrights import detect_copyrights
94+
from cluecode.copyrights import Detection
95+
96+
detections = detect_copyrights(
97+
location,
98+
include_copyrights=True,
99+
include_holders=True,
100+
include_authors=True,
101+
include_copyright_years=True,
102+
include_copyright_allrights=True,
103+
deadline=deadline,
104+
)
105+
106+
copyrights, holders, authors = Detection.split(detections, to_dict=True)
107+
108+
results = dict([
109+
('copyrights', copyrights),
110+
('holders', holders),
111+
('authors', authors),
112+
])
113+
114+
return results
115+
116+
82117
def get_emails(
83-
location,
84-
threshold=50,
85-
test_slow_mode=False,
86-
test_error_mode=False,
87-
**kwargs,
118+
location,
119+
threshold=50,
120+
test_slow_mode=False,
121+
test_error_mode=False,
122+
**kwargs,
88123
):
89124
"""
90125
Return a mapping with a single 'emails' key with a value that is a list of
@@ -148,14 +183,14 @@ def get_urls(location, threshold=50, **kwargs):
148183

149184

150185
def get_licenses(
151-
location,
152-
min_score=0,
153-
include_text=False,
154-
license_text_diagnostics=False,
155-
license_diagnostics=False,
156-
deadline=sys.maxsize,
157-
unknown_licenses=False,
158-
**kwargs,
186+
location,
187+
min_score=0,
188+
include_text=False,
189+
license_text_diagnostics=False,
190+
license_diagnostics=False,
191+
deadline=sys.maxsize,
192+
unknown_licenses=False,
193+
**kwargs,
159194
):
160195
"""
161196
Return a mapping or license_detections for licenses detected in the file at
@@ -257,12 +292,12 @@ def get_licenses(
257292

258293

259294
def _get_package_data(
260-
location,
261-
application=True,
262-
system=False,
263-
compiled=False,
264-
package_only=False,
265-
**kwargs
295+
location,
296+
application=True,
297+
system=False,
298+
compiled=False,
299+
package_only=False,
300+
**kwargs
266301
):
267302
"""
268303
Return a mapping of package manifest information detected in the file at ``location``.
@@ -309,12 +344,12 @@ def get_package_info(location, **kwargs):
309344

310345

311346
def get_package_data(
312-
location,
313-
application=True,
314-
system=False,
315-
compiled=False,
316-
package_only=False,
317-
**kwargs
347+
location,
348+
application=True,
349+
system=False,
350+
compiled=False,
351+
package_only=False,
352+
**kwargs
318353
):
319354
"""
320355
Return a mapping of package manifest information detected in the file at

0 commit comments

Comments
 (0)