@cyclonedx/cdxgen 9.9.0 → 9.9.2

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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![cdxgen logo](cdxgen.png)
4
4
 
5
- cdxgen is a cli tool, library, [REPL](./ADVANCED.md), and server to create a valid and compliant [CycloneDX][cyclonedx-homepage] Software Bill of Materials (SBOM) containing an aggregate of all project dependencies for c/c++, node.js, php, python, ruby, rust, java, .Net, dart, haskell, elixir, and Go projects in JSON format. CycloneDX 1.5 is a lightweight SBOM specification that is easily created, human and machine-readable, and simple to parse.
5
+ cdxgen is a CLI tool, library, [REPL](./ADVANCED.md), and server to create a valid and compliant [CycloneDX][cyclonedx-homepage] Software Bill of Materials (SBOM) containing an aggregate of all project dependencies for C/C++, Node.js, PHP, Python, Ruby, Rust, Java, .Net, Dart, Haskell, Elixir, and Go projects in JSON format. CycloneDX 1.5 is a lightweight SBOM specification that is easily created, human and machine-readable, and simple to parse.
6
6
 
7
7
  When used with plugins, cdxgen could generate an OBOM for Linux docker images and even VMs running Linux or Windows operating systems. cdxgen also includes an evinse tool to generate component evidence and SaaSBOM for some languages.
8
8
 
@@ -20,21 +20,21 @@ Most SBOM tools are like barcode scanners. They can scan a few package manifest
20
20
 
21
21
  | Language/Platform | Package format | Transitive dependencies | Evidence |
22
22
  | ------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------- |
23
- | node.js | npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js | Yes except .min.js | Yes |
24
- | java | maven (pom.xml [1]), gradle (build.gradle, .kts), scala (sbt), bazel | Yes unless pom.xml is manually parsed due to unavailability of maven or errors | Yes |
25
- | php | composer.lock | Yes | |
26
- | python | pyproject.toml, setup.py, requirements.txt [2], Pipfile.lock, poetry.lock, pdm.lock, bdist_wheel, .whl, .egg-info | Yes using the automatic pip install/freeze. When disabled, only with Pipfile.lock and poetry.lock | Yes |
27
- | go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary | Yes |
28
- | ruby | Gemfile.lock, gemspec | Only for Gemfile.lock | |
29
- | rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock | |
23
+ | Node.js | npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js | Yes except .min.js | Yes |
24
+ | Java | maven (pom.xml [1]), gradle (build.gradle, .kts), scala (sbt), bazel | Yes unless pom.xml is manually parsed due to unavailability of maven or errors | Yes |
25
+ | PHP | composer.lock | Yes | |
26
+ | Python | pyproject.toml, setup.py, requirements.txt [2], Pipfile.lock, poetry.lock, pdm.lock, bdist_wheel, .whl, .egg-info | Yes using the automatic pip install/freeze. When disabled, only with Pipfile.lock and poetry.lock | Yes |
27
+ | Go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary | Yes |
28
+ | Ruby | Gemfile.lock, gemspec | Only for Gemfile.lock | |
29
+ | Rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock | |
30
30
  | .Net | .csproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock | Only for project.assets.json, packages.lock.json, paket.lock | |
31
- | dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock | |
32
- | haskell | cabal.project.freeze | Yes | |
33
- | elixir | mix.lock | Yes | |
34
- | c/c++/Objective C/c++11 | conan.lock, conanfile.txt, \*.cmake, CMakeLists.txt, meson.build, codebase without package managers! | Yes only for conan.lock. Best effort basis for cmake without version numbers. | Yes |
35
- | clojure | Clojure CLI (deps.edn), Leiningen (project.clj) | Yes unless the files are parsed manually due to lack of clojure cli or leiningen command | |
36
- | swift | Package.resolved, Package.swift (swiftpm) | Yes | |
37
- | docker / oci image | All supported languages. Linux OS packages with plugins [4] | Best effort based on lock files | Yes |
31
+ | Dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock | |
32
+ | Haskell | cabal.project.freeze | Yes | |
33
+ | Elixir | mix.lock | Yes | |
34
+ | C/C++/Objective C/C++11 | conan.lock, conanfile.txt, \*.cmake, CMakeLists.txt, meson.build, codebase without package managers! | Yes only for conan.lock. Best effort basis for cmake without version numbers. | Yes |
35
+ | Clojure | Clojure CLI (deps.edn), Leiningen (project.clj) | Yes unless the files are parsed manually due to lack of clojure cli or leiningen command | |
36
+ | Swift | Package.resolved, Package.swift (swiftpm) | Yes | |
37
+ | Docker / oci image | All supported languages. Linux OS packages with plugins [4] | Best effort based on lock files | Yes |
38
38
  | GitHub Actions | .github/workflows/\*.yml | N/A | Yes |
39
39
  | Linux | All supported languages. Linux OS packages with plugins [5] | Best effort based on lock files | Yes |
40
40
  | Windows | All supported languages. OS packages with best effort [5] | Best effort based on lock files | Yes |
@@ -170,10 +170,7 @@ Options:
170
170
  faults to true. Pass --no-validate to disable.
171
171
  [boolean] [default: true]
172
172
  --evidence Generate SBOM with evidence for supported languag
173
- es. WIP [boolean] [default: false]
174
- --usages-slices-file Path for the usages slice file created by atom.
175
- --data-flow-slices-file Path for the data-flow slice file created by atom
176
- .
173
+ es. [boolean] [default: false]
177
174
  --spec-version CycloneDX Specification version to use. Defaults
178
175
  to 1.5 [default: 1.5]
179
176
  --filter Filter components containining this word in purl.
@@ -184,6 +181,10 @@ Options:
184
181
  --author The person(s) who created the BOM. Set this value
185
182
  if you're intending the modify the BOM and claim
186
183
  authorship.[array] [default: "OWASP Foundation"]
184
+ --profile BOM profile to use for generation. Default generi
185
+ c.
186
+ [choices: "appsec", "research", "operational", "threat-modeling", "license-com
187
+ pliance", "generic"] [default: "generic"]
187
188
  --auto-compositions Automatically set compositions when the BOM was f
188
189
  iltered. Defaults to true
189
190
  [boolean] [default: true]
@@ -376,7 +377,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
376
377
  | SBOM_SIGN_ALGORITHM | Signature algorithm. Some valid values are RS256, RS384, RS512, PS256, PS384, PS512, ES256 etc |
377
378
  | SBOM_SIGN_PRIVATE_KEY | Private key to use for signing |
378
379
  | SBOM_SIGN_PUBLIC_KEY | Optional. Public key to include in the SBOM signature |
379
- | CDX_MAVEN_PLUGIN | CycloneDX Maven plugin to use. Default "org.cyclonedx:cyclonedx-maven-plugin:2.7.8" |
380
+ | CDX_MAVEN_PLUGIN | CycloneDX Maven plugin to use. Default "org.cyclonedx:cyclonedx-maven-plugin:2.7.10" |
380
381
  | CDX_MAVEN_GOAL | CycloneDX Maven plugin goal to use. Default makeAggregateBom. Other options: makeBom, makePackageBom |
381
382
  | CDX_MAVEN_INCLUDE_TEST_SCOPE | Whether test scoped dependencies should be included from Maven projects, Default: true |
382
383
  | ASTGEN_IGNORE_DIRS | Comma separated list of directories to ignore while analyzing using babel. The environment variable is also used by atom and astgen. |
@@ -399,7 +400,7 @@ sudo npm install -g @cyclonedx/cdxgen-plugins-bin
399
400
  cdxgen odoo@sha256:4e1e147f0e6714e8f8c5806d2b484075b4076ca50490577cdf9162566086d15e -o /tmp/bom.json
400
401
  ```
401
402
 
402
- You can also pass `-t docker` for simple labels. Only the `latest` tag would be pulled if none was specified.
403
+ You can also pass `-t docker` with repository names. Only the `latest` tag would be pulled if none was specified.
403
404
 
404
405
  ```shell
405
406
  cdxgen shiftleft/scan-slim -o /tmp/bom.json -t docker
package/bin/cdxgen.js CHANGED
@@ -10,10 +10,18 @@ import crypto from "node:crypto";
10
10
  import { fileURLToPath } from "node:url";
11
11
  import globalAgent from "global-agent";
12
12
  import process from "node:process";
13
- import { printTable, printDependencyTree } from "../display.js";
13
+ import {
14
+ printCallStack,
15
+ printOccurrences,
16
+ printServices,
17
+ printReachables,
18
+ printTable,
19
+ printDependencyTree
20
+ } from "../display.js";
14
21
  import { findUpSync } from "find-up";
15
22
  import { load as _load } from "js-yaml";
16
23
  import { postProcess } from "../postgen.js";
24
+ import { ATOM_DB } from "../utils.js";
17
25
 
18
26
  // Support for config files
19
27
  const configPath = findUpSync([
@@ -48,7 +56,14 @@ const args = yargs(hideBin(process.argv))
48
56
  .env("CDXGEN")
49
57
  .option("output", {
50
58
  alias: "o",
51
- description: "Output file for bom.xml or bom.json. Default bom.json"
59
+ description: "Output file for bom.xml or bom.json. Default bom.json",
60
+ default: "bom.json"
61
+ })
62
+ .option("evinse-output", {
63
+ description:
64
+ "Create bom with evidence as a separate file. Default bom.json",
65
+ default: "bom.json",
66
+ hidden: true
52
67
  })
53
68
  .option("type", {
54
69
  alias: "t",
@@ -90,14 +105,17 @@ const args = yargs(hideBin(process.argv))
90
105
  })
91
106
  .option("project-version", {
92
107
  description: "Dependency track project version",
93
- default: ""
108
+ default: "",
109
+ type: "string"
94
110
  })
95
111
  .option("project-id", {
96
112
  description:
97
- "Dependency track project id. Either provide the id or the project name and version together"
113
+ "Dependency track project id. Either provide the id or the project name and version together",
114
+ type: "string"
98
115
  })
99
116
  .option("parent-project-id", {
100
- description: "Dependency track parent project id"
117
+ description: "Dependency track parent project id",
118
+ type: "string"
101
119
  })
102
120
  .option("required-only", {
103
121
  type: "boolean",
@@ -143,20 +161,34 @@ const args = yargs(hideBin(process.argv))
143
161
  "Validate the generated SBOM using json schema. Defaults to true. Pass --no-validate to disable."
144
162
  })
145
163
  .option("evidence", {
146
- hidden: true,
147
164
  type: "boolean",
148
165
  default: false,
149
- description: "Generate SBOM with evidence for supported languages. WIP"
166
+ description: "Generate SBOM with evidence for supported languages."
167
+ })
168
+ .option("deps-slices-file", {
169
+ description: "Path for the parsedeps slice file created by atom.",
170
+ default: "deps.slices.json",
171
+ hidden: true
150
172
  })
151
173
  .option("usages-slices-file", {
152
- description: "Path for the usages slice file created by atom."
174
+ description: "Path for the usages slices file created by atom.",
175
+ default: "usages.slices.json",
176
+ hidden: true
153
177
  })
154
178
  .option("data-flow-slices-file", {
155
- description: "Path for the data-flow slice file created by atom."
179
+ description: "Path for the data-flow slices file created by atom.",
180
+ default: "data-flow.slices.json",
181
+ hidden: true
182
+ })
183
+ .option("reachables-slices-file", {
184
+ description: "Path for the reachables slices file created by atom.",
185
+ default: "reachables.slices.json",
186
+ hidden: true
156
187
  })
157
188
  .option("spec-version", {
158
189
  description: "CycloneDX Specification version to use. Defaults to 1.5",
159
- default: 1.5
190
+ default: 1.5,
191
+ type: "number"
160
192
  })
161
193
  .option("filter", {
162
194
  description:
@@ -171,6 +203,18 @@ const args = yargs(hideBin(process.argv))
171
203
  "The person(s) who created the BOM. Set this value if you're intending the modify the BOM and claim authorship.",
172
204
  default: "OWASP Foundation"
173
205
  })
206
+ .option("profile", {
207
+ description: "BOM profile to use for generation. Default generic.",
208
+ default: "generic",
209
+ choices: [
210
+ "appsec",
211
+ "research",
212
+ "operational",
213
+ "threat-modeling",
214
+ "license-compliance",
215
+ "generic"
216
+ ]
217
+ })
174
218
  .completion("completion", "Generate bash/zsh completion")
175
219
  .array("filter")
176
220
  .array("only")
@@ -226,6 +270,32 @@ if (process.argv[1].includes("obom") && !args.type) {
226
270
  args.type = "os";
227
271
  }
228
272
 
273
+ const applyProfile = (options) => {
274
+ switch (options.profile) {
275
+ case "appsec":
276
+ options.deep = true;
277
+ break;
278
+ case "research":
279
+ options.deep = true;
280
+ options.evidence = true;
281
+ process.env.CDX_MAVEN_INCLUDE_TEST_SCOPE = true;
282
+ process.env.ASTGEN_IGNORE_DIRS = "";
283
+ process.env.ASTGEN_IGNORE_FILE_PATTERN = "";
284
+ break;
285
+ case "operational":
286
+ options.projectType = options.projectType || "os";
287
+ break;
288
+ case "threat-modeling": // unused
289
+ break;
290
+ case "license-compliance":
291
+ process.env.FETCH_LICENSE = true;
292
+ break;
293
+ default:
294
+ break;
295
+ }
296
+ return options;
297
+ };
298
+
229
299
  /**
230
300
  * Command line options
231
301
  */
@@ -233,8 +303,10 @@ const options = Object.assign({}, args, {
233
303
  projectType: args.type,
234
304
  multiProject: args.recurse,
235
305
  noBabel: args.noBabel || args.babel === false,
236
- project: args.projectId
306
+ project: args.projectId,
307
+ deep: args.deep || args.evidence
237
308
  });
309
+ applyProfile(options);
238
310
 
239
311
  /**
240
312
  * Check for node >= 20 permissions
@@ -273,7 +345,7 @@ const checkPermissions = (filePath) => {
273
345
  */
274
346
  (async () => {
275
347
  // Start SBOM server
276
- if (args.server) {
348
+ if (options.server) {
277
349
  const serverModule = await import("../server.js");
278
350
  return serverModule.start(options);
279
351
  }
@@ -289,19 +361,16 @@ const checkPermissions = (filePath) => {
289
361
  if (options.requiredOnly || options["filter"] || options["only"]) {
290
362
  bomNSData = postProcess(bomNSData, options);
291
363
  }
292
- if (!args.output) {
293
- args.output = "bom.json";
294
- }
295
364
  if (
296
- args.output &&
297
- (typeof args.output === "string" || args.output instanceof String)
365
+ options.output &&
366
+ (typeof options.output === "string" || options.output instanceof String)
298
367
  ) {
299
368
  if (bomNSData.bomXmlFiles) {
300
369
  console.log("BOM files produced:", bomNSData.bomXmlFiles);
301
370
  } else {
302
- const jsonFile = args.output.replace(".xml", ".json");
371
+ const jsonFile = options.output.replace(".xml", ".json");
303
372
  // Create bom json file
304
- if (!args.output.endsWith(".xml") && bomNSData.bomJson) {
373
+ if (!options.output.endsWith(".xml") && bomNSData.bomJson) {
305
374
  let jsonPayload = undefined;
306
375
  if (
307
376
  typeof bomNSData.bomJson === "string" ||
@@ -315,7 +384,7 @@ const checkPermissions = (filePath) => {
315
384
  }
316
385
  if (
317
386
  jsonPayload &&
318
- (args.generateKeyAndSign ||
387
+ (options.generateKeyAndSign ||
319
388
  (process.env.SBOM_SIGN_ALGORITHM &&
320
389
  process.env.SBOM_SIGN_ALGORITHM !== "none" &&
321
390
  process.env.SBOM_SIGN_PRIVATE_KEY &&
@@ -328,7 +397,7 @@ const checkPermissions = (filePath) => {
328
397
  let privateKeyToUse = undefined;
329
398
  let jwkPublicKey = undefined;
330
399
  let publicKeyFile = undefined;
331
- if (args.generateKeyAndSign) {
400
+ if (options.generateKeyAndSign) {
332
401
  const jdirName = dirname(jsonFile);
333
402
  publicKeyFile = join(jdirName, "public.key");
334
403
  const privateKeyFile = join(jdirName, "private.key");
@@ -438,8 +507,8 @@ const checkPermissions = (filePath) => {
438
507
  }
439
508
  }
440
509
  // Create bom xml file
441
- if (args.output.endsWith(".xml") && bomNSData.bomXml) {
442
- fs.writeFileSync(args.output, bomNSData.bomXml);
510
+ if (options.output.endsWith(".xml") && bomNSData.bomXml) {
511
+ fs.writeFileSync(options.output, bomNSData.bomXml);
443
512
  }
444
513
  //
445
514
  if (bomNSData.nsMapping && Object.keys(bomNSData.nsMapping).length) {
@@ -448,7 +517,7 @@ const checkPermissions = (filePath) => {
448
517
  console.log("Namespace mapping file written to", nsFile);
449
518
  }
450
519
  }
451
- } else if (!args.print) {
520
+ } else if (!options.print) {
452
521
  if (bomNSData.bomJson) {
453
522
  console.log(JSON.stringify(bomNSData.bomJson, null, 2));
454
523
  } else if (bomNSData.bomXml) {
@@ -458,23 +527,58 @@ const checkPermissions = (filePath) => {
458
527
  console.log("Try running the command with -t <type> or -r argument");
459
528
  }
460
529
  }
530
+ // Evidence generation
531
+ if (options.evidence) {
532
+ const evinserModule = await import("../evinser.js");
533
+ const evinseOptions = {
534
+ _: args._,
535
+ input: options.output,
536
+ output: options.evinseOutput,
537
+ language: options.projectType || "java",
538
+ dbPath: process.env.ATOM_DB || ATOM_DB,
539
+ skipMavenCollector: false,
540
+ force: false,
541
+ withReachables: options.deep,
542
+ usagesSlicesFile: options.usagesSlicesFile,
543
+ dataFlowSlicesFile: options.dataFlowSlicesFile,
544
+ reachablesSlicesFile: options.reachablesSlicesFile
545
+ };
546
+ const dbObjMap = await evinserModule.prepareDB(evinseOptions);
547
+ if (dbObjMap) {
548
+ const sliceArtefacts = await evinserModule.analyzeProject(
549
+ dbObjMap,
550
+ evinseOptions
551
+ );
552
+ const evinseJson = evinserModule.createEvinseFile(
553
+ sliceArtefacts,
554
+ evinseOptions
555
+ );
556
+ bomNSData.bomJson = evinseJson;
557
+ if (options.print && evinseJson) {
558
+ printOccurrences(evinseJson);
559
+ printCallStack(evinseJson);
560
+ printReachables(sliceArtefacts);
561
+ printServices(evinseJson);
562
+ }
563
+ }
564
+ }
461
565
  // Perform automatic validation
462
- if (args.validate) {
566
+ if (options.validate) {
463
567
  if (!validateBom(bomNSData.bomJson)) {
464
568
  process.exit(1);
465
569
  }
466
570
  }
467
571
  // Automatically submit the bom data
468
- if (args.serverUrl && args.serverUrl != true && args.apiKey) {
572
+ if (options.serverUrl && options.serverUrl != true && options.apiKey) {
469
573
  try {
470
- const dbody = await submitBom(args, bomNSData.bomJson);
574
+ const dbody = await submitBom(options, bomNSData.bomJson);
471
575
  console.log("Response from server", dbody);
472
576
  } catch (err) {
473
577
  console.log(err);
474
578
  }
475
579
  }
476
580
 
477
- if (args.print && bomNSData.bomJson && bomNSData.bomJson.components) {
581
+ if (options.print && bomNSData.bomJson && bomNSData.bomJson.components) {
478
582
  printDependencyTree(bomNSData.bomJson);
479
583
  printTable(bomNSData.bomJson);
480
584
  }
package/bin/evinse.js CHANGED
@@ -3,9 +3,7 @@
3
3
  // Evinse (Evinse Verification Is Nearly SBOM Evidence)
4
4
  import yargs from "yargs";
5
5
  import { hideBin } from "yargs/helpers";
6
- import { join } from "node:path";
7
6
  import fs from "node:fs";
8
- import { homedir, platform as _platform } from "node:os";
9
7
  import process from "node:process";
10
8
  import { analyzeProject, createEvinseFile, prepareDB } from "../evinser.js";
11
9
  import { validateBom } from "../validator.js";
@@ -15,6 +13,7 @@ import {
15
13
  printServices,
16
14
  printReachables
17
15
  } from "../display.js";
16
+ import { ATOM_DB } from "../utils.js";
18
17
  import { findUpSync } from "find-up";
19
18
  import { load as _load } from "js-yaml";
20
19
 
@@ -38,22 +37,6 @@ if (configPath) {
38
37
  }
39
38
  }
40
39
 
41
- const isWin = _platform() === "win32";
42
- const isMac = _platform() === "darwin";
43
- let ATOM_DB = join(homedir(), ".local", "share", ".atomdb");
44
- if (isWin) {
45
- ATOM_DB = join(homedir(), "AppData", "Local", ".atomdb");
46
- } else if (isMac) {
47
- ATOM_DB = join(homedir(), "Library", "Application Support", ".atomdb");
48
- }
49
-
50
- if (!process.env.ATOM_DB && !fs.existsSync(ATOM_DB)) {
51
- try {
52
- fs.mkdirSync(ATOM_DB, { recursive: true });
53
- } catch (e) {
54
- // ignore
55
- }
56
- }
57
40
  const args = yargs(hideBin(process.argv))
58
41
  .env("EVINSE")
59
42
  .option("input", {
@@ -4,8 +4,8 @@
4
4
  "System.ServiceModel",
5
5
  "System.Data",
6
6
  "spring",
7
- "flask",
8
- "django",
7
+ "pkg:pypi/flask",
8
+ "pkg:pypi/django",
9
9
  "beego",
10
10
  "chi",
11
11
  "echo",
@@ -30,15 +30,33 @@
30
30
  "express",
31
31
  "knex",
32
32
  "vue",
33
- "aiohttp",
34
- "bottle",
35
- "cherrypy",
36
- "drt",
37
- "falcon",
38
- "hug",
39
- "pyramid",
40
- "sanic",
41
- "tornado",
33
+ "pkg:pypi/aiohttp",
34
+ "pkg:pypi/bottle",
35
+ "pkg:pypi/cherrypy",
36
+ "pkg:pypi/drt",
37
+ "pkg:pypi/falcon",
38
+ "pkg:pypi/hug",
39
+ "pkg:pypi/pyramid",
40
+ "pkg:pypi/sanic",
41
+ "pkg:pypi/tornado",
42
+ "pkg:pypi/fastapi",
43
+ "pkg:pypi/pyqt",
44
+ "pkg:pypi/tkinter",
45
+ "pkg:pypi/kivy",
46
+ "pkg:pypi/pyside",
47
+ "pkg:pypi/scikit",
48
+ "pkg:pypi/tensorflow",
49
+ "pkg:pypi/pytorch",
50
+ "pkg:pypi/keras",
51
+ "pkg:pypi/numpy",
52
+ "pkg:pypi/scipy",
53
+ "pkg:pypi/pandas",
54
+ "pkg:pypi/matplotlib",
55
+ "pkg:pypi/google-api-core",
56
+ "pkg:pypi/google-cloud",
57
+ "pkg:pypi/botocore",
58
+ "pkg:pypi/boto3",
59
+ "pkg:pypi/azure",
42
60
  "vibora",
43
61
  "koa",
44
62
  "-sdk",
@@ -2,12 +2,14 @@
2
2
  {
3
3
  "exp": "Apache-2.0",
4
4
  "names": [
5
+ "Apache2",
5
6
  "Apache 2",
6
7
  "Apache 2.0",
7
8
  "Apache Version 2.0",
8
9
  "Apache 2.0 License",
9
10
  "Apache Software License, Version 2.0",
10
11
  "The Apache Software License, Version 2.0",
12
+ "Apache License v2.0",
11
13
  "Apache License (v2.0)",
12
14
  "Apache License 2.0",
13
15
  "Apache License Version 2.0",
@@ -20,6 +22,9 @@
20
22
  "Apache-2.0 OR MIT",
21
23
  "Apache2.0",
22
24
  "apache-2-0",
25
+ "APL2",
26
+ "the Apache License, ASL Version 2.0",
27
+ "Apache Publich License 2.0",
23
28
  "https://opensource.org/licenses/Apache2.0",
24
29
  "https://opensource.org/license/apache-2-0",
25
30
  "http://www.apache.org/licenses/LICENSE-2.0.html"
@@ -27,7 +32,14 @@
27
32
  },
28
33
  {
29
34
  "exp": "0BSD",
30
- "names": ["Zero-Clause BSD", "BSD", "BSD License", "BSD-like"]
35
+ "names": [
36
+ "Zero-Clause BSD",
37
+ "BSD",
38
+ "BSD License",
39
+ "BSD-like",
40
+ "new BSD License",
41
+ "new BSD"
42
+ ]
31
43
  },
32
44
  {
33
45
  "exp": "BSD-2-Clause",
@@ -37,7 +49,8 @@
37
49
  "BSD-2-Clause",
38
50
  "BSD 2-Clause License",
39
51
  "The BSD 2-Clause License",
40
- "The 2-Clause BSD License"
52
+ "The 2-Clause BSD License",
53
+ "The BSD License"
41
54
  ]
42
55
  },
43
56
  {
@@ -46,6 +59,7 @@
46
59
  "BSD 3 Clause",
47
60
  "BSD 3-Clause",
48
61
  "BSD-3-Clause",
62
+ "BSD 3-clause",
49
63
  "BSD 3-Clause License",
50
64
  "The BSD 3-Clause License",
51
65
  "BSD 3-Clause \"New\" or \"Revised\" License (BSD-3-Clause)",
@@ -55,7 +69,8 @@
55
69
  "Revised BSD",
56
70
  "Revised BSD License",
57
71
  "The New BSD License",
58
- "BSD (3-clause)"
72
+ "BSD (3-clause)",
73
+ "3-Clause BSD License"
59
74
  ]
60
75
  },
61
76
  {
@@ -70,6 +85,10 @@
70
85
  "BSD (4-clause)"
71
86
  ]
72
87
  },
88
+ {
89
+ "exp": "CC0-1.0",
90
+ "names": ["CC0"]
91
+ },
73
92
  {
74
93
  "exp": "CDDL-1.0",
75
94
  "names": [
@@ -151,6 +170,7 @@
151
170
  "LGPL v2.1",
152
171
  "LGPL-2.1",
153
172
  "LGPL2.1",
173
+ "LGPL, version 2.1",
154
174
  "GNU Lesser General Public License",
155
175
  "GNU Lesser General Public License Version 2.1",
156
176
  "GNU Lesser General Public License Version 2.1, February 1999",
@@ -270,7 +290,13 @@
270
290
  },
271
291
  {
272
292
  "exp": "MPL-2.0",
273
- "names": ["MPL 2.0", "Mozilla Public License 2.0"]
293
+ "names": [
294
+ "MPL 2.0",
295
+ "Mozilla Public License 2.0",
296
+ "Mozilla Public License version 2.0",
297
+ "Mozilla Public License, version 2.0",
298
+ "Mozilla Public License 2.0 (MPL 2.0)"
299
+ ]
274
300
  },
275
301
  {
276
302
  "exp": "NetCDF",
@@ -282,6 +308,19 @@
282
308
  },
283
309
  {
284
310
  "exp": "ISC",
285
- "names": ["ISC license"]
311
+ "names": ["ISC license", "ISC License (ISCL)"]
312
+ },
313
+ {
314
+ "exp": "ICU",
315
+ "names": ["Unicode/ICU License"]
316
+ },
317
+ {
318
+ "exp": "PSF-2.0",
319
+ "names": [
320
+ "Python Software Foundation License",
321
+ "Python Software Foundation License (PSFL)",
322
+ "Python Software Foundation License 2.0",
323
+ "PSFL"
324
+ ]
286
325
  }
287
326
  ]
@@ -553,6 +553,7 @@
553
553
  "creole": "python-creole",
554
554
  "creoleparser": "creoleparser",
555
555
  "crispy-forms": "django-crispy-forms",
556
+ "crum": "django-crum",
556
557
  "cronlog": "python-crontab",
557
558
  "crontab": "python-crontab",
558
559
  "crypto": "pycryptodome",
@@ -589,6 +590,7 @@
589
590
  "djcelery": "django-celery",
590
591
  "djkombu": "django-kombu",
591
592
  "djorm-pgarray": "djorm-ext-pgarray",
593
+ "django-filters": "filters-django",
592
594
  "dns": "dnspython",
593
595
  "docgen": "ansible-docgenerator",
594
596
  "docker": "docker-py",
@@ -631,6 +633,7 @@
631
633
  "fdpexpect": "pexpect",
632
634
  "fedora": "python-fedora",
633
635
  "fias": "ailove-django-fias",
636
+ "fieldsignals": "django-fieldsignals",
634
637
  "fiftyone-degrees": "51degrees-mobile-detector",
635
638
  "fiftyonedegrees": "51degrees-mobile-detector-v3-wrapper",
636
639
  "five": "five.customerize",
@@ -709,6 +712,7 @@
709
712
  "igraph": "python-igraph",
710
713
  "imdb": "imdbpy",
711
714
  "impala": "impyla",
715
+ "imagekit": "django-imagekit",
712
716
  "impersonate": "django-impersonate",
713
717
  "inmemorystorage": "ambition-inmemorystorage",
714
718
  "ipaddress": "backport-ipaddress",
@@ -845,6 +849,7 @@
845
849
  "path": "path.py",
846
850
  "patricia": "patricia-trie",
847
851
  "paver": "paver",
852
+ "packageurl": "packageurl-python",
848
853
  "peak": "proxytypes",
849
854
  "picasso": "anderson.picasso",
850
855
  "picklefield": "django-picklefield",
@@ -1057,6 +1062,7 @@
1057
1062
  "slugify": "unicode-slugify",
1058
1063
  "smarkets": "smk-python-sdk",
1059
1064
  "snappy": "ctypes-snappy",
1065
+ "social-core": "social-auth-core",
1060
1066
  "social-django": "social-auth-app-django",
1061
1067
  "socketio": "python-socketio",
1062
1068
  "socketserver": "pies2overrides",