From efa154e13337ea207741d183822e52840c5daf86 Mon Sep 17 00:00:00 2001 From: NucleonGodX Date: Sun, 9 Feb 2025 21:08:48 +0530 Subject: [PATCH 1/4] Add support for componentjs #4107 Signed-off-by: NucleonGodX --- src/packagedcode/__init__.py | 3 +- src/packagedcode/componentjs.py | 151 ++++++++ .../angular-ui-sortable/component.json | 25 ++ .../angular-ui-sortable/expectedoutput.json | 106 +++++ .../data/componentjs/chai/component.json | 51 +++ .../data/componentjs/chai/expectedoutput.json | 144 +++++++ .../data/componentjs/jszip/component.json | 16 + .../componentjs/jszip/expectedoutput.json | 90 +++++ .../data/componentjs/knockback/component.json | 18 + .../componentjs/knockback/expectedoutput.json | 127 ++++++ .../componentjs/seedrandom/component.json | 10 + .../seedrandom/expectedoutput.json | 91 +++++ tests/packagedcode/test_componentjs.py | 363 ++++++++++++++++++ 13 files changed, 1194 insertions(+), 1 deletion(-) create mode 100644 src/packagedcode/componentjs.py create mode 100644 tests/packagedcode/data/componentjs/angular-ui-sortable/component.json create mode 100644 tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json create mode 100644 tests/packagedcode/data/componentjs/chai/component.json create mode 100644 tests/packagedcode/data/componentjs/chai/expectedoutput.json create mode 100644 tests/packagedcode/data/componentjs/jszip/component.json create mode 100644 tests/packagedcode/data/componentjs/jszip/expectedoutput.json create mode 100644 tests/packagedcode/data/componentjs/knockback/component.json create mode 100644 tests/packagedcode/data/componentjs/knockback/expectedoutput.json create mode 100644 tests/packagedcode/data/componentjs/seedrandom/component.json create mode 100644 tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json create mode 100644 tests/packagedcode/test_componentjs.py diff --git a/src/packagedcode/__init__.py b/src/packagedcode/__init__.py index 9cc46d0e09..fb3b09fd08 100644 --- a/src/packagedcode/__init__.py +++ b/src/packagedcode/__init__.py @@ -15,6 +15,7 @@ from packagedcode import build_gradle from packagedcode import cargo from packagedcode import chef +from packagedcode import componentjs from packagedcode import debian from packagedcode import debian_copyright from packagedcode import distro @@ -81,7 +82,7 @@ conan.ConanDataHandler, cran.CranDescriptionFileHandler, - + componentjs.ComponentJSONMetadataHandler, debian_copyright.DebianCopyrightFileInPackageHandler, debian_copyright.StandaloneDebianCopyrightFileHandler, debian.DebianDscFileHandler, diff --git a/src/packagedcode/componentjs.py b/src/packagedcode/componentjs.py new file mode 100644 index 0000000000..c511f06034 --- /dev/null +++ b/src/packagedcode/componentjs.py @@ -0,0 +1,151 @@ +import json +from packagedcode import models +from packageurl import PackageURL +import yaml + +class ComponentJSONMetadataHandler(models.NonAssemblableDatafileHandler): + """ + Handle JSON metadata files for package analysis. + """ + datasource_id = "json_metadata" + path_patterns = ("*component.json",) + default_package_type = "library" + description = "JSON package metadata file" + + @classmethod + def parse(cls, location, package_only=False): + """ + Parse the JSON metadata file at `location` and yield PackageData. + """ + with open(location, "r", encoding="utf-8") as f: + data = json.load(f) + + name = data.get('name') or data.get('repo', '').split('/')[-1] + if not name: + return + + namespace = None + if 'repo' in data and '/' in data['repo']: + namespace, name = data['repo'].split('/', 1) + + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + name=name, + namespace=namespace, + version=data.get('version'), + description=data.get('description', ''), + homepage_url=cls._extract_homepage(data), + keywords=data.get('keywords', []), + dependencies=cls._process_dependencies(data), + extracted_license_statement=cls._extract_license_statement(data), + extra_data=cls._extract_extra_data(data) + ) + + if namespace and name: + try: + package_data['purl'] = PackageURL( + type='generic', + namespace=namespace, + name=name, + version=package_data.get('version') + ).to_string() + except Exception: + pass + + yield models.PackageData.from_data(package_data, package_only) + + @staticmethod + def _extract_homepage(data): + """ + Extract homepage URL from various possible sources. + """ + if data.get('homepage'): + return data['homepage'] + + if data.get('repo'): + return f'https://github.com/{data["repo"]}' + + desc = data.get('description', '') + if 'http' in desc: + urls = [word for word in desc.split() if word.startswith('http')] + return urls[0] if urls else None + + return None + + @staticmethod + def _process_dependencies(data): + """ + Process dependencies into DependentPackage objects. + """ + dependencies = [] + + for dep_name, dep_version in data.get('dependencies', {}).items(): + try: + if '/' in dep_name: + namespace, name = dep_name.split('/', 1) + else: + namespace, name = None, dep_name + + purl = PackageURL( + type='generic', + namespace=namespace, + name=name, + version=dep_version + ).to_string() + + dependencies.append( + models.DependentPackage( + purl=purl, + scope='runtime', + is_runtime=True, + is_optional=False + ) + ) + except Exception: + continue + + return dependencies + + @classmethod + def _extract_license_statement(cls, data): + """ + Extract license statement similar to BuildpackHandler. + + Handles various license formats: + - Simple string license + - Multiple licenses + - Complex license strings + """ + license_field = data.get('license') + if not license_field: + return None + + if isinstance(license_field, str): + return yaml.dump({"type": license_field.strip()}).strip() + + if isinstance(license_field, list): + license_statements = [ + yaml.dump({"type": lic.strip()}).strip() + for lic in license_field + if lic.strip() + ] + return "\n".join(license_statements) if license_statements else None + + return None + + @staticmethod + def _extract_extra_data(data): + """ + Extract additional metadata not in core package data. + """ + extra_fields = [ + 'main', 'scripts', 'styles', 'bin', + 'repository', 'private', 'dev', 'development' + ] + + return { + field: data[field] + for field in extra_fields + if field in data + } \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/angular-ui-sortable/component.json b/tests/packagedcode/data/componentjs/angular-ui-sortable/component.json new file mode 100644 index 0000000000..282aa5d737 --- /dev/null +++ b/tests/packagedcode/data/componentjs/angular-ui-sortable/component.json @@ -0,0 +1,25 @@ +{ + "name": "angular-ui-sortable", + "version": "0.0.1", + "description": "This directive allows you to jQueryUI Sortable.", + "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", + "license": "MIT", + "homepage": "http://angular-ui.github.com", + "main": "./src/sortable.js", + "ignore": [ + "**/.*", + "node_modules", + "components", + "test*", + "demo*", + "gruntFile.js", + "package.json" + ], + "dependencies": { + "angular": "~1.x", + "jquery-ui": ">= 1.9" + }, + "devDependencies": { + "angular-mocks": "~1.x" + } + } \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json b/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json new file mode 100644 index 0000000000..62e7473407 --- /dev/null +++ b/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json @@ -0,0 +1,106 @@ +{ + "packages": [], + "dependencies": [], + "files": [ + { + "path": "component.json", + "type": "file", + "package_data": [ + { + "type": "library", + "namespace": null, + "name": "angular-ui-sortable", + "version": "0.0.1", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "This directive allows you to jQueryUI Sortable.", + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": "http://angular-ui.github.com", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "component.json", + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "type: MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "main": "./src/sortable.js" + }, + "dependencies": [ + { + "purl": "pkg:generic/angular@~1.x", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:generic/jquery-ui@%3E%3D%201.9", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "json_metadata", + "purl": "pkg:library/angular-ui-sortable@0.0.1" + } + ], + "for_packages": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/chai/component.json b/tests/packagedcode/data/componentjs/chai/component.json new file mode 100644 index 0000000000..660ea92d2f --- /dev/null +++ b/tests/packagedcode/data/componentjs/chai/component.json @@ -0,0 +1,51 @@ +{ + "name": "chai" + , "repo": "chaijs/chai" + , "version": "2.1.2" + , "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic." + , "license": "MIT" + , "keywords": [ + "test" + , "assertion" + , "assert" + , "testing" + , "chai" + ] + , "main": "index.js" + , "scripts": [ + "index.js" + , "lib/chai.js" + , "lib/chai/assertion.js" + , "lib/chai/config.js" + , "lib/chai/core/assertions.js" + , "lib/chai/interface/assert.js" + , "lib/chai/interface/expect.js" + , "lib/chai/interface/should.js" + , "lib/chai/utils/addChainableMethod.js" + , "lib/chai/utils/addMethod.js" + , "lib/chai/utils/addProperty.js" + , "lib/chai/utils/flag.js" + , "lib/chai/utils/getActual.js" + , "lib/chai/utils/getEnumerableProperties.js" + , "lib/chai/utils/getMessage.js" + , "lib/chai/utils/getName.js" + , "lib/chai/utils/getPathValue.js" + , "lib/chai/utils/getPathInfo.js" + , "lib/chai/utils/hasProperty.js" + , "lib/chai/utils/getProperties.js" + , "lib/chai/utils/index.js" + , "lib/chai/utils/inspect.js" + , "lib/chai/utils/objDisplay.js" + , "lib/chai/utils/overwriteMethod.js" + , "lib/chai/utils/overwriteProperty.js" + , "lib/chai/utils/overwriteChainableMethod.js" + , "lib/chai/utils/test.js" + , "lib/chai/utils/transferFlags.js" + , "lib/chai/utils/type.js" + ] + , "dependencies": { + "chaijs/assertion-error": "1.0.0" + , "chaijs/deep-eql": "0.1.3" + } + , "development": {} +} \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/chai/expectedoutput.json b/tests/packagedcode/data/componentjs/chai/expectedoutput.json new file mode 100644 index 0000000000..1c652a4f95 --- /dev/null +++ b/tests/packagedcode/data/componentjs/chai/expectedoutput.json @@ -0,0 +1,144 @@ +{ + "packages": [], + "dependencies": [], + "files": [ + { + "path": "component.json", + "type": "file", + "package_data": [ + { + "type": "library", + "namespace": "chaijs", + "name": "chai", + "version": "2.1.2", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "release_date": null, + "parties": [], + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "homepage_url": "https://github.com/chaijs/chai", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "component.json", + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "type: MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "main": "index.js", + "scripts": [ + "index.js", + "lib/chai.js", + "lib/chai/assertion.js", + "lib/chai/config.js", + "lib/chai/core/assertions.js", + "lib/chai/interface/assert.js", + "lib/chai/interface/expect.js", + "lib/chai/interface/should.js", + "lib/chai/utils/addChainableMethod.js", + "lib/chai/utils/addMethod.js", + "lib/chai/utils/addProperty.js", + "lib/chai/utils/flag.js", + "lib/chai/utils/getActual.js", + "lib/chai/utils/getEnumerableProperties.js", + "lib/chai/utils/getMessage.js", + "lib/chai/utils/getName.js", + "lib/chai/utils/getPathValue.js", + "lib/chai/utils/getPathInfo.js", + "lib/chai/utils/hasProperty.js", + "lib/chai/utils/getProperties.js", + "lib/chai/utils/index.js", + "lib/chai/utils/inspect.js", + "lib/chai/utils/objDisplay.js", + "lib/chai/utils/overwriteMethod.js", + "lib/chai/utils/overwriteProperty.js", + "lib/chai/utils/overwriteChainableMethod.js", + "lib/chai/utils/test.js", + "lib/chai/utils/transferFlags.js", + "lib/chai/utils/type.js" + ], + "development": {} + }, + "dependencies": [ + { + "purl": "pkg:generic/chaijs/assertion-error@1.0.0", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:generic/chaijs/deep-eql@0.1.3", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "json_metadata", + "purl": "pkg:library/chaijs/chai@2.1.2" + } + ], + "for_packages": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/jszip/component.json b/tests/packagedcode/data/componentjs/jszip/component.json new file mode 100644 index 0000000000..aa8da9c196 --- /dev/null +++ b/tests/packagedcode/data/componentjs/jszip/component.json @@ -0,0 +1,16 @@ +{ + "name": "jszip", + "repo": "Stuk/jszip", + "description": "Create, read and edit .zip files with JavaScript http://stuartk.com/jszip", + "version": "3.2.0", + "keywords": [ + "zip", + "deflate", + "inflate" + ], + "main": "dist/jszip.js", + "license": "MIT or GPLv3", + "scripts": [ + "dist/jszip.js" + ] + } \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/jszip/expectedoutput.json b/tests/packagedcode/data/componentjs/jszip/expectedoutput.json new file mode 100644 index 0000000000..e65c9b3d59 --- /dev/null +++ b/tests/packagedcode/data/componentjs/jszip/expectedoutput.json @@ -0,0 +1,90 @@ +{ + "packages": [], + "dependencies": [], + "files": [ + { + "path": "component.json", + "type": "file", + "package_data": [ + { + "type": "library", + "namespace": "Stuk", + "name": "jszip", + "version": "3.2.0", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "Create, read and edit .zip files with JavaScript http://stuartk.com/jszip", + "release_date": null, + "parties": [], + "keywords": [ + "zip", + "deflate", + "inflate" + ], + "homepage_url": "https://github.com/Stuk/jszip", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit OR gpl-3.0", + "declared_license_expression_spdx": "MIT OR GPL-3.0-only", + "license_detections": [ + { + "license_expression": "mit OR gpl-3.0", + "license_expression_spdx": "MIT OR GPL-3.0-only", + "matches": [ + { + "license_expression": "mit OR gpl-3.0", + "license_expression_spdx": "MIT OR GPL-3.0-only", + "from_file": "component.json", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_or_gpl-3.0_1.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_or_gpl-3.0_1.RULE", + "matched_text": "type: MIT or GPLv3" + } + ], + "identifier": "mit_or_gpl_3_0-9dbb60be-81c9-331c-96a6-8e6723aa5ce9" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "type: MIT or GPLv3", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "main": "dist/jszip.js", + "scripts": [ + "dist/jszip.js" + ] + }, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "json_metadata", + "purl": "pkg:library/Stuk/jszip@3.2.0" + } + ], + "for_packages": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/knockback/component.json b/tests/packagedcode/data/componentjs/knockback/component.json new file mode 100644 index 0000000000..cd0716092d --- /dev/null +++ b/tests/packagedcode/data/componentjs/knockback/component.json @@ -0,0 +1,18 @@ +{ + "name": "knockback", + "author": "Kevin Malakoff (https://github.com/kmalakoff)", + "version": "1.2.3", + "description": "Knockback.js provides Knockout.js magic for Backbone.js Models and Collections", + "keywords" : ["knockback", "knockbackjs", "backbone", "backbonejs", "knockout", "knockoutjs"], + "repo": "kmalakoff/knockback", + "dependencies": { + "jashkenas/underscore": "*", + "jashkenas/backbone": "*", + "kmalakoff/knockout": "*" + }, + "main": "knockback.js", + "scripts": [ + "knockback.js" + ], + "license": "MIT" + } \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/knockback/expectedoutput.json b/tests/packagedcode/data/componentjs/knockback/expectedoutput.json new file mode 100644 index 0000000000..f01db6bd75 --- /dev/null +++ b/tests/packagedcode/data/componentjs/knockback/expectedoutput.json @@ -0,0 +1,127 @@ +{ + "packages": [], + "dependencies": [], + "files": [ + { + "path": "component.json", + "type": "file", + "package_data": [ + { + "type": "library", + "namespace": "kmalakoff", + "name": "knockback", + "version": "1.2.3", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "Knockback.js provides Knockout.js magic for Backbone.js Models and Collections", + "release_date": null, + "parties": [], + "keywords": [ + "knockback", + "knockbackjs", + "backbone", + "backbonejs", + "knockout", + "knockoutjs" + ], + "homepage_url": "https://github.com/kmalakoff/knockback", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "component.json", + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "type: MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "main": "knockback.js", + "scripts": [ + "knockback.js" + ] + }, + "dependencies": [ + { + "purl": "pkg:generic/jashkenas/underscore@%2A", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:generic/jashkenas/backbone@%2A", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:generic/kmalakoff/knockout@%2A", + "extracted_requirement": null, + "scope": "runtime", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "json_metadata", + "purl": "pkg:library/kmalakoff/knockback@1.2.3" + } + ], + "for_packages": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/seedrandom/component.json b/tests/packagedcode/data/componentjs/seedrandom/component.json new file mode 100644 index 0000000000..67ab013594 --- /dev/null +++ b/tests/packagedcode/data/componentjs/seedrandom/component.json @@ -0,0 +1,10 @@ +{ + "name": "seedrandom", + "version": "2.3.10", + "description": "Seeded random number generator for Javascript", + "repository": "davidbau/seedrandom", + "main": "seedrandom.js", + "scripts": [ "seedrandom.js" ], + "keywords": [ "random", "seed", "crypto" ], + "license": "MIT" + } \ No newline at end of file diff --git a/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json b/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json new file mode 100644 index 0000000000..3f313024b5 --- /dev/null +++ b/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json @@ -0,0 +1,91 @@ +{ + "packages": [], + "dependencies": [], + "files": [ + { + "path": "component.json", + "type": "file", + "package_data": [ + { + "type": "library", + "namespace": null, + "name": "seedrandom", + "version": "2.3.10", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "Seeded random number generator for Javascript", + "release_date": null, + "parties": [], + "keywords": [ + "random", + "seed", + "crypto" + ], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "component.json", + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "type: MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "main": "seedrandom.js", + "scripts": [ + "seedrandom.js" + ], + "repository": "davidbau/seedrandom" + }, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "json_metadata", + "purl": "pkg:library/seedrandom@2.3.10" + } + ], + "for_packages": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/test_componentjs.py b/tests/packagedcode/test_componentjs.py new file mode 100644 index 0000000000..97fd8143b1 --- /dev/null +++ b/tests/packagedcode/test_componentjs.py @@ -0,0 +1,363 @@ +import os +from packagedcode import models +from commoncode.testcase import FileBasedTesting +from packageurl import PackageURL +from packages_test_utils import compare_package_results +from scancode.cli_test_utils import check_json_scan +from scancode.cli_test_utils import run_scan_click +from scancode_config import REGEN_TEST_FIXTURES +from packagedcode import componentjs + +class TestComponentJSON(FileBasedTesting): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_scanworks_on_component_jszip(self): + test_file = self.get_test_loc('componentjs/jszip/component.json') + expected_file = self.get_test_loc('componentjs/jszip/expectedoutput.json') + result_file = self.get_temp_file('results.json') + run_scan_click(['--package', test_file, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, regen=REGEN_TEST_FIXTURES) + + def test_scanworks_on_component_knockback(self): + test_file = self.get_test_loc('componentjs/knockback/component.json') + expected_file = self.get_test_loc('componentjs/knockback/expectedoutput.json') + result_file = self.get_temp_file('results.json') + run_scan_click(['--package', test_file, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, regen=REGEN_TEST_FIXTURES) + + def test_scanworks_on_component_angular_ui_sortable(self): + test_file = self.get_test_loc('componentjs/angular-ui-sortable/component.json') + expected_file = self.get_test_loc('componentjs/angular-ui-sortable/expectedoutput.json') + result_file = self.get_temp_file('results.json') + run_scan_click(['--package', test_file, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, regen=REGEN_TEST_FIXTURES) + + def test_scanworks_on_component_seedrandom(self): + test_file = self.get_test_loc('componentjs/seedrandom/component.json') + expected_file = self.get_test_loc('componentjs/seedrandom/expectedoutput.json') + result_file = self.get_temp_file('results.json') + run_scan_click(['--package', test_file, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, regen=REGEN_TEST_FIXTURES) + + def test_scanworks_on_component_chai(self): + test_file = self.get_test_loc('componentjs/chai/component.json') + expected_file = self.get_test_loc('componentjs/chai/expectedoutput.json') + result_file = self.get_temp_file('results.json') + run_scan_click(['--package', test_file, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, regen=REGEN_TEST_FIXTURES) + + def test_parse_jszip_component_json(self): + test_file = self.get_test_loc('componentjs/jszip/component.json') + result_packages = list(componentjs.ComponentJSONMetadataHandler.parse(test_file)) + expected_packages = [ + models.PackageData( + type=componentjs.ComponentJSONMetadataHandler.default_package_type, + datasource_id=componentjs.ComponentJSONMetadataHandler.datasource_id, + declared_license_expression= "mit OR gpl-3.0", + declared_license_expression_spdx= "MIT OR GPL-3.0-only", + name="jszip", + namespace="Stuk", + version="3.2.0", + description="Create, read and edit .zip files with JavaScript http://stuartk.com/jszip", + homepage_url="https://github.com/Stuk/jszip", + keywords=["zip", "deflate", "inflate"], + extracted_license_statement="type: MIT or GPLv3", + license_detections= [ + { + "license_expression": "mit OR gpl-3.0", + "license_expression_spdx": "MIT OR GPL-3.0-only", + "matches": [ + { + "license_expression": "mit OR gpl-3.0", + "license_expression_spdx": "MIT OR GPL-3.0-only", + "from_file": None, + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_or_gpl-3.0_1.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_or_gpl-3.0_1.RULE", + "matched_text": "type: MIT or GPLv3" + } + ], + "identifier": "mit_or_gpl_3_0-9dbb60be-81c9-331c-96a6-8e6723aa5ce9" + } + ], + extra_data={ + "main": "dist/jszip.js", + "scripts": ["dist/jszip.js"] + } + ) + ] + compare_package_results(expected_packages, result_packages) + + def test_parse_knockback_component_json(self): + test_file = self.get_test_loc('componentjs/knockback/component.json') + result_packages = list(componentjs.ComponentJSONMetadataHandler.parse(test_file)) + expected_packages = [ + models.PackageData( + type=componentjs.ComponentJSONMetadataHandler.default_package_type, + datasource_id=componentjs.ComponentJSONMetadataHandler.datasource_id, + declared_license_expression= "mit", + declared_license_expression_spdx= "MIT", + name="knockback", + namespace="kmalakoff", + version="1.2.3", + description="Knockback.js provides Knockout.js magic for Backbone.js Models and Collections", + homepage_url="https://github.com/kmalakoff/knockback", + keywords=["knockback", "knockbackjs", "backbone", "backbonejs", "knockout", "knockoutjs"], + extracted_license_statement="type: MIT", + license_detections= [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": None, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + dependencies=[ + models.DependentPackage( + purl="pkg:generic/jashkenas/underscore@%2A", + scope="runtime", + is_runtime=True, + is_optional=False + ), + models.DependentPackage( + purl="pkg:generic/jashkenas/backbone@%2A", + scope="runtime", + is_runtime=True, + is_optional=False + ), + models.DependentPackage( + purl="pkg:generic/kmalakoff/knockout@%2A", + scope="runtime", + is_runtime=True, + is_optional=False + ) + ], + extra_data={ + "main": "knockback.js", + "scripts": ["knockback.js"] + } + ) + ] + compare_package_results(expected_packages, result_packages) + + def test_parse_angular_ui_sortable_component_json(self): + test_file = self.get_test_loc('componentjs/angular-ui-sortable/component.json') + result_packages = list(componentjs.ComponentJSONMetadataHandler.parse(test_file)) + expected_packages = [ + models.PackageData( + type=componentjs.ComponentJSONMetadataHandler.default_package_type, + datasource_id=componentjs.ComponentJSONMetadataHandler.datasource_id, + declared_license_expression= "mit", + declared_license_expression_spdx= "MIT", + name="angular-ui-sortable", + version="0.0.1", + description="This directive allows you to jQueryUI Sortable.", + homepage_url="http://angular-ui.github.com", + dependencies=[ + models.DependentPackage( + purl="pkg:generic/angular@~1.x", + scope="runtime", + is_runtime=True, + is_optional=False + ), + models.DependentPackage( + purl="pkg:generic/jquery-ui@%3E%3D%201.9", + scope="runtime", + is_runtime=True, + is_optional=False + ) + ], + extracted_license_statement="type: MIT", + license_detections= [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": None, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + extra_data={ + "main": "./src/sortable.js" + } + ) + ] + compare_package_results(expected_packages, result_packages) + + def test_parse_seedrandom_component_json(self): + test_file = self.get_test_loc('componentjs/seedrandom/component.json') + result_packages = list(componentjs.ComponentJSONMetadataHandler.parse(test_file)) + expected_packages = [ + models.PackageData( + type=componentjs.ComponentJSONMetadataHandler.default_package_type, + datasource_id=componentjs.ComponentJSONMetadataHandler.datasource_id, + declared_license_expression= "mit", + declared_license_expression_spdx= "MIT", + name="seedrandom", + version="2.3.10", + description="Seeded random number generator for Javascript", + homepage_url=None, + keywords=["random", "seed", "crypto"], + license_detections= [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": None, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + extracted_license_statement="type: MIT", + extra_data={ + "main": "seedrandom.js", + "scripts": ["seedrandom.js"], + "repository": "davidbau/seedrandom" + } + ) + ] + compare_package_results(expected_packages, result_packages) + + def test_parse_chai_component_json(self): + test_file = self.get_test_loc('componentjs/chai/component.json') + result_packages = list(componentjs.ComponentJSONMetadataHandler.parse(test_file)) + expected_packages = [ + models.PackageData( + type=componentjs.ComponentJSONMetadataHandler.default_package_type, + datasource_id=componentjs.ComponentJSONMetadataHandler.datasource_id, + declared_license_expression= "mit", + declared_license_expression_spdx= "MIT", + name="chai", + namespace="chaijs", + version="2.1.2", + description="BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + homepage_url="https://github.com/chaijs/chai", + keywords=["test", "assertion", "assert", "testing", "chai"], + dependencies=[ + models.DependentPackage( + purl="pkg:generic/chaijs/assertion-error@1.0.0", + scope="runtime", + is_runtime=True, + is_optional=False + ), + models.DependentPackage( + purl="pkg:generic/chaijs/deep-eql@0.1.3", + scope="runtime", + is_runtime=True, + is_optional=False + ) + ], + extracted_license_statement="type: MIT", + license_detections= [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": None, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 16.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 16, + "rule_identifier": "mit_1301.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_1301.RULE", + "matched_text": "license type: MIT" + } + ], + "identifier": "mit-1c9cba21-81d2-7522-ac3e-dfde6630f8d1" + } + ], + extra_data={ + "main": "index.js", + "scripts": [ + "index.js", + "lib/chai.js", + "lib/chai/assertion.js", + "lib/chai/config.js", + "lib/chai/core/assertions.js", + "lib/chai/interface/assert.js", + "lib/chai/interface/expect.js", + "lib/chai/interface/should.js", + "lib/chai/utils/addChainableMethod.js", + "lib/chai/utils/addMethod.js", + "lib/chai/utils/addProperty.js", + "lib/chai/utils/flag.js", + "lib/chai/utils/getActual.js", + "lib/chai/utils/getEnumerableProperties.js", + "lib/chai/utils/getMessage.js", + "lib/chai/utils/getName.js", + "lib/chai/utils/getPathValue.js", + "lib/chai/utils/getPathInfo.js", + "lib/chai/utils/hasProperty.js", + "lib/chai/utils/getProperties.js", + "lib/chai/utils/index.js", + "lib/chai/utils/inspect.js", + "lib/chai/utils/objDisplay.js", + "lib/chai/utils/overwriteMethod.js", + "lib/chai/utils/overwriteProperty.js", + "lib/chai/utils/overwriteChainableMethod.js", + "lib/chai/utils/test.js", + "lib/chai/utils/transferFlags.js", + "lib/chai/utils/type.js" + ], + "development": {} + } + ) + ] + compare_package_results(expected_packages, result_packages) \ No newline at end of file From 14ba0aebd1c0ee505d41cd8daed6de45994121c7 Mon Sep 17 00:00:00 2001 From: Manit Singh <79140607+NucleonGodX@users.noreply.github.com> Date: Sun, 9 Feb 2025 23:49:51 +0530 Subject: [PATCH 2/4] code cleanup Signed-off-by: NucleonGodX Signed-off-by: NucleonGodX --- src/packagedcode/componentjs.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/packagedcode/componentjs.py b/src/packagedcode/componentjs.py index c511f06034..88b24ed0aa 100644 --- a/src/packagedcode/componentjs.py +++ b/src/packagedcode/componentjs.py @@ -5,12 +5,12 @@ class ComponentJSONMetadataHandler(models.NonAssemblableDatafileHandler): """ - Handle JSON metadata files for package analysis. + Handle component JSON metadata files for package analysis. """ datasource_id = "json_metadata" path_patterns = ("*component.json",) default_package_type = "library" - description = "JSON package metadata file" + description = "component JSON package metadata file" @classmethod def parse(cls, location, package_only=False): @@ -110,12 +110,8 @@ def _process_dependencies(data): @classmethod def _extract_license_statement(cls, data): """ - Extract license statement similar to BuildpackHandler. - - Handles various license formats: - - Simple string license - - Multiple licenses - - Complex license strings + Extract license statement. + """ license_field = data.get('license') if not license_field: @@ -148,4 +144,4 @@ def _extract_extra_data(data): field: data[field] for field in extra_fields if field in data - } \ No newline at end of file + } From d75e86d6f4db24606191e8fc62eb158ad5193cd3 Mon Sep 17 00:00:00 2001 From: NucleonGodX Date: Mon, 10 Feb 2025 21:22:02 +0530 Subject: [PATCH 3/4] add header and code cleanup Signed-off-by: NucleonGodX --- src/packagedcode/componentjs.py | 27 ++++++++++++++++---------- tests/packagedcode/test_componentjs.py | 10 +++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/packagedcode/componentjs.py b/src/packagedcode/componentjs.py index 88b24ed0aa..3d8c7f13aa 100644 --- a/src/packagedcode/componentjs.py +++ b/src/packagedcode/componentjs.py @@ -1,3 +1,12 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# ScanCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/scancode-toolkit for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + import json from packagedcode import models from packageurl import PackageURL @@ -7,7 +16,7 @@ class ComponentJSONMetadataHandler(models.NonAssemblableDatafileHandler): """ Handle component JSON metadata files for package analysis. """ - datasource_id = "json_metadata" + datasource_id = "component_json_metadata" path_patterns = ("*component.json",) default_package_type = "library" description = "component JSON package metadata file" @@ -43,15 +52,13 @@ def parse(cls, location, package_only=False): ) if namespace and name: - try: - package_data['purl'] = PackageURL( - type='generic', - namespace=namespace, - name=name, - version=package_data.get('version') - ).to_string() - except Exception: - pass + package_data['purl'] = PackageURL( + type='generic', + namespace=namespace, + name=name, + version=package_data.get('version') + ).to_string() + yield models.PackageData.from_data(package_data, package_only) diff --git a/tests/packagedcode/test_componentjs.py b/tests/packagedcode/test_componentjs.py index 97fd8143b1..14248ec5de 100644 --- a/tests/packagedcode/test_componentjs.py +++ b/tests/packagedcode/test_componentjs.py @@ -1,7 +1,15 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# ScanCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/scancode-toolkit for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + import os from packagedcode import models from commoncode.testcase import FileBasedTesting -from packageurl import PackageURL from packages_test_utils import compare_package_results from scancode.cli_test_utils import check_json_scan from scancode.cli_test_utils import run_scan_click From 75352193fa8dba277ee6760f50f625bf3a54a193 Mon Sep 17 00:00:00 2001 From: NucleonGodX Date: Mon, 10 Feb 2025 21:34:32 +0530 Subject: [PATCH 4/4] tests updated Signed-off-by: NucleonGodX --- .../componentjs/angular-ui-sortable/expectedoutput.json | 6 +++--- .../packagedcode/data/componentjs/chai/expectedoutput.json | 6 +++--- .../packagedcode/data/componentjs/jszip/expectedoutput.json | 6 +++--- .../data/componentjs/knockback/expectedoutput.json | 6 +++--- .../data/componentjs/seedrandom/expectedoutput.json | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json b/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json index 62e7473407..39d51f3708 100644 --- a/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json +++ b/tests/packagedcode/data/componentjs/angular-ui-sortable/expectedoutput.json @@ -7,7 +7,7 @@ "type": "file", "package_data": [ { - "type": "library", + "type": "generic", "namespace": null, "name": "angular-ui-sortable", "version": "0.0.1", @@ -95,8 +95,8 @@ "repository_homepage_url": null, "repository_download_url": null, "api_data_url": null, - "datasource_id": "json_metadata", - "purl": "pkg:library/angular-ui-sortable@0.0.1" + "datasource_id": "component_json_metadata", + "purl": "pkg:generic/angular-ui-sortable@0.0.1" } ], "for_packages": [], diff --git a/tests/packagedcode/data/componentjs/chai/expectedoutput.json b/tests/packagedcode/data/componentjs/chai/expectedoutput.json index 1c652a4f95..3a73ad2448 100644 --- a/tests/packagedcode/data/componentjs/chai/expectedoutput.json +++ b/tests/packagedcode/data/componentjs/chai/expectedoutput.json @@ -7,7 +7,7 @@ "type": "file", "package_data": [ { - "type": "library", + "type": "generic", "namespace": "chaijs", "name": "chai", "version": "2.1.2", @@ -133,8 +133,8 @@ "repository_homepage_url": null, "repository_download_url": null, "api_data_url": null, - "datasource_id": "json_metadata", - "purl": "pkg:library/chaijs/chai@2.1.2" + "datasource_id": "component_json_metadata", + "purl": "pkg:generic/chaijs/chai@2.1.2" } ], "for_packages": [], diff --git a/tests/packagedcode/data/componentjs/jszip/expectedoutput.json b/tests/packagedcode/data/componentjs/jszip/expectedoutput.json index e65c9b3d59..e245a594f5 100644 --- a/tests/packagedcode/data/componentjs/jszip/expectedoutput.json +++ b/tests/packagedcode/data/componentjs/jszip/expectedoutput.json @@ -7,7 +7,7 @@ "type": "file", "package_data": [ { - "type": "library", + "type": "generic", "namespace": "Stuk", "name": "jszip", "version": "3.2.0", @@ -79,8 +79,8 @@ "repository_homepage_url": null, "repository_download_url": null, "api_data_url": null, - "datasource_id": "json_metadata", - "purl": "pkg:library/Stuk/jszip@3.2.0" + "datasource_id": "component_json_metadata", + "purl": "pkg:generic/Stuk/jszip@3.2.0" } ], "for_packages": [], diff --git a/tests/packagedcode/data/componentjs/knockback/expectedoutput.json b/tests/packagedcode/data/componentjs/knockback/expectedoutput.json index f01db6bd75..d86c74c756 100644 --- a/tests/packagedcode/data/componentjs/knockback/expectedoutput.json +++ b/tests/packagedcode/data/componentjs/knockback/expectedoutput.json @@ -7,7 +7,7 @@ "type": "file", "package_data": [ { - "type": "library", + "type": "generic", "namespace": "kmalakoff", "name": "knockback", "version": "1.2.3", @@ -116,8 +116,8 @@ "repository_homepage_url": null, "repository_download_url": null, "api_data_url": null, - "datasource_id": "json_metadata", - "purl": "pkg:library/kmalakoff/knockback@1.2.3" + "datasource_id": "component_json_metadata", + "purl": "pkg:generic/kmalakoff/knockback@1.2.3" } ], "for_packages": [], diff --git a/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json b/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json index 3f313024b5..28ab8a2690 100644 --- a/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json +++ b/tests/packagedcode/data/componentjs/seedrandom/expectedoutput.json @@ -7,7 +7,7 @@ "type": "file", "package_data": [ { - "type": "library", + "type": "generic", "namespace": null, "name": "seedrandom", "version": "2.3.10", @@ -80,8 +80,8 @@ "repository_homepage_url": null, "repository_download_url": null, "api_data_url": null, - "datasource_id": "json_metadata", - "purl": "pkg:library/seedrandom@2.3.10" + "datasource_id": "component_json_metadata", + "purl": "pkg:generic/seedrandom@2.3.10" } ], "for_packages": [],