diff --git a/cachito/web/api_v1.py b/cachito/web/api_v1.py index b453d0e22..63808c05c 100644 --- a/cachito/web/api_v1.py +++ b/cachito/web/api_v1.py @@ -6,7 +6,7 @@ from collections import OrderedDict from copy import deepcopy from datetime import date, datetime -from typing import Any, Dict, Union +from typing import Any, Dict, List, Set, Union import flask import kombu.exceptions @@ -24,7 +24,7 @@ from cachito.common.utils import b64encode from cachito.errors import MessageBrokerError, NoWorkers, RequestErrorOrigin, ValidationError from cachito.web import db -from cachito.web.content_manifest import BASE_ICM +from cachito.web.content_manifest import BASE_ICM, BASE_SBOM from cachito.web.metrics import cachito_metrics from cachito.web.models import ( ConfigFileBase64, @@ -218,7 +218,7 @@ def get_request_content_manifest(request_id): ) content_manifest = request.content_manifest content_manifest_json = content_manifest.to_json() - return send_content_manifest_back(content_manifest_json) + return send_json_file_back(content_manifest_json) @api_v1.route("/requests//environment-variables", methods=["GET"]) @@ -744,68 +744,135 @@ def get_request_logs(request_id): ) -def send_content_manifest_back(content_manifest: Dict[str, Any]) -> flask.Response: - """Send content manifest back to the client.""" +def send_json_file_back(json_content: Dict[str, Any]) -> flask.Response: + """Send json file back to the client.""" debug = flask.current_app.logger.debug - fd, filename = tempfile.mkstemp(prefix="request-content-manifest-json-", text=True) - debug("Write content manifest into file: %s", filename) + fd, filename = tempfile.mkstemp(prefix="request-json-", text=True) + debug("Write json into file: %s", filename) try: with open(fd, "w") as f: - json.dump(content_manifest, f, sort_keys=True) + json.dump(json_content, f, sort_keys=True) return flask.send_file(filename, mimetype="application/json") finally: - debug("The content manifest is sent back to the client. Remove %s", filename) + debug("Json file is sent back to the client. Remove %s", filename) os.unlink(filename) -@api_v1.route("/content-manifest", methods=["GET"]) -def get_content_manifest_by_requests(): - """ - Retrieve the content manifest associated with the given requests. - - :return: a Flask JSON response - :rtype: flask.Response - :raise BadRequest: if any of the given request is not in the "complete" or - "stale" state, If any of the given request cannot be found. - """ - arg = flask.request.args.get("requests") - if not arg: - return flask.jsonify(BASE_ICM) +def _get_valid_request_ids(all_request_ids: str) -> List[int]: request_ids = set() item: str - for item in arg.split(","): + for item in all_request_ids.split(","): if not item.strip(): continue if not item.strip().isdigit(): raise BadRequest(f"{item} is not an integer.") request_ids.add(int(item)) + return list(request_ids) + + +def _get_all_requests(request_ids: List[int]) -> list[Request]: requests = ( Request.query.filter(Request.id.in_(request_ids)) .options(load_only("id"), joinedload(Request.state)) .all() ) - states = (RequestStateMapping.complete.name, RequestStateMapping.stale.name) + request: Request for request in requests: - if request.state.state_name not in states: - raise BadRequest( - f"Request {request.id} is in state {request.state.state_name}, " - f"not complete or stale." - ) request_ids.remove(request.id) if request_ids: nonexistent_ids = ",".join(map(str, request_ids)) raise BadRequest(f"Cannot find request(s) {nonexistent_ids}.") + return requests + + +def _check_requests_state(requests: List[Request], valid_states: Set[str]) -> None: + error_msg = "" + + request: Request + for request in requests: + if request.state.state_name not in valid_states: + error_msg += ( + f"Request {request.id} is in state {request.state.state_name}, " + f"not in {valid_states}.\n" + ) + + if error_msg: + raise BadRequest(error_msg) + + +@api_v1.route("/content-manifest", methods=["GET"]) +def get_content_manifest_by_requests(): + """ + Retrieve the content manifest associated with the given requests. + + :return: a Flask JSON response + :rtype: flask.Response + :raise BadRequest: if any of the given request is not in the "complete" or + "stale" state, If any of the given request cannot be found. + """ + arg = flask.request.args.get("requests") + if not arg: + return flask.jsonify(BASE_ICM) + + request_ids = _get_valid_request_ids(arg) + requests = _get_all_requests(request_ids) + + valid_states = set([RequestStateMapping.complete.name]) + _check_requests_state(requests, valid_states) + + request: Request assembled_icm = deepcopy(BASE_ICM) for request in requests: manifest = request.content_manifest.to_json() assembled_icm["image_contents"].extend(manifest["image_contents"]) if len(requests) > 1: deep_sort_icm(assembled_icm) - return send_content_manifest_back(assembled_icm) + return send_json_file_back(assembled_icm) + + +@api_v1.route("/sbom", methods=["GET"]) +def get_sbom_by_requests() -> flask.Response: + """ + Retrieve the content manifest sbom associated with the given requests. + + :return: a Flask JSON response + :rtype: flask.Response + :raise BadRequest: if any of the given request is not in the "complete" or + "stale" state, If any of the given request cannot be found. + """ + arg = flask.request.args.get("requests") + if not arg: + return flask.jsonify(BASE_SBOM) + + request_ids = _get_valid_request_ids(arg) + requests = _get_all_requests(request_ids) + + valid_states = set([RequestStateMapping.complete.name]) + _check_requests_state(requests, valid_states) + + request: Request + assembled_sbom = deepcopy(BASE_SBOM) + + all_components = [] + for request in requests: + sbom_components = request.content_manifest.sbom_components_list() + all_components.extend(sbom_components) + + unique_components: List[Dict[str, Any]] = [] + + all_components.sort(key=lambda c: (c["purl"], c["name"], c.get("version"))) + + for component in all_components: + if not unique_components or component != unique_components[-1]: + unique_components.append(component) + + assembled_sbom["components"] = unique_components + + return send_json_file_back(assembled_sbom) class RequestMetricsArgs(pydantic.BaseModel): diff --git a/cachito/web/content_manifest.py b/cachito/web/content_manifest.py index a50383b65..6b8ab498a 100644 --- a/cachito/web/content_manifest.py +++ b/cachito/web/content_manifest.py @@ -3,7 +3,7 @@ from copy import deepcopy from functools import cached_property from pathlib import Path -from typing import List, Optional +from typing import Any, Dict, List, Optional import flask @@ -22,6 +22,9 @@ "https://raw.githubusercontent.com/containerbuildsystem/atomic-reactor/" "f4abcfdaf8247a6b074f94fa84f3846f82d781c6/atomic_reactor/schemas/content_manifest.json" ) +SBOM_SCHEMA_URL = ( + "https://raw.githubusercontent.com/CycloneDX/specification/1.4/schema/bom-1.4.schema.json" +) UNKNOWN_LAYER_INDEX = -1 # A base (empty) image content manifest which will be used as a template to @@ -36,6 +39,13 @@ "image_contents": [], } +BASE_SBOM = { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "components": [], +} + class ContentManifest: """A content manifest associated with a Cachito request.""" @@ -64,18 +74,21 @@ def __init__(self, request, packages): # dict to store gitsubmodule package level data; uses the package id as key to identify a # package self._gitsubmodule_data = {} + # list to store sbom components + self._sbom_components = [] @cached_property def go_modules_by_name(self) -> dict[str, "Package"]: """Get a mapping of go module names to their respective package object.""" return {module.name: module for module in self.packages if module.type == "gomod"} - def process_gomod(self, package, dependency): + def process_gomod(self, package, dependency, type="icm"): """ Process gomod package. :param Package package: the gomod package to process :param Dependency dependency: the gomod package dependency to process + :param type: icm or sbom component """ if dependency.type == "gomod": @@ -99,14 +112,27 @@ def process_gomod(self, package, dependency): dep_purl = to_purl(dependency, relpath_from_parent_module_to_dep) dep_purl = replace_parent_purl_placeholder(dep_purl, parent_purl) icm_source = {"purl": dep_purl} - self._gomod_data[package.name]["dependencies"].append(icm_source) - def process_go_package(self, package, dependency): + if type == "icm": + self._gomod_data[package.name]["dependencies"].append(icm_source) + elif type == "sbom": + component = { + "type": "library", + "name": dependency.name, + "purl": dep_purl, + } + if dependency.version: + component["version"] = dependency.version + + self._sbom_components.append(component) + + def process_go_package(self, package, dependency, type="icm"): """ Process go-package package. :param Package package: the go-package package to process :param Dependency dependency: the go-package package dependency to process + :param type: icm or sbom component """ if dependency.type == "go-package": if dependency.version and dependency.version.startswith("."): @@ -115,7 +141,18 @@ def process_go_package(self, package, dependency): dep_purl = to_purl(dependency) icm_dependency = {"purl": dep_purl} - self._gopkg_data[package]["dependencies"].append(icm_dependency) + + if type == "icm": + self._gopkg_data[package]["dependencies"].append(icm_dependency) + elif type == "sbom": + component = { + "type": "library", + "name": dependency.name, + "purl": dep_purl, + } + if dependency.version: + component["version"] = dependency.version + self._sbom_components.append(component) def _get_local_go_package_dep_purl(self, package: "Package", dependency: "Package") -> str: """ @@ -178,35 +215,47 @@ def set_go_package_sources(self): "Could not find a Go module for %s", pkg_data["purl"] ) - def process_npm_package(self, package, dependency): + def process_npm_package(self, package, dependency, type="icm"): """ Process npm package. :param Package package: the npm package to process :param Dependency dependency: the npm package dependency to process + :param type: icm or sbom component """ if dependency.type == "npm": - self._process_standard_package("npm", package, dependency) + if type == "icm": + self._process_standard_package("npm", package, dependency) + elif type == "sbom": + self._process_standard_package_sbom(dependency) - def process_pip_package(self, package, dependency): + def process_pip_package(self, package, dependency, type="icm"): """ Process pip package. :param Package package: the pip package to process :param Dependency dependency: the pip package dependency to process + :param type: icm or sbom component """ if dependency.type == "pip": - self._process_standard_package("pip", package, dependency) + if type == "icm": + self._process_standard_package("pip", package, dependency) + elif type == "sbom": + self._process_standard_package_sbom(dependency) - def process_yarn_package(self, package, dependency): + def process_yarn_package(self, package, dependency, type="icm"): """ Process yarn package. :param Package package: the yarn package to process :param Dependency dependency: the yarn package dependency to process + :param type: icm or sbom component """ if dependency.type == "yarn": - self._process_standard_package("yarn", package, dependency) + if type == "icm": + self._process_standard_package("yarn", package, dependency) + elif type == "sbom": + self._process_standard_package_sbom(dependency) def _process_standard_package(self, pkg_type, package, dependency): """ @@ -221,12 +270,29 @@ def _process_standard_package(self, pkg_type, package, dependency): if not dependency.dev: pkg_type_data[package]["dependencies"].append(icm_dependency) - def process_rubygems_package(self, package, dependency): + def _process_standard_package_sbom(self, dependency: "Package") -> None: + """ + Process a standard package (standard = does not require the same magic as go packages). + + Currently, all package types except for gomod and go-package are standard. + """ + purl = to_purl(dependency) + component = { + "type": "library", + "name": dependency.name, + "purl": purl, + } + if dependency.version: + component["version"] = dependency.version + self._sbom_components.append(component) + + def process_rubygems_package(self, package, dependency, type="icm"): """ Process RubyGems package. :param Package package: the RubyGems package to process :param Dependency dependency: the RubyGems package dependency to process + :param type: icm or sbom component """ if dependency.type == "rubygems": parent_package_name = get_repo_name(self.request.repo).split("/")[-1] @@ -236,8 +302,19 @@ def process_rubygems_package(self, package, dependency): dep_purl = replace_parent_purl_placeholder(dep_purl, parent_purl) icm_dependency = {"purl": dep_purl} - self._rubygems_data[package]["sources"].append(icm_dependency) - self._rubygems_data[package]["dependencies"].append(icm_dependency) + + if type == "icm": + self._rubygems_data[package]["sources"].append(icm_dependency) + self._rubygems_data[package]["dependencies"].append(icm_dependency) + elif type == "sbom": + component = { + "type": "library", + "name": dependency.name, + "purl": dep_purl, + } + if dependency.version: + component["version"] = dependency.version + self._sbom_components.append(component) def to_json(self): """ @@ -320,6 +397,60 @@ def generate_icm(self, image_contents=None): deep_sort_icm(icm) return icm + def sbom_components_list(self) -> List[Dict[str, Any]]: + """ + Generate sbom components list. + + :return: the CycloneDX components dict + :rtype: list + """ + self._sbom_components = [] + self._gomod_data = {} + + for package in self.packages: + component = {"type": "library", "name": package.name} + if package.version: + component["version"] = package.version + + if package.type in ( + "go-package", + "gomod", + "npm", + "pip", + "yarn", + "rubygems", + "git-submodule", + ): + purl = to_top_level_purl(package, self.request, subpath=package.path) + component["purl"] = purl + + if package.type == "gomod": + self._gomod_data.setdefault(package.name, {"purl": purl, "dependencies": []}) + + self._sbom_components.append(component) + + else: + flask.current_app.logger.debug( + "No SBOM implementation for '%s' packages", package.type + ) + + for package in self.packages: + for dependency in package.dependencies: + if package.type == "go-package": + self.process_go_package(package, dependency, type="sbom") + elif package.type == "gomod": + self.process_gomod(package, dependency, type="sbom") + elif package.type == "npm": + self.process_npm_package(package, dependency, type="sbom") + elif package.type == "pip": + self.process_pip_package(package, dependency, type="sbom") + elif package.type == "yarn": + self.process_yarn_package(package, dependency, type="sbom") + elif package.type == "rubygems": + self.process_rubygems_package(package, dependency, type="sbom") + + return self._sbom_components + class Package: """ diff --git a/cachito/web/static/api_v1.yaml b/cachito/web/static/api_v1.yaml index 4bbba7e69..8411d411b 100644 --- a/cachito/web/static/api_v1.yaml +++ b/cachito/web/static/api_v1.yaml @@ -665,6 +665,35 @@ paths: error: type: string example: "Request 1 is in state in_progress, not complete or stale." + "/sbom": + get: + summary: Get the sbom of multiple requests + description: Return the sbom of the specified Cachito requests + parameters: + - name: requests + in: query + required: false + description: The comma separated IDs of the Cachito requests to retrieve the sbom for + schema: + type: string + example: [1,2,3] + responses: + "200": + description: The sbom of the Cachito requests + content: + application/json: + schema: + $ref: "#/components/schemas/Sbom" + "400": + description: Any of the input Cachito request id is invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: "Request 1 is in state in_progress, not complete or stale." "/request-metrics": get: summary: List requests with a final state information @@ -1248,6 +1277,34 @@ components: properties: purl: $ref: "#/components/schemas/Purl" + Sbom: + type: object + properties: + bomFormat: + type: string + example: "CycloneDX" + specVersion: + type: string + example: "1.4" + version: + type: integer + example: 1 + components: + type: array + items: + type: object + properties: + type: + type: string + example: "library" + name: + type: string + example: "vim" + version: + type: string + example: "9.0" + purl: + $ref: "#/components/schemas/Purl" RequestState: type: string example: in_progress diff --git a/docs/metadata.md b/docs/metadata.md index 05489786f..4a49c0d5e 100644 --- a/docs/metadata.md +++ b/docs/metadata.md @@ -579,12 +579,71 @@ Any Golang repository processed by Cachito will contain both modules and package [go-package type][go-package-type]). The Content Manifest lists only the packages. That is usually good enough. Modules for dependencies *are* listed in [sources](#sources). +## SBOM + +The SBOM (full name Software bill of materials) is a document that describes the +content present in a container image and it is in CycloneDx format. +It contains all components (packages and dependencies) for specified requests. +A JSON Schema specification is available in the +CycloneDX repository): [sbom.json]. +Purl follows the same rules as in Content Manifest. + +The document returned from the +`/api/v1/sbom?requests={id1},{id2},..` endpoint conforms to the schema. + +
+Example + +SBOM for [cachito-yarn-lorem-ipsum@bootstrap-yarn][cachito-yarn-lorem-ipsum] + +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "components": [ + { + "name": "axios", + "version": "0.21.1", + "purl": "pkg:npm/axios@0.21.1", + "type": "library", + }, + { + "name": "follow-redirects", + "version": "1.14.0", + "purl": "pkg:npm/follow-redirects@1.14.0", + "type": "library", + }, + { + "name": "lorem-ipsum", + "version": "1.0.0", + "purl": "pkg:github/cachito-testing/cachito-yarn-lorem-ipsum@b470410e50caff0447bc18ca4f011663681e7e17", + "type": "library", + }, + { + "name": "yarn", + "version": "1.22.10", + "purl": "pkg:npm/yarn@1.22.10", + "type": "library", + }, + { + "name": "bootstrap-yarn", + "version": "1.0.0", + "purl": "pkg:github/cachito-testing/cachito-yarn-lorem-ipsum@b470410e50caff0447bc18ca4f011663681e7e17#bootstrap-yarn", + "type": "library", + }, + ] +} +``` +
+ [cachito-yarn-lorem-ipsum]: https://github.com/cachito-testing/cachito-yarn-lorem-ipsum/tree/b470410e50caff0447bc18ca4f011663681e7e17 [go-package-type]: ../README.md#go-package-level-dependencies-and-the-go-package-cachito-package-type [feature-support]: ../README.md#feature-support [gomod-replace]: https://golang.org/ref/mod#go-mod-file-replace [atomic-reactor]: https://github.com/containerbuildsystem/atomic-reactor [content_manifest.json]: https://github.com/containerbuildsystem/atomic-reactor/blob/master/atomic_reactor/schemas/content_manifest.json +[sbom.json]: https://raw.githubusercontent.com/CycloneDX/specification/1.4/schema/bom-1.4.schema.json [OSBS]: https://osbs.readthedocs.io [purl-spec]: https://github.com/package-url/purl-spec [openshift-apiserver]: https://github.com/openshift/kubernetes-apiserver diff --git a/tests/integration/test_content_manifest.py b/tests/integration/test_content_manifest.py index 2768140b3..b4f62c854 100644 --- a/tests/integration/test_content_manifest.py +++ b/tests/integration/test_content_manifest.py @@ -1,9 +1,12 @@ # SPDX-License-Identifier: GPL-3.0-or-later +from typing import Any, Dict + import pytest import requests from . import utils +from .conftest import DefaultRequest def test_invalid_content_manifest_request(test_env): @@ -39,3 +42,44 @@ def test_valid_content_manifest_request(test_env, default_requests): response_data = content_manifest_response.data utils.assert_content_manifest_schema(response_data) + + +def test_invalid_sbom_request(test_env: Dict[str, Any]) -> None: + """ + Send an invalid sbom request to the Cachito API. + + Checks: + * Check that the response code is 400 + """ + client = utils.Client(test_env["api_url"], test_env["api_auth_type"], test_env.get("timeout")) + + with pytest.raises(requests.HTTPError) as e: + client.fetch_sbom(request_ids=0) + assert e.value.response.status_code == 400 + assert e.value.response.json() == {"error": "Cannot find request(s) 0."} + + +def test_valid_sbom_request( + test_env: Dict[str, Any], default_requests: Dict[str, DefaultRequest] +) -> None: + """ + Send a valid sbom request to the Cachito API. + + Checks: + * Check that the response code is 200 + * Check validation of the response data with content manifest JSON schema + """ + client = utils.Client(test_env["api_url"], test_env["api_auth_type"], test_env.get("timeout")) + + pkg_managers = test_env["content_manifest"]["pkg_managers"] + + request_ids = [] + for pkg_manager in pkg_managers: + initial_response = default_requests[pkg_manager].initial_response + request_ids.append(initial_response.id) + + sbom_response = client.fetch_sbom(",".join(map(str, request_ids))) + assert sbom_response.status == 200 + + response_data = sbom_response.data + utils.assert_sbom_schema(response_data) diff --git a/tests/integration/test_data/git_submodule_packages.yaml b/tests/integration/test_data/git_submodule_packages.yaml index 566f73f0a..4baf58053 100644 --- a/tests/integration/test_data/git_submodule_packages.yaml +++ b/tests/integration/test_data/git_submodule_packages.yaml @@ -23,3 +23,8 @@ git_submodule_no_master_branch: version: https://github.com/cachito-testing/repo-no-master-branch.git#309749e2ef8755319cb4f7dd5faa8f2fbdacda70 content_manifest: - purl: "pkg:github/cachito-testing/repo-no-master-branch@309749e2ef8755319cb4f7dd5faa8f2fbdacda70" + sbom: + - name: repo-no-master-branch + type: library + version: https://github.com/cachito-testing/repo-no-master-branch.git#309749e2ef8755319cb4f7dd5faa8f2fbdacda70 + purl: pkg:github/cachito-testing/repo-no-master-branch@309749e2ef8755319cb4f7dd5faa8f2fbdacda70 diff --git a/tests/integration/test_data/go_generate_packages.yaml b/tests/integration/test_data/go_generate_packages.yaml index d7c8f075b..2155f9eb0 100644 --- a/tests/integration/test_data/go_generate_packages.yaml +++ b/tests/integration/test_data/go_generate_packages.yaml @@ -673,6 +673,159 @@ go_generate: - "pkg:golang/unicode%2Futf8" - "pkg:golang/unsafe" purl: "pkg:golang/github.com%2Fcachito-testing%2Fgo-generate@v0.0.0-20211021002400-45a57f36d5e8" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: encoding + type: library + purl: pkg:golang/encoding + - name: encoding/base64 + type: library + purl: pkg:golang/encoding%2Fbase64 + - name: encoding/binary + type: library + purl: pkg:golang/encoding%2Fbinary + - name: encoding/json + type: library + purl: pkg:golang/encoding%2Fjson + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/go-generate/internal/generate + type: library + version: v0.0.0-20211021002400-45a57f36d5e8 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate%2Finternal%2Fgenerate@v0.0.0-20211021002400-45a57f36d5e8 + - name: github.com/cachito-testing/go-generate + type: library + version: v0.0.0-20211021002400-45a57f36d5e8 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate@v0.0.0-20211021002400-45a57f36d5e8 + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: io/ioutil + type: library + purl: pkg:golang/io%2Fioutil + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf16 + type: library + purl: pkg:golang/unicode%2Futf16 + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe go_generate_generated: repo: https://github.com/cachito-testing/go-generate-generated.git ref: 35e24a2ce7d77f7e2adb83c61b26b9e0cf5cf420 @@ -1539,6 +1692,163 @@ go_generate_generated: - "pkg:golang/unicode%2Futf8" - "pkg:golang/unsafe" purl: "pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-generated@v0.0.0-20211021002827-35e24a2ce7d7" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: encoding + type: library + purl: pkg:golang/encoding + - name: encoding/base64 + type: library + purl: pkg:golang/encoding%2Fbase64 + - name: encoding/binary + type: library + purl: pkg:golang/encoding%2Fbinary + - name: encoding/json + type: library + purl: pkg:golang/encoding%2Fjson + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/go-generate-generated/foobar + type: library + version: v0.0.0-20211021002827-35e24a2ce7d7 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-generated%2Ffoobar@v0.0.0-20211021002827-35e24a2ce7d7 + - name: github.com/cachito-testing/go-generate-generated/internal/generate + type: library + version: v0.0.0-20211021002827-35e24a2ce7d7 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-generated%2Finternal%2Fgenerate@v0.0.0-20211021002827-35e24a2ce7d7 + - name: github.com/cachito-testing/go-generate-generated + type: library + version: v0.0.0-20211021002827-35e24a2ce7d7 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-generated@v0.0.0-20211021002827-35e24a2ce7d7 + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: io/ioutil + type: library + purl: pkg:golang/io%2Fioutil + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf16 + type: library + purl: pkg:golang/unicode%2Futf16 + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe go_generate_imported: repo: https://github.com/cachito-testing/go-generate-imported.git ref: 56659413f7db4f5feed9bbde4560cb55fbb85d67 @@ -2067,6 +2377,163 @@ go_generate_imported: - "pkg:golang/runtime%2Finternal%2Fsys" - "pkg:golang/runtime%2Finternal%2Fsyscall" - "pkg:golang/unsafe" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: encoding + type: library + purl: pkg:golang/encoding + - name: encoding/base64 + type: library + purl: pkg:golang/encoding%2Fbase64 + - name: encoding/binary + type: library + purl: pkg:golang/encoding%2Fbinary + - name: encoding/json + type: library + purl: pkg:golang/encoding%2Fjson + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/go-generate-imported/foobar + type: library + version: v0.0.0-20211021010705-56659413f7db + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported%2Ffoobar@v0.0.0-20211021010705-56659413f7db + - name: github.com/cachito-testing/go-generate-imported/internal/generate + type: library + version: v0.0.0-20211021010705-56659413f7db + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported%2Finternal%2Fgenerate@v0.0.0-20211021010705-56659413f7db + - name: github.com/cachito-testing/go-generate-imported + type: library + version: v0.0.0-20211021010705-56659413f7db + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported@v0.0.0-20211021010705-56659413f7db + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: io/ioutil + type: library + purl: pkg:golang/io%2Fioutil + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf16 + type: library + purl: pkg:golang/unicode%2Futf16 + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe go_generate_imported_generated: repo: https://github.com/cachito-testing/go-generate-imported-generated.git ref: 27ad22ae910c3282fb09bfc7f8b6334f56bd06d9 @@ -2735,3 +3202,160 @@ go_generate_imported_generated: - "pkg:golang/unicode" - "pkg:golang/unicode%2Futf8" - "pkg:golang/unsafe" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: encoding + type: library + purl: pkg:golang/encoding + - name: encoding/base64 + type: library + purl: pkg:golang/encoding%2Fbase64 + - name: encoding/binary + type: library + purl: pkg:golang/encoding%2Fbinary + - name: encoding/json + type: library + purl: pkg:golang/encoding%2Fjson + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/go-generate-imported-generated/foobar + type: library + version: v0.0.0-20211021013725-27ad22ae910c + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported-generated%2Ffoobar@v0.0.0-20211021013725-27ad22ae910c + - name: github.com/cachito-testing/go-generate-imported-generated/internal/generate + type: library + version: v0.0.0-20211021013725-27ad22ae910c + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported-generated%2Finternal%2Fgenerate@v0.0.0-20211021013725-27ad22ae910c + - name: github.com/cachito-testing/go-generate-imported-generated + type: library + version: v0.0.0-20211021013725-27ad22ae910c + purl: pkg:golang/github.com%2Fcachito-testing%2Fgo-generate-imported-generated@v0.0.0-20211021013725-27ad22ae910c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: io/ioutil + type: library + purl: pkg:golang/io%2Fioutil + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf16 + type: library + purl: pkg:golang/unicode%2Futf16 + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe diff --git a/tests/integration/test_data/gomod_packages.yaml b/tests/integration/test_data/gomod_packages.yaml index bb6a6c11f..0676af5c3 100644 --- a/tests/integration/test_data/gomod_packages.yaml +++ b/tests/integration/test_data/gomod_packages.yaml @@ -26,6 +26,11 @@ without_deps: deps/gomod/pkg/mod/cache/download: null content_manifest: - purl: "pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a" + sbom: + - name: github.com/cachito-testing/cachito-gomod-without-deps + type: library + version: v0.0.0-20200925115855-a888f7261b9a + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a # same as above but uses the gomod-vendor-check flag to test how Cachito # behaves when vendoring is requested but there is nothing to vendor without_deps_vendor_check: @@ -49,6 +54,11 @@ without_deps_vendor_check: deps/gomod/pkg/mod/cache/download: null content_manifest: - purl: "pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a" + sbom: + - name: github.com/cachito-testing/cachito-gomod-without-deps + type: library + version: v0.0.0-20200925115855-a888f7261b9a + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a with_deps: repo: https://github.com/cachito-testing/cachito-gomod-with-deps.git ref: 4c65d49cae6bfbada4d479b321d8c0109fa1aa97 @@ -512,6 +522,157 @@ with_deps: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/cachito-gomod-with-deps + type: library + version: v0.0.0-20201001160613-4c65d49cae6b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-with-deps@v0.0.0-20201001160613-4c65d49cae6b + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe # The test data for gomod package with vendor directory # and with `gomod-vendor` flag. vendored_with_flag: @@ -978,6 +1139,157 @@ vendored_with_flag: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/gomod-vendored + type: library + version: v0.0.0-20200916135625-ff1960095dd1 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgomod-vendored@v0.0.0-20200916135625-ff1960095dd1 + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe # The test data for gomod package with vendor directory # and without `gomod-vendor` flag. vendored_without_flag: @@ -1447,6 +1759,157 @@ implicit_gomod: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/cachito-gomod-with-deps + type: library + version: v0.0.0-20201001160613-4c65d49cae6b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-with-deps@v0.0.0-20201001160613-4c65d49cae6b + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe # The test data for gomod package manager test: missing go.mod file missing_gomod: repo: https://github.com/cachito-testing/cachito-missing-gomod-file.git @@ -1459,6 +1922,7 @@ missing_gomod: app: https://github.com/cachito-testing/cachito-missing-gomod-file/tarball/0ae32a94a2a4f17b6702f8dddb1ddb88154f4473 deps: null content_manifest: [] + sbom: [] # gomod package without dependencies and with force-gomod-tidy flag # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -1488,6 +1952,11 @@ force_tidy_without_deps: deps/gomod/pkg/mod/cache/download: null content_manifest: - purl: "pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a" + sbom: + - name: github.com/cachito-testing/cachito-gomod-without-deps + type: library + version: v0.0.0-20200925115855-a888f7261b9a + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-without-deps@v0.0.0-20200925115855-a888f7261b9a # The test data for gomod package with vendor directory and with force-gomod-tidy flag force_tidy_vendored: repo: https://github.com/cachito-testing/gomod-vendored.git @@ -1953,6 +2422,157 @@ force_tidy_vendored: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/gomod-vendored + type: library + version: v0.0.0-20200916135625-ff1960095dd1 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgomod-vendored@v0.0.0-20200916135625-ff1960095dd1 + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe symlink_loop: repo: https://github.com/cachito-testing/cachito-gomod-symlink-loop.git ref: 2448c37cc276b5d0db613ec58178c30810bb045c @@ -1973,6 +2593,11 @@ symlink_loop: deps/gomod/pkg/mod/cache/download: null content_manifest: - purl: "pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-symlink-loop@v0.0.0-20220712180726-2448c37cc276" + sbom: + - name: github.com/cachito-testing/cachito-gomod-symlink-loop + type: library + version: v0.0.0-20220712180726-2448c37cc276 + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-symlink-loop@v0.0.0-20220712180726-2448c37cc276 # gomod package without package manager and dependencies # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -1992,6 +2617,7 @@ without_pkg_manager: app: https://github.com/cachito-testing/cachito-gomod-without-deps/tarball/a888f7261b9a9683972fbd77da2d12fe86faef5e deps: null content_manifest: [] + sbom: [] # The test data for gomod package manager test: check for Go workspaces with_workspace: repo: https://github.com/cachito-testing/cachito-gomod-with-workspace.git @@ -2704,3 +3330,168 @@ with_local_replacements_in_parent_dir: - pkg:golang/unsafe purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0 source_purls: [] + sbom: + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/baz-package + type: library + version: v1.0.0 + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Fbaz-package@v1.0.0 + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/foo-module/bar-module/bar-package + type: library + version: v0.0.0-20230131175254-651e1901735b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Ffoo-module%2Fbar-module%2Fbar-package@v0.0.0-20230131175254-651e1901735b + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/foo-module/bar-module + type: library + version: ./foo-package/../bar-module + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Ffoo-module%2Fbar-module@v0.0.0-20230131175254-651e1901735b + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/foo-module/bar-module + type: library + version: v0.0.0-20230131175254-651e1901735b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Ffoo-module%2Fbar-module@v0.0.0-20230131175254-651e1901735b + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/foo-module/foo-package + type: library + version: v0.0.0-20230131175254-651e1901735b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Ffoo-module%2Ffoo-package@v0.0.0-20230131175254-651e1901735b + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps/foo-module + type: library + version: v0.0.0-20230131175254-651e1901735b + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps%2Ffoo-module@v0.0.0-20230131175254-651e1901735b + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps + type: library + version: ../ + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0 + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps + type: library + version: ../../ + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0 + - name: github.com/cachito-testing/cachito-gomod-local-parent-deps + type: library + version: v1.0.0 + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0 + - name: github.com/cachito-testing/spam-module + type: library + version: ../staging/src/spam-module + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0#staging/src/spam-module + - name: github.com/cachito-testing/spam-module/spam + type: library + version: ../staging/src/spam-module/spam + purl: pkg:golang/github.com%2Fcachito-testing%2Fcachito-gomod-local-parent-deps@v1.0.0#staging/src/spam-module/spam + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe \ No newline at end of file diff --git a/tests/integration/test_data/gomod_vendor_check.yaml b/tests/integration/test_data/gomod_vendor_check.yaml index 5c5e50725..df19119d1 100644 --- a/tests/integration/test_data/gomod_vendor_check.yaml +++ b/tests/integration/test_data/gomod_vendor_check.yaml @@ -479,6 +479,157 @@ correct_vendor: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/gomod-vendor-check-pass + type: library + version: v0.0.0-20210802173203-0543a5034b68 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgomod-vendor-check-pass@v0.0.0-20210802173203-0543a5034b68 + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe no_vendor: repo: https://github.com/cachito-testing/gomod-vendor-check-no-vendor.git ref: 7ba383d5592910edbf7f287d4b5a00c5ababf751 @@ -942,3 +1093,154 @@ no_vendor: - "pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c" - "pkg:golang/rsc.io%2Fquote@v1.5.2" - "pkg:golang/rsc.io%2Fsampler@v1.3.0" + sbom: + - name: bytes + type: library + purl: pkg:golang/bytes + - name: errors + type: library + purl: pkg:golang/errors + - name: fmt + type: library + purl: pkg:golang/fmt + - name: github.com/cachito-testing/gomod-vendor-check-pass + type: library + version: v0.0.0-20210802184302-7ba383d55929 + purl: pkg:golang/github.com%2Fcachito-testing%2Fgomod-vendor-check-pass@v0.0.0-20210802184302-7ba383d55929 + - name: golang.org/x/text/internal/tag + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Finternal%2Ftag@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text/language + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext%2Flanguage@v0.0.0-20170915032832-14c0d48ead0c + - name: golang.org/x/text + type: library + version: v0.0.0-20170915032832-14c0d48ead0c + purl: pkg:golang/golang.org%2Fx%2Ftext@v0.0.0-20170915032832-14c0d48ead0c + - name: internal/abi + type: library + purl: pkg:golang/internal%2Fabi + - name: internal/bytealg + type: library + purl: pkg:golang/internal%2Fbytealg + - name: internal/cpu + type: library + purl: pkg:golang/internal%2Fcpu + - name: internal/fmtsort + type: library + purl: pkg:golang/internal%2Ffmtsort + - name: internal/goarch + type: library + purl: pkg:golang/internal%2Fgoarch + - name: internal/goexperiment + type: library + purl: pkg:golang/internal%2Fgoexperiment + - name: internal/goos + type: library + purl: pkg:golang/internal%2Fgoos + - name: internal/itoa + type: library + purl: pkg:golang/internal%2Fitoa + - name: internal/oserror + type: library + purl: pkg:golang/internal%2Foserror + - name: internal/poll + type: library + purl: pkg:golang/internal%2Fpoll + - name: internal/race + type: library + purl: pkg:golang/internal%2Frace + - name: internal/reflectlite + type: library + purl: pkg:golang/internal%2Freflectlite + - name: internal/safefilepath + type: library + purl: pkg:golang/internal%2Fsafefilepath + - name: internal/syscall/execenv + type: library + purl: pkg:golang/internal%2Fsyscall%2Fexecenv + - name: internal/syscall/unix + type: library + purl: pkg:golang/internal%2Fsyscall%2Funix + - name: internal/testlog + type: library + purl: pkg:golang/internal%2Ftestlog + - name: internal/unsafeheader + type: library + purl: pkg:golang/internal%2Funsafeheader + - name: io + type: library + purl: pkg:golang/io + - name: io/fs + type: library + purl: pkg:golang/io%2Ffs + - name: math + type: library + purl: pkg:golang/math + - name: math/bits + type: library + purl: pkg:golang/math%2Fbits + - name: os + type: library + purl: pkg:golang/os + - name: path + type: library + purl: pkg:golang/path + - name: reflect + type: library + purl: pkg:golang/reflect + - name: rsc.io/quote + type: library + version: v1.5.2 + purl: pkg:golang/rsc.io%2Fquote@v1.5.2 + - name: rsc.io/sampler + type: library + version: v1.3.0 + purl: pkg:golang/rsc.io%2Fsampler@v1.3.0 + - name: runtime + type: library + purl: pkg:golang/runtime + - name: runtime/internal/atomic + type: library + purl: pkg:golang/runtime%2Finternal%2Fatomic + - name: runtime/internal/math + type: library + purl: pkg:golang/runtime%2Finternal%2Fmath + - name: runtime/internal/sys + type: library + purl: pkg:golang/runtime%2Finternal%2Fsys + - name: runtime/internal/syscall + type: library + purl: pkg:golang/runtime%2Finternal%2Fsyscall + - name: sort + type: library + purl: pkg:golang/sort + - name: strconv + type: library + purl: pkg:golang/strconv + - name: strings + type: library + purl: pkg:golang/strings + - name: sync + type: library + purl: pkg:golang/sync + - name: sync/atomic + type: library + purl: pkg:golang/sync%2Fatomic + - name: syscall + type: library + purl: pkg:golang/syscall + - name: time + type: library + purl: pkg:golang/time + - name: unicode + type: library + purl: pkg:golang/unicode + - name: unicode/utf8 + type: library + purl: pkg:golang/unicode%2Futf8 + - name: unsafe + type: library + purl: pkg:golang/unsafe \ No newline at end of file diff --git a/tests/integration/test_data/npm_packages.yaml b/tests/integration/test_data/npm_packages.yaml index 564c71d77..a72f6c3c1 100644 --- a/tests/integration/test_data/npm_packages.yaml +++ b/tests/integration/test_data/npm_packages.yaml @@ -23,6 +23,11 @@ without_deps: version: "1.0.0" content_manifest: - purl: "pkg:github/cachito-testing/cachito-npm-without-deps@2f0ce1d7b1f8b35572d919428b965285a69583f6" + sbom: + - name: cachito-npm-without-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-npm-without-deps@2f0ce1d7b1f8b35572d919428b965285a69583f6 # npm package with dependencies package.json # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -175,6 +180,51 @@ with_deps: - "pkg:npm/get-func-name@2.0.0" - "pkg:npm/pathval@1.1.1" - "pkg:npm/type-detect@4.0.8" + sbom: + - name: cachito-npm-without-deps + type: library + version: git+https://github.com/cachito-testing/cachito-npm-without-deps.git#2f0ce1d7b1f8b35572d919428b965285a69583f6 + purl: pkg:generic/cachito-npm-without-deps?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Fcachito-testing%2Fcachito-npm-without-deps.git%232f0ce1d7b1f8b35572d919428b965285a69583f6 + - name: fecha + type: library + version: https://github.com/taylorhakes/fecha/archive/91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz + purl: pkg:generic/fecha?download_url=https%3A%2F%2Fgithub.com%2Ftaylorhakes%2Ffecha%2Farchive%2F91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz + - name: cachito-npm-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-npm-with-deps@565aba4c7f210c6196c1b522e2279f853f77d6d2 + - name: is-positive + type: library + version: github:kevva/is-positive#97edff6f525f192a3f83cea1944765f769ae2678 + purl: pkg:github/kevva/is-positive@97edff6f525f192a3f83cea1944765f769ae2678 + - name: assertion-error + type: library + version: 1.1.0 + purl: pkg:npm/assertion-error@1.1.0 + - name: chai + type: library + version: 4.2.0 + purl: pkg:npm/chai@4.2.0 + - name: check-error + type: library + version: 1.0.2 + purl: pkg:npm/check-error@1.0.2 + - name: deep-eql + type: library + version: 3.0.1 + purl: pkg:npm/deep-eql@3.0.1 + - name: get-func-name + type: library + version: 2.0.0 + purl: pkg:npm/get-func-name@2.0.0 + - name: pathval + type: library + version: 1.1.1 + purl: pkg:npm/pathval@1.1.1 + - name: type-detect + type: library + version: 4.0.8 + purl: pkg:npm/type-detect@4.0.8 # With npm git-submodule git_submodule: repo: https://github.com/cachito-testing/git-submodule-npm.git @@ -329,6 +379,55 @@ git_submodule: - "pkg:npm/get-func-name@2.0.0" - "pkg:npm/pathval@1.1.1" - "pkg:npm/type-detect@4.0.8" + sbom: + - name: cachito-npm-without-deps + type: library + version: git+https://github.com/cachito-testing/cachito-npm-without-deps.git#2f0ce1d7b1f8b35572d919428b965285a69583f6 + purl: pkg:generic/cachito-npm-without-deps?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Fcachito-testing%2Fcachito-npm-without-deps.git%232f0ce1d7b1f8b35572d919428b965285a69583f6 + - name: fecha + type: library + version: https://github.com/taylorhakes/fecha/archive/91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz + purl: pkg:generic/fecha?download_url=https%3A%2F%2Fgithub.com%2Ftaylorhakes%2Ffecha%2Farchive%2F91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz + - name: cachito-npm-with-deps + type: library + version: https://github.com/cachito-testing/cachito-npm-with-deps.git#565aba4c7f210c6196c1b522e2279f853f77d6d2 + purl: pkg:github/cachito-testing/cachito-npm-with-deps@565aba4c7f210c6196c1b522e2279f853f77d6d2 + - name: cachito-npm-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/git-submodule-npm@a209a89d1b88b757cd7dfd19bb2d96dd979398d6#cachito-npm-with-deps + - name: is-positive + type: library + version: github:kevva/is-positive#97edff6f525f192a3f83cea1944765f769ae2678 + purl: pkg:github/kevva/is-positive@97edff6f525f192a3f83cea1944765f769ae2678 + - name: assertion-error + type: library + version: 1.1.0 + purl: pkg:npm/assertion-error@1.1.0 + - name: chai + type: library + version: 4.2.0 + purl: pkg:npm/chai@4.2.0 + - name: check-error + type: library + version: 1.0.2 + purl: pkg:npm/check-error@1.0.2 + - name: deep-eql + type: library + version: 3.0.1 + purl: pkg:npm/deep-eql@3.0.1 + - name: get-func-name + type: library + version: 2.0.0 + purl: pkg:npm/get-func-name@2.0.0 + - name: pathval + type: library + version: 1.1.1 + purl: pkg:npm/pathval@1.1.1 + - name: type-detect + type: library + version: 4.0.8 + purl: pkg:npm/type-detect@4.0.8 # npm package for testing workspaces # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -365,3 +464,12 @@ workspaces: - "pkg:npm/abbrev@1.1.1" source_purls: - "pkg:npm/abbrev@1.1.1" + sbom: + - name: npm_test + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-npm-workspaces@7a83936be7177246a549acf66ab8074ea4c0d6f5 + - name: abbrev + type: library + version: 1.1.1 + purl: pkg:npm/abbrev@1.1.1 diff --git a/tests/integration/test_data/pip_packages.yaml b/tests/integration/test_data/pip_packages.yaml index 551d5826c..6f803b24b 100644 --- a/tests/integration/test_data/pip_packages.yaml +++ b/tests/integration/test_data/pip_packages.yaml @@ -22,6 +22,11 @@ without_deps: version: "1.0.0" content_manifest: - purl: "pkg:github/cachito-testing/cachito-pip-without-deps@fb07c8492432631d557aba15e1715af9cef9c844" + sbom: + - name: cachito-pip-empty + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-pip-without-deps@fb07c8492432631d557aba15e1715af9cef9c844 # pip package with dependencies in requirements.txt # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -85,6 +90,23 @@ with_deps: - "pkg:generic/appr?download_url=https%3A%2F%2Fgithub.com%2Fquay%2Fappr%2Farchive%2F37ff9a487a54ad41b59855ecd76ee092fe206a84.zip%23egg%3Dappr%26cachito_hash%3Dsha256%3Aee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c&checksum=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c" - "pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b" - "pkg:pypi/aiowsgi@0.7" + sbom: + - name: appr + type: library + version: https://github.com/quay/appr/archive/37ff9a487a54ad41b59855ecd76ee092fe206a84.zip#egg=appr&cachito_hash=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + purl: pkg:generic/appr?download_url=https%3A%2F%2Fgithub.com%2Fquay%2Fappr%2Farchive%2F37ff9a487a54ad41b59855ecd76ee092fe206a84.zip%23egg%3Dappr%26cachito_hash%3Dsha256%3Aee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c&checksum=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + - name: cachito-pip-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-pip-with-deps@83b387568b6287f6829403cff1e1377b0fb2f5d8 + - name: appr + type: library + version: git+https://github.com/quay/appr.git@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + purl: pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + - name: aiowsgi + type: library + version: "0.7" + purl: pkg:pypi/aiowsgi@0.7 # pip package with local path # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -166,6 +188,27 @@ multiple: - "pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b" source_purls: - "pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b" + sbom: + - name: appr + type: library + version: https://github.com/quay/appr/archive/37ff9a487a54ad41b59855ecd76ee092fe206a84.zip#egg=appr&cachito_hash=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + purl: pkg:generic/appr?download_url=https%3A%2F%2Fgithub.com%2Fquay%2Fappr%2Farchive%2F37ff9a487a54ad41b59855ecd76ee092fe206a84.zip%23egg%3Dappr%26cachito_hash%3Dsha256%3Aee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c&checksum=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + - name: first_pkg + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-pip-multiple@93c6c44b36075454a509d595850b81be29e53db0#first_pkg + - name: second_pkg + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-pip-multiple@93c6c44b36075454a509d595850b81be29e53db0#second_pkg + - name: appr + type: library + version: git+https://github.com/quay/appr.git@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + purl: pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + - name: aiowsgi + type: library + version: "0.7" + purl: pkg:pypi/aiowsgi@0.7 # With pip git-submodule git_submodule: repo: https://github.com/cachito-testing/git-submodule-pip.git @@ -232,3 +275,24 @@ git_submodule: - "pkg:generic/appr?download_url=https%3A%2F%2Fgithub.com%2Fquay%2Fappr%2Farchive%2F37ff9a487a54ad41b59855ecd76ee092fe206a84.zip%23egg%3Dappr%26cachito_hash%3Dsha256%3Aee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c&checksum=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c" - "pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b" - "pkg:pypi/aiowsgi@0.7" + sbom: + - name: appr + type: library + version: https://github.com/quay/appr/archive/37ff9a487a54ad41b59855ecd76ee092fe206a84.zip#egg=appr&cachito_hash=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + purl: pkg:generic/appr?download_url=https%3A%2F%2Fgithub.com%2Fquay%2Fappr%2Farchive%2F37ff9a487a54ad41b59855ecd76ee092fe206a84.zip%23egg%3Dappr%26cachito_hash%3Dsha256%3Aee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c&checksum=sha256:ee6a0a38bed8cff46a562ed3620bc453141a02262ab0c8dd055824af2829ee5c + - name: cachito-pip-with-deps + type: library + version: https://github.com/cachito-testing/cachito-pip-with-deps.git#56efa5f7eb4ff1b7ea1409dbad76f5bb378291e6 + purl: pkg:github/cachito-testing/cachito-pip-with-deps@56efa5f7eb4ff1b7ea1409dbad76f5bb378291e6 + - name: cachito-pip-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/git-submodule-pip@6ff2f48835a224c0b170c2c79f48d8507aed89d7#cachito-pip-with-deps + - name: appr + type: library + version: git+https://github.com/quay/appr.git@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + purl: pkg:github/quay/appr@58c88e4952e95935c0dd72d4a24b0c44f2249f5b + - name: aiowsgi + type: library + version: "0.7" + purl: pkg:pypi/aiowsgi@0.7 diff --git a/tests/integration/test_data/rubygems_packages.yaml b/tests/integration/test_data/rubygems_packages.yaml index f8dc26abd..fcab6e896 100644 --- a/tests/integration/test_data/rubygems_packages.yaml +++ b/tests/integration/test_data/rubygems_packages.yaml @@ -22,6 +22,11 @@ without_deps: version: "4f1ca077899d42064d097dad90f3565fbf4e1ce7" content_manifest: - purl: "pkg:github/cachito-testing/cachito-rubygems-without-deps@4f1ca077899d42064d097dad90f3565fbf4e1ce7" + sbom: + - name: cachito-rubygems-without-deps + type: library + version: 4f1ca077899d42064d097dad90f3565fbf4e1ce7 + purl: pkg:github/cachito-testing/cachito-rubygems-without-deps@4f1ca077899d42064d097dad90f3565fbf4e1ce7 # RubyGems package with GEM, GIT and PATH dependencies in Gemfile and Gemfile.lock # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -78,6 +83,23 @@ with_deps: - "pkg:gem/zeitwerk@2.6.0" - "pkg:github/cachito-testing/cachito-rubygems-with-dependencies@ef6b2d7f9e4719be204531639a3ab90cfd731f26#vendor/pathgem" - "pkg:github/radpad/swagger-ui_rails@7234e21e621b628d6b43194f9ba5cce5ca587f16" + sbom: + - name: zeitwerk + type: library + version: 2.6.0 + purl: pkg:gem/zeitwerk@2.6.0 + - name: cachito-rubygems-with-dependencies + type: library + version: ef6b2d7f9e4719be204531639a3ab90cfd731f26 + purl: pkg:github/cachito-testing/cachito-rubygems-with-dependencies@ef6b2d7f9e4719be204531639a3ab90cfd731f26 + - name: pathgem + type: library + version: ./vendor/pathgem + purl: pkg:github/cachito-testing/cachito-rubygems-with-dependencies@ef6b2d7f9e4719be204531639a3ab90cfd731f26#vendor/pathgem + - name: swagger-ui_rails + type: library + version: git+https://github.com/RadPad/swagger-ui_rails.git@7234e21e621b628d6b43194f9ba5cce5ca587f16 + purl: pkg:github/radpad/swagger-ui_rails@7234e21e621b628d6b43194f9ba5cce5ca587f16 # Multiple RubyGems packages # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -135,3 +157,20 @@ multiple: - "pkg:gem/tilt@2.0.11" source_purls: - "pkg:gem/tilt@2.0.11" + sbom: + - name: tilt + type: library + version: 2.0.11 + purl: pkg:gem/tilt@2.0.11 + - name: cachito-rubygems-multiple/first_pkg + type: library + version: d5f91c54a8b35c3f2bdcf9a602184022b003ed75 + purl: pkg:github/cachito-testing/cachito-rubygems-multiple@d5f91c54a8b35c3f2bdcf9a602184022b003ed75#first_pkg + - name: pathgem + type: library + version: ./vendor/pathgem + purl: pkg:github/cachito-testing/cachito-rubygems-multiple@d5f91c54a8b35c3f2bdcf9a602184022b003ed75#first_pkg/vendor/pathgem + - name: cachito-rubygems-multiple/second_pkg + type: library + version: d5f91c54a8b35c3f2bdcf9a602184022b003ed75 + purl: pkg:github/cachito-testing/cachito-rubygems-multiple@d5f91c54a8b35c3f2bdcf9a602184022b003ed75#second_pkg diff --git a/tests/integration/test_data/yarn_packages.yaml b/tests/integration/test_data/yarn_packages.yaml index 202f5392c..0843ba450 100644 --- a/tests/integration/test_data/yarn_packages.yaml +++ b/tests/integration/test_data/yarn_packages.yaml @@ -23,6 +23,11 @@ without_deps: version: "1.0.0" content_manifest: - purl: "pkg:github/cachito-testing/cachito-yarn-without-deps@da0a2888aa7aab37fec34c0b36d9e44560d2cf3e" + sbom: + - name: cachito-yarn-without-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-yarn-without-deps@da0a2888aa7aab37fec34c0b36d9e44560d2cf3e # yarn package with dependencies package.json # repo: The URL for the upstream git repository # ref: A git reference at the given git repository @@ -175,6 +180,51 @@ with_deps: - "pkg:npm/is-positive@3.1.0" - "pkg:npm/pathval@1.1.1" - "pkg:npm/type-detect@4.0.8" + sbom: + - name: cachito-yarn-without-deps + type: library + version: git+https://github.com/cachito-testing/cachito-yarn-without-deps.git#da0a2888aa7aab37fec34c0b36d9e44560d2cf3e + purl: pkg:generic/cachito-yarn-without-deps?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Fcachito-testing%2Fcachito-yarn-without-deps.git%23da0a2888aa7aab37fec34c0b36d9e44560d2cf3e + - name: fecha + type: library + version: https://github.com/taylorhakes/fecha/archive/91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz#f09ea0b8115b9733dddc88227086c73ba4ddc926 + purl: pkg:generic/fecha?download_url=https%3A%2F%2Fgithub.com%2Ftaylorhakes%2Ffecha%2Farchive%2F91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz%23f09ea0b8115b9733dddc88227086c73ba4ddc926 + - name: cachito-yarn-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/cachito-yarn-with-deps@e1cc10b76c580cdd6cbdfc83bf1692503385447e + - name: assertion-error + type: library + version: 1.1.0 + purl: pkg:npm/assertion-error@1.1.0 + - name: chai + type: library + version: 4.2.0 + purl: pkg:npm/chai@4.2.0 + - name: check-error + type: library + version: 1.0.2 + purl: pkg:npm/check-error@1.0.2 + - name: deep-eql + type: library + version: 3.0.1 + purl: pkg:npm/deep-eql@3.0.1 + - name: get-func-name + type: library + version: 2.0.0 + purl: pkg:npm/get-func-name@2.0.0 + - name: is-positive + type: library + version: 3.1.0 + purl: pkg:npm/is-positive@3.1.0 + - name: pathval + type: library + version: 1.1.1 + purl: pkg:npm/pathval@1.1.1 + - name: type-detect + type: library + version: 4.0.8 + purl: pkg:npm/type-detect@4.0.8 # With yarn git-submodule git_submodule: repo: https://github.com/cachito-testing/git-submodule-yarn.git @@ -330,3 +380,52 @@ git_submodule: - "pkg:npm/is-positive@3.1.0" - "pkg:npm/pathval@1.1.1" - "pkg:npm/type-detect@4.0.8" + sbom: + - name: cachito-yarn-without-deps + type: library + version: git+https://github.com/cachito-testing/cachito-yarn-without-deps.git#da0a2888aa7aab37fec34c0b36d9e44560d2cf3e + purl: pkg:generic/cachito-yarn-without-deps?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Fcachito-testing%2Fcachito-yarn-without-deps.git%23da0a2888aa7aab37fec34c0b36d9e44560d2cf3e + - name: fecha + type: library + version: https://github.com/taylorhakes/fecha/archive/91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz#f09ea0b8115b9733dddc88227086c73ba4ddc926 + purl: pkg:generic/fecha?download_url=https%3A%2F%2Fgithub.com%2Ftaylorhakes%2Ffecha%2Farchive%2F91680e4db1415fea33eac878cfd889c80a7b55c7.tar.gz%23f09ea0b8115b9733dddc88227086c73ba4ddc926 + - name: cachito-yarn-with-deps + type: library + version: https://github.com/cachito-testing/cachito-yarn-with-deps.git#e1cc10b76c580cdd6cbdfc83bf1692503385447e + purl: pkg:github/cachito-testing/cachito-yarn-with-deps@e1cc10b76c580cdd6cbdfc83bf1692503385447e + - name: cachito-yarn-with-deps + type: library + version: 1.0.0 + purl: pkg:github/cachito-testing/git-submodule-yarn@7cbcabdf6fb506fe1e07a6e40f72a02293852565#cachito-yarn-with-deps + - name: assertion-error + type: library + version: 1.1.0 + purl: pkg:npm/assertion-error@1.1.0 + - name: chai + type: library + version: 4.2.0 + purl: pkg:npm/chai@4.2.0 + - name: check-error + type: library + version: 1.0.2 + purl: pkg:npm/check-error@1.0.2 + - name: deep-eql + type: library + version: 3.0.1 + purl: pkg:npm/deep-eql@3.0.1 + - name: get-func-name + type: library + version: 2.0.0 + purl: pkg:npm/get-func-name@2.0.0 + - name: is-positive + type: library + version: 3.1.0 + purl: pkg:npm/is-positive@3.1.0 + - name: pathval + type: library + version: 1.1.1 + purl: pkg:npm/pathval@1.1.1 + - name: type-detect + type: library + version: 4.0.8 + purl: pkg:npm/type-detect@4.0.8 diff --git a/tests/integration/test_packages.py b/tests/integration/test_packages.py index 6826e7008..409a075f4 100755 --- a/tests/integration/test_packages.py +++ b/tests/integration/test_packages.py @@ -108,3 +108,6 @@ def test_packages(env_package, env_name, test_env, tmpdir): {"dependencies": dep_purls, "purl": purl, "sources": source_purls} ) utils.assert_content_manifest(client, completed_response.id, image_contents) + + sbom_components = env_data.get("sbom") + utils.assert_sbom(client, completed_response.id, sbom_components) diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 48894c782..459a29181 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -12,6 +12,7 @@ from requests.packages.urllib3.util.retry import Retry from requests_kerberos import HTTPKerberosAuth +from cachito.web.content_manifest import SBOM_SCHEMA_URL from tests.helper_utils import assert_directories_equal Response = namedtuple("Response", "data id status") @@ -136,6 +137,18 @@ def fetch_content_manifest(self, request_id): resp.raise_for_status() return Response(resp.json(), request_id, resp.status_code) + def fetch_sbom(self, request_ids): + """ + Fetch a sbom for request_ids from the Cachito API. + + :param str request_ids: The IDs of the Cachito requests separated by ',' + :return: An object that contains the response from the Cachito API + :rtype: Response + """ + resp = self.requests_session.get(f"{self._cachito_api_url}/sbom?requests={request_ids}") + resp.raise_for_status() + return Response(resp.json(), request_ids, resp.status_code) + def fetch_request_metrics(self, **params) -> requests.Response: resp = self.requests_session.get(f"{self._cachito_api_url}/request-metrics", params=params) resp.raise_for_status() @@ -294,6 +307,15 @@ def assert_content_manifest_schema(response_data): ), f"ICM data not valid for schema at {response_data['metadata']['icm_spec']}: {response_data}" +def assert_sbom_schema(response_data): + """Validate sbom according with JSON schema.""" + requests_session = get_requests_session() + schema = requests_session.get(SBOM_SCHEMA_URL, timeout=30).json() + assert validate_json( + schema, response_data + ), f"SBOM data not valid for schema at {SBOM_SCHEMA_URL}: {response_data}" + + def assert_elements_from_response(response_data, expected_response_data): """ Check elements from the response data. @@ -429,6 +451,34 @@ def assert_content_manifest(client, request_id, image_contents): ) +def assert_sbom(client, request_id, sbom_components): + """ + Check that the sbom is successfully generated and contains correct content. + + Checks: + * Check that status of sbom request is 200 + * Validate sbom schema + * Check components from sbom + + :param Client client: the Cachito API client + :param int request_id: The Cachito request id + :param list sbom_components: expected components part from sbom + """ + sbom_response = client.fetch_sbom(request_ids=str(request_id)) + assert ( + sbom_response.status == 200 + ), f"#{sbom_response.id}: response status {sbom_response.status} != 200" + + response_data = sbom_response.data + assert_sbom_schema(response_data) + assert sbom_components == sbom_response.data["components"], ( + f"#{sbom_response.id}: components in response differs from test expectations." + f"\nResponse components: " + f"{json.dumps(sbom_response.data['components'], indent=4, sort_keys=True)}," + f"\nTest expectations: {json.dumps(sbom_components, indent=4, sort_keys=True)}" + ) + + def assert_properly_completed_response(completed_response): """ Check that the request completed successfully. diff --git a/tests/test_api_v1.py b/tests/test_api_v1.py index 6edbb4267..22e56424f 100644 --- a/tests/test_api_v1.py +++ b/tests/test_api_v1.py @@ -11,6 +11,7 @@ from unittest import mock import flask +import flask_sqlalchemy import kombu.exceptions import pytest @@ -18,7 +19,7 @@ from cachito.common.packages_data import PackagesData from cachito.common.paths import RequestBundleDir from cachito.errors import NoWorkers, RequestErrorOrigin, ValidationError -from cachito.web.content_manifest import BASE_ICM, Package +from cachito.web.content_manifest import BASE_ICM, BASE_SBOM, Package from cachito.web.models import ( ConfigFileBase64, EnvironmentVariable, @@ -2407,6 +2408,155 @@ def test_get_content_manifests_by_requests(app, client, db, auth_env, tmpdir): assert assembled_icm == json.loads(resp.data) +def test_get_content_manifests_sbom_by_requests( + app: flask.Flask, + client: flask.testing.FlaskClient, + db: flask_sqlalchemy.SQLAlchemy, + auth_env: Dict[str, Any], + tmpdir, +) -> None: + # create request objects + request_data = [ + ( + # request_json, request_state + { + "repo": "https://github.com/release-engineering/dummy.git", + "ref": "c50b93a32df1c9d700e3e80996845bc2e13be848", + "pkg_managers": ["npm"], + }, + RequestStateMapping.complete, + ), + ( + { + "repo": "https://github.com/release-engineering/dummy-foo.git", + "ref": "450b93a32df1c9d700e3e80996845bc2e13be848", + "pkg_managers": ["pip"], + }, + RequestStateMapping.complete, + ), + ( + { + "repo": "https://github.com/org/foo.git", + "ref": "c50b93a32df1c9d700e3e80996845bc2e13be848", + "pkg_managers": ["gomod"], + }, + RequestStateMapping.complete, + ), + ( + { + "repo": "https://github.com/release-engineering/dummy-bar.git", + "ref": "b50b93a32df1c9d700e3e80996845bc2e13be848", + "pkg_managers": ["npm"], + }, + RequestStateMapping.in_progress, + ), + ] + + requests = [] + + for item in request_data: + request_json = item[0] + state = item[1] + + with app.test_request_context(environ_base=auth_env): + request = Request.from_json(request_json) + + request.add_state(state.name, f"Set {state.name} directly for test") + db.session.add(request) + + requests.append(request) + + db.session.commit() + + # create packages json files + cachito_bundles_dir = str(tmpdir) + app.config["CACHITO_BUNDLES_DIR"] = cachito_bundles_dir + + package_data = [ + {"name": "pkg1", "version": "0.1", "type": "npm", "dependencies": []}, + {"name": "pkg2", "version": "0.3", "type": "pip", "dependencies": []}, + {"name": "pkg2", "version": "", "type": "gomod", "dependencies": []}, + {"name": "pkg3", "version": "0.2", "type": "npm", "dependencies": []}, + ] + + for i in range(len(package_data)): + to_write = [package_data[i]] + request_id = requests[i].id + + bundle_dir = RequestBundleDir(request_id, root=cachito_bundles_dir) + _write_test_packages_data(to_write, bundle_dir.packages_data) + + # define api call parameters and corresponding expected result data + pkg1 = Package.from_json(package_data[0]) + pkg2 = Package.from_json(package_data[1]) + pkg3 = Package.from_json(package_data[2]) + + test_data = [ + # requests, expected_image_contents + ["", []], + ["requests=", []], + [ + f"requests={requests[0].id}", + [ + { + "name": package_data[0]["name"], + "purl": to_top_level_purl(pkg1, requests[0]), + "version": package_data[0]["version"], + "type": "library", + }, + ], + ], + [ + f"requests={requests[0].id},,{requests[1].id},{requests[2].id}", + [ + { + "name": package_data[0]["name"], + "purl": to_top_level_purl(pkg1, requests[0]), + "version": package_data[0]["version"], + "type": "library", + }, + { + "name": package_data[1]["name"], + "purl": to_top_level_purl(pkg2, requests[1]), + "version": package_data[1]["version"], + "type": "library", + }, + { + "name": package_data[2]["name"], + "purl": to_top_level_purl(pkg3, requests[2]), + "type": "library", + }, + ], + ], + [ + f"requests={requests[3].id}", + f"Request {requests[3].id} is in state {requests[3].state.state_name}", + ], + [ + f"requests={requests[1].id},{requests[3].id}", + f"Request {requests[3].id} is in state {requests[3].state.state_name}", + ], + ["requests=a100", "a100 is not an integer"], + [ + f"requests={requests[0].id},{requests[1].id + 100}", + f"Cannot find request(s) {requests[1].id + 100}.", + ], + ] + + # run tests + for requests, expected_image_contents in test_data: + resp = client.get(f"/api/v1/sbom?{requests}") + if isinstance(expected_image_contents, str): + assert HTTPStatus.BAD_REQUEST == resp.status_code + assert expected_image_contents in resp.data.decode() + else: + assembled_sbom = copy.deepcopy(BASE_SBOM) + assembled_sbom["components"] = expected_image_contents + deep_sort_icm(assembled_sbom) + + assert json.loads(resp.data) == assembled_sbom + + @pytest.mark.parametrize( "querystring,expected_items_count,expected_repos", [ diff --git a/tests/test_content_manifest.py b/tests/test_content_manifest.py index 032e8786f..e2af3f1f4 100644 --- a/tests/test_content_manifest.py +++ b/tests/test_content_manifest.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later from collections import OrderedDict +from typing import Any, Dict, List from unittest import mock import pytest @@ -617,6 +618,541 @@ def test_to_json(mock_top_level_purl, app, package, subpath): mock_top_level_purl.assert_called_once_with(package, request, subpath=subpath) +@pytest.mark.parametrize( + "package, components", + [ + [ + None, + [], + ], + [ + { + "name": "example.com/org/project", + "type": "go-package", + "version": "1.1.1", + "dependencies": [ + { + "name": "example.com/org/project_dep", + "type": "go-package", + "version": "1.1.1_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "example.com/org/project", + "version": "1.1.1", + "purl": "pkg:golang/example.com%2Forg%2Fproject@1.1.1", + }, + { + "type": "library", + "name": "example.com/org/project_dep", + "version": "1.1.1_dep", + "purl": "pkg:golang/example.com%2Forg%2Fproject_dep@1.1.1_dep", + }, + ], + ], + [ + { + "name": "example.com/org/project", + "type": "go-package", + "version": "1.1.1", + "path": "some/path", + "dependencies": [ + { + "name": "example.com/org/project_dep", + "type": "go-package", + "version": "1.1.1_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "example.com/org/project", + "version": "1.1.1", + "purl": "pkg:golang/example.com%2Forg%2Fproject@1.1.1", + }, + { + "type": "library", + "name": "example.com/org/project_dep", + "version": "1.1.1_dep", + "purl": "pkg:golang/example.com%2Forg%2Fproject_dep@1.1.1_dep", + }, + ], + ], + [ + { + "name": "gomod-some", + "type": "gomod", + "version": "1.0.0", + "dependencies": [ + { + "name": "gomod-some_dep", + "type": "gomod", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "gomod-some", + "version": "1.0.0", + "purl": "pkg:golang/gomod-some@1.0.0", + }, + { + "type": "library", + "name": "gomod-some_dep", + "version": "1.0.0_dep", + "purl": "pkg:golang/gomod-some_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "gomod-some", + "type": "gomod", + "version": "1.0.0", + "path": "some/path", + "dependencies": [ + { + "name": "gomod-some_dep", + "type": "gomod", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "gomod-some", + "version": "1.0.0", + "purl": "pkg:golang/gomod-some@1.0.0", + }, + { + "type": "library", + "name": "gomod-some_dep", + "version": "1.0.0_dep", + "purl": "pkg:golang/gomod-some_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "grc-ui", + "type": "npm", + "version": "1.0.0", + "dependencies": [ + { + "name": "grc-ui_dep", + "type": "npm", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "grc-ui", + "version": "1.0.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "grc-ui_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "grc-ui", + "type": "npm", + "version": "1.0.0", + "path": "some/path", + "dependencies": [ + { + "name": "grc-ui_dep", + "type": "npm", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "grc-ui", + "version": "1.0.0", + "purl": f"{DEFAULT_PURL}#some/path", + }, + { + "type": "library", + "name": "grc-ui_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "requests", + "type": "pip", + "version": "2.24.0", + "dependencies": [ + { + "name": "requests_dep", + "type": "pip", + "version": "2.24.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "requests", + "version": "2.24.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "requests_dep", + "version": "2.24.0_dep", + "purl": "pkg:pypi/requests-dep@2.24.0_dep", + }, + ], + ], + [ + { + "name": "requests", + "type": "pip", + "version": "2.24.0", + "path": "some/path", + "dependencies": [ + { + "name": "requests_dep", + "type": "pip", + "version": "2.24.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "requests", + "version": "2.24.0", + "purl": f"{DEFAULT_PURL}#some/path", + }, + { + "type": "library", + "name": "requests_dep", + "version": "2.24.0_dep", + "purl": "pkg:pypi/requests-dep@2.24.0_dep", + }, + ], + ], + [ + { + "name": "grc-ui", + "type": "yarn", + "version": "1.0.0", + "dependencies": [ + { + "name": "grc-ui_dep", + "type": "yarn", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "grc-ui", + "version": "1.0.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "grc-ui_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "grc-ui", + "type": "yarn", + "version": "1.0.0", + "path": "some/path", + "dependencies": [ + { + "name": "grc-ui_dep", + "type": "yarn", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "grc-ui", + "version": "1.0.0", + "purl": f"{DEFAULT_PURL}#some/path", + }, + { + "type": "library", + "name": "grc-ui_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "ruby-some", + "type": "rubygems", + "version": "1.0.0", + "dependencies": [ + { + "name": "ruby-some_dep", + "type": "rubygems", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "ruby-some", + "version": "1.0.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "ruby-some_dep", + "version": "1.0.0_dep", + "purl": "pkg:gem/ruby-some_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "ruby-some", + "type": "rubygems", + "version": "1.0.0", + "path": "some/path", + "dependencies": [ + { + "name": "ruby-some_dep", + "type": "rubygems", + "version": "1.0.0_dep", + }, + ], + }, + [ + { + "type": "library", + "name": "ruby-some", + "version": "1.0.0", + "purl": f"{DEFAULT_PURL}#some/path", + }, + { + "type": "library", + "name": "ruby-some_dep", + "version": "1.0.0_dep", + "purl": "pkg:gem/ruby-some_dep@1.0.0_dep", + }, + ], + ], + [ + { + "name": "submodule-some", + "type": "git-submodule", + "version": "example.com/some.git#58c88e4952e95935c0dd72d4a24b0c44f2249f5b", + }, + [ + { + "type": "library", + "name": "submodule-some", + "version": "example.com/some.git#58c88e4952e95935c0dd72d4a24b0c44f2249f5b", + "purl": "pkg:generic/submodule-some?vcs_url=example.com%2Fsome.git%" + "4058c88e4952e95935c0dd72d4a24b0c44f2249f5b", + }, + ], + ], + [ + { + "name": "submodule-some", + "type": "git-submodule", + "path": "some/path", + "version": "example.com/some.git#58c88e4952e95935c0dd72d4a24b0c44f2249f5b", + }, + [ + { + "type": "library", + "name": "submodule-some", + "version": "example.com/some.git#58c88e4952e95935c0dd72d4a24b0c44f2249f5b", + "purl": "pkg:generic/submodule-some?vcs_url=example.com%2Fsome.git%" + "4058c88e4952e95935c0dd72d4a24b0c44f2249f5b", + }, + ], + ], + ], +) +def test_sbom_components_one_package( + package: Dict[str, Any], components: List[Dict[str, Any]], default_request: Request +) -> None: + packages = _load_packages_from_json([package]) if package else [] + + cm = ContentManifest(default_request, packages) + + assert components == cm.sbom_components_list() + + +@pytest.mark.parametrize( + "packages_json, components", + [ + [ + [ + { + "name": "example.com/org/project", + "type": "go-package", + "version": "1.1.1", + "dependencies": [ + { + "name": "example.com/org/project_dep", + "type": "go-package", + "version": "1.1.1_dep", + }, + ], + }, + { + "name": "grc-ui", + "type": "npm", + "version": "1.0.0", + "dependencies": [ + { + "name": "grc-ui_dep", + "type": "npm", + "version": "1.0.0_dep", + }, + ], + }, + { + "name": "requests", + "type": "pip", + "version": "2.24.0", + "dependencies": [ + { + "name": "requests_dep", + "type": "pip", + "version": "2.24.0_dep", + }, + ], + }, + { + "name": "grc-ui2", + "type": "yarn", + "version": "1.0.0", + "dependencies": [ + { + "name": "grc-ui2_dep", + "type": "yarn", + "version": "1.0.0_dep", + }, + ], + }, + { + "name": "gomod-some", + "type": "gomod", + "version": "1.0.0", + "dependencies": [ + { + "name": "gomod-some_dep", + "type": "gomod", + "version": "1.0.0_dep", + }, + ], + }, + ], + [ + { + "type": "library", + "name": "example.com/org/project", + "version": "1.1.1", + "purl": "pkg:golang/example.com%2Forg%2Fproject@1.1.1", + }, + { + "type": "library", + "name": "grc-ui", + "version": "1.0.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "requests", + "version": "2.24.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "grc-ui2", + "version": "1.0.0", + "purl": DEFAULT_PURL, + }, + { + "type": "library", + "name": "gomod-some", + "version": "1.0.0", + "purl": "pkg:golang/gomod-some@1.0.0", + }, + { + "type": "library", + "name": "example.com/org/project_dep", + "version": "1.1.1_dep", + "purl": "pkg:golang/example.com%2Forg%2Fproject_dep@1.1.1_dep", + }, + { + "type": "library", + "name": "grc-ui_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui_dep@1.0.0_dep", + }, + { + "type": "library", + "name": "requests_dep", + "version": "2.24.0_dep", + "purl": "pkg:pypi/requests-dep@2.24.0_dep", + }, + { + "type": "library", + "name": "grc-ui2_dep", + "version": "1.0.0_dep", + "purl": "pkg:npm/grc-ui2_dep@1.0.0_dep", + }, + { + "type": "library", + "name": "gomod-some_dep", + "version": "1.0.0_dep", + "purl": "pkg:golang/gomod-some_dep@1.0.0_dep", + }, + ], + ], + ], +) +def test_sbom_components_multiple_packages( + packages_json: List[Dict[str, Any]], components: List[Dict[str, Any]], default_request: Request +) -> None: + packages = _load_packages_from_json(packages_json) + + cm = ContentManifest(default_request, packages) + + assert components == cm.sbom_components_list() + + @pytest.mark.parametrize( "packages_json", [