diff --git a/index.js b/index.js index 52fab56..b8c2031 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ var scan = require('./scan') var parse = require('./parse') -module.exports = function (source) { - return parse(scan(source)) +module.exports = function (source, options) { + options = options || {} + return parse(scan(source, options)) } diff --git a/parse.js b/parse.js index a4a52ce..711ebd7 100644 --- a/parse.js +++ b/parse.js @@ -78,6 +78,9 @@ module.exports = function (tokens) { node.exception = exception } return node + } else if (t && t.type === 'NOASSERTION') { + next() + return {noassertion: true} } } diff --git a/scan.js b/scan.js index d0567f4..3a8b223 100644 --- a/scan.js +++ b/scan.js @@ -5,7 +5,8 @@ var licenses = [] .concat(require('spdx-license-ids/deprecated')) var exceptions = require('spdx-exceptions') -module.exports = function (source) { +module.exports = function (source, options) { + options = options || {} var index = 0 function hasMore () { @@ -82,9 +83,12 @@ module.exports = function (source) { } function identifier () { - var begin = index var string = idstring() + if (typeof options.licenseVisitor === 'function') { + string = options.licenseVisitor(string) + } + if (licenses.indexOf(string) !== -1) { return { type: 'LICENSE', @@ -95,9 +99,12 @@ module.exports = function (source) { type: 'EXCEPTION', string: string } + } else { + return { + type: 'NOASSERTION', + string: string + } } - - index = begin } // Tries to read the next token. Returns `undefined` if no token is @@ -120,7 +127,7 @@ module.exports = function (source) { } var token = parseToken() - if (!token) { + if (!token || typeof token.string === 'undefined') { throw new Error('Unexpected `' + source[index] + '` at offset ' + index) } diff --git a/test/index.js b/test/index.js index 46318fa..5f7745b 100644 --- a/test/index.js +++ b/test/index.js @@ -83,3 +83,28 @@ it('parses `AND`, `OR` and `WITH` with the correct precedence', function () { } ) }) + +it('uses licenseVisitor to normalize licenseIdentifiers', function () { + assert.deepEqual( + p('mit OR Apache-2.0', { licenseVisitor: function (identifier) { + if (identifier === 'mit') return 'MIT' + return identifier + }}), + { + left: {license: 'MIT'}, + conjunction: 'or', + right: {license: 'Apache-2.0'} + } + ) +}) + +it('parses non-spdx licenses with noassertion', function () { + assert.deepEqual( + p('MIT OR Commercial'), + { + left: {license: 'MIT'}, + conjunction: 'or', + right: {noassertion: true} + } + ) +})