Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for buildpack.toml files #4031

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/packagedcode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from packagedcode import alpine
from packagedcode import bower
from packagedcode import build
from packagedcode import buildpack
from packagedcode import build_gradle
from packagedcode import cargo
from packagedcode import chef
Expand Down Expand Up @@ -62,6 +63,8 @@
build.BuckMetadataBzlHandler,
build.BuckPackageHandler,

buildpack.BuildpackHandler,

cargo.CargoLockHandler,
cargo.CargoTomlHandler,

Expand Down
143 changes: 143 additions & 0 deletions src/packagedcode/buildpack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#
# 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 toml
from packagedcode import models
from packageurl import PackageURL

class BuildpackHandler(models.DatafileHandler):
"""
Handle buildpack.toml manifests.
See https://buildpacks.io/ for details on buildpack format.
"""
datasource_id = "buildpack_toml"
path_patterns = ("*buildpack.toml",)
default_package_type = "buildpack"
description = "Cloud Native Buildpack manifest"
documentation_url = "https://buildpacks.io/"

@classmethod
def parse(cls, location, package_only=False):
"""
Parse the buildpack.toml file at `location` and yield PackageData.
"""
with open(location, "r", encoding="utf-8") as f:
data = toml.load(f)

# Extract required fields
api_version = data.get("api")
buildpack = data.get("buildpack", {})
if not buildpack:
return

name = buildpack.get("name")
if not name:
return

# Initialize common package data
package_data = dict(
datasource_id=cls.datasource_id,
type=cls.default_package_type,
name=name,
version="unknown",
description=None,
homepage_url=None,
keywords=[],
declared_license_expression=None,
dependencies=[],
)

# Handle Paketo-specific fields if present
if "api" in data:
cls.handle_paketo_buildpack(data, buildpack, package_data)

# Handle Heroku-specific fields if present
elif "publish" in data and "Ignore" in data["publish"]:
cls.handle_heroku_buildpack(data, buildpack, package_data)

yield models.PackageData.from_data(package_data, package_only)

@staticmethod
def handle_paketo_buildpack(data, buildpack, package_data):
buildpack_id = buildpack.get("id")
if buildpack_id:
package_data["extra_data"] = {"id": buildpack_id}

package_data.update({
"version": buildpack.get("version", "unknown"),
"description": buildpack.get("description"),
"homepage_url": buildpack.get("homepage"),
"keywords": buildpack.get("keywords", []),
})

licenses = buildpack.get("licenses", [])
license_expressions = [
license_entry.get("type") for license_entry in licenses if license_entry.get("type")
]
if license_expressions:
package_data["declared_license_expression"] = " AND ".join(license_expressions)

dependencies = []
metadata = data.get("metadata", {})
metadata_dependencies = metadata.get("dependencies", [])
for dep in metadata_dependencies:
dep_purl = dep.get("purl")
dep_name = dep.get("name")
dep_version = dep.get("version")
if dep_purl:
dependencies.append(
models.DependentPackage(
purl=dep_purl,
scope="runtime",
is_runtime=True,
is_optional=False,
)
)
elif dep_name and dep_version:
dependencies.append(
models.DependentPackage(
purl=PackageURL(type="generic", name=dep_name, version=dep_version).to_string(),
scope="runtime",
is_runtime=True,
is_optional=False,
)
)

orders = data.get("order", [])
for order in orders:
for group in order.get("group", []):
group_id = group.get("id")
group_version = group.get("version")
if group_id and group_version:
dependencies.append(
models.DependentPackage(
purl=PackageURL(type="buildpack", name=group_id, version=group_version).to_string(),
scope="runtime",
is_runtime=True,
is_optional=group.get("optional", False),
)
)

package_data["dependencies"] = dependencies

@staticmethod
def handle_heroku_buildpack(data, buildpack, package_data):
publish_section = data.get("publish", {})
if "Ignore" in publish_section:
ignore_files = publish_section["Ignore"].get("files", [])
if ignore_files: # Only add if files are found
package_data["extra_data"] = {"ignore_files": ignore_files}
else:
package_data["extra_data"] = {"ignore_files": []}
else:
package_data["extra_data"] = {"ignore_files": []}

# Add description for Heroku buildpack
package_data["description"] = f"Heroku buildpack for {buildpack.get('name')}"

2 changes: 1 addition & 1 deletion src/packagedcode/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ class PackageData(IdentifiablePackageData):
download_url = String(
label='Download URL',
help='A direct download URL.')

size = Integer(
default=None,
label='download size',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[buildpack]
name = "Java"

[publish.Ignore]
files = [
"etc/",
"spec/",
"test/",
".gitignore",
".github/",
"hatchet.json",
"Gemfile",
"Gemfile.lock"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"packages": [
{
"type": "buildpack",
"namespace": null,
"name": "Java",
"version": "unknown",
"qualifiers": {},
"subpath": null,
"primary_language": null,
"description": "Heroku buildpack for Java",
"release_date": null,
"parties": [],
"keywords": [],
"homepage_url": null,
"download_url": null,
"size": null,
"sha1": null,
"md5": null,
"sha256": null,
"sha512": null,
"bug_tracking_url": null,
"code_view_url": null,
"vcs_url": null,
"copyright": null,
"holder": null,
"declared_license_expression": null,
"declared_license_expression_spdx": null,
"license_detections": [],
"other_license_expression": null,
"other_license_expression_spdx": null,
"other_license_detections": [],
"extracted_license_statement": null,
"notice_text": null,
"source_packages": [],
"is_private": false,
"is_virtual": false,
"extra_data": {
"ignore_files": [
"etc/",
"spec/",
"test/",
".gitignore",
".github/",
"hatchet.json",
"Gemfile",
"Gemfile.lock"
]
},
"repository_homepage_url": null,
"repository_download_url": null,
"api_data_url": null,
"package_uid": "pkg:buildpack/Java@unknown?uuid=d332d23b-1b4e-415a-96a8-141416e7e7f2",
"datafile_paths": [
"buildpack.toml"
],
"datasource_ids": [
"buildpack_toml"
],
"purl": "pkg:buildpack/Java@unknown"
}
],
"dependencies": [],
"files": [
{
"path": "buildpack.toml",
"type": "file",
"package_data": [
{
"type": "buildpack",
"namespace": null,
"name": "Java",
"version": "unknown",
"qualifiers": {},
"subpath": null,
"primary_language": null,
"description": "Heroku buildpack for Java",
"release_date": null,
"parties": [],
"keywords": [],
"homepage_url": null,
"download_url": null,
"size": null,
"sha1": null,
"md5": null,
"sha256": null,
"sha512": null,
"bug_tracking_url": null,
"code_view_url": null,
"vcs_url": null,
"copyright": null,
"holder": null,
"declared_license_expression": null,
"declared_license_expression_spdx": null,
"license_detections": [],
"other_license_expression": null,
"other_license_expression_spdx": null,
"other_license_detections": [],
"extracted_license_statement": null,
"notice_text": null,
"source_packages": [],
"file_references": [],
"is_private": false,
"is_virtual": false,
"extra_data": {
"ignore_files": [
"etc/",
"spec/",
"test/",
".gitignore",
".github/",
"hatchet.json",
"Gemfile",
"Gemfile.lock"
]
},
"dependencies": [],
"repository_homepage_url": null,
"repository_download_url": null,
"api_data_url": null,
"datasource_id": "buildpack_toml",
"purl": "pkg:buildpack/Java@unknown"
}
],
"for_packages": [
"pkg:buildpack/Java@unknown?uuid=d332d23b-1b4e-415a-96a8-141416e7e7f2"
],
"scan_errors": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[buildpack]
name = "PHP"

[publish.Ignore]
files = [
".github/",
".gitignore",
".rspec_parallel",
"support/build/",
"support/devcenter/",
"test/",
"Gemfile",
"Gemfile.lock",
"hatchet.json",
"hatchet.lock",
"requirements.txt",
]
Loading