diff --git a/src/packagedcode/__init__.py b/src/packagedcode/__init__.py index 6692087aa4..dc9cde4589 100644 --- a/src/packagedcode/__init__.py +++ b/src/packagedcode/__init__.py @@ -20,6 +20,7 @@ from packagedcode import debian from packagedcode import debian_copyright from packagedcode import distro +from packagedcode import dockerfileLABEL from packagedcode import conda from packagedcode import conan from packagedcode import cocoapods @@ -97,6 +98,7 @@ debian.DebianSourcePackageTarballHandler, distro.EtcOsReleaseHandler, + dockerfileLABEL.DockerfileHandler, freebsd.CompactManifestHandler, diff --git a/src/packagedcode/dockerfileLABEL.py b/src/packagedcode/dockerfileLABEL.py new file mode 100644 index 0000000000..b9e46dddc2 --- /dev/null +++ b/src/packagedcode/dockerfileLABEL.py @@ -0,0 +1,72 @@ +# +# 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 io +from pathlib import Path +from dockerfile_parse import DockerfileParser +from packagedcode import models +from packagedcode import utils + + +class DockerfileHandler(models.DatafileHandler): + datasource_id = 'dockerfile' + default_package_type = 'docker-image' + path_patterns = ('Dockerfile', 'containerfile', '*.dockerfile') + description = 'Dockerfile (OCI) metadata handler' + documentation_url = 'https://docs.docker.com/engine/reference/builder/' + + @classmethod + def parse(cls, location, package_only=False): + """ + Parse a Dockerfile and yield one or more PackageData objects with OCI labels and metadata. + """ + labels = cls.extract_oci_labels_from_dockerfile(location) + + + package_data = { + 'datasource_id': cls.datasource_id, + 'type': cls.default_package_type, + 'name': labels.get('name', 'unknown'), + 'version': labels.get('version', 'unknown'), + 'license_expression': labels.get('license', 'unknown'), + 'labels': labels, + } + + yield models.PackageData.from_data(package_data, package_only) + + @classmethod + def extract_oci_labels_from_dockerfile(cls, dockerfile_path): + """ + Extract OCI labels from the Dockerfile using container-inspector. + """ + labels = {} + parser = DockerfileParser() + parser.parse(dockerfile_path) + labels = parser.labels + return labels + + @classmethod + def assemble(cls, package_data, resource, codebase, package_adder): + """ + Assemble a Package from the parsed Dockerfile data. + """ + if package_data.purl: + package = models.Package.from_package_data(package_data=package_data, datafile_path=resource.path) + + + package.populate_license_fields() + + yield package + + + package_adder(package.package_uid, resource, codebase) + + yield resource