Skip to content

Commit 54207c1

Browse files
committed
Always yield package resource #2929 #2943
* Update test expectations Signed-off-by: Jono Yang <[email protected]>
1 parent 54f0ff3 commit 54207c1

File tree

161 files changed

+845
-702
lines changed

Some content is hidden

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

161 files changed

+845
-702
lines changed

src/packagedcode/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
pypi.PipfileLockHandler,
170170
pypi.PipRequirementsFileHandler,
171171
pypi.PypiEggHandler,
172-
pypi.PypiSdistArchiveHandler,
172+
# pypi.PypiSdistArchiveHandler,
173173
pypi.PypiWheelHandler,
174174
pypi.PyprojectTomlHandler,
175175
pypi.PythonEditableInstallationPkgInfoFile,

src/packagedcode/npm.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,32 @@ def assemble(cls, package_data, resource, codebase):
5656
If there is no package.json, we do not have a package instance. In this
5757
case, we yield each of the dependencies in each lock file.
5858
"""
59-
datafile_name_patterns = (
59+
lockfile_names = {
6060
'package-lock.json',
6161
'.package-lock.json',
6262
'npm-shrinkwrap.json',
6363
'yarn.lock',
64-
)
64+
}
6565

6666
package_resource = None
6767
if resource.name == 'package.json':
6868
package_resource = resource
69-
elif resource.name in datafile_name_patterns:
69+
elif resource.name in lockfile_names:
7070
if resource.has_parent():
7171
siblings = resource.siblings(codebase)
7272
package_resource = [r for r in siblings if r.name == 'package.json']
7373
if package_resource:
7474
package_resource = package_resource[0]
7575

7676
if package_resource:
77+
assert len(package_resource.package_data) == 1, f'Invalid package.json for {package_resource.path}'
78+
pkg_data = package_resource.package_data[0]
79+
pkg_data = models.PackageData.from_dict(pkg_data)
80+
7781
# do we have enough to create a package?
78-
if package_data.purl:
82+
if pkg_data.purl:
7983
package = models.Package.from_package_data(
80-
package_data=package_data,
84+
package_data=pkg_data,
8185
datafile_path=package_resource.path,
8286
)
8387
package_uid = package.package_uid
@@ -96,27 +100,28 @@ def assemble(cls, package_data, resource, codebase):
96100
if package_uid not in package_resource.for_packages:
97101
package_resource.for_packages.append(package_uid)
98102
package_resource.save(codebase)
99-
yield package_resource
100103

104+
# Always yield the package resource in all cases
105+
yield package_resource
101106
yield package
102107
else:
103108
# we have no package, so deps are not for a specific package uid
104109
package_uid = None
105110

106111
# in all cases yield possible dependencies
107-
yield from yield_dependencies_from_package_data(package_data, package_resource.path, package_uid)
112+
yield from yield_dependencies_from_package_data(pkg_data, package_resource.path, package_uid)
108113

109114
# we yield this as we do not want this further processed
110115
yield package_resource
111116

112-
for sibling in package_resource.siblings(codebase):
113-
if sibling.name in datafile_name_patterns:
114-
yield from yield_dependencies_from_package_resource(sibling, package_uid)
117+
for lock_file in package_resource.siblings(codebase):
118+
if lock_file.name in lockfile_names:
119+
yield from yield_dependencies_from_package_resource(lock_file, package_uid)
115120

116-
if package_uid not in sibling.for_packages:
117-
sibling.for_packages.append(package_uid)
118-
sibling.save(codebase)
119-
yield sibling
121+
if package_uid not in lock_file.for_packages:
122+
lock_file.for_packages.append(package_uid)
123+
lock_file.save(codebase)
124+
yield lock_file
120125
else:
121126
# we do not have a package.json
122127
yield from yield_dependencies_from_package_resource(resource)

src/packagedcode/pypi.py

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#
1010

1111
import ast
12+
from distutils.core import setup
1213
import io
1314
import json
1415
import logging
@@ -132,66 +133,109 @@ class BaseExtractedPythonLayout(BasePypiHandler):
132133
def assemble(cls, package_data, resource, codebase):
133134
# a source distribution can have many manifests
134135
datafile_name_patterns = (
135-
'PKG-INFO',
136-
'setup.py',
137-
'setup.cfg',
138136
'Pipfile.lock',
139137
'Pipfile',
140138
) + PipRequirementsFileHandler.path_patterns
141139

140+
# TODO: we want PKG-INFO first, then (setup.py, setup.cfg), then pyproject.toml for poetry
141+
# then we have the rest of the lock files (pipfile, pipfile.lock, etc.)
142+
142143
package_resource = None
143-
if resource.name in datafile_name_patterns:
144+
if resource.name == 'PKG-INFO':
144145
package_resource = resource
145-
146+
elif resource.name in datafile_name_patterns:
147+
if resource.has_parent():
148+
siblings = resource.siblings(codebase)
149+
package_resource = [r for r in siblings if r.name == 'PKG-INFO']
150+
if package_resource:
151+
package_resource = package_resource[0]
152+
153+
package = None
146154
if package_resource:
147-
# do we have enough to create a package?
148-
if package_data.purl:
155+
pkg_data = package_resource.package_data[0]
156+
pkg_data = models.PackageData.from_dict(pkg_data)
157+
if pkg_data.purl:
149158
package = models.Package.from_package_data(
150-
package_data=package_data,
159+
package_data=pkg_data,
151160
datafile_path=package_resource.path,
152161
)
153-
package_uid = package.package_uid
154-
155-
if not package.license_expression:
156-
package.license_expression = compute_normalized_license(package.declared_license)
157-
158-
root = package_resource.parent(codebase)
159-
if root:
160-
for py_res in root.walk(codebase):
161-
if py_res.is_dir:
162-
continue
163-
if package_uid not in py_res.for_packages:
164-
py_res.for_packages.append(package_uid)
165-
py_res.save(codebase)
166-
yield py_res
167-
elif codebase.has_single_resource:
168-
if package_uid not in package_resource.for_packages:
169-
package_resource.for_packages.append(package_uid)
170-
package_resource.save(codebase)
171-
yield package_resource
172-
yield package
173-
else:
174-
# we have no package, so deps are not for a specific package uid
175-
package_uid = None
162+
package_resource.for_packages.append(package.package_uid)
163+
package_resource.save(codebase)
164+
yield package_resource
176165

177-
# in all cases yield possible dependencies
178-
yield from yield_dependencies_from_package_data(package_data, package_resource.path, package_uid)
179-
yield package_resource
166+
yield from yield_dependencies_from_package_data(
167+
package_data=pkg_data,
168+
datafile_path=package_resource.path,
169+
package_uid=package.package_uid
170+
)
171+
else:
172+
setup_resources = []
173+
if resource.has_parent():
174+
siblings = resource.siblings(codebase)
175+
setup_resources = [r for r in siblings if r.name in ('setup.py', 'setup.cfg')]
176+
setup_package_data = [
177+
(setup_resource, models.PackageData.from_dict(setup_resource.package_data[0]))
178+
for setup_resource in setup_resources
179+
]
180+
setup_package_data = sorted(setup_package_data, key=lambda s: bool(s[1].purl), reverse=True)
181+
for setup_resource, setup_pkg_data in setup_package_data:
182+
if setup_pkg_data.purl:
183+
if not package:
184+
package = models.Package.from_package_data(
185+
package_data=setup_pkg_data,
186+
datafile_path=setup_resource.path,
187+
)
188+
package_resource = setup_resource
189+
else:
190+
package.update(setup_pkg_data, setup_resource.path)
191+
if package:
192+
for setup_resource, setup_pkg_data in setup_package_data:
193+
setup_resource.for_packages.append(package.package_uid)
194+
setup_resource.save(codebase)
195+
yield setup_resource
196+
197+
yield from yield_dependencies_from_package_data(
198+
package_data=setup_pkg_data,
199+
datafile_path=setup_resource.path,
200+
package_uid=package.package_uid
201+
)
202+
203+
if package:
204+
if not package.license_expression:
205+
package.license_expression = compute_normalized_license(package.declared_license)
206+
package_uid = package.package_uid
207+
208+
root = package_resource.parent(codebase)
209+
if root:
210+
# TODO: skip site-package directory
211+
for py_res in root.walk(codebase):
212+
if py_res.is_dir:
213+
continue
214+
if package_uid not in py_res.for_packages:
215+
py_res.for_packages.append(package_uid)
216+
py_res.save(codebase)
217+
yield py_res
218+
elif codebase.has_single_resource:
219+
if package_uid not in package_resource.for_packages:
220+
package_resource.for_packages.append(package_uid)
221+
package_resource.save(codebase)
180222

181-
for sibling in package_resource.siblings(codebase):
182-
if sibling.name in datafile_name_patterns:
183-
yield from yield_dependencies_from_package_resource(sibling, package_uid)
223+
yield package
184224

185-
if package_uid not in sibling.for_packages:
186-
sibling.for_packages.append(package_uid)
187-
sibling.save(codebase)
188-
yield sibling
189225
else:
190-
yield from yield_dependencies_from_package_resource(resource)
226+
package_uid = None
191227

192-
@classmethod
193-
def assign_package_to_resources(cls, package, resource, codebase):
194-
return models.DatafileHandler.assign_package_to_parent_tree(package, resource, codebase)
228+
for sibling in package_resource.siblings(codebase):
229+
if sibling.name in datafile_name_patterns:
230+
yield from yield_dependencies_from_package_resource(
231+
resource=sibling,
232+
package_uid=package_uid
233+
)
234+
235+
if package_uid and package_uid not in sibling.for_packages:
236+
sibling.for_packages.append(package_uid)
237+
sibling.save(codebase)
238+
yield sibling
195239

196240

197241
class PythonSdistPkgInfoFile(BaseExtractedPythonLayout):
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
what:
22
- copyrights
33
- holders
4-
54
copyrights:
65
- Copyright (c) AliasDotCom Ltd.
7-
86
holders:
97
- AliasDotCom Ltd.

tests/cluecode/data/copyrights/copr.txt.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@ what:
33
- holders
44
- copyrights_summary
55
- holders_summary
6-
76
copyrights:
87
- copr. (c) Foobar Pvt. Ltd.
9-
108
holders:
119
- Foobar Pvt. Ltd.
12-
13-
copyrights_summary:
14-
- value: copr. (c) Foobar Pvt. Ltd.
15-
count: 1
16-
1710
holders_summary:
1811
- value: Foobar Pvt. Ltd.
1912
count: 1
13+
copyrights_summary:
14+
- value: copr. (c) Foobar Pvt. Ltd.
15+
count: 1
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
what:
2-
- copyrights
3-
- holders
4-
5-
copyrights:
6-
- Copr. (c) 1999 Random Corp. Ltd.
7-
8-
holders:
9-
- Random Corp. Ltd.
1+
what:
2+
- copyrights
3+
- holders
4+
copyrights:
5+
- Copr. (c) 1999 Random Corp. Ltd.
6+
holders:
7+
- Random Corp. Ltd.
Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
what:
2-
- copyrights
3-
- holders
4-
- copyrights_summary
5-
- holders_summary
6-
7-
copyrights:
8-
- Copyright Foobar Pvt. Ltd
9-
10-
holders:
11-
- Foobar Pvt. Ltd
12-
13-
copyrights_summary:
14-
- value: Copyright Foobar Pvt. Ltd
15-
count: 1
16-
17-
holders_summary:
18-
- value: Foobar Pvt. Ltd
19-
count: 1
1+
what:
2+
- copyrights
3+
- holders
4+
- copyrights_summary
5+
- holders_summary
6+
copyrights:
7+
- Copyright Foobar Pvt. Ltd
8+
holders:
9+
- Foobar Pvt. Ltd
10+
holders_summary:
11+
- value: Foobar Pvt. Ltd
12+
count: 1
13+
copyrights_summary:
14+
- value: Copyright Foobar Pvt. Ltd
15+
count: 1
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
what:
2-
- copyrights
3-
- holders
1+
what:
2+
- copyrights
3+
- holders
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
what:
2-
- copyrights
3-
- holders
4-
5-
copyrights:
6-
- Copyright (c) Microsoft
7-
8-
holders:
9-
- Microsoft
1+
what:
2+
- copyrights
3+
- holders
4+
copyrights:
5+
- Copyright (c) Microsoft
6+
holders:
7+
- Microsoft

tests/cluecode/data/copyrights/in_docstring.py.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ what:
22
- copyrights
33
- holders
44
- authors
5-
65
copyrights:
76
- (c) 1989-2000 Baz Corporation
8-
97
holders:
108
- Baz Corporation

0 commit comments

Comments
 (0)