Skip to content

Commit 754966a

Browse files
Support --package-only for all package types
Reference: #3464 Signed-off-by: Ayan Sinha Mahapatra <[email protected]>
1 parent 5a92ee9 commit 754966a

37 files changed

+405
-248
lines changed

src/packagedcode/about.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AboutFileHandler(models.DatafileHandler):
4747
documentation_url = 'https://aboutcode-toolkit.readthedocs.io/en/latest/specification.html'
4848

4949
@classmethod
50-
def parse(cls, location):
50+
def parse(cls, location, package_only=False):
5151
"""
5252
Yield one or more Package manifest objects given a file ``location`` pointing to a
5353
package archive, manifest or similar.
@@ -90,7 +90,7 @@ def parse(cls, location):
9090
file_references.append(models.FileReference(path=about_resource))
9191

9292
# FIXME: we should put the unprocessed attributes in extra data
93-
yield models.PackageData(
93+
package_data = dict(
9494
datasource_id=cls.datasource_id,
9595
type=package_type,
9696
namespace=package_ns,
@@ -103,6 +103,7 @@ def parse(cls, location):
103103
download_url=download_url,
104104
file_references=file_references,
105105
)
106+
yield models.PackageData.from_data(package_data, package_only)
106107

107108
@classmethod
108109
def assemble(cls, package_data, resource, codebase, package_adder):

src/packagedcode/alpine.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ class AlpineInstalledDatabaseHandler(models.DatafileHandler):
6363
description = 'Alpine Linux installed package database'
6464

6565
@classmethod
66-
def parse(cls, location):
66+
def parse(cls, location, package_only=False):
6767
yield from parse_alpine_installed_db(
6868
location=location,
6969
datasource_id=cls.datasource_id,
7070
package_type=cls.default_package_type,
71+
package_only=package_only,
7172
)
7273

7374
@classmethod
@@ -134,9 +135,14 @@ class AlpineApkbuildHandler(models.DatafileHandler):
134135
documentation_url = 'https://wiki.alpinelinux.org/wiki/APKBUILD_Reference'
135136

136137
@classmethod
137-
def parse(cls, location):
138-
package_data = parse_apkbuild(location, strict=True)
139-
cls.populate_license_fields(package_data)
138+
def parse(cls, location, package_only=False):
139+
package_data = parse_apkbuild(
140+
location=location,
141+
strict=True,
142+
package_only=package_only
143+
)
144+
if not package_only:
145+
cls.populate_license_fields(package_data)
140146
if package_data:
141147
yield package_data
142148

@@ -165,7 +171,7 @@ def assign_package_to_resources(cls, package, resource, codebase, package_adder)
165171
)
166172

167173

168-
def parse_alpine_installed_db(location, datasource_id, package_type):
174+
def parse_alpine_installed_db(location, datasource_id, package_type, package_only=False):
169175
"""
170176
Yield PackageData objects from an installed database file at `location`
171177
or None. Typically found at '/lib/apk/db/installed' in an Alpine
@@ -179,6 +185,7 @@ def parse_alpine_installed_db(location, datasource_id, package_type):
179185
package_fields=package_fields,
180186
datasource_id=datasource_id,
181187
package_type=package_type,
188+
package_only=package_only,
182189
)
183190

184191

@@ -241,7 +248,7 @@ def get_alpine_installed_db_fields(location):
241248
])
242249

243250

244-
def parse_apkbuild(location, strict=False):
251+
def parse_apkbuild(location, strict=False, package_only=False):
245252
"""
246253
Return a PackageData object from an APKBUILD file at ``location`` or None.
247254
@@ -256,6 +263,7 @@ def parse_apkbuild(location, strict=False):
256263
datasource_id=AlpineApkbuildHandler.datasource_id,
257264
package_type=AlpineApkbuildHandler.default_package_type,
258265
strict=strict,
266+
package_only=package_only,
259267
)
260268

261269

@@ -732,7 +740,7 @@ def fix_apkbuild(text):
732740
return text
733741

734742

735-
def parse_apkbuild_text(text, datasource_id, package_type, strict=False):
743+
def parse_apkbuild_text(text, datasource_id, package_type, strict=False, package_only=False):
736744
"""
737745
Return a PackageData object from an APKBUILD text context or None. Only
738746
consider variables with a name listed in the ``names`` set.
@@ -761,7 +769,8 @@ def parse_apkbuild_text(text, datasource_id, package_type, strict=False):
761769
package = build_package_data(
762770
variables,
763771
datasource_id=datasource_id,
764-
package_type=package_type
772+
package_type=package_type,
773+
package_only=package_only,
765774
)
766775

767776
if package and unresolved:
@@ -800,7 +809,7 @@ def parse_pkginfo(location):
800809
raise NotImplementedError
801810

802811

803-
def build_package_data(package_fields, datasource_id, package_type):
812+
def build_package_data(package_fields, datasource_id, package_type, package_only=False):
804813
"""
805814
Return a PackageData object from a ``package_fields`` iterable of (name,
806815
value) tuples.
@@ -850,7 +859,16 @@ def build_package_data(package_fields, datasource_id, package_type):
850859

851860
converted_fields.update(converted)
852861

853-
return models.PackageData.from_dict(converted_fields)
862+
fields_not_required = ["current_file", "current_dir"]
863+
for field in fields_not_required:
864+
value = converted_fields.get(field)
865+
if value:
866+
converted_fields.pop(field)
867+
868+
return models.PackageData.from_data(
869+
package_data=converted_fields,
870+
package_only=package_only,
871+
)
854872

855873
#####################################
856874
# Note: all handlers MUST accept **kwargs as they also receive the current data

src/packagedcode/build.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class AutotoolsConfigureHandler(models.DatafileHandler):
5555
documentation_url = 'https://www.gnu.org/software/automake/'
5656

5757
@classmethod
58-
def parse(cls, location):
58+
def parse(cls, location, package_only=False):
5959
# we use the parent directory as a package name
6060
name = fileutils.file_name(fileutils.parent_directory(location))
6161
# we could use checksums as version in the future
@@ -67,12 +67,13 @@ def parse(cls, location):
6767
# there are dependencies we could use
6868
# dependencies = []
6969

70-
yield models.PackageData(
70+
package_data = dict(
7171
datasource_id=cls.datasource_id,
7272
type=cls.default_package_type,
7373
name=name,
7474
version=version,
7575
)
76+
yield models.PackageData.from_data(package_data, package_only)
7677

7778
@classmethod
7879
def assign_package_to_resources(cls, package, resource, codebase, package_adder):
@@ -112,6 +113,7 @@ def assemble(cls, package_data, resource, codebase, package_adder):
112113
package = models.Package.from_package_data(
113114
package_data=package_data,
114115
datafile_path=resource.path,
116+
package_only=True,
115117
)
116118

117119
if TRACE:
@@ -143,8 +145,7 @@ def assemble(cls, package_data, resource, codebase, package_adder):
143145
yield resource
144146

145147
@classmethod
146-
def parse(cls, location):
147-
148+
def parse(cls, location, package_only=False):
148149
# Thanks to Starlark being a Python dialect, we can use `ast` to parse it
149150
with open(location, 'rb') as f:
150151
tree = ast.parse(f.read())
@@ -196,23 +197,28 @@ def parse(cls, location):
196197
if TRACE:
197198
logger_debug(f"build: parse: license_files: {license_files}")
198199

199-
package_data = models.PackageData(
200+
package_data = dict(
200201
datasource_id=cls.datasource_id,
201202
type=cls.default_package_type,
202203
name=name,
204+
extracted_license_statement=license_files,
205+
)
206+
# `package_only` is True as we do the license detection
207+
# on assembly
208+
yield models.PackageData.from_data(
209+
package_data=package_data,
210+
package_only=True,
203211
)
204-
205-
package_data.extracted_license_statement = license_files
206-
yield package_data
207212

208213
else:
209214
# If we don't find anything in the pkgdata file, we yield a Package
210215
# with the parent directory as the name
211-
yield models.PackageData(
216+
package_data = dict(
212217
datasource_id=cls.datasource_id,
213218
type=cls.default_package_type,
214219
name=fileutils.file_name(fileutils.parent_directory(location))
215220
)
221+
yield models.PackageData.from_data(package_data, package_only)
216222

217223
@classmethod
218224
def assign_package_to_resources(cls, package, resource, codebase, package_adder, skip_name=None):
@@ -334,7 +340,7 @@ class BuckMetadataBzlHandler(BaseStarlarkManifestHandler):
334340
documentation_url = 'https://buck.build/'
335341

336342
@classmethod
337-
def parse(cls, location):
343+
def parse(cls, location, package_only=True):
338344

339345
with open(location, 'rb') as f:
340346
tree = ast.parse(f.read())
@@ -386,7 +392,7 @@ def parse(cls, location):
386392
):
387393
# TODO: Create function that determines package type from download URL,
388394
# then create a package of that package type from the metadata info
389-
yield models.PackageData(
395+
package_data = dict(
390396
datasource_id=cls.datasource_id,
391397
type=metadata_fields.get('upstream_type', cls.default_package_type),
392398
name=metadata_fields.get('name'),
@@ -396,6 +402,7 @@ def parse(cls, location):
396402
homepage_url=metadata_fields.get('upstream_address', ''),
397403
# TODO: Store 'upstream_hash` somewhere
398404
)
405+
yield models.PackageData.from_data(package_data, package_only=True)
399406

400407
if (
401408
'package_type'
@@ -409,7 +416,7 @@ def parse(cls, location):
409416
and 'vcs_commit_hash'
410417
in metadata_fields
411418
):
412-
yield models.PackageData(
419+
package_data = dict(
413420
datasource_id=cls.datasource_id,
414421
type=metadata_fields.get('package_type', cls.default_package_type),
415422
name=metadata_fields.get('name'),
@@ -422,6 +429,7 @@ def parse(cls, location):
422429
sha1=metadata_fields.get('download_archive_sha1', ''),
423430
extra_data=dict(vcs_commit_hash=metadata_fields.get('vcs_commit_hash', ''))
424431
)
432+
yield models.PackageData.from_data(package_data, package_only=True)
425433

426434
@classmethod
427435
def assign_package_to_resources(cls, package, resource, codebase, package_adder):

src/packagedcode/build_gradle.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class BuildGradleHandler(models.DatafileHandler):
5959
description = 'Gradle build script'
6060

6161
@classmethod
62-
def parse(cls, location):
62+
def parse(cls, location, package_only=False):
6363
dependencies = get_dependencies(location)
64-
return build_package(cls, dependencies)
64+
return build_package(cls, dependencies, package_only)
6565

6666
# TODO: handle complex cases of nested builds with many packages
6767
@classmethod
@@ -328,7 +328,7 @@ def get_dependencies(build_gradle_location):
328328
return list(get_dependencies_from_parse_tree(parse_tree))
329329

330330

331-
def build_package(cls, dependencies):
331+
def build_package(cls, dependencies, package_only=False):
332332
"""
333333
Yield PackageData from a ``dependencies`` list of mappings.
334334
"""
@@ -364,10 +364,11 @@ def build_package(cls, dependencies):
364364
)
365365
)
366366

367-
yield models.PackageData(
367+
package_data = dict(
368368
datasource_id=cls.datasource_id,
369369
type=cls.default_package_type,
370370
primary_language=BuildGradleHandler.default_primary_language,
371371
dependencies=package_dependencies,
372372
)
373+
yield models.PackageData.from_data(package_data, package_only)
373374

src/packagedcode/cargo.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class CargoTomlHandler(models.DatafileHandler):
2929
documentation_url = 'https://doc.rust-lang.org/cargo/reference/manifest.html'
3030

3131
@classmethod
32-
def parse(cls, location):
32+
def parse(cls, location, package_only=False):
3333
package_data = toml.load(location, _dict=dict)
3434

3535
core_package_data = package_data.get('package', {})
@@ -67,7 +67,7 @@ def parse(cls, location):
6767
repository_download_url = name and version and f'https://crates.io/api/v1/crates/{name}/{version}/download'
6868
api_data_url = name and f'https://crates.io/api/v1/crates/{name}'
6969

70-
yield models.PackageData(
70+
package_data = dict(
7171
datasource_id=cls.datasource_id,
7272
type=cls.default_package_type,
7373
name=name,
@@ -83,6 +83,7 @@ def parse(cls, location):
8383
api_data_url=api_data_url,
8484
dependencies=dependencies,
8585
)
86+
yield models.PackageData.from_data(package_data, package_only)
8687

8788
@classmethod
8889
def assemble(cls, package_data, resource, codebase, package_adder):
@@ -116,7 +117,7 @@ class CargoLockHandler(models.DatafileHandler):
116117
# ]
117118

118119
@classmethod
119-
def parse(cls, location):
120+
def parse(cls, location, package_only=False):
120121
cargo_lock = toml.load(location, _dict=dict)
121122
dependencies = []
122123
package = cargo_lock.get('package', [])
@@ -137,12 +138,13 @@ def parse(cls, location):
137138
)
138139
)
139140

140-
yield models.PackageData(
141+
package_data = dict(
141142
datasource_id=cls.datasource_id,
142143
type=cls.default_package_type,
143144
primary_language=cls.default_primary_language,
144145
dependencies=dependencies,
145146
)
147+
yield models.PackageData.from_data(package_data, package_only)
146148

147149
@classmethod
148150
def assemble(cls, package_data, resource, codebase, package_adder):

0 commit comments

Comments
 (0)