diff --git a/index.js b/index.js index a3a1aac..b30e58d 100644 --- a/index.js +++ b/index.js @@ -19,14 +19,15 @@ const NOASSERTION = 'NOASSERTION' * * @param {string} expression SPDX expression * @param {Function} licenseVisitor Optional. Bring your own visitor to clean each node + * @param {Function} licenseRefLookup Optional. Bring your own lookup to scan licenseRef * @returns {object} the AST representing the parsed expression */ -function parse(expression, licenseVisitor) { +function parse(expression, licenseVisitor, licenseRefLookup) { // if the expression is already an expression, just return it. if (!(typeof expression === 'string')) return expression licenseVisitor = licenseVisitor || normalizeSingle try { - return spdxExpressionParse(expression, { relaxed: true, licenseVisitor }) + return spdxExpressionParse(expression, { relaxed: true, licenseVisitor, licenseRefLookup }) } catch (e) { return { noassertion: true } } diff --git a/package-lock.json b/package-lock.json index 483f543..18b9c2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@clearlydefined/spdx", - "version": "0.1.8", + "version": "0.1.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@clearlydefined/spdx", - "version": "0.1.8", + "version": "0.1.9", "license": "MIT", "dependencies": { "spdx-expression-parse": "github:clearlydefined/spdx-expression-parse.js#fork", - "spdx-license-ids": "^3.0.18", + "spdx-license-ids": "^3.0.20", "spdx-license-list": "^6.9.0", "spdx-satisfies": "github:clearlydefined/spdx-satisfies.js#parse-override" }, @@ -3214,9 +3214,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==" + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==" }, "node_modules/spdx-license-list": { "version": "6.9.0", diff --git a/package.json b/package.json index 8d55054..7919a78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@clearlydefined/spdx", - "version": "0.1.8", + "version": "0.1.9", "description": "SPDX custom libraries of clearlydefined.io.", "license": "MIT", "repository": { @@ -20,7 +20,7 @@ }, "dependencies": { "spdx-expression-parse": "github:clearlydefined/spdx-expression-parse.js#fork", - "spdx-license-ids": "^3.0.18", + "spdx-license-ids": "^3.0.20", "spdx-license-list": "^6.9.0", "spdx-satisfies": "github:clearlydefined/spdx-satisfies.js#parse-override" }, diff --git a/test.js b/test.js index 9c283d7..a79a7f0 100644 --- a/test.js +++ b/test.js @@ -98,6 +98,129 @@ describe('SPDX utility functions', () => { }) }) + it('parses licenseRef with lookup', () => { + const data = new Map([ + ['afpl-9.0', { license: 'LicenseRef-scancode-afpl-9.0' }], + ['(afpl-9.0)', { license: 'LicenseRef-scancode-afpl-9.0' }], + [ + '(afpl-9.0 OR Apache-2.0)', + { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'or', + right: { license: 'Apache-2.0' } + } + ], + [ + 'Apache-2.0 AND (afpl-9.0)', + { + left: { license: 'Apache-2.0' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-afpl-9.0' } + } + ], + [ + 'Apache-2.0 AND (afpl-9.0 AND afpl-9.0)', + { + left: { license: 'Apache-2.0' }, + conjunction: 'and', + right: { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-afpl-9.0' } + } + } + ], + [ + '(afpl-9.0 AND afpl-9.0) AND Apache-2.0', + { + right: { license: 'Apache-2.0' }, + conjunction: 'and', + left: { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-afpl-9.0' } + } + } + ], + [ + 'Apache-2.0 AND (afpl-9.0 OR afpl-9.0)', + { + left: { license: 'Apache-2.0' }, + conjunction: 'and', + right: { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'or', + right: { license: 'LicenseRef-scancode-afpl-9.0' } + } + } + ], + [ + 'MIT AND GPL-3.0', + { + left: { license: 'MIT' }, + conjunction: 'and', + right: { license: 'GPL-3.0' } + } + ], + [ + 'AFL-1.1 AND afpl-9.0', + { + left: { license: 'AFL-1.1' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-afpl-9.0' } + } + ], + [ + 'afpl-9.0 AND MIT', + { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'MIT' } + } + ], + [ + 'afpl-9.0 AND activestate-community', + { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-activestate-community' } + } + ], + [ + 'afpl-9.0 AND activestate-community OR ac3filter', + { + left: { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'LicenseRef-scancode-activestate-community' } + }, + conjunction: 'or', + right: { license: 'LicenseRef-scancode-ac3filter' } + } + ], + ['INVALID', { noassertion: null }], + [ + 'LicenseRef-scancode-afpl-9.0 AND MIT', + { + left: { license: 'LicenseRef-scancode-afpl-9.0' }, + conjunction: 'and', + right: { license: 'MIT' } + } + ] + ]) + + const licenseRefLookup = function (identifier) { + if (identifier === 'afpl-9.0') return 'LicenseRef-scancode-afpl-9.0' + if (identifier === 'activestate-community') return 'LicenseRef-scancode-activestate-community' + if (identifier === 'ac3filter') return 'LicenseRef-scancode-ac3filter' + return identifier + } + + data.forEach((expected, input) => { + expect(SPDX.parse(input, undefined, licenseRefLookup)).to.deep.equal(expected) + }) + }) + it('stringifies spdx objects', () => { const data = new Map([ [{ license: 'MIT' }, 'MIT'],