@cdxgen/cdxgen 13.4.0 → 13.6.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.
- package/README.md +9 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +29 -5
- package/bin/evinse.js +8 -0
- package/bin/hbom.js +15 -7
- package/bin/repl.js +29 -0
- package/bin/validate.js +6 -0
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/license-aliases.json +24 -2
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +407 -1
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/data/rules/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +14 -0
- package/lib/cli/bomAssembly.js +120 -6
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +182 -6
- package/lib/cli/jsBom.js +153 -64
- package/lib/cli/jvmBom.js +363 -66
- package/lib/cli/managedBom.js +853 -87
- package/lib/cli/nativeBom.js +267 -33
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +38 -8
- package/lib/core/fs.js +40 -19
- package/lib/core/httpClient.js +172 -46
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +5 -0
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/core/toolRegistry.js +170 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +550 -6
- package/lib/ecosystems/gradleutils.js +858 -244
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-dotnet.js +117 -18
- package/lib/ecosystems/parsers-go.js +1090 -367
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-jvm.js +259 -17
- package/lib/ecosystems/parsers-misc.js +438 -64
- package/lib/ecosystems/parsers-python.js +100 -12
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/rubyutils.js +544 -34
- package/lib/ecosystems/rusi.js +10 -0
- package/lib/ecosystems/scalacliutils.js +4 -1
- package/lib/ecosystems/scalasem.js +798 -151
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +472 -61
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +413 -93
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +110 -0
- package/lib/inventory/auditCategories.js +3 -3
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +41 -4
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +639 -63
- package/lib/inventory/dotnetRuntime.js +217 -0
- package/lib/inventory/dynamic.js +45 -3
- package/lib/inventory/envcontext.js +475 -18
- package/lib/inventory/evidenceUtils.js +447 -23
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +32 -3
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +271 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/phpBuildInfo.js +438 -0
- package/lib/inventory/phpHostProbe.js +185 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +256 -5
- package/lib/inventory/spdx.js +144 -0
- package/lib/inventory/traceRunner.js +5 -1
- package/lib/inventory/tracedCrypto.js +129 -0
- package/lib/managers/binary.js +866 -186
- package/lib/managers/docker.js +245 -12
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +62 -13
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +198 -2
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +5 -5
- package/lib/stages/postgen/ruleEngine.js +71 -6
- package/lib/stages/postgen/specVersionCompat.js +30 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +231 -62
- package/lib/validator/bomValidator.js +32 -6
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +27 -8
- package/lib/validator/generated/validate-1.7.mjs +32 -13
- package/lib/validator/generated/validate-2.0.mjs +31 -12
- package/lib/validator/index.js +1 -1
- package/package.json +19 -18
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +22 -3
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +1 -17
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +20 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +70 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +22 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +2 -0
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +57 -21
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +40 -4
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +85 -13
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +28 -2
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +37 -58
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +14 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +88 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +33 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +2 -1
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +162 -7
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +44 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/dynamic.d.ts +6 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +92 -8
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +29 -10
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +44 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +38 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +15 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +4 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +22 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +24 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +17 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +8 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +26 -9
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
package/lib/cli/jvmBom.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
2
|
import { readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
|
-
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
4
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
|
|
7
7
|
import { build } from "@cdxgen/cdx-purl";
|
|
8
8
|
import { gte, lte } from "semver";
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
DEBUG_MODE,
|
|
12
|
-
isSecureMode,
|
|
13
|
-
readEnvironmentVariable,
|
|
14
|
-
} from "../core/activity.js";
|
|
10
|
+
import { DEBUG_MODE, readEnvironmentVariable } from "../core/activity.js";
|
|
15
11
|
import { commandOutputText, recordDegradation } from "../core/buildLedger.js";
|
|
16
12
|
import {
|
|
17
13
|
deferFailOnError,
|
|
@@ -39,23 +35,33 @@ import {
|
|
|
39
35
|
} from "../core/fs.js";
|
|
40
36
|
import { thoughtLog } from "../core/logger.js";
|
|
41
37
|
import { dirNameStr } from "../core/paths.js";
|
|
38
|
+
import {
|
|
39
|
+
isSecureModeActive,
|
|
40
|
+
reportProjectToolingSkipped,
|
|
41
|
+
} from "../core/projectTooling.js";
|
|
42
42
|
import { extractJarArchive, getMvnMetadata } from "../ecosystems/ecosystems.js";
|
|
43
43
|
import {
|
|
44
44
|
buildGradleCommandArguments,
|
|
45
45
|
buildObjectForGradleModule,
|
|
46
46
|
collectGradleDependencies,
|
|
47
|
+
excludeGradleBuildTooling,
|
|
47
48
|
executeParallelGradleProperties,
|
|
48
49
|
findMillDaemons,
|
|
49
50
|
getGradleCommand,
|
|
50
51
|
getMavenCommand,
|
|
51
52
|
getMillCommand,
|
|
52
53
|
getMillVersion,
|
|
54
|
+
gradleArgsFromEnv,
|
|
55
|
+
gradleDependencyTasks,
|
|
53
56
|
hasGradleInvocationFailure,
|
|
57
|
+
isProjectToolingAllowed,
|
|
58
|
+
loadGradleModulesForReports,
|
|
54
59
|
parseGradleDep,
|
|
55
60
|
parseGradleInfoLogsForUrls,
|
|
56
61
|
parseGradleProperties,
|
|
57
62
|
parseGradleResolvedDistributions,
|
|
58
63
|
parseGradleVersionCatalog,
|
|
64
|
+
reconcileGradleComponents,
|
|
59
65
|
recordGradleInvocationFailure,
|
|
60
66
|
splitOutputByGradleProjects,
|
|
61
67
|
stopMillDaemons,
|
|
@@ -72,6 +78,7 @@ import {
|
|
|
72
78
|
parseMavenTreeJson,
|
|
73
79
|
parseMillDependency,
|
|
74
80
|
parsePom,
|
|
81
|
+
parsePomWithLocalParents,
|
|
75
82
|
readMavenModuleTrees,
|
|
76
83
|
} from "../ecosystems/parsers-jvm.js";
|
|
77
84
|
import {
|
|
@@ -89,6 +96,7 @@ import {
|
|
|
89
96
|
} from "../ecosystems/sbtutils.js";
|
|
90
97
|
import { collectScalaCliComponents } from "../ecosystems/scalacliutils.js";
|
|
91
98
|
import { collectScalaJsNpmComponents } from "../ecosystems/scalasem.js";
|
|
99
|
+
import { isInVendoredDir } from "../ecosystems/vendoredCode.js";
|
|
92
100
|
import {
|
|
93
101
|
isBuildToolRateLimited,
|
|
94
102
|
noteBuildToolRateLimit,
|
|
@@ -97,6 +105,7 @@ import {
|
|
|
97
105
|
collectJarNS,
|
|
98
106
|
collectMvnDependencies,
|
|
99
107
|
convertJarNSToPackages,
|
|
108
|
+
namespaceMappingOfComponents,
|
|
100
109
|
} from "../inventory/deps.js";
|
|
101
110
|
import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
|
|
102
111
|
import {
|
|
@@ -110,8 +119,20 @@ import {
|
|
|
110
119
|
projectSettingsArgs,
|
|
111
120
|
} from "../inventory/jvmLocalRepos.js";
|
|
112
121
|
import { readGradleWrapperVersion } from "../inventory/jvmToolEnv.js";
|
|
113
|
-
import {
|
|
122
|
+
import {
|
|
123
|
+
bazelMirrorArgs,
|
|
124
|
+
coursierMirrorEnv,
|
|
125
|
+
gradleMirrorInitScriptArgs,
|
|
126
|
+
mavenMirrorSettingsArgs,
|
|
127
|
+
mavenWrapperMirrorEnv,
|
|
128
|
+
sbtMirrorEnv,
|
|
129
|
+
} from "../inventory/mavenCentralMirror.js";
|
|
130
|
+
import { applyPurl, mavenPurl, tryBuildPurl } from "../inventory/purl.js";
|
|
114
131
|
import { publishedArtifactId } from "../inventory/scalaCoords.js";
|
|
132
|
+
import {
|
|
133
|
+
mergeScalaDuplicateComponents,
|
|
134
|
+
rekeyNamespaceMapping,
|
|
135
|
+
} from "../inventory/scalaDedupe.js";
|
|
115
136
|
import {
|
|
116
137
|
buildBomNSData,
|
|
117
138
|
createDefaultParentComponent,
|
|
@@ -251,6 +272,67 @@ export async function collectSbtDependencyJars(pkgList, known = {}) {
|
|
|
251
272
|
return nsMapping;
|
|
252
273
|
}
|
|
253
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Keep apart two independent Maven projects that declare the same
|
|
277
|
+
* coordinates, such as sample projects in `one/` and `two/` that both call
|
|
278
|
+
* themselves `com.example:demo:0.0.1-SNAPSHOT`. When `component` has the
|
|
279
|
+
* bom-ref of the parent or of a module already collected but comes from a
|
|
280
|
+
* different pom.xml, it gets the directory of its pom, relative to the scan
|
|
281
|
+
* root, as the purl subpath, and the dependency entries that name it follow.
|
|
282
|
+
*
|
|
283
|
+
* @param {Object} component Root component of a Maven tree, updated in place
|
|
284
|
+
* @param {Object} parentComponent Parent component and the modules under it
|
|
285
|
+
* @param {string} rootPath Directory being scanned
|
|
286
|
+
* @param {Object[]} dependenciesList Dependency entries of the tree, updated in place
|
|
287
|
+
* @returns {boolean} True when the component got a distinct identity
|
|
288
|
+
*/
|
|
289
|
+
export function separateDuplicateMavenProject(
|
|
290
|
+
component,
|
|
291
|
+
parentComponent,
|
|
292
|
+
rootPath,
|
|
293
|
+
dependenciesList = [],
|
|
294
|
+
) {
|
|
295
|
+
const ref = component?.["bom-ref"];
|
|
296
|
+
if (!ref || !component.purl) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
const holder = [parentComponent, ...(parentComponent?.components || [])].find(
|
|
300
|
+
(candidate) => candidate?.["bom-ref"] === ref,
|
|
301
|
+
);
|
|
302
|
+
const srcFile = (c) =>
|
|
303
|
+
c?.properties?.find((p) => p.name === "internal:SrcFile")?.value;
|
|
304
|
+
const ownPom = srcFile(component);
|
|
305
|
+
const holderPom = srcFile(holder);
|
|
306
|
+
if (!ownPom || !holderPom || resolve(ownPom) === resolve(holderPom)) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
const subpath = relative(resolve(rootPath), dirname(resolve(ownPom)))
|
|
310
|
+
.split(sep)
|
|
311
|
+
.filter((segment) => segment && segment !== "..")
|
|
312
|
+
.join("/");
|
|
313
|
+
const purl =
|
|
314
|
+
subpath &&
|
|
315
|
+
tryBuildPurl({
|
|
316
|
+
type: "maven",
|
|
317
|
+
namespace: component.group || null,
|
|
318
|
+
name: component.name,
|
|
319
|
+
version: component.version || null,
|
|
320
|
+
qualifiers: component.qualifiers || { type: "jar" },
|
|
321
|
+
subpath,
|
|
322
|
+
});
|
|
323
|
+
if (!purl) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
applyPurl(component, purl);
|
|
327
|
+
const newRef = component["bom-ref"];
|
|
328
|
+
for (const entry of dependenciesList) {
|
|
329
|
+
if (entry.ref === ref) {
|
|
330
|
+
entry.ref = newRef;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
|
|
254
336
|
/**
|
|
255
337
|
* The purls and bom-refs of a parent component and the module components
|
|
256
338
|
* nested under it.
|
|
@@ -495,6 +577,63 @@ export function discoverSbtProjectsFromCmd(
|
|
|
495
577
|
return discoverSbtProjects(basePath);
|
|
496
578
|
}
|
|
497
579
|
|
|
580
|
+
/**
|
|
581
|
+
* Read one pom.xml without running Maven: the module it declares and its
|
|
582
|
+
* direct dependencies. Versions resolve from the pom's properties and
|
|
583
|
+
* dependencyManagement and from parent poms inside the scanned directory.
|
|
584
|
+
* Versions that an imported BOM or a parent outside the directory manages
|
|
585
|
+
* stay empty, and transitive dependencies are unknown.
|
|
586
|
+
*
|
|
587
|
+
* No dependency edges are produced. The build-fidelity rules (BF-JVM-001,
|
|
588
|
+
* BF-GEN-001) recognise a pom read without Maven by its missing graph, and a
|
|
589
|
+
* graph of direct edges alone would pass for a resolved one.
|
|
590
|
+
*
|
|
591
|
+
* @param {string} pomFile pom.xml to read
|
|
592
|
+
* @param {string} rootPath Scanned directory
|
|
593
|
+
* @param {Map} [cache] Parent pom results shared by the poms of one scan
|
|
594
|
+
* @returns {{moduleComponent: Object|undefined, pkgList: Object[]}}
|
|
595
|
+
*/
|
|
596
|
+
export function readMavenModuleStatically(pomFile, rootPath, cache) {
|
|
597
|
+
let pomMap;
|
|
598
|
+
try {
|
|
599
|
+
pomMap = parsePomWithLocalParents(pomFile, rootPath, cache);
|
|
600
|
+
} catch (_err) {
|
|
601
|
+
return { moduleComponent: undefined, pkgList: [] };
|
|
602
|
+
}
|
|
603
|
+
const pkgList = [];
|
|
604
|
+
for (const dep of pomMap?.dependencies || []) {
|
|
605
|
+
const purl = mavenPurl(
|
|
606
|
+
dep.group || undefined,
|
|
607
|
+
dep.name,
|
|
608
|
+
dep.version || undefined,
|
|
609
|
+
dep.qualifiers,
|
|
610
|
+
);
|
|
611
|
+
pkgList.push(
|
|
612
|
+
purl ? { ...dep, purl, "bom-ref": decodeURIComponent(purl) } : dep,
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
const { artifactId, groupId, packaging, version } = pomMap?.properties || {};
|
|
616
|
+
const modulePurl = artifactId
|
|
617
|
+
? mavenPurl(groupId || undefined, artifactId, version || undefined, {
|
|
618
|
+
type: packaging || "jar",
|
|
619
|
+
})
|
|
620
|
+
: undefined;
|
|
621
|
+
if (!modulePurl) {
|
|
622
|
+
return { moduleComponent: undefined, pkgList };
|
|
623
|
+
}
|
|
624
|
+
const moduleComponent = {
|
|
625
|
+
group: groupId || "",
|
|
626
|
+
name: artifactId,
|
|
627
|
+
version: version || "",
|
|
628
|
+
qualifiers: { type: packaging || "jar" },
|
|
629
|
+
type: "application",
|
|
630
|
+
purl: modulePurl,
|
|
631
|
+
"bom-ref": decodeURIComponent(modulePurl),
|
|
632
|
+
properties: [{ name: "internal:SrcFile", value: pomFile }],
|
|
633
|
+
};
|
|
634
|
+
return { moduleComponent, pkgList };
|
|
635
|
+
}
|
|
636
|
+
|
|
498
637
|
/**
|
|
499
638
|
* Function to create bom string for Java projects
|
|
500
639
|
*
|
|
@@ -654,6 +793,55 @@ export async function createJavaBom(path, options) {
|
|
|
654
793
|
}
|
|
655
794
|
const firstPom = pomFiles.length ? pomFiles[0] : undefined;
|
|
656
795
|
let mavenCmd = getMavenCommand(path, path, options);
|
|
796
|
+
// Executing Maven evaluates the pom's build section, loads `.mvn/`
|
|
797
|
+
// configuration such as jvm.config or extensions.xml, and resolves
|
|
798
|
+
// build extensions, so it belongs to the dependency-tooling surface
|
|
799
|
+
// disabled by --no-install-deps and the pre-build lifecycle. The scan
|
|
800
|
+
// then keeps only the direct dependencies each pom declares.
|
|
801
|
+
const mavenToolingAllowed = isProjectToolingAllowed(options);
|
|
802
|
+
if (!mavenToolingAllowed) {
|
|
803
|
+
reportProjectToolingSkipped(
|
|
804
|
+
options,
|
|
805
|
+
"jvm.maven.tooling-disabled",
|
|
806
|
+
"Skipping Maven since dependency installation is disabled. Only the direct dependencies declared in pom.xml files will be used.",
|
|
807
|
+
{
|
|
808
|
+
ecosystem: "java",
|
|
809
|
+
tool: "maven",
|
|
810
|
+
impact: "transitive-deps",
|
|
811
|
+
detail:
|
|
812
|
+
"Dependency installation is disabled, so Maven was not run and only the direct dependencies parsed from pom.xml are available.",
|
|
813
|
+
},
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
// Poms read without Maven: what their local parents define is shared
|
|
817
|
+
// across the scan, and each pom adds its module and direct dependencies.
|
|
818
|
+
const staticPomCache = new Map();
|
|
819
|
+
const addStaticMavenModule = (pomFile) => {
|
|
820
|
+
const staticModule = readMavenModuleStatically(
|
|
821
|
+
pomFile,
|
|
822
|
+
path,
|
|
823
|
+
staticPomCache,
|
|
824
|
+
);
|
|
825
|
+
if (staticModule.pkgList.length) {
|
|
826
|
+
pkgList = pkgList.concat(staticModule.pkgList);
|
|
827
|
+
}
|
|
828
|
+
const moduleComponent = staticModule.moduleComponent;
|
|
829
|
+
if (!moduleComponent) {
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
if (!Object.keys(parentComponent).length) {
|
|
833
|
+
parentComponent = moduleComponent;
|
|
834
|
+
parentComponent.components = [];
|
|
835
|
+
} else if (
|
|
836
|
+
parentComponent["bom-ref"] !== moduleComponent["bom-ref"] &&
|
|
837
|
+
!parentComponent.components?.some(
|
|
838
|
+
(c) => c["bom-ref"] === moduleComponent["bom-ref"],
|
|
839
|
+
)
|
|
840
|
+
) {
|
|
841
|
+
parentComponent.components = parentComponent.components || [];
|
|
842
|
+
parentComponent.components.push(moduleComponent);
|
|
843
|
+
}
|
|
844
|
+
};
|
|
657
845
|
// Pom files whose own tree a recursive run of their aggregator already
|
|
658
846
|
// returned. Each is skipped when its turn comes, so a reactor is run
|
|
659
847
|
// once from its aggregator instead of once per member.
|
|
@@ -668,6 +856,12 @@ export async function createJavaBom(path, options) {
|
|
|
668
856
|
}
|
|
669
857
|
continue;
|
|
670
858
|
}
|
|
859
|
+
// Without Maven every pom is read on its own, Quarkus modules too:
|
|
860
|
+
// the plugin run that would have covered them does not happen.
|
|
861
|
+
if (!mavenToolingAllowed) {
|
|
862
|
+
addStaticMavenModule(f);
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
671
865
|
if (
|
|
672
866
|
isQuarkus &&
|
|
673
867
|
!options.deep &&
|
|
@@ -688,10 +882,7 @@ export async function createJavaBom(path, options) {
|
|
|
688
882
|
`Parsing ${f} without Maven: the repository rate limited Maven in this scan.`,
|
|
689
883
|
);
|
|
690
884
|
}
|
|
691
|
-
|
|
692
|
-
if (dlist.length) {
|
|
693
|
-
pkgList = pkgList.concat(dlist);
|
|
694
|
-
}
|
|
885
|
+
addStaticMavenModule(f);
|
|
695
886
|
continue;
|
|
696
887
|
}
|
|
697
888
|
if (mavenCmd?.endsWith("mvn")) {
|
|
@@ -701,8 +892,19 @@ export async function createJavaBom(path, options) {
|
|
|
701
892
|
// user's own settings.xml, with its mirrors and credentials, still
|
|
702
893
|
// applies on top of it.
|
|
703
894
|
const projectSettings = projectSettingsArgs(basePath, {
|
|
704
|
-
secureMode:
|
|
895
|
+
secureMode: isSecureModeActive(),
|
|
705
896
|
});
|
|
897
|
+
// When the mirror switch is on, Maven resolves Central from the
|
|
898
|
+
// mirror through a generated global settings file; a project
|
|
899
|
+
// settings.xml is merged into that copy so its repositories and its
|
|
900
|
+
// own mirror survive. A settings file the user named keeps winning.
|
|
901
|
+
const mirrorSettingsArgs = mavenMirrorSettingsArgs(
|
|
902
|
+
projectSettings.settingsFile,
|
|
903
|
+
);
|
|
904
|
+
const mvnSettingsArgs = mirrorSettingsArgs.length
|
|
905
|
+
? mirrorSettingsArgs
|
|
906
|
+
: projectSettings.args;
|
|
907
|
+
const mvnSpawnEnv = { ...process.env, ...mavenWrapperMirrorEnv() };
|
|
706
908
|
if (projectSettings.args.length) {
|
|
707
909
|
console.log(
|
|
708
910
|
`Passing ${projectSettings.settingsFile} to Maven as global settings (-gs), so your own settings.xml still applies. Name a settings file in MVN_ARGS to change this.`,
|
|
@@ -728,9 +930,10 @@ export async function createJavaBom(path, options) {
|
|
|
728
930
|
if (!useMavenDepsTree && !isBuildToolRateLimited("maven")) {
|
|
729
931
|
thoughtLog("The user wants me to use the cyclonedx-maven plugin.");
|
|
730
932
|
console.log(`Executing '${mavenCmd}' in`, basePath);
|
|
731
|
-
result = safeSpawnSync(mavenCmd, mvnArgs, {
|
|
933
|
+
result = safeSpawnSync(mavenCmd, mvnArgs.concat(mirrorSettingsArgs), {
|
|
732
934
|
cwd: basePath,
|
|
733
935
|
shell: isWin,
|
|
936
|
+
env: mvnSpawnEnv,
|
|
734
937
|
});
|
|
735
938
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
736
939
|
command: `${basename(mavenCmd)} ${mvnArgs.join(" ")}`,
|
|
@@ -795,7 +998,7 @@ export async function createJavaBom(path, options) {
|
|
|
795
998
|
addArgs = parseMavenArgs(readEnvironmentVariable("MVN_ARGS"));
|
|
796
999
|
mvnTreeArgs = mvnTreeArgs.concat(addArgs);
|
|
797
1000
|
}
|
|
798
|
-
mvnTreeArgs = mvnTreeArgs.concat(
|
|
1001
|
+
mvnTreeArgs = mvnTreeArgs.concat(mvnSettingsArgs);
|
|
799
1002
|
// For the first pom alone, we need to execute first in non-recursive mode to capture
|
|
800
1003
|
// the parent component. Then, we execute all of them in recursive mode
|
|
801
1004
|
// A rate limit the --deep copy-dependencies run met ends it too.
|
|
@@ -811,11 +1014,12 @@ export async function createJavaBom(path, options) {
|
|
|
811
1014
|
];
|
|
812
1015
|
findParentComponentArgs = findParentComponentArgs.concat(
|
|
813
1016
|
addArgs,
|
|
814
|
-
|
|
1017
|
+
mvnSettingsArgs,
|
|
815
1018
|
);
|
|
816
1019
|
result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
|
|
817
1020
|
cwd: basePath,
|
|
818
1021
|
shell: isWin,
|
|
1022
|
+
env: mvnSpawnEnv,
|
|
819
1023
|
});
|
|
820
1024
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
821
1025
|
command: `${basename(mavenCmd)} ${findParentComponentArgs.join(" ")}`,
|
|
@@ -845,10 +1049,11 @@ export async function createJavaBom(path, options) {
|
|
|
845
1049
|
"dependency:tree",
|
|
846
1050
|
"-N",
|
|
847
1051
|
`-DoutputFile=${tempMvnParentTreeText}`,
|
|
848
|
-
].concat(addArgs,
|
|
1052
|
+
].concat(addArgs, mvnSettingsArgs);
|
|
849
1053
|
result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
|
|
850
1054
|
cwd: basePath,
|
|
851
1055
|
shell: isWin,
|
|
1056
|
+
env: mvnSpawnEnv,
|
|
852
1057
|
});
|
|
853
1058
|
}
|
|
854
1059
|
if (result.status === 0) {
|
|
@@ -893,6 +1098,7 @@ export async function createJavaBom(path, options) {
|
|
|
893
1098
|
result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
|
|
894
1099
|
cwd: basePath,
|
|
895
1100
|
shell: isWin,
|
|
1101
|
+
env: mvnSpawnEnv,
|
|
896
1102
|
});
|
|
897
1103
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
898
1104
|
command: `${basename(mavenCmd)} ${mvnTreeArgs.join(" ")}`,
|
|
@@ -918,10 +1124,11 @@ export async function createJavaBom(path, options) {
|
|
|
918
1124
|
mvnTreeArgs = [
|
|
919
1125
|
"dependency:tree",
|
|
920
1126
|
`-DoutputFile=${tempMvnTreeText}`,
|
|
921
|
-
].concat(addArgs,
|
|
1127
|
+
].concat(addArgs, mvnSettingsArgs);
|
|
922
1128
|
result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
|
|
923
1129
|
cwd: basePath,
|
|
924
1130
|
shell: isWin,
|
|
1131
|
+
env: mvnSpawnEnv,
|
|
925
1132
|
});
|
|
926
1133
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
927
1134
|
command: `${basename(mavenCmd)} ${mvnTreeArgs.join(" ")}`,
|
|
@@ -1031,11 +1238,7 @@ export async function createJavaBom(path, options) {
|
|
|
1031
1238
|
thoughtLog(
|
|
1032
1239
|
"**MAVEN**: There appear to be build errors, so the SBOM will be incomplete.",
|
|
1033
1240
|
);
|
|
1034
|
-
|
|
1035
|
-
const dlist = pomMap?.dependencies || [];
|
|
1036
|
-
if (dlist.length) {
|
|
1037
|
-
pkgList = pkgList.concat(dlist);
|
|
1038
|
-
}
|
|
1241
|
+
addStaticMavenModule(f);
|
|
1039
1242
|
} else {
|
|
1040
1243
|
// The text trees exist only when the JSON run failed and was
|
|
1041
1244
|
// retried. Each reactor module has its own tree, and a member
|
|
@@ -1075,6 +1278,12 @@ export async function createJavaBom(path, options) {
|
|
|
1075
1278
|
parentComponent = tmpParentComponent;
|
|
1076
1279
|
parentComponent.components = [];
|
|
1077
1280
|
} else {
|
|
1281
|
+
separateDuplicateMavenProject(
|
|
1282
|
+
tmpParentComponent,
|
|
1283
|
+
parentComponent,
|
|
1284
|
+
path,
|
|
1285
|
+
parsedList.dependenciesList,
|
|
1286
|
+
);
|
|
1078
1287
|
parentComponent.components.push(tmpParentComponent);
|
|
1079
1288
|
}
|
|
1080
1289
|
if (parsedList?.dependenciesList?.length) {
|
|
@@ -1202,9 +1411,14 @@ export async function createJavaBom(path, options) {
|
|
|
1202
1411
|
}
|
|
1203
1412
|
}
|
|
1204
1413
|
const allProjects = [];
|
|
1205
|
-
|
|
1414
|
+
// Modules keyed by bom-ref: a module without a purl still has a bom-ref
|
|
1415
|
+
// of its own, while every such module shares an undefined purl.
|
|
1416
|
+
const allProjectsAddedRefs = new Map();
|
|
1206
1417
|
const rootDependsOn = new Set();
|
|
1207
1418
|
const gradleModules = new Map();
|
|
1419
|
+
// Included builds that build Gradle plugins, such as a build-logic build
|
|
1420
|
+
// included from pluginManagement. Their classpath is build tooling.
|
|
1421
|
+
const gradlePluginBuilds = new Set();
|
|
1208
1422
|
// Determine the root path for gradle
|
|
1209
1423
|
// Fixes gradle invocation for microservices-demo
|
|
1210
1424
|
let gradleRootPath = path;
|
|
@@ -1306,14 +1520,19 @@ export async function createJavaBom(path, options) {
|
|
|
1306
1520
|
const gradleInitArgs = readEnvironmentVariable("GRADLE_INCLUDED_BUILDS")
|
|
1307
1521
|
? []
|
|
1308
1522
|
: ["--init-script", GRADLE_INIT_SCRIPT];
|
|
1523
|
+
// The mirror init script joins cdxgen's own helper script; Gradle
|
|
1524
|
+
// applies every init script it is given.
|
|
1525
|
+
const gradleMirrorArgs = gradleMirrorInitScriptArgs();
|
|
1526
|
+
if (gradleMirrorArgs.length) {
|
|
1527
|
+
gradleInitArgs.push(...gradleMirrorArgs);
|
|
1528
|
+
}
|
|
1309
1529
|
if (resolveGradleDistribution && gradleInitArgs.length) {
|
|
1310
1530
|
gradleInitArgs.push("-PcdxgenResolveDistribution=true");
|
|
1311
1531
|
}
|
|
1312
1532
|
// `gradle properties` evaluates the project's build scripts, so it is
|
|
1313
1533
|
// part of the dependency-tooling surface gated by --no-install-deps
|
|
1314
1534
|
// (and the pre-build lifecycle).
|
|
1315
|
-
const gradleToolingAllowed =
|
|
1316
|
-
options.installDeps !== false || options.introspect === true;
|
|
1535
|
+
const gradleToolingAllowed = isProjectToolingAllowed(options);
|
|
1317
1536
|
if (gradleToolingAllowed) {
|
|
1318
1537
|
parallelPropTaskOut = executeParallelGradleProperties(
|
|
1319
1538
|
gradleRootPath,
|
|
@@ -1378,12 +1597,19 @@ export async function createJavaBom(path, options) {
|
|
|
1378
1597
|
);
|
|
1379
1598
|
if (!includedBuilds.includes(key)) {
|
|
1380
1599
|
parentComponent = rootComponent;
|
|
1600
|
+
} else if (retMap.gradlePlugin) {
|
|
1601
|
+
gradlePluginBuilds.add(key);
|
|
1381
1602
|
}
|
|
1382
1603
|
gradleModules.set(key, rootComponent);
|
|
1383
|
-
if (
|
|
1604
|
+
if (
|
|
1605
|
+
!allProjectsAddedRefs.has(rootComponent["bom-ref"] ?? rootComponent)
|
|
1606
|
+
) {
|
|
1384
1607
|
allProjects.push(rootComponent);
|
|
1385
1608
|
rootDependsOn.add(rootComponent["bom-ref"]);
|
|
1386
|
-
|
|
1609
|
+
allProjectsAddedRefs.set(
|
|
1610
|
+
rootComponent["bom-ref"] ?? rootComponent,
|
|
1611
|
+
rootComponent,
|
|
1612
|
+
);
|
|
1387
1613
|
}
|
|
1388
1614
|
allProjectsStr = allProjectsStr.concat(retMap.projects);
|
|
1389
1615
|
}
|
|
@@ -1416,14 +1642,60 @@ export async function createJavaBom(path, options) {
|
|
|
1416
1642
|
);
|
|
1417
1643
|
const rootSubProject = retMap.rootProject;
|
|
1418
1644
|
if (rootSubProject) {
|
|
1645
|
+
// A subproject whose properties task printed nothing is named as
|
|
1646
|
+
// Gradle publishes it by default: the last segment of its path,
|
|
1647
|
+
// with the root project's group and version.
|
|
1648
|
+
if (!splitPropTaskOut.has(subProject)) {
|
|
1649
|
+
retMap.metadata.group ||= parentComponent?.group || "";
|
|
1650
|
+
if (
|
|
1651
|
+
retMap.metadata.version === "latest" &&
|
|
1652
|
+
parentComponent?.version
|
|
1653
|
+
) {
|
|
1654
|
+
retMap.metadata.version = parentComponent.version;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1419
1657
|
const rootSubProjectObj = await buildObjectForGradleModule(
|
|
1420
|
-
rootSubProject === "root"
|
|
1658
|
+
rootSubProject === "root"
|
|
1659
|
+
? subProject.split(":").pop()
|
|
1660
|
+
: rootSubProject,
|
|
1421
1661
|
retMap.metadata,
|
|
1422
1662
|
);
|
|
1423
|
-
|
|
1663
|
+
// Two subprojects that Gradle would publish under the same
|
|
1664
|
+
// coordinates, such as `:a:util` and `:b:util` with a shared group
|
|
1665
|
+
// and version, stay apart: the later one gets its project path as
|
|
1666
|
+
// the purl subpath. A module that shares the root project's
|
|
1667
|
+
// coordinates is the root's own artifact and merges with it.
|
|
1668
|
+
const holder = allProjectsAddedRefs.get(
|
|
1669
|
+
rootSubProjectObj["bom-ref"],
|
|
1670
|
+
);
|
|
1671
|
+
if (
|
|
1672
|
+
holder &&
|
|
1673
|
+
holder !== parentComponent &&
|
|
1674
|
+
holder !== gradleModules.get(subProject)
|
|
1675
|
+
) {
|
|
1676
|
+
const subpath = subProject.split(":").filter(Boolean).join("/");
|
|
1677
|
+
const distinctPurl = rootSubProjectObj.purl
|
|
1678
|
+
? tryBuildPurl({
|
|
1679
|
+
type: "maven",
|
|
1680
|
+
namespace: rootSubProjectObj.group || null,
|
|
1681
|
+
name: rootSubProjectObj.name,
|
|
1682
|
+
version: rootSubProjectObj.version || null,
|
|
1683
|
+
qualifiers: { type: "jar" },
|
|
1684
|
+
subpath,
|
|
1685
|
+
})
|
|
1686
|
+
: null;
|
|
1687
|
+
if (distinctPurl) {
|
|
1688
|
+
applyPurl(rootSubProjectObj, distinctPurl);
|
|
1689
|
+
} else {
|
|
1690
|
+
rootSubProjectObj["bom-ref"] =
|
|
1691
|
+
`${rootSubProjectObj["bom-ref"]}#${subpath}`;
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
const moduleKey = rootSubProjectObj["bom-ref"] ?? rootSubProjectObj;
|
|
1695
|
+
if (!allProjectsAddedRefs.has(moduleKey)) {
|
|
1424
1696
|
allProjects.push(rootSubProjectObj);
|
|
1425
1697
|
rootDependsOn.add(rootSubProjectObj["bom-ref"]);
|
|
1426
|
-
|
|
1698
|
+
allProjectsAddedRefs.set(moduleKey, rootSubProjectObj);
|
|
1427
1699
|
}
|
|
1428
1700
|
gradleModules.set(subProject, rootSubProjectObj);
|
|
1429
1701
|
}
|
|
@@ -1455,7 +1727,6 @@ export async function createJavaBom(path, options) {
|
|
|
1455
1727
|
? readEnvironmentVariable("GRADLE_DEPENDENCY_TASK")
|
|
1456
1728
|
: "dependencies";
|
|
1457
1729
|
|
|
1458
|
-
const gradleSubCommands = [];
|
|
1459
1730
|
let modulesToSkip = readEnvironmentVariable("GRADLE_SKIP_MODULES")
|
|
1460
1731
|
? readEnvironmentVariable("GRADLE_SKIP_MODULES").split(",")
|
|
1461
1732
|
: [];
|
|
@@ -1464,23 +1735,16 @@ export async function createJavaBom(path, options) {
|
|
|
1464
1735
|
readEnvironmentVariable("GRADLE_SKIP_MODULE_DEPENDENCIES").split(","),
|
|
1465
1736
|
);
|
|
1466
1737
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
gradleSubCommands.push(`${key}:${gradleDepTask}`);
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1738
|
+
const gradleSubCommands = gradleDependencyTasks(
|
|
1739
|
+
gradleModules,
|
|
1740
|
+
parentComponent,
|
|
1741
|
+
gradleDepTask,
|
|
1742
|
+
modulesToSkip,
|
|
1743
|
+
);
|
|
1476
1744
|
const gradleArguments = buildGradleCommandArguments(
|
|
1477
|
-
|
|
1478
|
-
? readEnvironmentVariable("GRADLE_ARGS").split(" ")
|
|
1479
|
-
: [],
|
|
1745
|
+
gradleArgsFromEnv("GRADLE_ARGS"),
|
|
1480
1746
|
gradleSubCommands,
|
|
1481
|
-
|
|
1482
|
-
? readEnvironmentVariable("GRADLE_ARGS_DEPENDENCIES").split(" ")
|
|
1483
|
-
: [],
|
|
1747
|
+
gradleArgsFromEnv("GRADLE_ARGS_DEPENDENCIES"),
|
|
1484
1748
|
gradleCmd.length,
|
|
1485
1749
|
);
|
|
1486
1750
|
const allOutputs = [];
|
|
@@ -1541,14 +1805,30 @@ export async function createJavaBom(path, options) {
|
|
|
1541
1805
|
const perProjectOutput = splitOutputByGradleProjects(cmdOutput, [
|
|
1542
1806
|
gradleDepTask,
|
|
1543
1807
|
]);
|
|
1808
|
+
await loadGradleModulesForReports(
|
|
1809
|
+
perProjectOutput.values(),
|
|
1810
|
+
gradleModules,
|
|
1811
|
+
gradleRootPath,
|
|
1812
|
+
options,
|
|
1813
|
+
);
|
|
1814
|
+
const reportedProjects = new Set(perProjectOutput.keys());
|
|
1544
1815
|
for (const key of gradleModules.keys()) {
|
|
1545
1816
|
const parsedList = await parseGradleDep(
|
|
1546
1817
|
perProjectOutput.has(key) ? perProjectOutput.get(key) : "",
|
|
1547
1818
|
key,
|
|
1548
1819
|
gradleModules,
|
|
1549
1820
|
gradleRootPath,
|
|
1821
|
+
reportedProjects,
|
|
1550
1822
|
);
|
|
1551
1823
|
const dlist = parsedList.pkgList;
|
|
1824
|
+
if (
|
|
1825
|
+
dlist?.length &&
|
|
1826
|
+
[...gradlePluginBuilds].some(
|
|
1827
|
+
(build) => key === build || key.startsWith(`${build}:`),
|
|
1828
|
+
)
|
|
1829
|
+
) {
|
|
1830
|
+
excludeGradleBuildTooling(dlist, gradleModules);
|
|
1831
|
+
}
|
|
1552
1832
|
if (parsedList?.dependenciesList?.length) {
|
|
1553
1833
|
dependencies = mergeDependencies(
|
|
1554
1834
|
dependencies,
|
|
@@ -1566,6 +1846,7 @@ export async function createJavaBom(path, options) {
|
|
|
1566
1846
|
pkgList = pkgList.concat(dlist);
|
|
1567
1847
|
}
|
|
1568
1848
|
}
|
|
1849
|
+
reconcileGradleComponents(pkgList);
|
|
1569
1850
|
}
|
|
1570
1851
|
if (pkgList.length) {
|
|
1571
1852
|
const fileToUrlMap = parseGradleInfoLogsForUrls(sstdout);
|
|
@@ -1579,9 +1860,15 @@ export async function createJavaBom(path, options) {
|
|
|
1579
1860
|
if (!p.externalReferences) {
|
|
1580
1861
|
p.externalReferences = [];
|
|
1581
1862
|
}
|
|
1582
|
-
|
|
1863
|
+
// The repository URLs name jar files, which a platform does not
|
|
1864
|
+
// have. The leading slash keeps group `foo` from matching a URL
|
|
1865
|
+
// under `org/foo/`.
|
|
1866
|
+
if (
|
|
1867
|
+
p.qualifiers?.type !== "pom" &&
|
|
1868
|
+
!p.externalReferences.find((r) => r.type === "distribution")
|
|
1869
|
+
) {
|
|
1583
1870
|
const groupPath = p.group.replace(/\./g, "/");
|
|
1584
|
-
const matchPath =
|
|
1871
|
+
const matchPath = `/${groupPath}/${p.name}/${p.version}/`;
|
|
1585
1872
|
let matchedUrl = Object.values(fileToUrlMap).find((url) =>
|
|
1586
1873
|
url.includes(matchPath),
|
|
1587
1874
|
);
|
|
@@ -1703,11 +1990,14 @@ export async function createJavaBom(path, options) {
|
|
|
1703
1990
|
// Bazel
|
|
1704
1991
|
// Look for the BUILD file only in the root directory
|
|
1705
1992
|
// NOTE: This can match BUILD files used by perl, so could lead to errors in some projects
|
|
1993
|
+
// A workspace under third_party/ or vendor/ is a copied project's: its
|
|
1994
|
+
// bazel_dep entries are that project's build tooling, and building it
|
|
1995
|
+
// would run its build.
|
|
1706
1996
|
const bazelFiles = getAllFiles(
|
|
1707
1997
|
path,
|
|
1708
1998
|
`${options.multiProject ? "**/" : ""}{WORKSPACE{,.bazel},MODULE.bazel}`,
|
|
1709
1999
|
options,
|
|
1710
|
-
);
|
|
2000
|
+
).filter((f) => !isInVendoredDir(path, f));
|
|
1711
2001
|
if (
|
|
1712
2002
|
bazelFiles?.length &&
|
|
1713
2003
|
!hasAnyProjectType(
|
|
@@ -1780,6 +2070,9 @@ export async function createJavaBom(path, options) {
|
|
|
1780
2070
|
) {
|
|
1781
2071
|
bArgs = ["--bazelrc=.bazelrc", "build", bazelTarget];
|
|
1782
2072
|
}
|
|
2073
|
+
// Repository rules see the mirror through their own environment,
|
|
2074
|
+
// which only a --repo_env flag reaches.
|
|
2075
|
+
bArgs = bArgs.concat(bazelMirrorArgs());
|
|
1783
2076
|
console.log("Executing", BAZEL_CMD, "in", basePath);
|
|
1784
2077
|
let result = safeSpawnSync(BAZEL_CMD, bArgs, {
|
|
1785
2078
|
cwd: basePath,
|
|
@@ -1941,7 +2234,7 @@ export async function createJavaBom(path, options) {
|
|
|
1941
2234
|
pkgList = pkgList.concat(dlist);
|
|
1942
2235
|
}
|
|
1943
2236
|
}
|
|
1944
|
-
} else if (
|
|
2237
|
+
} else if (!isProjectToolingAllowed(options)) {
|
|
1945
2238
|
// Executing sbt evaluates the project's build definition (arbitrary
|
|
1946
2239
|
// Scala), so it belongs to the dependency-tooling surface disabled
|
|
1947
2240
|
// by --no-install-deps and the pre-build lifecycle.
|
|
@@ -1993,7 +2286,7 @@ export async function createJavaBom(path, options) {
|
|
|
1993
2286
|
// sbt resolves into the user's own caches, so a project that has been
|
|
1994
2287
|
// built resolves without the network. The dependency trees download
|
|
1995
2288
|
// the jar of every dependency they list, which is all --deep reads.
|
|
1996
|
-
const env = { ...process.env };
|
|
2289
|
+
const env = { ...process.env, ...sbtMirrorEnv() };
|
|
1997
2290
|
for (const i in sbtProjects) {
|
|
1998
2291
|
if (isBuildToolRateLimited("sbt")) {
|
|
1999
2292
|
// Every remaining sbt build in this scan resolves from the same
|
|
@@ -2344,26 +2637,20 @@ export async function createJavaBom(path, options) {
|
|
|
2344
2637
|
const jarNSData = await createJarBom(path, options);
|
|
2345
2638
|
if (jarNSData?.bomJson?.components) {
|
|
2346
2639
|
pkgList = pkgList.concat(jarNSData?.bomJson?.components);
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
);
|
|
2355
|
-
if (nsProp.length) {
|
|
2356
|
-
targetJarNSMapping[p.purl] = nsProp[0].value;
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
jarNSMapping = { ...jarNSMapping, ...targetJarNSMapping };
|
|
2640
|
+
jarNSMapping = {
|
|
2641
|
+
...jarNSMapping,
|
|
2642
|
+
...namespaceMappingOfComponents(
|
|
2643
|
+
jarNSData.bomJson.components,
|
|
2644
|
+
jarNSMapping,
|
|
2645
|
+
),
|
|
2646
|
+
};
|
|
2360
2647
|
}
|
|
2361
2648
|
}
|
|
2362
2649
|
}
|
|
2363
2650
|
|
|
2364
2651
|
if (
|
|
2365
2652
|
millFiles?.length &&
|
|
2366
|
-
(options
|
|
2653
|
+
isProjectToolingAllowed(options) &&
|
|
2367
2654
|
isPackageManagerAllowed(
|
|
2368
2655
|
"mill",
|
|
2369
2656
|
["bazel", "sbt", "gradle", "maven"],
|
|
@@ -2398,10 +2685,12 @@ export async function createJavaBom(path, options) {
|
|
|
2398
2685
|
if (DEBUG_MODE) {
|
|
2399
2686
|
console.log("Executing", millCmd, "in", millRootPath);
|
|
2400
2687
|
}
|
|
2688
|
+
const millSpawnEnv = { ...process.env, ...coursierMirrorEnv() };
|
|
2401
2689
|
let sresult = safeSpawnSync(millCmd, millArgs, {
|
|
2402
2690
|
cwd: millRootPath,
|
|
2403
2691
|
shell: isWin,
|
|
2404
2692
|
maxBuffer: MAX_BUFFER * 10,
|
|
2693
|
+
env: millSpawnEnv,
|
|
2405
2694
|
});
|
|
2406
2695
|
noteBuildToolRateLimit("mill", commandOutputText(sresult), {
|
|
2407
2696
|
command: `${basename(millCmd)} ${millArgs.join(" ")}`,
|
|
@@ -2440,6 +2729,7 @@ export async function createJavaBom(path, options) {
|
|
|
2440
2729
|
sresult = safeSpawnSync(millCmd, millResolveArgs, {
|
|
2441
2730
|
cwd: millRootPath,
|
|
2442
2731
|
shell: isWin,
|
|
2732
|
+
env: millSpawnEnv,
|
|
2443
2733
|
});
|
|
2444
2734
|
if (sresult.status !== 0 || sresult.error) {
|
|
2445
2735
|
if (options.failOnError || DEBUG_MODE) {
|
|
@@ -2572,7 +2862,7 @@ export async function createJavaBom(path, options) {
|
|
|
2572
2862
|
} finally {
|
|
2573
2863
|
// A build this scan ran can have started a Mill daemon of its own
|
|
2574
2864
|
// without --no-server; stop those even when a later step failed.
|
|
2575
|
-
stopMillDaemons(path, millDaemonsBefore);
|
|
2865
|
+
stopMillDaemons(path, millDaemonsBefore, options);
|
|
2576
2866
|
}
|
|
2577
2867
|
// A Scala.js build bundles npm packages: scalajs-bundler installs them
|
|
2578
2868
|
// under target, and a bundler workspace keeps its lock file beside the
|
|
@@ -2604,6 +2894,13 @@ export async function createJavaBom(path, options) {
|
|
|
2604
2894
|
// Deduplication and metadata belong to whatever was collected, so they run
|
|
2605
2895
|
// on the deferred path too.
|
|
2606
2896
|
pkgList = trimComponents(pkgList);
|
|
2897
|
+
// A library the build tool reported and a jar on disk named again is one
|
|
2898
|
+
// component, wherever the jar scan spelled it differently. The jar
|
|
2899
|
+
// namespace map follows the purls the merge settled on.
|
|
2900
|
+
const scalaMerge = mergeScalaDuplicateComponents(pkgList, dependencies);
|
|
2901
|
+
pkgList = scalaMerge.components;
|
|
2902
|
+
dependencies = scalaMerge.dependencies;
|
|
2903
|
+
jarNSMapping = rekeyNamespaceMapping(jarNSMapping, scalaMerge.purlMap);
|
|
2607
2904
|
// --deep collects namespaces; it does not opt in to remote licence lookups,
|
|
2608
2905
|
// which FETCH_LICENSE controls. The project's own modules are never looked
|
|
2609
2906
|
// up remotely: they are not published.
|