spdx-satisfies 5.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +9 -39
  2. package/index.js +30 -26
  3. package/package.json +8 -3
package/README.md CHANGED
@@ -1,44 +1,14 @@
1
+ `satisfies(SPDX license expression, array of approved licenses)`
2
+
3
+ Approved licenses may be simple license identifiers like `MIT`, plus-ranges like `EPL-2.0+`, or licenses with exceptions like `Apache-2.0 WITH LLVM`. They may _not_ be compound expressions using `AND` or `OR`.
4
+
1
5
  ```javascript
2
6
  var assert = require('assert')
3
7
  var satisfies = require('spdx-satisfies')
4
8
 
5
- assert(satisfies('MIT', 'MIT'))
6
-
7
- assert(satisfies('MIT', '(ISC OR MIT)'))
8
- assert(satisfies('Zlib', '(ISC OR (MIT OR Zlib))'))
9
- assert(!satisfies('GPL-3.0', '(ISC OR MIT)'))
10
-
11
- assert(satisfies('GPL-2.0', 'GPL-2.0+'))
12
- assert(satisfies('GPL-3.0', 'GPL-2.0+'))
13
- assert(satisfies('GPL-1.0+', 'GPL-2.0+'))
14
- assert(!satisfies('GPL-1.0', 'GPL-2.0+'))
15
- assert(satisfies('GPL-2.0-only', 'GPL-2.0-only'))
16
- assert(satisfies('GPL-3.0-only', 'GPL-2.0+'))
17
-
18
- assert(!satisfies(
19
- 'GPL-2.0',
20
- 'GPL-2.0+ WITH Bison-exception-2.2'
21
- ))
22
-
23
- assert(satisfies(
24
- 'GPL-3.0 WITH Bison-exception-2.2',
25
- 'GPL-2.0+ WITH Bison-exception-2.2'
26
- ))
27
-
28
- assert(satisfies('(MIT OR GPL-2.0)', '(ISC OR MIT)'))
29
- assert(satisfies('(MIT AND GPL-2.0)', '(MIT AND GPL-2.0)'))
30
- assert(satisfies('MIT AND GPL-2.0 AND ISC', 'MIT AND GPL-2.0 AND ISC'))
31
- assert(satisfies('MIT AND GPL-2.0 AND ISC', 'ISC AND GPL-2.0 AND MIT'))
32
- assert(satisfies('(MIT OR GPL-2.0) AND ISC', 'MIT AND ISC'))
33
- assert(satisfies('MIT AND ISC', '(MIT OR GPL-2.0) AND ISC'))
34
- assert(satisfies('MIT AND ISC', '(MIT AND GPL-2.0) OR ISC'))
35
- assert(satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'Apache-2.0 AND ISC'))
36
- assert(satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'Apache-2.0 OR ISC'))
37
- assert(satisfies('(MIT AND GPL-2.0)', '(MIT OR GPL-2.0)'))
38
- assert(satisfies('(MIT AND GPL-2.0)', '(GPL-2.0 AND MIT)'))
39
- assert(satisfies('MIT', '(GPL-2.0 OR MIT) AND (MIT OR ISC)'))
40
- assert(satisfies('MIT AND ICU', '(MIT AND GPL-2.0) OR (ISC AND (Apache-2.0 OR ICU))'))
41
- assert(!satisfies('(MIT AND GPL-2.0)', '(ISC OR GPL-2.0)'))
42
- assert(!satisfies('MIT AND (GPL-2.0 OR ISC)', 'MIT'))
43
- assert(!satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'MIT'))
9
+ assert(satisfies('MIT', ['MIT', 'ISC', 'BSD-2-Clause', 'Apache-2.0']))
10
+ assert(satisfies('GPL-2.0 OR MIT', ['MIT']))
11
+ assert(!satisfies('GPL-2.0 AND MIT', ['MIT']))
12
+ assert(satisfies('GPL-3.0', ['GPL-2.0+']))
13
+ assert(!satisfies('GPL-1.0', ['GPL-2.0+']))
44
14
  ```
package/index.js CHANGED
@@ -2,7 +2,7 @@ var compare = require('spdx-compare')
2
2
  var parse = require('spdx-expression-parse')
3
3
  var ranges = require('spdx-ranges')
4
4
 
5
- var rangesAreCompatible = function (first, second) {
5
+ function rangesAreCompatible (first, second) {
6
6
  return (
7
7
  first.license === second.license ||
8
8
  ranges.some(function (range) {
@@ -26,7 +26,7 @@ function licenseInRange (license, range) {
26
26
  )
27
27
  }
28
28
 
29
- var identifierInRange = function (identifier, range) {
29
+ function identifierInRange (identifier, range) {
30
30
  return (
31
31
  identifier.license === range.license ||
32
32
  compare.gt(identifier.license, range.license) ||
@@ -34,7 +34,7 @@ var identifierInRange = function (identifier, range) {
34
34
  )
35
35
  }
36
36
 
37
- var licensesAreCompatible = function (first, second) {
37
+ function licensesAreCompatible (first, second) {
38
38
  if (first.exception !== second.exception) {
39
39
  return false
40
40
  } else if (second.hasOwnProperty('license')) {
@@ -58,30 +58,36 @@ var licensesAreCompatible = function (first, second) {
58
58
  }
59
59
  }
60
60
 
61
- function normalizeGPLIdentifiers (argument) {
61
+ function replaceGPLOnlyOrLaterWithRanges (argument) {
62
62
  var license = argument.license
63
63
  if (license) {
64
64
  if (endsWith(license, '-or-later')) {
65
65
  argument.license = license.replace('-or-later', '')
66
66
  argument.plus = true
67
67
  } else if (endsWith(license, '-only')) {
68
- argument.license = license.replace('-or-later', '')
68
+ argument.license = license.replace('-only', '')
69
69
  delete argument.plus
70
70
  }
71
71
  } else if (argument.left && argument.right) {
72
- argument.left = normalizeGPLIdentifiers(argument.left)
73
- argument.right = normalizeGPLIdentifiers(argument.right)
72
+ argument.left = replaceGPLOnlyOrLaterWithRanges(argument.left)
73
+ argument.right = replaceGPLOnlyOrLaterWithRanges(argument.right)
74
74
  }
75
75
  return argument
76
76
  }
77
77
 
78
78
  function endsWith (string, substring) {
79
- return string.indexOf(substring) === string.length - 1
79
+ return string.indexOf(substring) === string.length - substring.length
80
80
  }
81
81
 
82
82
  function licenseString (e) {
83
83
  if (e.hasOwnProperty('noassertion')) return 'NOASSERTION'
84
- if (e.license) return `${e.license}${e.plus ? '+' : ''}${e.exception ? ` WITH ${e.exception}` : ''}`
84
+ if (e.license) {
85
+ return (
86
+ e.license +
87
+ (e.plus ? '+' : '') +
88
+ (e.exception ? ('WITH ' + e.exception) : '')
89
+ )
90
+ }
85
91
  }
86
92
 
87
93
  // Expand the given expression into an equivalent array where each member is an array of licenses AND'd
@@ -89,16 +95,7 @@ function licenseString (e) {
89
95
  // `[[GPL-3.0 AND MIT], [ISC AND MIT]]`. Note that within each array of licenses, the entries are
90
96
  // normalized (sorted) by license name.
91
97
  function expand (expression) {
92
- return sort(Array.from(expandInner(expression)))
93
- }
94
-
95
- // Flatten the given expression into an array of all licenses mentioned in the expression.
96
- function flatten (expression) {
97
- const expanded = Array.from(expandInner(expression))
98
- const flattened = expanded.reduce(function (result, clause) {
99
- return Object.assign(result, clause)
100
- }, {})
101
- return sort([flattened])[0]
98
+ return sort(expandInner(expression))
102
99
  }
103
100
 
104
101
  function expandInner (expression) {
@@ -123,16 +120,23 @@ function sort (licenseList) {
123
120
  })
124
121
  }
125
122
 
126
- function isANDCompatible (one, two) {
127
- return one.every(function (o) {
128
- return two.some(function (t) { return licensesAreCompatible(o, t) })
123
+ function isANDCompatible (parsedExpression, parsedLicenses) {
124
+ return parsedExpression.every(function (element) {
125
+ return parsedLicenses.some(function (approvedLicense) {
126
+ return licensesAreCompatible(element, approvedLicense)
127
+ })
129
128
  })
130
129
  }
131
130
 
132
- function satisfies (first, second) {
133
- var one = expand(normalizeGPLIdentifiers(parse(first)))
134
- var two = flatten(normalizeGPLIdentifiers(parse(second)))
135
- return one.some(function (o) { return isANDCompatible(o, two) })
131
+ function satisfies (spdxExpression, arrayOfLicenses) {
132
+ var parsedExpression = expand(replaceGPLOnlyOrLaterWithRanges(parse(spdxExpression)))
133
+ var parsedLicenses = arrayOfLicenses.map(function (l) { return replaceGPLOnlyOrLaterWithRanges(parse(l)) })
134
+ for (const parsed of parsedLicenses) {
135
+ if (parsed.hasOwnProperty('conjunction')) {
136
+ throw new Error('Approved licenses cannot be AND or OR expressions.')
137
+ }
138
+ }
139
+ return parsedExpression.some(function (o) { return isANDCompatible(o, parsedLicenses) })
136
140
  }
137
141
 
138
142
  module.exports = satisfies
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "spdx-satisfies",
3
3
  "description": "test whether SPDX expressions satisfy licensing criteria",
4
- "version": "5.0.0",
4
+ "version": "6.0.0",
5
5
  "author": "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)",
6
6
  "contributors": [
7
7
  "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)",
@@ -14,7 +14,7 @@
14
14
  "spdx-ranges": "^2.0.0"
15
15
  },
16
16
  "devDependencies": {
17
- "defence-cli": "^2.0.1",
17
+ "defence-cli": "^3.0.1",
18
18
  "replace-require-self": "^1.1.1",
19
19
  "standard": "^11.0.0"
20
20
  },
@@ -30,8 +30,13 @@
30
30
  ],
31
31
  "license": "MIT",
32
32
  "repository": "kemitchell/spdx-satisfies.js",
33
+ "files": [
34
+ "index.js"
35
+ ],
33
36
  "scripts": {
34
- "test": "defence -i javascript README.md | replace-require-self | node",
37
+ "test": "npm run test:suite && npm run test:readme",
38
+ "test:suite": "node test.js",
39
+ "test:readme": "defence -i javascript README.md | replace-require-self | node",
35
40
  "lint": "standard"
36
41
  }
37
42
  }