licenseguard-cli 2.0.0 → 2.1.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.
@@ -1,146 +1,72 @@
1
1
  /**
2
- * Dependency License Scanner
3
- * Scans node_modules for license conflicts
2
+ * Dependency License Scanner - Orchestrator
3
+ * Auto-detects project type and delegates to appropriate plugin
4
4
  */
5
5
 
6
- const fs = require('fs')
7
- const path = require('path')
8
6
  const chalk = require('chalk')
9
- const { checkCompatibility } = require('./compat-checker')
10
- const { showProgress } = require('./progress')
11
7
 
12
- /**
13
- * Parse package.json to get dependencies
14
- * @returns {{deps: string[], packageJson: Object}} Dependency list and package.json
15
- */
16
- function parsePackageJson() {
17
- try {
18
- const content = fs.readFileSync('package.json', 'utf8')
19
- const packageJson = JSON.parse(content)
20
-
21
- // Only scan production dependencies
22
- const deps = Object.keys(packageJson.dependencies || {})
23
-
24
- return { deps, packageJson }
25
- } catch (error) {
26
- throw new Error('Failed to read package.json: ' + error.message)
27
- }
8
+ // Import explainCompatibility for --explain flag support
9
+ const { explainCompatibility } = require('./compat-checker')
10
+
11
+ // Import ecosystem plugins
12
+ const nodePlugin = require('./plugins/node')
13
+ const cppPlugin = require('./plugins/cpp')
14
+ const rustPlugin = require('./plugins/rust')
15
+ const pythonPlugin = require('./plugins/python')
16
+ const goPlugin = require('./plugins/go')
17
+
18
+ // Plugin registry with priority ordering
19
+ // Priority: node > cpp > rust > python > go
20
+ const plugins = {
21
+ node: nodePlugin,
22
+ cpp: cppPlugin,
23
+ rust: rustPlugin,
24
+ python: pythonPlugin,
25
+ go: goPlugin
28
26
  }
29
27
 
28
+ // Plugin detection order (first match wins)
29
+ const pluginOrder = ['node', 'cpp', 'rust', 'python', 'go']
30
+
30
31
  /**
31
- * Extract license info from a dependency
32
- * @param {string} depName - Dependency name
33
- * @returns {{name: string, version: string, license: string, path: string}} License info
32
+ * Auto-detect project type and get the appropriate plugin
33
+ * @returns {{name: string, plugin: Object}|null} Detected plugin or null
34
34
  */
35
- function extractLicense(depName) {
36
- const depPath = path.join('node_modules', depName, 'package.json')
37
-
38
- if (!fs.existsSync(depPath)) {
39
- return {
40
- name: depName,
41
- version: 'unknown',
42
- license: 'NOT_INSTALLED',
43
- path: depPath
44
- }
45
- }
46
-
47
- try {
48
- const content = fs.readFileSync(depPath, 'utf8')
49
- const depPackageJson = JSON.parse(content)
50
-
51
- return {
52
- name: depName,
53
- version: depPackageJson.version || 'unknown',
54
- license: depPackageJson.license || 'UNKNOWN',
55
- path: depPath
56
- }
57
- } catch (error) {
58
- return {
59
- name: depName,
60
- version: 'unknown',
61
- license: 'PARSE_ERROR',
62
- path: depPath
35
+ function detectPlugin() {
36
+ for (const name of pluginOrder) {
37
+ const plugin = plugins[name]
38
+ if (plugin && plugin.detect()) {
39
+ return { name, plugin }
63
40
  }
64
41
  }
42
+ return null
65
43
  }
66
44
 
67
45
  /**
68
46
  * Scan all dependencies for license compatibility
47
+ * Auto-detects project type and delegates to appropriate plugin
69
48
  * @param {string} projectLicense - The project's license
70
49
  * @returns {Promise<Object>} Scan results
71
50
  */
72
51
  async function scanDependencies(projectLicense) {
73
- // 1. Read project package.json
74
- const { deps } = parsePackageJson()
75
-
76
- const results = {
77
- timestamp: new Date().toISOString(),
78
- totalDependencies: deps.length,
79
- compatible: 0,
80
- incompatible: 0,
81
- unknown: 0,
82
- issues: []
83
- }
84
-
85
- // 2. Scan each dependency
86
- for (let i = 0; i < deps.length; i++) {
87
- showProgress(i + 1, deps.length)
88
-
89
- const depName = deps[i]
90
- const depInfo = extractLicense(depName)
52
+ const detected = detectPlugin()
91
53
 
92
- // Skip if not installed
93
- if (depInfo.license === 'NOT_INSTALLED') {
94
- continue
95
- }
96
-
97
- // Handle parse errors as unknown
98
- if (depInfo.license === 'PARSE_ERROR') {
99
- results.unknown++
100
- results.issues.push({
101
- package: `${depName}@${depInfo.version}`,
102
- license: 'UNKNOWN',
103
- type: 'warning',
104
- reason: 'Failed to parse package.json',
105
- location: depInfo.path
106
- })
107
- continue
108
- }
109
-
110
- // 3. Check compatibility
111
- const compatResult = checkCompatibility(projectLicense, depInfo.license)
112
-
113
- if (!compatResult.compatible) {
114
- const isUnknown = depInfo.license === 'UNKNOWN'
115
-
116
- if (isUnknown) {
117
- results.unknown++
118
- } else {
119
- results.incompatible++
120
- }
121
-
122
- results.issues.push({
123
- package: `${depName}@${depInfo.version}`,
124
- license: depInfo.license,
125
- type: isUnknown ? 'warning' : 'conflict',
126
- reason: compatResult.reason,
127
- location: depInfo.path
128
- })
129
- } else {
130
- results.compatible++
131
- }
54
+ if (!detected) {
55
+ throw new Error('No supported package manager detected')
132
56
  }
133
57
 
134
- return results
58
+ return await detected.plugin.scanDependencies(projectLicense)
135
59
  }
136
60
 
137
61
  /**
138
62
  * Display conflict report to console
139
63
  * @param {Object} scanResult - Scan results
140
64
  * @param {string} projectLicense - The project's license
65
+ * @param {Object} options - Display options
66
+ * @param {boolean} options.explain - Show authoritative source citations
141
67
  * @returns {boolean} True if conflicts found (incompatible licenses), false otherwise
142
68
  */
143
- function displayConflictReport(scanResult, projectLicense) {
69
+ function displayConflictReport(scanResult, projectLicense, options = {}) {
144
70
  if (scanResult.incompatible === 0 && scanResult.unknown === 0) {
145
71
  console.log(chalk.green(`\n✅ All ${scanResult.totalDependencies} dependencies compatible with ${projectLicense.toUpperCase()}!`))
146
72
  return false // No conflicts
@@ -163,7 +89,27 @@ function displayConflictReport(scanResult, projectLicense) {
163
89
  console.log(chalk.yellow(`⚠️ ${issue.package} (${issue.license})`))
164
90
  }
165
91
  console.log(chalk.gray(` ${issue.reason}`))
166
- console.log(chalk.gray(` Location: ${issue.location}\n`))
92
+ console.log(chalk.gray(` Location: ${issue.location}`))
93
+
94
+ // Show authoritative source citations when --explain is used
95
+ if (options.explain && issue.license && issue.license !== 'UNKNOWN') {
96
+ const explanation = explainCompatibility(projectLicense, issue.license)
97
+ // Extract source citation from explanation (after "📚 Source:")
98
+ const sourceMatch = explanation.match(/📚 Source: (.+?)(?:\n|$)/)
99
+ const urlMatch = explanation.match(/🔗 URL: (.+?)(?:\n|$)/)
100
+
101
+ if (sourceMatch || urlMatch) {
102
+ console.log(chalk.blue(' ────────────────────────'))
103
+ if (sourceMatch) {
104
+ console.log(chalk.blue(` 📚 ${sourceMatch[1]}`))
105
+ }
106
+ if (urlMatch) {
107
+ console.log(chalk.blue(` 🔗 ${urlMatch[1]}`))
108
+ }
109
+ }
110
+ }
111
+
112
+ console.log() // Blank line between issues
167
113
  }
168
114
 
169
115
  // Only return true if there are actual conflicts (incompatible licenses)
@@ -171,9 +117,15 @@ function displayConflictReport(scanResult, projectLicense) {
171
117
  return hasConflicts
172
118
  }
173
119
 
120
+ // Re-export plugin functions for backward compatibility
121
+ // These are deprecated but kept for BC
122
+ const { parsePackageJson, extractLicense } = nodePlugin
123
+
174
124
  module.exports = {
175
125
  scanDependencies,
176
126
  parsePackageJson,
177
127
  extractLicense,
178
- displayConflictReport
128
+ displayConflictReport,
129
+ // Additional exports for testing
130
+ detectPlugin
179
131
  }
@@ -0,0 +1,338 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "last_updated": "2025-11-22",
4
+ "description": "Authoritative license compatibility matrix for top 20 open source licenses covering ~95% of packages",
5
+ "methodology": "Based on FSF GPL Compatibility List, Mozilla MPL FAQ, Apache Foundation guidance, and SPDX specifications",
6
+
7
+ "sources": {
8
+ "fsf_gpl_compat": {
9
+ "title": "FSF GPL Compatibility List",
10
+ "url": "https://www.gnu.org/licenses/license-compatibility.html"
11
+ },
12
+ "fsf_license_list": {
13
+ "title": "FSF License List",
14
+ "url": "https://www.gnu.org/licenses/license-list.html"
15
+ },
16
+ "mozilla_mpl_faq": {
17
+ "title": "Mozilla MPL 2.0 FAQ",
18
+ "url": "https://www.mozilla.org/en-US/MPL/2.0/FAQ/"
19
+ },
20
+ "mozilla_mpl_gpl": {
21
+ "title": "Mozilla MPL-GPL Combining Guide",
22
+ "url": "https://www.mozilla.org/en-US/MPL/2.0/combining-mpl-and-gpl/"
23
+ },
24
+ "apache_gpl_compat": {
25
+ "title": "Apache-GPL Compatibility",
26
+ "url": "https://www.apache.org/licenses/GPL-compatibility.html"
27
+ },
28
+ "spdx_spec": {
29
+ "title": "SPDX License Expressions",
30
+ "url": "https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/"
31
+ },
32
+ "lgpl_section_3": {
33
+ "title": "LGPL Section 3 (Upgrade Clause)",
34
+ "url": "https://www.gnu.org/licenses/lgpl-3.0.html#section3"
35
+ }
36
+ },
37
+
38
+ "licenses": {
39
+ "MIT": {
40
+ "type": "permissive",
41
+ "description": "Highly permissive license with minimal restrictions",
42
+ "compatible_with": ["*permissive*"],
43
+ "incompatible_with": ["*copyleft*"],
44
+ "can_upgrade_from": [],
45
+ "sources": {
46
+ "citation": "FSF: MIT license is permissive and GPL-compatible",
47
+ "url": "https://www.gnu.org/licenses/license-list.html#Expat"
48
+ },
49
+ "reasoning": "Permissive licenses cannot incorporate copyleft-licensed code without violating copyleft requirements"
50
+ },
51
+
52
+ "Apache-2.0": {
53
+ "type": "permissive-with-patent-grant",
54
+ "description": "Permissive license with explicit patent grant",
55
+ "compatible_with": ["*permissive*", "GPL-3.0-only", "GPL-3.0-or-later"],
56
+ "incompatible_with": ["GPL-2.0-only", "GPL-2.0-or-later", "LGPL-2.1-only", "LGPL-2.1-or-later"],
57
+ "can_upgrade_from": [],
58
+ "sources": {
59
+ "citation": "Apache 2.0 patent clause incompatible with GPL-2.0, but compatible with GPL-3.0",
60
+ "url": "https://www.apache.org/licenses/GPL-compatibility.html"
61
+ },
62
+ "reasoning": "Apache 2.0's patent grant conflicts with GPLv2 section 6, but GPLv3 was designed to resolve this"
63
+ },
64
+
65
+ "BSD-3-Clause": {
66
+ "type": "permissive",
67
+ "description": "Permissive BSD license with 3 clauses",
68
+ "compatible_with": ["*permissive*"],
69
+ "incompatible_with": ["*copyleft*"],
70
+ "can_upgrade_from": [],
71
+ "sources": {
72
+ "citation": "FSF: 3-clause BSD is permissive and GPL-compatible",
73
+ "url": "https://www.gnu.org/licenses/license-list.html#ModifiedBSD"
74
+ },
75
+ "reasoning": "Permissive license, same reasoning as MIT"
76
+ },
77
+
78
+ "BSD-2-Clause": {
79
+ "type": "permissive",
80
+ "description": "Simplified BSD license with 2 clauses",
81
+ "compatible_with": ["*permissive*"],
82
+ "incompatible_with": ["*copyleft*"],
83
+ "can_upgrade_from": [],
84
+ "sources": {
85
+ "citation": "FSF: 2-clause BSD is permissive and GPL-compatible",
86
+ "url": "https://www.gnu.org/licenses/license-list.html#FreeBSD"
87
+ },
88
+ "reasoning": "Even more permissive than BSD-3-Clause"
89
+ },
90
+
91
+ "ISC": {
92
+ "type": "permissive",
93
+ "description": "Functionally equivalent to MIT/BSD-2-Clause",
94
+ "compatible_with": ["*permissive*"],
95
+ "incompatible_with": ["*copyleft*"],
96
+ "can_upgrade_from": [],
97
+ "sources": {
98
+ "citation": "FSF: ISC license is permissive and GPL-compatible",
99
+ "url": "https://www.gnu.org/licenses/license-list.html#ISC"
100
+ },
101
+ "reasoning": "Permissive license, same reasoning as MIT"
102
+ },
103
+
104
+ "0BSD": {
105
+ "type": "public-domain",
106
+ "description": "BSD Zero Clause (public domain equivalent)",
107
+ "compatible_with": ["*"],
108
+ "incompatible_with": [],
109
+ "can_upgrade_from": [],
110
+ "sources": {
111
+ "citation": "FSF: 0BSD is ultra-permissive public domain equivalent",
112
+ "url": "https://www.gnu.org/licenses/license-list.html#0BSD"
113
+ },
114
+ "reasoning": "Public domain equivalent - compatible with everything"
115
+ },
116
+
117
+ "GPL-3.0-only": {
118
+ "type": "strong-copyleft",
119
+ "description": "GNU General Public License v3.0",
120
+ "compatible_with": ["*permissive*", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
121
+ "incompatible_with": ["GPL-2.0-only", "AGPL-3.0-only", "AGPL-3.0-or-later"],
122
+ "can_upgrade_from": ["LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later"],
123
+ "sources": {
124
+ "citation": "FSF: GPL-3.0 is compatible with LGPL (via Section 3 upgrade), Apache-2.0, MPL-2.0",
125
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility"
126
+ },
127
+ "reasoning": "Strong copyleft - requires all combined code to be GPL-3.0. LGPL can upgrade to GPL (Section 3). MPL 2.0 Section 3.3 allows GPL combination. Apache-2.0 patent clause resolved in GPLv3."
128
+ },
129
+
130
+ "GPL-3.0-or-later": {
131
+ "type": "strong-copyleft",
132
+ "description": "GNU General Public License v3.0 or any later version",
133
+ "compatible_with": ["*permissive*", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
134
+ "incompatible_with": ["GPL-2.0-only"],
135
+ "can_upgrade_from": ["LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later"],
136
+ "sources": {
137
+ "citation": "FSF: GPL-3.0-or-later provides upgrade path flexibility",
138
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#VersionThreeOrLater"
139
+ },
140
+ "reasoning": "Same as GPL-3.0-only but with upgrade flexibility"
141
+ },
142
+
143
+ "GPL-2.0-only": {
144
+ "type": "strong-copyleft",
145
+ "description": "GNU General Public License v2.0",
146
+ "compatible_with": ["*permissive*", "GPL-2.0-only", "GPL-2.0-or-later", "LGPL-2.1-only", "LGPL-2.1-or-later"],
147
+ "incompatible_with": ["GPL-3.0-only", "GPL-3.0-or-later", "Apache-2.0", "MPL-2.0"],
148
+ "can_upgrade_from": ["LGPL-2.1-only", "LGPL-2.1-or-later"],
149
+ "sources": {
150
+ "citation": "FSF: GPL-2.0 incompatible with Apache-2.0 (patent clause), MPL-2.0, and GPL-3.0",
151
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#v2v3Compatibility"
152
+ },
153
+ "reasoning": "Strong copyleft. Incompatible with Apache-2.0 (patent clause conflict), MPL-2.0 (file-level copyleft incompatibility), and GPL-3.0 (different copyleft terms)"
154
+ },
155
+
156
+ "GPL-2.0-or-later": {
157
+ "type": "strong-copyleft",
158
+ "description": "GNU General Public License v2.0 or any later version",
159
+ "compatible_with": ["*permissive*", "GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
160
+ "incompatible_with": [],
161
+ "can_upgrade_from": ["LGPL-2.1-or-later", "LGPL-3.0-or-later"],
162
+ "sources": {
163
+ "citation": "FSF: GPL-2.0-or-later can upgrade to GPL-3.0, resolving compatibility issues",
164
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#v2v3Compatibility"
165
+ },
166
+ "reasoning": "Upgrade path to GPL-3.0 resolves Apache-2.0 and MPL-2.0 incompatibilities"
167
+ },
168
+
169
+ "LGPL-2.1-only": {
170
+ "type": "weak-copyleft",
171
+ "description": "GNU Lesser General Public License v2.1",
172
+ "compatible_with": ["*permissive*", "GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-2.1-or-later"],
173
+ "incompatible_with": ["Apache-2.0"],
174
+ "can_upgrade_from": [],
175
+ "sources": {
176
+ "citation": "LGPL Section 3: Can upgrade to corresponding GPL version",
177
+ "url": "https://www.gnu.org/licenses/lgpl-3.0.html#section3"
178
+ },
179
+ "reasoning": "Weak copyleft - Section 3 allows upgrading to GPL. Incompatible with Apache-2.0 due to GPLv2 patent clause conflict."
180
+ },
181
+
182
+ "LGPL-2.1-or-later": {
183
+ "type": "weak-copyleft",
184
+ "description": "GNU Lesser General Public License v2.1 or any later version",
185
+ "compatible_with": ["*permissive*", "GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
186
+ "incompatible_with": [],
187
+ "can_upgrade_from": [],
188
+ "sources": {
189
+ "citation": "LGPL Section 3: Upgrade path to GPL resolves incompatibilities",
190
+ "url": "https://www.gnu.org/licenses/lgpl-3.0.html#section3"
191
+ },
192
+ "reasoning": "Can upgrade to LGPL-3.0 or GPL-3.0, resolving Apache-2.0 incompatibility"
193
+ },
194
+
195
+ "LGPL-3.0-only": {
196
+ "type": "weak-copyleft",
197
+ "description": "GNU Lesser General Public License v3.0",
198
+ "compatible_with": ["*permissive*", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
199
+ "incompatible_with": ["GPL-2.0-only", "GPL-2.0-or-later"],
200
+ "can_upgrade_from": [],
201
+ "sources": {
202
+ "citation": "LGPL-3.0 Section 3: Can upgrade to GPL-3.0",
203
+ "url": "https://www.gnu.org/licenses/lgpl-3.0.html#section3"
204
+ },
205
+ "reasoning": "Weak copyleft with GPL upgrade path. Compatible with Apache-2.0 and MPL-2.0 via GPL-3.0 upgrade."
206
+ },
207
+
208
+ "LGPL-3.0-or-later": {
209
+ "type": "weak-copyleft",
210
+ "description": "GNU Lesser General Public License v3.0 or any later version",
211
+ "compatible_with": ["*permissive*", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
212
+ "incompatible_with": ["GPL-2.0-only", "GPL-2.0-or-later"],
213
+ "can_upgrade_from": [],
214
+ "sources": {
215
+ "citation": "LGPL-3.0-or-later provides upgrade flexibility",
216
+ "url": "https://www.gnu.org/licenses/lgpl-3.0.html"
217
+ },
218
+ "reasoning": "Same as LGPL-3.0-only but with upgrade flexibility"
219
+ },
220
+
221
+ "MPL-2.0": {
222
+ "type": "weak-copyleft",
223
+ "description": "Mozilla Public License 2.0 (file-level copyleft)",
224
+ "compatible_with": ["*permissive*", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "MPL-2.0", "Apache-2.0"],
225
+ "incompatible_with": ["GPL-2.0-only", "LGPL-2.1-only"],
226
+ "can_upgrade_from": [],
227
+ "sources": {
228
+ "citation": "MPL 2.0 Section 3.3: Secondary licenses allow GPL combination",
229
+ "url": "https://www.mozilla.org/en-US/MPL/2.0/combining-mpl-and-gpl/"
230
+ },
231
+ "reasoning": "Section 3.3 allows MPL-2.0 code to be relicensed under GPL/LGPL when combined. Incompatible with GPL-2.0-only due to terms conflict."
232
+ },
233
+
234
+ "AGPL-3.0-only": {
235
+ "type": "network-copyleft",
236
+ "description": "GNU Affero General Public License v3.0 (network use = distribution)",
237
+ "compatible_with": ["*permissive*", "AGPL-3.0-only", "AGPL-3.0-or-later", "Apache-2.0"],
238
+ "incompatible_with": ["GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later"],
239
+ "can_upgrade_from": [],
240
+ "sources": {
241
+ "citation": "FSF: AGPL-3.0 incompatible with GPL (stricter terms)",
242
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility"
243
+ },
244
+ "reasoning": "Network copyleft - stricter than GPL. Cannot combine AGPL with GPL due to additional restrictions."
245
+ },
246
+
247
+ "AGPL-3.0-or-later": {
248
+ "type": "network-copyleft",
249
+ "description": "GNU Affero General Public License v3.0 or any later version",
250
+ "compatible_with": ["*permissive*", "AGPL-3.0-only", "AGPL-3.0-or-later", "Apache-2.0"],
251
+ "incompatible_with": ["GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later"],
252
+ "can_upgrade_from": [],
253
+ "sources": {
254
+ "citation": "FSF: AGPL-3.0-or-later incompatible with GPL",
255
+ "url": "https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility"
256
+ },
257
+ "reasoning": "Same as AGPL-3.0-only"
258
+ },
259
+
260
+ "Unlicense": {
261
+ "type": "public-domain",
262
+ "description": "Public domain dedication",
263
+ "compatible_with": ["*"],
264
+ "incompatible_with": [],
265
+ "can_upgrade_from": [],
266
+ "sources": {
267
+ "citation": "Public domain dedication - no restrictions",
268
+ "url": "https://unlicense.org/"
269
+ },
270
+ "reasoning": "No restrictions - compatible with everything"
271
+ },
272
+
273
+ "CC0-1.0": {
274
+ "type": "public-domain",
275
+ "description": "Creative Commons Zero (public domain)",
276
+ "compatible_with": ["*"],
277
+ "incompatible_with": [],
278
+ "can_upgrade_from": [],
279
+ "sources": {
280
+ "citation": "Public domain waiver - no restrictions",
281
+ "url": "https://creativecommons.org/publicdomain/zero/1.0/"
282
+ },
283
+ "reasoning": "Public domain waiver - compatible with everything"
284
+ },
285
+
286
+ "WTFPL": {
287
+ "type": "public-domain",
288
+ "description": "Do What The F*ck You Want To Public License",
289
+ "compatible_with": ["*"],
290
+ "incompatible_with": [],
291
+ "can_upgrade_from": [],
292
+ "sources": {
293
+ "citation": "Ultra-permissive - no restrictions",
294
+ "url": "http://www.wtfpl.net/"
295
+ },
296
+ "reasoning": "No restrictions - compatible with everything"
297
+ }
298
+ },
299
+
300
+ "wildcards": {
301
+ "*permissive*": [
302
+ "MIT",
303
+ "Apache-2.0",
304
+ "BSD-3-Clause",
305
+ "BSD-2-Clause",
306
+ "BSD-1-Clause",
307
+ "ISC",
308
+ "0BSD",
309
+ "Zlib",
310
+ "bzip2-1.0.6",
311
+ "BSL-1.0",
312
+ "PSF-2.0"
313
+ ],
314
+ "*copyleft*": [
315
+ "GPL-2.0-only",
316
+ "GPL-2.0-or-later",
317
+ "GPL-3.0-only",
318
+ "GPL-3.0-or-later",
319
+ "LGPL-2.1-only",
320
+ "LGPL-2.1-or-later",
321
+ "LGPL-3.0-only",
322
+ "LGPL-3.0-or-later",
323
+ "MPL-2.0",
324
+ "MPL-1.1",
325
+ "AGPL-3.0-only",
326
+ "AGPL-3.0-or-later",
327
+ "EPL-2.0",
328
+ "EUPL-1.2",
329
+ "CDDL-1.0"
330
+ ],
331
+ "*public-domain*": [
332
+ "Unlicense",
333
+ "CC0-1.0",
334
+ "WTFPL",
335
+ "0BSD"
336
+ ]
337
+ }
338
+ }