spdx-satisfies 4.0.1 → 5.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 (4) hide show
  1. package/README.md +4 -0
  2. package/index.js +57 -38
  3. package/package.json +3 -2
  4. package/test.log +0 -70
package/README.md CHANGED
@@ -28,12 +28,16 @@ assert(satisfies(
28
28
  assert(satisfies('(MIT OR GPL-2.0)', '(ISC OR MIT)'))
29
29
  assert(satisfies('(MIT AND GPL-2.0)', '(MIT AND GPL-2.0)'))
30
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'))
31
32
  assert(satisfies('(MIT OR GPL-2.0) AND ISC', 'MIT AND ISC'))
32
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'))
33
35
  assert(satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'Apache-2.0 AND ISC'))
34
36
  assert(satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'Apache-2.0 OR ISC'))
35
37
  assert(satisfies('(MIT AND GPL-2.0)', '(MIT OR GPL-2.0)'))
36
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))'))
37
41
  assert(!satisfies('(MIT AND GPL-2.0)', '(ISC OR GPL-2.0)'))
38
42
  assert(!satisfies('MIT AND (GPL-2.0 OR ISC)', 'MIT'))
39
43
  assert(!satisfies('(MIT OR Apache-2.0) AND (ISC OR GPL-2.0)', 'MIT'))
package/index.js CHANGED
@@ -58,38 +58,6 @@ var licensesAreCompatible = function (first, second) {
58
58
  }
59
59
  }
60
60
 
61
- var recurseLeftAndRight = function (first, second) {
62
- var firstConjunction = first.conjunction
63
- var secondConjunction = second.conjunction
64
-
65
- if (firstConjunction === 'and' && secondConjunction === 'and') {
66
- return (
67
- (recurse(first.left, second.left) && recurse(first.right, second.right)) ||
68
- (recurse(first.left, second.right) && recurse(first.right, second.left))
69
- )
70
- } else if (firstConjunction === 'and') {
71
- return (
72
- recurse(first.left, second) &&
73
- recurse(first.right, second)
74
- )
75
- } else if (firstConjunction === 'or') {
76
- return (
77
- recurse(first.left, second) ||
78
- recurse(first.right, second)
79
- )
80
- }
81
- }
82
-
83
- var recurse = function (first, second) {
84
- if (first.hasOwnProperty('conjunction')) {
85
- return recurseLeftAndRight(first, second)
86
- } else if (second.hasOwnProperty('conjunction')) {
87
- return recurseLeftAndRight(second, first)
88
- } else {
89
- return licensesAreCompatible(first, second)
90
- }
91
- }
92
-
93
61
  function normalizeGPLIdentifiers (argument) {
94
62
  var license = argument.license
95
63
  if (license) {
@@ -100,7 +68,7 @@ function normalizeGPLIdentifiers (argument) {
100
68
  argument.license = license.replace('-or-later', '')
101
69
  delete argument.plus
102
70
  }
103
- } else {
71
+ } else if (argument.left && argument.right) {
104
72
  argument.left = normalizeGPLIdentifiers(argument.left)
105
73
  argument.right = normalizeGPLIdentifiers(argument.right)
106
74
  }
@@ -111,9 +79,60 @@ function endsWith (string, substring) {
111
79
  return string.indexOf(substring) === string.length - 1
112
80
  }
113
81
 
114
- module.exports = function (first, second) {
115
- return recurse(
116
- normalizeGPLIdentifiers(parse(first)),
117
- normalizeGPLIdentifiers(parse(second))
118
- )
82
+ function licenseString (e) {
83
+ if (e.hasOwnProperty('noassertion')) return 'NOASSERTION'
84
+ if (e.license) return `${e.license}${e.plus ? '+' : ''}${e.exception ? ` WITH ${e.exception}` : ''}`
85
+ }
86
+
87
+ // Expand the given expression into an equivalent array where each member is an array of licenses AND'd
88
+ // together and the members are OR'd together. For example, `(MIT OR ISC) AND GPL-3.0` expands to
89
+ // `[[GPL-3.0 AND MIT], [ISC AND MIT]]`. Note that within each array of licenses, the entries are
90
+ // normalized (sorted) by license name.
91
+ 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]
102
+ }
103
+
104
+ function expandInner (expression) {
105
+ if (!expression.conjunction) return [{ [licenseString(expression)]: expression }]
106
+ if (expression.conjunction === 'or') return expandInner(expression.left).concat(expandInner(expression.right))
107
+ if (expression.conjunction === 'and') {
108
+ var left = expandInner(expression.left)
109
+ var right = expandInner(expression.right)
110
+ return left.reduce(function (result, l) {
111
+ right.forEach(function (r) { result.push(Object.assign({}, l, r)) })
112
+ return result
113
+ }, [])
114
+ }
115
+ }
116
+
117
+ function sort (licenseList) {
118
+ var sortedLicenseLists = licenseList
119
+ .filter(function (e) { return Object.keys(e).length })
120
+ .map(function (e) { return Object.keys(e).sort() })
121
+ return sortedLicenseLists.map(function (list, i) {
122
+ return list.map(function (license) { return licenseList[i][license] })
123
+ })
119
124
  }
125
+
126
+ function isANDCompatible (one, two) {
127
+ return one.every(function (o) {
128
+ return two.some(function (t) { return licensesAreCompatible(o, t) })
129
+ })
130
+ }
131
+
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) })
136
+ }
137
+
138
+ module.exports = satisfies
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "spdx-satisfies",
3
3
  "description": "test whether SPDX expressions satisfy licensing criteria",
4
- "version": "4.0.1",
4
+ "version": "5.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)",
8
- "Dan Butvinik <butvinik@outlook.com>"
8
+ "Dan Butvinik <butvinik@outlook.com>",
9
+ "Jeff McAffer <jeffmcaffer@gmail.com>"
9
10
  ],
10
11
  "dependencies": {
11
12
  "spdx-compare": "^1.0.0",
package/test.log DELETED
@@ -1,70 +0,0 @@
1
-
2
- > spdx-satisfies@4.0.0 test /home/kyle/spdx-satisfies.js
3
- > defence -i javascript README.md | replace-require-self | node
4
-
5
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"MIT"}}
6
- second is {"license":"MIT"}
7
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Zlib"}}}
8
- second is {"license":"Zlib"}
9
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Zlib"}}
10
- second is {"license":"Zlib"}
11
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"MIT"}}
12
- second is {"license":"GPL-3.0"}
13
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
14
- second is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"MIT"}}
15
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"MIT"}}
16
- second is {"license":"MIT"}
17
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"GPL-2.0"}}
18
- second is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"GPL-2.0"}}
19
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"left":{"license":"GPL-2.0"},"conjunction":"and","right":{"license":"ISC"}}}
20
- second is {"left":{"license":"MIT"},"conjunction":"and","right":{"left":{"license":"GPL-2.0"},"conjunction":"and","right":{"license":"ISC"}}}
21
- first is {"left":{"license":"GPL-2.0"},"conjunction":"and","right":{"license":"ISC"}}
22
- second is {"left":{"license":"GPL-2.0"},"conjunction":"and","right":{"license":"ISC"}}
23
- first is {"left":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}},"conjunction":"and","right":{"license":"ISC"}}
24
- second is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"ISC"}}
25
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
26
- second is {"license":"MIT"}
27
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"ISC"}}
28
- second is {"left":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}},"conjunction":"and","right":{"license":"ISC"}}
29
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
30
- second is {"license":"MIT"}
31
- first is {"left":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}},"conjunction":"and","right":{"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}}
32
- second is {"left":{"license":"Apache-2.0"},"conjunction":"and","right":{"license":"ISC"}}
33
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}}
34
- second is {"license":"Apache-2.0"}
35
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}
36
- second is {"license":"ISC"}
37
- first is {"left":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}},"conjunction":"and","right":{"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}}
38
- second is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
39
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}}
40
- second is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
41
- first is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
42
- second is {"license":"MIT"}
43
- first is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
44
- second is {"license":"Apache-2.0"}
45
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}
46
- second is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
47
- first is {"left":{"license":"Apache-2.0"},"conjunction":"or","right":{"license":"ISC"}}
48
- second is {"license":"ISC"}
49
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"GPL-2.0"}}
50
- second is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
51
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
52
- second is {"license":"MIT"}
53
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"GPL-2.0"}}
54
- second is {"license":"GPL-2.0"}
55
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"GPL-2.0"}}
56
- second is {"left":{"license":"GPL-2.0"},"conjunction":"and","right":{"license":"MIT"}}
57
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"license":"GPL-2.0"}}
58
- second is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}
59
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}
60
- second is {"license":"MIT"}
61
- first is {"left":{"license":"MIT"},"conjunction":"and","right":{"left":{"license":"GPL-2.0"},"conjunction":"or","right":{"license":"ISC"}}}
62
- second is {"license":"MIT"}
63
- first is {"left":{"license":"GPL-2.0"},"conjunction":"or","right":{"license":"ISC"}}
64
- second is {"license":"MIT"}
65
- first is {"left":{"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}},"conjunction":"and","right":{"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}}
66
- second is {"license":"MIT"}
67
- first is {"left":{"license":"MIT"},"conjunction":"or","right":{"license":"Apache-2.0"}}
68
- second is {"license":"MIT"}
69
- first is {"left":{"license":"ISC"},"conjunction":"or","right":{"license":"GPL-2.0"}}
70
- second is {"license":"MIT"}