forked from aboutcode-org/scancode-toolkit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrecognize.py
More file actions
123 lines (96 loc) · 3.49 KB
/
recognize.py
File metadata and controls
123 lines (96 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#
# Copyright (c) nexB Inc. and others. All rights reserved.
# ScanCode is a trademark of nexB Inc.
# SPDX-License-Identifier: Apache-2.0
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
# See https://github.com/nexB/scancode-toolkit for support or download.
# See https://aboutcode.org for more information about nexB OSS projects.
#
import os
import sys
from commoncode import filetype
from packagedcode import APPLICATION_PACKAGE_DATAFILE_HANDLERS
from packagedcode import SYSTEM_PACKAGE_DATAFILE_HANDLERS
from packagedcode import ALL_DATAFILE_HANDLERS
from packagedcode import models
TRACE = os.environ.get('SCANCODE_DEBUG_PACKAGE_API', False)
def logger_debug(*args):
pass
if TRACE:
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout)
logger.setLevel(logging.DEBUG)
def logger_debug(*args):
return logger.debug(' '.join(isinstance(a, str) and a or repr(a) for a in args))
logger_debug = print
"""
Recognize and parse package datafiles, manifests, or lockfiles.
"""
def recognize_package_data(
location,
application=True,
system=False,
package_only=False,
):
"""
Return a list of Package objects if any package_data were recognized for
this `location`, or None if there were no Packages found. Raises Exceptions
on errors.
Include ``application`` packages (such as pypi) and/or ``system`` packages.
Default to use application packages
"""
if not filetype.is_file(location):
return []
assert application or system or package_only
if package_only or (application and system):
datafile_handlers = ALL_DATAFILE_HANDLERS
elif application:
datafile_handlers = APPLICATION_PACKAGE_DATAFILE_HANDLERS
elif system:
datafile_handlers = SYSTEM_PACKAGE_DATAFILE_HANDLERS
return list(_parse(
location=location,
package_only=package_only,
datafile_handlers=datafile_handlers,
))
def _parse(
location,
package_only=False,
datafile_handlers=APPLICATION_PACKAGE_DATAFILE_HANDLERS,
):
"""
Yield parsed PackageData objects from ``location``. Raises Exceptions on errors.
Use the provided ``datafile_handlers`` list of DatafileHandler classes.
Default to use application packages
"""
for handler in datafile_handlers:
if TRACE:
logger_debug(f'_parse:.is_datafile: {handler}')
if not handler.is_datafile(location):
continue
if TRACE:
logger_debug(f'_parse:.is_datafile: {location}')
try:
for parsed in handler.parse(location=location, package_only=package_only):
if TRACE:
logger_debug(f' _parse: parsed: {parsed!r}')
yield parsed
except NotImplementedError:
# build a plain package if parse is not yet implemented
pkg = models.PackageData(
datasource_id=handler.datasource_id,
type=handler.default_package_type,
primary_language=handler.default_primary_language,
)
if TRACE:
logger_debug('_parse: NotImplementedError: handler', handler)
yield pkg
if TRACE:
raise
except Exception as e:
# We should continue when an Exception has occured when trying to
# recognize a package
if TRACE:
logger_debug(f'_parse: Exception: {str(e)}')
continue