@cdxgen/cdxgen 13.4.0 → 13.5.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 +7 -7
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +25 -5
- package/bin/evinse.js +5 -0
- package/bin/hbom.js +15 -7
- package/bin/repl.js +29 -0
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +283 -1
- 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/lib/audit/index.js +14 -0
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +73 -4
- package/lib/cli/jvmBom.js +126 -20
- package/lib/cli/managedBom.js +711 -71
- package/lib/cli/nativeBom.js +225 -28
- package/lib/core/env.js +30 -8
- package/lib/core/fs.js +28 -19
- package/lib/core/httpClient.js +74 -45
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/ecosystems/golem.js +550 -6
- package/lib/ecosystems/gradleutils.js +30 -20
- package/lib/ecosystems/parsers-dotnet.js +117 -18
- package/lib/ecosystems/parsers-go.js +1090 -367
- package/lib/ecosystems/parsers-jvm.js +259 -17
- package/lib/ecosystems/parsers-misc.js +229 -44
- package/lib/ecosystems/parsers-python.js +11 -10
- package/lib/ecosystems/rubyutils.js +6 -3
- package/lib/ecosystems/rusi.js +10 -0
- package/lib/ecosystems/scalacliutils.js +2 -1
- package/lib/ecosystems/scalasem.js +3 -1
- package/lib/evinser/evinser.js +126 -18
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +33 -0
- package/lib/inventory/auditCategories.js +3 -3
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +6 -4
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +500 -58
- package/lib/inventory/dynamic.js +45 -3
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +436 -23
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/source.js +207 -3
- 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 +529 -183
- package/lib/managers/docker.js +166 -12
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/server/server.js +186 -1
- 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 +58 -1
- package/lib/stages/postgen/specVersionCompat.js +30 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/package.json +17 -17
- 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 +9 -2
- 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/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/env.d.ts +18 -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.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/ecosystems/cppEvidence.d.ts +1 -1
- 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 +10 -8
- package/types/lib/ecosystems/gradleutils.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-jvm.d.ts +28 -2
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +18 -58
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +4 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +1 -1
- 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/evinser/evinser.d.ts +25 -0
- 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 +14 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.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 +145 -6
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- 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 +40 -2
- 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/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/hostTopology.d.ts.map +1 -1
- 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 +6 -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/source.d.ts +28 -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 +12 -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 +13 -0
- 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/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
|
@@ -20,17 +20,61 @@ import { applyPurl } from "../inventory/purl.js";
|
|
|
20
20
|
import { parseScalaArtifact } from "../inventory/scalaCoords.js";
|
|
21
21
|
import { xml2js } from "../parsers/xml.js";
|
|
22
22
|
|
|
23
|
+
/** Bound on the `${...}` references one pom value may expand through. */
|
|
24
|
+
const POM_PROPERTY_EXPANSION_LIMIT = 10;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Expand the `${name}` references in a pom value. The value is returned only
|
|
28
|
+
* when every reference resolves, so a version is never half expanded.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} value Raw pom value
|
|
31
|
+
* @param {Function} lookup Returns the value of a property name, or undefined
|
|
32
|
+
* @returns {string|undefined} Expanded value, or undefined
|
|
33
|
+
*/
|
|
34
|
+
function expandPomValue(value, lookup) {
|
|
35
|
+
let expanded = value;
|
|
36
|
+
for (
|
|
37
|
+
let i = 0;
|
|
38
|
+
i < POM_PROPERTY_EXPANSION_LIMIT && expanded?.includes("${");
|
|
39
|
+
i++
|
|
40
|
+
) {
|
|
41
|
+
const start = expanded.indexOf("${");
|
|
42
|
+
const end = expanded.indexOf("}", start + 2);
|
|
43
|
+
if (end < 0) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const replacement = lookup(expanded.slice(start + 2, end));
|
|
47
|
+
if (typeof replacement !== "string") {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
expanded = `${expanded.slice(0, start)}${replacement}${expanded.slice(end + 1)}`;
|
|
51
|
+
}
|
|
52
|
+
return expanded?.includes("${") ? undefined : expanded;
|
|
53
|
+
}
|
|
54
|
+
|
|
23
55
|
/**
|
|
24
56
|
* Parse pom file
|
|
25
57
|
*
|
|
58
|
+
* Versions resolve from the pom's own properties and dependencyManagement.
|
|
59
|
+
* A caller that has read the pom's parents passes what they define in
|
|
60
|
+
* `inherited`, so versions the parents manage resolve too. Imported BOMs and
|
|
61
|
+
* parents outside the scanned directory are not read.
|
|
62
|
+
*
|
|
26
63
|
* @param {string} pomFile pom file to parse
|
|
27
|
-
* @
|
|
64
|
+
* @param {Object} [inherited] Properties and managed versions from parent poms
|
|
65
|
+
* @param {Object} [inherited.properties] Property name to raw value
|
|
66
|
+
* @param {Object} [inherited.managedVersions] `groupId:artifactId` to version
|
|
67
|
+
* @returns {Object} Object containing pom properties, modules, the parent
|
|
68
|
+
* reference, the user properties and managed versions this pom defines, and
|
|
69
|
+
* array of dependencies
|
|
28
70
|
*/
|
|
29
|
-
export function parsePom(pomFile) {
|
|
71
|
+
export function parsePom(pomFile, inherited = {}) {
|
|
30
72
|
const deps = [];
|
|
31
73
|
let modules;
|
|
32
74
|
let pomPurl;
|
|
33
75
|
const properties = {};
|
|
76
|
+
const userProperties = {};
|
|
77
|
+
const managedVersions = {};
|
|
34
78
|
let isQuarkus = false;
|
|
35
79
|
const xmlData = readFileSync(pomFile, "utf-8");
|
|
36
80
|
const project = xml2js(xmlData, {
|
|
@@ -63,25 +107,30 @@ export function parsePom(pomFile) {
|
|
|
63
107
|
}
|
|
64
108
|
}
|
|
65
109
|
// Take the version from the parent if available
|
|
66
|
-
if (!properties.version && project
|
|
110
|
+
if (!properties.version && project?.parent?.version?._) {
|
|
67
111
|
properties.version = project.parent.version._;
|
|
68
112
|
}
|
|
69
113
|
// Take the groupId from the parent if available
|
|
70
|
-
if (!properties.groupId && project
|
|
114
|
+
if (!properties.groupId && project?.parent?.groupId?._) {
|
|
71
115
|
properties.groupId = project.parent.groupId._;
|
|
72
116
|
}
|
|
117
|
+
let parent;
|
|
118
|
+
if (project?.parent) {
|
|
119
|
+
parent = {
|
|
120
|
+
groupId: project.parent.groupId?._,
|
|
121
|
+
artifactId: project.parent.artifactId?._,
|
|
122
|
+
version: project.parent.version?._,
|
|
123
|
+
// An empty <relativePath/> tells Maven not to look for the parent on
|
|
124
|
+
// disk; a missing one means ../pom.xml.
|
|
125
|
+
relativePath:
|
|
126
|
+
project.parent.relativePath === undefined
|
|
127
|
+
? "../pom.xml"
|
|
128
|
+
: project.parent.relativePath?._ || "",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
73
131
|
if (project?.scm?.url?._) {
|
|
74
132
|
properties.scm = project.scm.url._;
|
|
75
133
|
}
|
|
76
|
-
if (properties.groupId || properties.artifactId) {
|
|
77
|
-
pomPurl = build({
|
|
78
|
-
type: "maven",
|
|
79
|
-
namespace: properties.groupId || "" || null,
|
|
80
|
-
name: properties.artifactId,
|
|
81
|
-
version: properties.version || null,
|
|
82
|
-
qualifiers: { type: properties.packaging || "jar" } || null,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
134
|
const moduleEntries = [];
|
|
86
135
|
if (project?.modules?.module) {
|
|
87
136
|
moduleEntries.push(project.modules.module);
|
|
@@ -100,11 +149,80 @@ export function parsePom(pomFile) {
|
|
|
100
149
|
if (project?.properties) {
|
|
101
150
|
for (const aprop of Object.keys(project.properties)) {
|
|
102
151
|
properties[aprop] = project.properties[aprop]?._;
|
|
152
|
+
userProperties[aprop] = project.properties[aprop]?._;
|
|
103
153
|
if (!isQuarkus && aprop.startsWith("quarkus.platform")) {
|
|
104
154
|
isQuarkus = true;
|
|
105
155
|
}
|
|
106
156
|
}
|
|
107
157
|
}
|
|
158
|
+
const inheritedProperties = inherited?.properties || {};
|
|
159
|
+
const lookupProperty = (name) => {
|
|
160
|
+
switch (name) {
|
|
161
|
+
case "project.version":
|
|
162
|
+
case "pom.version":
|
|
163
|
+
case "version":
|
|
164
|
+
return properties.version;
|
|
165
|
+
case "project.groupId":
|
|
166
|
+
case "pom.groupId":
|
|
167
|
+
case "groupId":
|
|
168
|
+
return properties.groupId;
|
|
169
|
+
case "project.artifactId":
|
|
170
|
+
case "pom.artifactId":
|
|
171
|
+
case "artifactId":
|
|
172
|
+
return properties.artifactId;
|
|
173
|
+
case "project.parent.version":
|
|
174
|
+
return parent?.version;
|
|
175
|
+
case "project.parent.groupId":
|
|
176
|
+
return parent?.groupId;
|
|
177
|
+
default:
|
|
178
|
+
return Object.hasOwn(userProperties, name)
|
|
179
|
+
? userProperties[name]
|
|
180
|
+
: inheritedProperties[name];
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
// A property can refer to another, so each lookup expands its value too.
|
|
184
|
+
const expand = (value) =>
|
|
185
|
+
expandPomValue(value, (name) => {
|
|
186
|
+
const raw = lookupProperty(name);
|
|
187
|
+
return raw?.includes("${")
|
|
188
|
+
? expandPomValue(raw, (inner) =>
|
|
189
|
+
inner === name ? undefined : lookupProperty(inner),
|
|
190
|
+
)
|
|
191
|
+
: raw;
|
|
192
|
+
});
|
|
193
|
+
let managedEntries = project?.dependencyManagement?.dependencies?.dependency;
|
|
194
|
+
if (managedEntries && !Array.isArray(managedEntries)) {
|
|
195
|
+
managedEntries = [managedEntries];
|
|
196
|
+
}
|
|
197
|
+
for (const amanaged of managedEntries || []) {
|
|
198
|
+
// An imported BOM manages versions this pom cannot see without fetching it
|
|
199
|
+
if (amanaged?.scope?._ === "import" || !amanaged?.version?._) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const group = expand(amanaged.groupId?._);
|
|
203
|
+
const name = expand(amanaged.artifactId?._);
|
|
204
|
+
const version = expand(amanaged.version._);
|
|
205
|
+
if (group && name && version) {
|
|
206
|
+
managedVersions[`${group}:${name}`] = version;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const inheritedManagedVersions = inherited?.managedVersions || {};
|
|
210
|
+
// CI friendly versions such as ${revision} resolve from the properties
|
|
211
|
+
for (const coordinate of ["groupId", "version"]) {
|
|
212
|
+
if (properties[coordinate]?.includes("${")) {
|
|
213
|
+
properties[coordinate] =
|
|
214
|
+
expand(properties[coordinate]) || properties[coordinate];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (properties.groupId || properties.artifactId) {
|
|
218
|
+
pomPurl = build({
|
|
219
|
+
type: "maven",
|
|
220
|
+
namespace: properties.groupId || "" || null,
|
|
221
|
+
name: properties.artifactId,
|
|
222
|
+
version: properties.version || null,
|
|
223
|
+
qualifiers: { type: properties.packaging || "jar" } || null,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
108
226
|
// Check the plugins for quarkus
|
|
109
227
|
if (!isQuarkus && project?.build?.plugins?.plugin) {
|
|
110
228
|
if (Array.isArray(project.build.plugins.plugin)) {
|
|
@@ -138,7 +256,18 @@ export function parsePom(pomFile) {
|
|
|
138
256
|
versionStr = version._;
|
|
139
257
|
}
|
|
140
258
|
if (versionStr?.includes("$")) {
|
|
141
|
-
versionStr =
|
|
259
|
+
versionStr = expand(versionStr);
|
|
260
|
+
}
|
|
261
|
+
let groupStr = adep.groupId ? adep.groupId._ : "";
|
|
262
|
+
if (groupStr?.includes("${")) {
|
|
263
|
+
groupStr = expand(groupStr) || groupStr;
|
|
264
|
+
}
|
|
265
|
+
const nameStr = adep.artifactId ? adep.artifactId._ : "";
|
|
266
|
+
if (!versionStr && !version?._) {
|
|
267
|
+
const managedKey = `${groupStr}:${nameStr}`;
|
|
268
|
+
versionStr = Object.hasOwn(managedVersions, managedKey)
|
|
269
|
+
? managedVersions[managedKey]
|
|
270
|
+
: inheritedManagedVersions[managedKey];
|
|
142
271
|
}
|
|
143
272
|
const scope = adep.scope?._;
|
|
144
273
|
const type = adep.type?._ || "jar";
|
|
@@ -156,8 +285,8 @@ export function parsePom(pomFile) {
|
|
|
156
285
|
}
|
|
157
286
|
if (includeMavenTestScope || scope !== "test") {
|
|
158
287
|
deps.push({
|
|
159
|
-
group:
|
|
160
|
-
name:
|
|
288
|
+
group: groupStr,
|
|
289
|
+
name: nameStr,
|
|
161
290
|
version: versionStr,
|
|
162
291
|
qualifiers,
|
|
163
292
|
scope: mapMavenScope(scope, optional === "true"),
|
|
@@ -179,7 +308,120 @@ export function parsePom(pomFile) {
|
|
|
179
308
|
}
|
|
180
309
|
}
|
|
181
310
|
}
|
|
182
|
-
return {
|
|
311
|
+
return {
|
|
312
|
+
isQuarkus,
|
|
313
|
+
pomPurl,
|
|
314
|
+
modules,
|
|
315
|
+
parent,
|
|
316
|
+
properties,
|
|
317
|
+
userProperties,
|
|
318
|
+
managedVersions,
|
|
319
|
+
dependencies: deps,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Bound on the chain of parent poms read from disk. */
|
|
324
|
+
const LOCAL_PARENT_DEPTH_LIMIT = 10;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* The pom file a `<parent>` reference points at on disk, when it lies inside
|
|
328
|
+
* the scanned directory and declares the coordinates the reference names.
|
|
329
|
+
*
|
|
330
|
+
* @param {string} pomFile Child pom file
|
|
331
|
+
* @param {Object} parentRef Parent reference from parsePom
|
|
332
|
+
* @param {string} rootDir Scanned directory
|
|
333
|
+
* @returns {string|undefined} Parent pom file
|
|
334
|
+
*/
|
|
335
|
+
function locateLocalParentPom(pomFile, parentRef, rootDir) {
|
|
336
|
+
if (!parentRef?.relativePath || !rootDir) {
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
let candidate = resolve(dirname(pomFile), parentRef.relativePath);
|
|
340
|
+
if (!candidate.endsWith(".xml")) {
|
|
341
|
+
candidate = join(candidate, "pom.xml");
|
|
342
|
+
}
|
|
343
|
+
const rel = relative(resolve(rootDir), candidate);
|
|
344
|
+
if (!rel || rel.startsWith("..") || isAbsolute(rel)) {
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
if (!safeExistsSync(candidate)) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
const { groupId, artifactId } = parsePom(candidate).properties || {};
|
|
352
|
+
if (
|
|
353
|
+
artifactId !== parentRef.artifactId ||
|
|
354
|
+
(parentRef.groupId && groupId !== parentRef.groupId)
|
|
355
|
+
) {
|
|
356
|
+
return undefined;
|
|
357
|
+
}
|
|
358
|
+
} catch (_err) {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
return candidate;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* What a pom passes on to its children: its user properties and managed
|
|
366
|
+
* versions over those of its own local parents.
|
|
367
|
+
*
|
|
368
|
+
* @param {string} pomFile Pom file
|
|
369
|
+
* @param {string} rootDir Scanned directory
|
|
370
|
+
* @param {Map} cache Results by pom file
|
|
371
|
+
* @param {number} depth Current depth of the parent chain
|
|
372
|
+
* @returns {Object} Inherited properties and managed versions
|
|
373
|
+
*/
|
|
374
|
+
function localPomInheritance(pomFile, rootDir, cache, depth) {
|
|
375
|
+
if (cache.has(pomFile)) {
|
|
376
|
+
return cache.get(pomFile);
|
|
377
|
+
}
|
|
378
|
+
const empty = { properties: {}, managedVersions: {} };
|
|
379
|
+
// A parent chain that loops back reads as having no parent
|
|
380
|
+
cache.set(pomFile, empty);
|
|
381
|
+
let inherited = empty;
|
|
382
|
+
try {
|
|
383
|
+
const parentPom =
|
|
384
|
+
depth < LOCAL_PARENT_DEPTH_LIMIT
|
|
385
|
+
? locateLocalParentPom(pomFile, parsePom(pomFile).parent, rootDir)
|
|
386
|
+
: undefined;
|
|
387
|
+
if (parentPom) {
|
|
388
|
+
inherited = localPomInheritance(parentPom, rootDir, cache, depth + 1);
|
|
389
|
+
}
|
|
390
|
+
const own = parsePom(pomFile, inherited);
|
|
391
|
+
const result = {
|
|
392
|
+
properties: { ...inherited.properties, ...own.userProperties },
|
|
393
|
+
managedVersions: { ...inherited.managedVersions, ...own.managedVersions },
|
|
394
|
+
};
|
|
395
|
+
cache.set(pomFile, result);
|
|
396
|
+
return result;
|
|
397
|
+
} catch (_err) {
|
|
398
|
+
return empty;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Parse a pom file together with the parent poms it names that are present
|
|
404
|
+
* inside the scanned directory, without running Maven. Properties and
|
|
405
|
+
* dependencyManagement versions from those parents resolve the versions the
|
|
406
|
+
* pom leaves to them. Parents outside the directory and imported BOMs are not
|
|
407
|
+
* read, so the versions they manage stay empty.
|
|
408
|
+
*
|
|
409
|
+
* @param {string} pomFile Pom file to parse
|
|
410
|
+
* @param {string} rootDir Scanned directory; parents outside it are ignored
|
|
411
|
+
* @param {Map} [cache] Reused across the poms of one scan
|
|
412
|
+
* @returns {Object} Same shape as parsePom
|
|
413
|
+
*/
|
|
414
|
+
export function parsePomWithLocalParents(pomFile, rootDir, cache = new Map()) {
|
|
415
|
+
const pomPath = resolve(pomFile);
|
|
416
|
+
const parentPom = locateLocalParentPom(
|
|
417
|
+
pomPath,
|
|
418
|
+
parsePom(pomPath).parent,
|
|
419
|
+
rootDir,
|
|
420
|
+
);
|
|
421
|
+
if (!parentPom) {
|
|
422
|
+
return parsePom(pomFile);
|
|
423
|
+
}
|
|
424
|
+
return parsePom(pomFile, localPomInheritance(parentPom, rootDir, cache, 1));
|
|
183
425
|
}
|
|
184
426
|
|
|
185
427
|
/** Bound on the reactor walk. A pom's module list is untrusted input, so the
|