@cdxgen/cdxgen 13.5.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 +6 -6
- package/bin/cdxgen.js +4 -0
- package/bin/evinse.js +3 -0
- package/bin/validate.js +6 -0
- package/data/license-aliases.json +24 -2
- package/data/remediations.json +124 -0
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -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/cli/bomAssembly.js +92 -3
- package/lib/cli/index.js +108 -1
- package/lib/cli/jsBom.js +153 -64
- package/lib/cli/jvmBom.js +237 -46
- package/lib/cli/managedBom.js +142 -16
- package/lib/cli/nativeBom.js +42 -5
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +8 -0
- package/lib/core/fs.js +12 -0
- package/lib/core/httpClient.js +98 -1
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +5 -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/gradleutils.js +828 -224
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-misc.js +209 -20
- package/lib/ecosystems/parsers-python.js +89 -2
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/rubyutils.js +538 -31
- package/lib/ecosystems/scalacliutils.js +2 -0
- package/lib/ecosystems/scalasem.js +796 -151
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +346 -43
- package/lib/helpers/agenticToolutils.js +413 -93
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/atomUtils.js +77 -0
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/deps.js +35 -0
- package/lib/inventory/dosai.js +139 -5
- package/lib/inventory/dotnetRuntime.js +217 -0
- package/lib/inventory/envcontext.js +307 -13
- package/lib/inventory/evidenceUtils.js +11 -0
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +31 -3
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -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/osPackageResolver.js +182 -0
- package/lib/inventory/phpBuildInfo.js +10 -59
- package/lib/inventory/phpHostProbe.js +32 -488
- 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 +49 -2
- package/lib/managers/binary.js +337 -3
- package/lib/managers/docker.js +79 -0
- package/lib/parsers/largeJson.js +28 -11
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +12 -1
- package/lib/stages/postgen/ruleEngine.js +13 -5
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +114 -57
- package/lib/validator/bomValidator.js +6 -1
- package/lib/validator/generated/validate-1.6.mjs +1 -1
- package/lib/validator/generated/validate-1.7.mjs +1 -1
- package/lib/validator/generated/validate-2.0.mjs +1 -1
- package/lib/validator/index.js +1 -1
- package/package.json +3 -2
- package/types/lib/cli/bomAssembly.d.ts +13 -1
- package/types/lib/cli/bomAssembly.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.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 +4 -0
- 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/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/gradleutils.d.ts +47 -13
- 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-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +10 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +20 -2
- 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/scalacliutils.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 +63 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/inventory/atomUtils.d.ts +19 -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/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +17 -1
- 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/envcontext.d.ts +52 -6
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/gtfobins.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/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/osPackageResolver.d.ts +38 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
- 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 +10 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/largeJson.d.ts +4 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +12 -8
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
package/lib/cli/jvmBom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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";
|
|
@@ -44,19 +44,24 @@ 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,
|
|
54
57
|
isProjectToolingAllowed,
|
|
58
|
+
loadGradleModulesForReports,
|
|
55
59
|
parseGradleDep,
|
|
56
60
|
parseGradleInfoLogsForUrls,
|
|
57
61
|
parseGradleProperties,
|
|
58
62
|
parseGradleResolvedDistributions,
|
|
59
63
|
parseGradleVersionCatalog,
|
|
64
|
+
reconcileGradleComponents,
|
|
60
65
|
recordGradleInvocationFailure,
|
|
61
66
|
splitOutputByGradleProjects,
|
|
62
67
|
stopMillDaemons,
|
|
@@ -91,6 +96,7 @@ import {
|
|
|
91
96
|
} from "../ecosystems/sbtutils.js";
|
|
92
97
|
import { collectScalaCliComponents } from "../ecosystems/scalacliutils.js";
|
|
93
98
|
import { collectScalaJsNpmComponents } from "../ecosystems/scalasem.js";
|
|
99
|
+
import { isInVendoredDir } from "../ecosystems/vendoredCode.js";
|
|
94
100
|
import {
|
|
95
101
|
isBuildToolRateLimited,
|
|
96
102
|
noteBuildToolRateLimit,
|
|
@@ -99,6 +105,7 @@ import {
|
|
|
99
105
|
collectJarNS,
|
|
100
106
|
collectMvnDependencies,
|
|
101
107
|
convertJarNSToPackages,
|
|
108
|
+
namespaceMappingOfComponents,
|
|
102
109
|
} from "../inventory/deps.js";
|
|
103
110
|
import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
|
|
104
111
|
import {
|
|
@@ -112,8 +119,20 @@ import {
|
|
|
112
119
|
projectSettingsArgs,
|
|
113
120
|
} from "../inventory/jvmLocalRepos.js";
|
|
114
121
|
import { readGradleWrapperVersion } from "../inventory/jvmToolEnv.js";
|
|
115
|
-
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";
|
|
116
131
|
import { publishedArtifactId } from "../inventory/scalaCoords.js";
|
|
132
|
+
import {
|
|
133
|
+
mergeScalaDuplicateComponents,
|
|
134
|
+
rekeyNamespaceMapping,
|
|
135
|
+
} from "../inventory/scalaDedupe.js";
|
|
117
136
|
import {
|
|
118
137
|
buildBomNSData,
|
|
119
138
|
createDefaultParentComponent,
|
|
@@ -253,6 +272,67 @@ export async function collectSbtDependencyJars(pkgList, known = {}) {
|
|
|
253
272
|
return nsMapping;
|
|
254
273
|
}
|
|
255
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
|
+
|
|
256
336
|
/**
|
|
257
337
|
* The purls and bom-refs of a parent component and the module components
|
|
258
338
|
* nested under it.
|
|
@@ -814,6 +894,17 @@ export async function createJavaBom(path, options) {
|
|
|
814
894
|
const projectSettings = projectSettingsArgs(basePath, {
|
|
815
895
|
secureMode: isSecureModeActive(),
|
|
816
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() };
|
|
817
908
|
if (projectSettings.args.length) {
|
|
818
909
|
console.log(
|
|
819
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.`,
|
|
@@ -839,9 +930,10 @@ export async function createJavaBom(path, options) {
|
|
|
839
930
|
if (!useMavenDepsTree && !isBuildToolRateLimited("maven")) {
|
|
840
931
|
thoughtLog("The user wants me to use the cyclonedx-maven plugin.");
|
|
841
932
|
console.log(`Executing '${mavenCmd}' in`, basePath);
|
|
842
|
-
result = safeSpawnSync(mavenCmd, mvnArgs, {
|
|
933
|
+
result = safeSpawnSync(mavenCmd, mvnArgs.concat(mirrorSettingsArgs), {
|
|
843
934
|
cwd: basePath,
|
|
844
935
|
shell: isWin,
|
|
936
|
+
env: mvnSpawnEnv,
|
|
845
937
|
});
|
|
846
938
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
847
939
|
command: `${basename(mavenCmd)} ${mvnArgs.join(" ")}`,
|
|
@@ -906,7 +998,7 @@ export async function createJavaBom(path, options) {
|
|
|
906
998
|
addArgs = parseMavenArgs(readEnvironmentVariable("MVN_ARGS"));
|
|
907
999
|
mvnTreeArgs = mvnTreeArgs.concat(addArgs);
|
|
908
1000
|
}
|
|
909
|
-
mvnTreeArgs = mvnTreeArgs.concat(
|
|
1001
|
+
mvnTreeArgs = mvnTreeArgs.concat(mvnSettingsArgs);
|
|
910
1002
|
// For the first pom alone, we need to execute first in non-recursive mode to capture
|
|
911
1003
|
// the parent component. Then, we execute all of them in recursive mode
|
|
912
1004
|
// A rate limit the --deep copy-dependencies run met ends it too.
|
|
@@ -922,11 +1014,12 @@ export async function createJavaBom(path, options) {
|
|
|
922
1014
|
];
|
|
923
1015
|
findParentComponentArgs = findParentComponentArgs.concat(
|
|
924
1016
|
addArgs,
|
|
925
|
-
|
|
1017
|
+
mvnSettingsArgs,
|
|
926
1018
|
);
|
|
927
1019
|
result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
|
|
928
1020
|
cwd: basePath,
|
|
929
1021
|
shell: isWin,
|
|
1022
|
+
env: mvnSpawnEnv,
|
|
930
1023
|
});
|
|
931
1024
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
932
1025
|
command: `${basename(mavenCmd)} ${findParentComponentArgs.join(" ")}`,
|
|
@@ -956,10 +1049,11 @@ export async function createJavaBom(path, options) {
|
|
|
956
1049
|
"dependency:tree",
|
|
957
1050
|
"-N",
|
|
958
1051
|
`-DoutputFile=${tempMvnParentTreeText}`,
|
|
959
|
-
].concat(addArgs,
|
|
1052
|
+
].concat(addArgs, mvnSettingsArgs);
|
|
960
1053
|
result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
|
|
961
1054
|
cwd: basePath,
|
|
962
1055
|
shell: isWin,
|
|
1056
|
+
env: mvnSpawnEnv,
|
|
963
1057
|
});
|
|
964
1058
|
}
|
|
965
1059
|
if (result.status === 0) {
|
|
@@ -1004,6 +1098,7 @@ export async function createJavaBom(path, options) {
|
|
|
1004
1098
|
result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
|
|
1005
1099
|
cwd: basePath,
|
|
1006
1100
|
shell: isWin,
|
|
1101
|
+
env: mvnSpawnEnv,
|
|
1007
1102
|
});
|
|
1008
1103
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
1009
1104
|
command: `${basename(mavenCmd)} ${mvnTreeArgs.join(" ")}`,
|
|
@@ -1029,10 +1124,11 @@ export async function createJavaBom(path, options) {
|
|
|
1029
1124
|
mvnTreeArgs = [
|
|
1030
1125
|
"dependency:tree",
|
|
1031
1126
|
`-DoutputFile=${tempMvnTreeText}`,
|
|
1032
|
-
].concat(addArgs,
|
|
1127
|
+
].concat(addArgs, mvnSettingsArgs);
|
|
1033
1128
|
result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
|
|
1034
1129
|
cwd: basePath,
|
|
1035
1130
|
shell: isWin,
|
|
1131
|
+
env: mvnSpawnEnv,
|
|
1036
1132
|
});
|
|
1037
1133
|
noteBuildToolRateLimit("maven", commandOutputText(result), {
|
|
1038
1134
|
command: `${basename(mavenCmd)} ${mvnTreeArgs.join(" ")}`,
|
|
@@ -1182,6 +1278,12 @@ export async function createJavaBom(path, options) {
|
|
|
1182
1278
|
parentComponent = tmpParentComponent;
|
|
1183
1279
|
parentComponent.components = [];
|
|
1184
1280
|
} else {
|
|
1281
|
+
separateDuplicateMavenProject(
|
|
1282
|
+
tmpParentComponent,
|
|
1283
|
+
parentComponent,
|
|
1284
|
+
path,
|
|
1285
|
+
parsedList.dependenciesList,
|
|
1286
|
+
);
|
|
1185
1287
|
parentComponent.components.push(tmpParentComponent);
|
|
1186
1288
|
}
|
|
1187
1289
|
if (parsedList?.dependenciesList?.length) {
|
|
@@ -1309,9 +1411,14 @@ export async function createJavaBom(path, options) {
|
|
|
1309
1411
|
}
|
|
1310
1412
|
}
|
|
1311
1413
|
const allProjects = [];
|
|
1312
|
-
|
|
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();
|
|
1313
1417
|
const rootDependsOn = new Set();
|
|
1314
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();
|
|
1315
1422
|
// Determine the root path for gradle
|
|
1316
1423
|
// Fixes gradle invocation for microservices-demo
|
|
1317
1424
|
let gradleRootPath = path;
|
|
@@ -1413,6 +1520,12 @@ export async function createJavaBom(path, options) {
|
|
|
1413
1520
|
const gradleInitArgs = readEnvironmentVariable("GRADLE_INCLUDED_BUILDS")
|
|
1414
1521
|
? []
|
|
1415
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
|
+
}
|
|
1416
1529
|
if (resolveGradleDistribution && gradleInitArgs.length) {
|
|
1417
1530
|
gradleInitArgs.push("-PcdxgenResolveDistribution=true");
|
|
1418
1531
|
}
|
|
@@ -1484,12 +1597,19 @@ export async function createJavaBom(path, options) {
|
|
|
1484
1597
|
);
|
|
1485
1598
|
if (!includedBuilds.includes(key)) {
|
|
1486
1599
|
parentComponent = rootComponent;
|
|
1600
|
+
} else if (retMap.gradlePlugin) {
|
|
1601
|
+
gradlePluginBuilds.add(key);
|
|
1487
1602
|
}
|
|
1488
1603
|
gradleModules.set(key, rootComponent);
|
|
1489
|
-
if (
|
|
1604
|
+
if (
|
|
1605
|
+
!allProjectsAddedRefs.has(rootComponent["bom-ref"] ?? rootComponent)
|
|
1606
|
+
) {
|
|
1490
1607
|
allProjects.push(rootComponent);
|
|
1491
1608
|
rootDependsOn.add(rootComponent["bom-ref"]);
|
|
1492
|
-
|
|
1609
|
+
allProjectsAddedRefs.set(
|
|
1610
|
+
rootComponent["bom-ref"] ?? rootComponent,
|
|
1611
|
+
rootComponent,
|
|
1612
|
+
);
|
|
1493
1613
|
}
|
|
1494
1614
|
allProjectsStr = allProjectsStr.concat(retMap.projects);
|
|
1495
1615
|
}
|
|
@@ -1522,14 +1642,60 @@ export async function createJavaBom(path, options) {
|
|
|
1522
1642
|
);
|
|
1523
1643
|
const rootSubProject = retMap.rootProject;
|
|
1524
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
|
+
}
|
|
1525
1657
|
const rootSubProjectObj = await buildObjectForGradleModule(
|
|
1526
|
-
rootSubProject === "root"
|
|
1658
|
+
rootSubProject === "root"
|
|
1659
|
+
? subProject.split(":").pop()
|
|
1660
|
+
: rootSubProject,
|
|
1527
1661
|
retMap.metadata,
|
|
1528
1662
|
);
|
|
1529
|
-
|
|
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)) {
|
|
1530
1696
|
allProjects.push(rootSubProjectObj);
|
|
1531
1697
|
rootDependsOn.add(rootSubProjectObj["bom-ref"]);
|
|
1532
|
-
|
|
1698
|
+
allProjectsAddedRefs.set(moduleKey, rootSubProjectObj);
|
|
1533
1699
|
}
|
|
1534
1700
|
gradleModules.set(subProject, rootSubProjectObj);
|
|
1535
1701
|
}
|
|
@@ -1561,7 +1727,6 @@ export async function createJavaBom(path, options) {
|
|
|
1561
1727
|
? readEnvironmentVariable("GRADLE_DEPENDENCY_TASK")
|
|
1562
1728
|
: "dependencies";
|
|
1563
1729
|
|
|
1564
|
-
const gradleSubCommands = [];
|
|
1565
1730
|
let modulesToSkip = readEnvironmentVariable("GRADLE_SKIP_MODULES")
|
|
1566
1731
|
? readEnvironmentVariable("GRADLE_SKIP_MODULES").split(",")
|
|
1567
1732
|
: [];
|
|
@@ -1570,23 +1735,16 @@ export async function createJavaBom(path, options) {
|
|
|
1570
1735
|
readEnvironmentVariable("GRADLE_SKIP_MODULE_DEPENDENCIES").split(","),
|
|
1571
1736
|
);
|
|
1572
1737
|
}
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
gradleSubCommands.push(`${key}:${gradleDepTask}`);
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1738
|
+
const gradleSubCommands = gradleDependencyTasks(
|
|
1739
|
+
gradleModules,
|
|
1740
|
+
parentComponent,
|
|
1741
|
+
gradleDepTask,
|
|
1742
|
+
modulesToSkip,
|
|
1743
|
+
);
|
|
1582
1744
|
const gradleArguments = buildGradleCommandArguments(
|
|
1583
|
-
|
|
1584
|
-
? readEnvironmentVariable("GRADLE_ARGS").split(" ")
|
|
1585
|
-
: [],
|
|
1745
|
+
gradleArgsFromEnv("GRADLE_ARGS"),
|
|
1586
1746
|
gradleSubCommands,
|
|
1587
|
-
|
|
1588
|
-
? readEnvironmentVariable("GRADLE_ARGS_DEPENDENCIES").split(" ")
|
|
1589
|
-
: [],
|
|
1747
|
+
gradleArgsFromEnv("GRADLE_ARGS_DEPENDENCIES"),
|
|
1590
1748
|
gradleCmd.length,
|
|
1591
1749
|
);
|
|
1592
1750
|
const allOutputs = [];
|
|
@@ -1647,14 +1805,30 @@ export async function createJavaBom(path, options) {
|
|
|
1647
1805
|
const perProjectOutput = splitOutputByGradleProjects(cmdOutput, [
|
|
1648
1806
|
gradleDepTask,
|
|
1649
1807
|
]);
|
|
1808
|
+
await loadGradleModulesForReports(
|
|
1809
|
+
perProjectOutput.values(),
|
|
1810
|
+
gradleModules,
|
|
1811
|
+
gradleRootPath,
|
|
1812
|
+
options,
|
|
1813
|
+
);
|
|
1814
|
+
const reportedProjects = new Set(perProjectOutput.keys());
|
|
1650
1815
|
for (const key of gradleModules.keys()) {
|
|
1651
1816
|
const parsedList = await parseGradleDep(
|
|
1652
1817
|
perProjectOutput.has(key) ? perProjectOutput.get(key) : "",
|
|
1653
1818
|
key,
|
|
1654
1819
|
gradleModules,
|
|
1655
1820
|
gradleRootPath,
|
|
1821
|
+
reportedProjects,
|
|
1656
1822
|
);
|
|
1657
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
|
+
}
|
|
1658
1832
|
if (parsedList?.dependenciesList?.length) {
|
|
1659
1833
|
dependencies = mergeDependencies(
|
|
1660
1834
|
dependencies,
|
|
@@ -1672,6 +1846,7 @@ export async function createJavaBom(path, options) {
|
|
|
1672
1846
|
pkgList = pkgList.concat(dlist);
|
|
1673
1847
|
}
|
|
1674
1848
|
}
|
|
1849
|
+
reconcileGradleComponents(pkgList);
|
|
1675
1850
|
}
|
|
1676
1851
|
if (pkgList.length) {
|
|
1677
1852
|
const fileToUrlMap = parseGradleInfoLogsForUrls(sstdout);
|
|
@@ -1685,9 +1860,15 @@ export async function createJavaBom(path, options) {
|
|
|
1685
1860
|
if (!p.externalReferences) {
|
|
1686
1861
|
p.externalReferences = [];
|
|
1687
1862
|
}
|
|
1688
|
-
|
|
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
|
+
) {
|
|
1689
1870
|
const groupPath = p.group.replace(/\./g, "/");
|
|
1690
|
-
const matchPath =
|
|
1871
|
+
const matchPath = `/${groupPath}/${p.name}/${p.version}/`;
|
|
1691
1872
|
let matchedUrl = Object.values(fileToUrlMap).find((url) =>
|
|
1692
1873
|
url.includes(matchPath),
|
|
1693
1874
|
);
|
|
@@ -1809,11 +1990,14 @@ export async function createJavaBom(path, options) {
|
|
|
1809
1990
|
// Bazel
|
|
1810
1991
|
// Look for the BUILD file only in the root directory
|
|
1811
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.
|
|
1812
1996
|
const bazelFiles = getAllFiles(
|
|
1813
1997
|
path,
|
|
1814
1998
|
`${options.multiProject ? "**/" : ""}{WORKSPACE{,.bazel},MODULE.bazel}`,
|
|
1815
1999
|
options,
|
|
1816
|
-
);
|
|
2000
|
+
).filter((f) => !isInVendoredDir(path, f));
|
|
1817
2001
|
if (
|
|
1818
2002
|
bazelFiles?.length &&
|
|
1819
2003
|
!hasAnyProjectType(
|
|
@@ -1886,6 +2070,9 @@ export async function createJavaBom(path, options) {
|
|
|
1886
2070
|
) {
|
|
1887
2071
|
bArgs = ["--bazelrc=.bazelrc", "build", bazelTarget];
|
|
1888
2072
|
}
|
|
2073
|
+
// Repository rules see the mirror through their own environment,
|
|
2074
|
+
// which only a --repo_env flag reaches.
|
|
2075
|
+
bArgs = bArgs.concat(bazelMirrorArgs());
|
|
1889
2076
|
console.log("Executing", BAZEL_CMD, "in", basePath);
|
|
1890
2077
|
let result = safeSpawnSync(BAZEL_CMD, bArgs, {
|
|
1891
2078
|
cwd: basePath,
|
|
@@ -2099,7 +2286,7 @@ export async function createJavaBom(path, options) {
|
|
|
2099
2286
|
// sbt resolves into the user's own caches, so a project that has been
|
|
2100
2287
|
// built resolves without the network. The dependency trees download
|
|
2101
2288
|
// the jar of every dependency they list, which is all --deep reads.
|
|
2102
|
-
const env = { ...process.env };
|
|
2289
|
+
const env = { ...process.env, ...sbtMirrorEnv() };
|
|
2103
2290
|
for (const i in sbtProjects) {
|
|
2104
2291
|
if (isBuildToolRateLimited("sbt")) {
|
|
2105
2292
|
// Every remaining sbt build in this scan resolves from the same
|
|
@@ -2450,19 +2637,13 @@ export async function createJavaBom(path, options) {
|
|
|
2450
2637
|
const jarNSData = await createJarBom(path, options);
|
|
2451
2638
|
if (jarNSData?.bomJson?.components) {
|
|
2452
2639
|
pkgList = pkgList.concat(jarNSData?.bomJson?.components);
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
);
|
|
2461
|
-
if (nsProp.length) {
|
|
2462
|
-
targetJarNSMapping[p.purl] = nsProp[0].value;
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
jarNSMapping = { ...jarNSMapping, ...targetJarNSMapping };
|
|
2640
|
+
jarNSMapping = {
|
|
2641
|
+
...jarNSMapping,
|
|
2642
|
+
...namespaceMappingOfComponents(
|
|
2643
|
+
jarNSData.bomJson.components,
|
|
2644
|
+
jarNSMapping,
|
|
2645
|
+
),
|
|
2646
|
+
};
|
|
2466
2647
|
}
|
|
2467
2648
|
}
|
|
2468
2649
|
}
|
|
@@ -2504,10 +2685,12 @@ export async function createJavaBom(path, options) {
|
|
|
2504
2685
|
if (DEBUG_MODE) {
|
|
2505
2686
|
console.log("Executing", millCmd, "in", millRootPath);
|
|
2506
2687
|
}
|
|
2688
|
+
const millSpawnEnv = { ...process.env, ...coursierMirrorEnv() };
|
|
2507
2689
|
let sresult = safeSpawnSync(millCmd, millArgs, {
|
|
2508
2690
|
cwd: millRootPath,
|
|
2509
2691
|
shell: isWin,
|
|
2510
2692
|
maxBuffer: MAX_BUFFER * 10,
|
|
2693
|
+
env: millSpawnEnv,
|
|
2511
2694
|
});
|
|
2512
2695
|
noteBuildToolRateLimit("mill", commandOutputText(sresult), {
|
|
2513
2696
|
command: `${basename(millCmd)} ${millArgs.join(" ")}`,
|
|
@@ -2546,6 +2729,7 @@ export async function createJavaBom(path, options) {
|
|
|
2546
2729
|
sresult = safeSpawnSync(millCmd, millResolveArgs, {
|
|
2547
2730
|
cwd: millRootPath,
|
|
2548
2731
|
shell: isWin,
|
|
2732
|
+
env: millSpawnEnv,
|
|
2549
2733
|
});
|
|
2550
2734
|
if (sresult.status !== 0 || sresult.error) {
|
|
2551
2735
|
if (options.failOnError || DEBUG_MODE) {
|
|
@@ -2710,6 +2894,13 @@ export async function createJavaBom(path, options) {
|
|
|
2710
2894
|
// Deduplication and metadata belong to whatever was collected, so they run
|
|
2711
2895
|
// on the deferred path too.
|
|
2712
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);
|
|
2713
2904
|
// --deep collects namespaces; it does not opt in to remote licence lookups,
|
|
2714
2905
|
// which FETCH_LICENSE controls. The project's own modules are never looked
|
|
2715
2906
|
// up remotely: they are not published.
|