Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions lib/utils/sbom-cyclonedx.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,20 @@ const toCyclonedxItem = (node, { packageType }) => {
node.package = toNormalize.content
}

let parsedLicense
try {
let license = node.package?.license
if (license) {
if (typeof license === 'object') {
license = license.type
}
let license = node.package?.license
if (license) {
if (typeof license === 'object') {
license = license.type
}
} else if (Array.isArray(node.package?.licenses)) {
license = node.package.licenses
.map(l => (typeof l === 'object' ? l.type : l))
.filter(Boolean)
.join(' OR ')
}

let parsedLicense
try {
parsedLicense = parseLicense(license)
} catch {
parsedLicense = null
Expand Down Expand Up @@ -158,7 +163,7 @@ const toCyclonedxItem = (node, { packageType }) => {
component.licenses = [{ license: { id: parsedLicense.license } }]
// If license is a conjunction, use the expression field
} else if (parsedLicense?.conjunction) {
component.licenses = [{ expression: node.package.license }]
component.licenses = [{ expression: license }]
}

return component
Expand Down
5 changes: 5 additions & 0 deletions lib/utils/sbom-spdx.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ const toSpdxItem = (node, { packageType }) => {
if (typeof license === 'object') {
license = license.type
}
} else if (Array.isArray(node.package?.licenses)) {
license = node.package.licenses
.map(l => (typeof l === 'object' ? l.type : l))
.filter(Boolean)
.join(' OR ')
}

const pkg = {
Expand Down
148 changes: 148 additions & 0 deletions tap-snapshots/test/lib/utils/sbom-cyclonedx.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,154 @@ exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - with issue tracker >
}
`

exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - with legacy licenses array (multiple) > must match snapshot 1`] = `
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:00000000-0000-0000-0000-000000000000",
"version": 1,
"metadata": {
"timestamp": "2020-01-01T00:00:00.000Z",
"lifecycles": [
{
"phase": "build"
}
],
"tools": [
{
"vendor": "npm",
"name": "cli",
"version": "10.0.0 "
}
],
"component": {
"bom-ref": "root@1.0.0",
"type": "library",
"name": "root",
"version": "1.0.0",
"scope": "required",
"author": "Author",
"purl": "pkg:npm/root@1.0.0",
"properties": [],
"externalReferences": [],
"licenses": [
{
"expression": "MIT OR Apache-2.0"
}
]
}
},
"components": [],
"dependencies": [
{
"ref": "root@1.0.0",
"dependsOn": []
}
]
}
`

exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - with legacy licenses array (single) > must match snapshot 1`] = `
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:00000000-0000-0000-0000-000000000000",
"version": 1,
"metadata": {
"timestamp": "2020-01-01T00:00:00.000Z",
"lifecycles": [
{
"phase": "build"
}
],
"tools": [
{
"vendor": "npm",
"name": "cli",
"version": "10.0.0 "
}
],
"component": {
"bom-ref": "root@1.0.0",
"type": "library",
"name": "root",
"version": "1.0.0",
"scope": "required",
"author": "Author",
"purl": "pkg:npm/root@1.0.0",
"properties": [],
"externalReferences": [],
"licenses": [
{
"license": {
"id": "MIT"
}
}
]
}
},
"components": [],
"dependencies": [
{
"ref": "root@1.0.0",
"dependsOn": []
}
]
}
`

exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - with legacy licenses array (string entries) > must match snapshot 1`] = `
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:00000000-0000-0000-0000-000000000000",
"version": 1,
"metadata": {
"timestamp": "2020-01-01T00:00:00.000Z",
"lifecycles": [
{
"phase": "build"
}
],
"tools": [
{
"vendor": "npm",
"name": "cli",
"version": "10.0.0 "
}
],
"component": {
"bom-ref": "root@1.0.0",
"type": "library",
"name": "root",
"version": "1.0.0",
"scope": "required",
"author": "Author",
"purl": "pkg:npm/root@1.0.0",
"properties": [],
"externalReferences": [],
"licenses": [
{
"license": {
"id": "MIT"
}
}
]
}
},
"components": [],
"dependencies": [
{
"ref": "root@1.0.0",
"dependsOn": []
}
]
}
`

exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - with license expression > must match snapshot 1`] = `
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
Expand Down
135 changes: 135 additions & 0 deletions tap-snapshots/test/lib/utils/sbom-spdx.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,141 @@ exports[`test/lib/utils/sbom-spdx.js TAP single node - with integrity > must mat
}
`

exports[`test/lib/utils/sbom-spdx.js TAP single node - with legacy licenses array (multiple) > must match snapshot 1`] = `
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "root@1.0.0",
"documentNamespace": "docns",
"creationInfo": {
"created": "2020-01-01T00:00:00.000Z",
"creators": [
"Tool: npm/cli-10.0.0 "
]
},
"documentDescribes": [
"SPDXRef-Package-root-1.0.0"
],
"packages": [
{
"name": "root",
"SPDXID": "SPDXRef-Package-root-1.0.0",
"versionInfo": "1.0.0",
"packageFileName": "",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"homepage": "NOASSERTION",
"licenseDeclared": "MIT OR Apache-2.0",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:npm/root@1.0.0"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-Package-root-1.0.0",
"relationshipType": "DESCRIBES"
}
]
}
`

exports[`test/lib/utils/sbom-spdx.js TAP single node - with legacy licenses array (single) > must match snapshot 1`] = `
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "root@1.0.0",
"documentNamespace": "docns",
"creationInfo": {
"created": "2020-01-01T00:00:00.000Z",
"creators": [
"Tool: npm/cli-10.0.0 "
]
},
"documentDescribes": [
"SPDXRef-Package-root-1.0.0"
],
"packages": [
{
"name": "root",
"SPDXID": "SPDXRef-Package-root-1.0.0",
"versionInfo": "1.0.0",
"packageFileName": "",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"homepage": "NOASSERTION",
"licenseDeclared": "MIT",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:npm/root@1.0.0"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-Package-root-1.0.0",
"relationshipType": "DESCRIBES"
}
]
}
`

exports[`test/lib/utils/sbom-spdx.js TAP single node - with legacy licenses array (string entries) > must match snapshot 1`] = `
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "root@1.0.0",
"documentNamespace": "docns",
"creationInfo": {
"created": "2020-01-01T00:00:00.000Z",
"creators": [
"Tool: npm/cli-10.0.0 "
]
},
"documentDescribes": [
"SPDXRef-Package-root-1.0.0"
],
"packages": [
{
"name": "root",
"SPDXID": "SPDXRef-Package-root-1.0.0",
"versionInfo": "1.0.0",
"packageFileName": "",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"homepage": "NOASSERTION",
"licenseDeclared": "MIT",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:npm/root@1.0.0"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-Package-root-1.0.0",
"relationshipType": "DESCRIBES"
}
]
}
`

exports[`test/lib/utils/sbom-spdx.js TAP single node - with license expression > must match snapshot 1`] = `
{
"spdxVersion": "SPDX-2.3",
Expand Down
47 changes: 47 additions & 0 deletions test/lib/utils/sbom-cyclonedx.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,53 @@ t.test('single node - with single license', t => {
t.end()
})

t.test('single node - with legacy licenses array (single)', t => {
const pkg = {
...rootPkg,
licenses: [
{
type: 'MIT',
url: 'http://opensource.org/licenses/mit-license.php',
},
],
}
const node = { ...root, package: pkg }
const res = cyclonedxOutput({ npm, nodes: [node] })
t.matchSnapshot(JSON.stringify(res))
t.end()
})

t.test('single node - with legacy licenses array (multiple)', t => {
const pkg = {
...rootPkg,
licenses: [
{
type: 'MIT',
url: 'http://opensource.org/licenses/mit-license.php',
},
{
type: 'Apache-2.0',
url: 'http://opensource.org/licenses/apache2.0.php',
},
],
}
const node = { ...root, package: pkg }
const res = cyclonedxOutput({ npm, nodes: [node] })
t.matchSnapshot(JSON.stringify(res))
t.end()
})

t.test('single node - with legacy licenses array (string entries)', t => {
const pkg = {
...rootPkg,
licenses: ['MIT'],
}
const node = { ...root, package: pkg }
const res = cyclonedxOutput({ npm, nodes: [node] })
t.matchSnapshot(JSON.stringify(res))
t.end()
})

t.test('single node - with license expression', t => {
const pkg = { ...rootPkg, license: '(MIT OR Apache-2.0)' }
const node = { ...root, package: pkg }
Expand Down
Loading
Loading