@cdxgen/cdxgen 13.3.0 → 13.4.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 -6
- package/bin/cdxgen.js +90 -26
- package/bin/evinse.js +18 -1
- package/bin/repl.js +86 -0
- package/bin/sign.js +45 -15
- package/bin/tracebom.js +5 -1
- package/bin/validate.js +84 -18
- package/bin/verify.js +155 -86
- package/data/helpers/init.gradle +46 -21
- package/data/remediations.json +61 -0
- package/data/rules/dependency-sources.yaml +67 -0
- package/data/rules/scala-evidence.yaml +115 -0
- package/lib/audit/index.js +38 -6
- package/lib/cli/index.js +113 -54
- package/lib/cli/jsBom.js +50 -29
- package/lib/cli/jvmBom.js +665 -138
- package/lib/cli/managedBom.js +320 -200
- package/lib/cli/nativeBom.js +139 -30
- package/lib/core/activity.js +12 -0
- package/lib/core/env.js +17 -9
- package/lib/core/fs.js +3 -2
- package/lib/core/httpClient.js +159 -24
- package/lib/core/pluginRun.js +184 -0
- package/lib/core/processTree.js +100 -0
- package/lib/core/runState.js +39 -0
- package/lib/core/toml.js +72 -0
- package/lib/ecosystems/asarutils.js +4 -2
- package/lib/ecosystems/bunutils.js +5 -7
- package/lib/ecosystems/cargoCache.js +231 -8
- package/lib/ecosystems/cmakeResolver.js +10 -21
- package/lib/ecosystems/cppBuildContext.js +631 -0
- package/lib/ecosystems/cppEvidence.js +337 -22
- package/lib/ecosystems/cppIncludeResolver.js +294 -0
- package/lib/ecosystems/denoutils.js +93 -66
- package/lib/ecosystems/ecosystems.js +1967 -788
- package/lib/ecosystems/golem.js +28 -12
- package/lib/ecosystems/gradleutils.js +314 -30
- package/lib/ecosystems/jsEvidence.js +85 -24
- package/lib/ecosystems/kosi.js +21 -4
- package/lib/ecosystems/npmutils.js +64 -0
- package/lib/ecosystems/parsers-dotnet.js +567 -151
- package/lib/ecosystems/parsers-elm.js +46 -28
- package/lib/ecosystems/parsers-gleam.js +3 -4
- package/lib/ecosystems/parsers-go.js +324 -61
- package/lib/ecosystems/parsers-js.js +92 -26
- package/lib/ecosystems/parsers-julia.js +2 -3
- package/lib/ecosystems/parsers-jvm.js +204 -12
- package/lib/ecosystems/parsers-misc.js +182 -55
- package/lib/ecosystems/parsers-python.js +141 -10
- package/lib/ecosystems/parsers-rust.js +4 -4
- package/lib/ecosystems/parsers-terraform.js +1573 -19
- package/lib/ecosystems/pythonutils.js +102 -6
- package/lib/ecosystems/remote/huggingface.js +3 -0
- package/lib/ecosystems/rubyutils.js +67 -17
- package/lib/ecosystems/rusi.js +22 -9
- package/lib/ecosystems/sbtutils.js +243 -187
- package/lib/ecosystems/scalacliutils.js +342 -0
- package/lib/ecosystems/scalasem.js +2618 -0
- package/lib/ecosystems/terraformRegistry.js +288 -0
- package/lib/ecosystems/utils.js +2 -0
- package/lib/ecosystems/vendoredCode.js +156 -0
- package/lib/evinser/evinser.js +578 -69
- package/lib/helpers/agenticToolutils.js +2 -2
- package/lib/helpers/bomSigner.js +576 -128
- package/lib/inventory/aiCollector.js +4 -1
- package/lib/inventory/analyzer.js +110 -127
- package/lib/inventory/atomUtils.js +171 -48
- package/lib/inventory/auditCategories.js +7 -0
- package/lib/inventory/buildToolRateLimit.js +144 -0
- package/lib/inventory/cacheCommands.js +2 -1
- package/lib/inventory/cmakeBuildDirs.js +254 -0
- package/lib/inventory/deps.js +501 -124
- package/lib/inventory/dosai.js +248 -44
- package/lib/inventory/dosaiParsers.js +310 -15
- package/lib/inventory/dynamic.js +52 -6
- package/lib/inventory/evidenceUtils.js +154 -109
- package/lib/inventory/fetchBatch.js +574 -38
- package/lib/inventory/fetchDiskCache.js +597 -0
- package/lib/inventory/forgeEnricher.js +14 -5
- package/lib/inventory/jvmLocalRepos.js +917 -0
- package/lib/inventory/mcpConfigParser.js +2 -3
- package/lib/inventory/parentSelection.js +146 -0
- package/lib/inventory/rustFormulationParser.js +3 -4
- package/lib/inventory/scalaCoords.js +153 -0
- package/lib/inventory/source.js +8 -8
- package/lib/inventory/spdx.js +101 -0
- package/lib/inventory/traceRunner.js +88 -7
- package/lib/inventory/tracedCrypto.js +294 -0
- package/lib/managers/docker.js +33 -32
- package/lib/managers/oci.js +24 -2
- package/lib/parsers/cmakeCache.js +69 -0
- package/lib/parsers/cmakeLists.js +16 -2
- package/lib/parsers/cmakePresets.js +400 -0
- package/lib/parsers/compileCommands.js +557 -0
- package/lib/parsers/strictJson.js +322 -0
- package/lib/parsers/terraformConfig.js +1073 -0
- package/lib/parsers/terraformSource.js +652 -0
- package/lib/server/server.js +23 -0
- package/lib/stages/postgen/introspection/markers.js +1 -1
- package/lib/stages/postgen/postgen.js +15 -1
- package/lib/stages/postgen/specVersionCompat.js +32 -0
- package/lib/validator/index.js +25 -10
- package/lib/validator/reporters/json.js +1 -0
- package/package.json +21 -21
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +24 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +7 -4
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +3 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +9 -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 +13 -8
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/pluginRun.d.ts +97 -0
- package/types/lib/core/pluginRun.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +36 -0
- package/types/lib/core/processTree.d.ts.map +1 -0
- package/types/lib/core/runState.d.ts +29 -0
- package/types/lib/core/runState.d.ts.map +1 -0
- package/types/lib/core/toml.d.ts +20 -0
- package/types/lib/core/toml.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +12 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
- package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +18 -2
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +9 -3
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +62 -13
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +50 -0
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmutils.d.ts +15 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +118 -4
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +44 -2
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +6 -1
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +46 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +3 -1
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +53 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +27 -2
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +21 -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/sbtutils.d.ts +88 -2
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
- package/types/lib/ecosystems/scalasem.d.ts +311 -0
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +2 -2
- package/types/lib/ecosystems/utils.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +75 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +80 -4
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/atomUtils.d.ts +82 -10
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +3 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
- package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +2 -1
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
- package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +59 -1
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +57 -8
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts +53 -7
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +10 -0
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +19 -4
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +83 -14
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
- package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/parentSelection.d.ts +34 -0
- package/types/lib/inventory/parentSelection.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts +80 -0
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +9 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +12 -0
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +42 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +3 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeCache.d.ts +16 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +2 -1
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
- package/types/lib/parsers/cmakePresets.d.ts +78 -0
- package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
- package/types/lib/parsers/compileCommands.d.ts +115 -0
- package/types/lib/parsers/compileCommands.d.ts.map +1 -0
- package/types/lib/parsers/strictJson.d.ts +46 -0
- package/types/lib/parsers/strictJson.d.ts.map +1 -0
- package/types/lib/parsers/terraformConfig.d.ts +70 -0
- package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
- package/types/lib/parsers/terraformSource.d.ts +66 -0
- package/types/lib/parsers/terraformSource.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +8 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure reader for CMake presets (`CMakePresets.json` and
|
|
3
|
+
* `CMakeUserPresets.json`, schema versions 1 to 10).
|
|
4
|
+
*
|
|
5
|
+
* A configure preset names how a project is configured: the generator, the
|
|
6
|
+
* build directory, the toolchain file and the cache variables (build type,
|
|
7
|
+
* compilers). Presets inherit from one another, may be hidden (templates
|
|
8
|
+
* that only exist to be inherited), may be enabled only under a condition,
|
|
9
|
+
* and spell paths with macros such as `${sourceDir}` and `$env{NAME}`.
|
|
10
|
+
*
|
|
11
|
+
* This module is layer 1: text and a context object in, data out. Reading the
|
|
12
|
+
* files (and their `include` lists) is done by the caller, which also supplies
|
|
13
|
+
* the process environment through `context.penv`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { isAbsolute, join, normalize } from "node:path";
|
|
17
|
+
|
|
18
|
+
/** Fields a preset does not inherit (CMake's rule). */
|
|
19
|
+
const NOT_INHERITED = new Set([
|
|
20
|
+
"name",
|
|
21
|
+
"hidden",
|
|
22
|
+
"inherits",
|
|
23
|
+
"description",
|
|
24
|
+
"displayName",
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
/** Fields merged key by key across the inheritance chain. */
|
|
28
|
+
const MAP_FIELDS = new Set(["cacheVariables", "environment"]);
|
|
29
|
+
|
|
30
|
+
/** An inheritance chain deeper than this is treated as malformed. */
|
|
31
|
+
const MAX_INHERITANCE_DEPTH = 32;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse the text of a presets file.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} text File contents
|
|
37
|
+
* @returns {{version: number|undefined, include: string[], configurePresets: Object[]}|null}
|
|
38
|
+
* `null` when the text is not a presets document
|
|
39
|
+
*/
|
|
40
|
+
export function parseCmakePresets(text) {
|
|
41
|
+
if (typeof text !== "string" || !text.trim()) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
let data;
|
|
45
|
+
try {
|
|
46
|
+
data = JSON.parse(text);
|
|
47
|
+
} catch (_err) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const configurePresets = Array.isArray(data.configurePresets)
|
|
54
|
+
? data.configurePresets.filter(
|
|
55
|
+
(p) =>
|
|
56
|
+
p &&
|
|
57
|
+
typeof p === "object" &&
|
|
58
|
+
!Array.isArray(p) &&
|
|
59
|
+
typeof p.name === "string" &&
|
|
60
|
+
p.name.length,
|
|
61
|
+
)
|
|
62
|
+
: [];
|
|
63
|
+
return {
|
|
64
|
+
version: Number.isInteger(data.version) ? data.version : undefined,
|
|
65
|
+
include: Array.isArray(data.include)
|
|
66
|
+
? data.include.filter((f) => typeof f === "string" && f.length)
|
|
67
|
+
: [],
|
|
68
|
+
configurePresets,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Expand the macros CMake allows in preset strings.
|
|
74
|
+
*
|
|
75
|
+
* Supported: `${sourceDir}`, `${sourceParentDir}`, `${sourceDirName}`,
|
|
76
|
+
* `${presetName}`, `${generator}`, `${hostSystemName}`, `${fileDir}`,
|
|
77
|
+
* `${dollar}`, `${pathListSep}`, `$env{NAME}` (the preset's own environment,
|
|
78
|
+
* then the process environment) and `$penv{NAME}` (the process environment).
|
|
79
|
+
* `$vendor{...}` and unknown macros are left as written.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} value String to expand
|
|
82
|
+
* @param {Object} context Macro values; `env` (preset environment, a plain
|
|
83
|
+
* object) and `penv` (a function reading the process environment) are
|
|
84
|
+
* optional
|
|
85
|
+
* @returns {string} Expanded string
|
|
86
|
+
*/
|
|
87
|
+
export function expandPresetMacros(value, context = {}) {
|
|
88
|
+
if (typeof value !== "string" || !value.includes("$")) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
let out = "";
|
|
92
|
+
let i = 0;
|
|
93
|
+
while (i < value.length) {
|
|
94
|
+
const dollar = value.indexOf("$", i);
|
|
95
|
+
if (dollar < 0) {
|
|
96
|
+
out += value.slice(i);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
out += value.slice(i, dollar);
|
|
100
|
+
const open = value.indexOf("{", dollar);
|
|
101
|
+
const close = open < 0 ? -1 : value.indexOf("}", open);
|
|
102
|
+
const namespace = open < 0 ? "" : value.slice(dollar + 1, open);
|
|
103
|
+
if (
|
|
104
|
+
open < 0 ||
|
|
105
|
+
close < 0 ||
|
|
106
|
+
!["", "env", "penv", "vendor"].includes(namespace)
|
|
107
|
+
) {
|
|
108
|
+
out += "$";
|
|
109
|
+
i = dollar + 1;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const name = value.slice(open + 1, close);
|
|
113
|
+
const replacement = macroValue(namespace, name, context);
|
|
114
|
+
out +=
|
|
115
|
+
replacement === undefined ? value.slice(dollar, close + 1) : replacement;
|
|
116
|
+
i = close + 1;
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function macroValue(namespace, name, context) {
|
|
122
|
+
if (namespace === "penv") {
|
|
123
|
+
return context.penv ? (context.penv(name) ?? "") : "";
|
|
124
|
+
}
|
|
125
|
+
if (namespace === "env") {
|
|
126
|
+
if (context.env && Object.hasOwn(context.env, name)) {
|
|
127
|
+
return context.env[name] ?? "";
|
|
128
|
+
}
|
|
129
|
+
return context.penv ? (context.penv(name) ?? "") : "";
|
|
130
|
+
}
|
|
131
|
+
if (namespace === "vendor") {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
switch (name) {
|
|
135
|
+
case "sourceDir":
|
|
136
|
+
case "sourceParentDir":
|
|
137
|
+
case "sourceDirName":
|
|
138
|
+
case "presetName":
|
|
139
|
+
case "generator":
|
|
140
|
+
case "hostSystemName":
|
|
141
|
+
case "fileDir":
|
|
142
|
+
case "pathListSep":
|
|
143
|
+
return context[name] ?? "";
|
|
144
|
+
case "dollar":
|
|
145
|
+
return "$";
|
|
146
|
+
default:
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Evaluate a preset condition (schema version 3 and later).
|
|
153
|
+
*
|
|
154
|
+
* @param {*} condition Condition object (or boolean, or null)
|
|
155
|
+
* @param {function(string): string} expand Macro expander for the preset
|
|
156
|
+
* @returns {boolean|undefined} `undefined` when the condition cannot be
|
|
157
|
+
* decided here: `matches`/`notMatches` take a regular expression from the
|
|
158
|
+
* repository, which is not run
|
|
159
|
+
*/
|
|
160
|
+
export function evaluatePresetCondition(condition, expand) {
|
|
161
|
+
if (condition === null || condition === undefined) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (typeof condition === "boolean") {
|
|
165
|
+
return condition;
|
|
166
|
+
}
|
|
167
|
+
if (typeof condition !== "object" || Array.isArray(condition)) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
const str = (v) => (typeof v === "string" ? expand(v) : undefined);
|
|
171
|
+
switch (condition.type) {
|
|
172
|
+
case "const":
|
|
173
|
+
return typeof condition.value === "boolean" ? condition.value : undefined;
|
|
174
|
+
case "equals":
|
|
175
|
+
case "notEquals": {
|
|
176
|
+
const lhs = str(condition.lhs);
|
|
177
|
+
const rhs = str(condition.rhs);
|
|
178
|
+
if (lhs === undefined || rhs === undefined) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
return (lhs === rhs) === (condition.type === "equals");
|
|
182
|
+
}
|
|
183
|
+
case "inList":
|
|
184
|
+
case "notInList": {
|
|
185
|
+
const needle = str(condition.string);
|
|
186
|
+
if (needle === undefined || !Array.isArray(condition.list)) {
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
const found = condition.list.some((v) => str(v) === needle);
|
|
190
|
+
return found === (condition.type === "inList");
|
|
191
|
+
}
|
|
192
|
+
case "anyOf":
|
|
193
|
+
case "allOf": {
|
|
194
|
+
if (!Array.isArray(condition.conditions)) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
const results = condition.conditions.map((c) =>
|
|
198
|
+
evaluatePresetCondition(c, expand),
|
|
199
|
+
);
|
|
200
|
+
if (condition.type === "anyOf") {
|
|
201
|
+
if (results.includes(true)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
return results.includes(undefined) ? undefined : false;
|
|
205
|
+
}
|
|
206
|
+
if (results.includes(false)) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return results.includes(undefined) ? undefined : true;
|
|
210
|
+
}
|
|
211
|
+
case "not": {
|
|
212
|
+
const inner = evaluatePresetCondition(condition.condition, expand);
|
|
213
|
+
return inner === undefined ? undefined : !inner;
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** A cache variable's value as CMake sets it, or `null` for an unset one. */
|
|
221
|
+
function cacheValue(entry) {
|
|
222
|
+
if (entry === null) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
const raw =
|
|
226
|
+
entry && typeof entry === "object" && !Array.isArray(entry)
|
|
227
|
+
? entry.value
|
|
228
|
+
: entry;
|
|
229
|
+
if (typeof raw === "boolean") {
|
|
230
|
+
return raw ? "TRUE" : "FALSE";
|
|
231
|
+
}
|
|
232
|
+
return typeof raw === "string" ? raw : undefined;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Resolve the configure presets of a set of presets documents.
|
|
237
|
+
*
|
|
238
|
+
* Inheritance follows CMake: a preset's own fields win, then those of its
|
|
239
|
+
* `inherits` entries in order (the first wins), recursively; `cacheVariables`
|
|
240
|
+
* and `environment` merge key by key the same way, and a `null` entry unsets
|
|
241
|
+
* the key. `name`, `hidden`, `inherits`, `description` and `displayName` are
|
|
242
|
+
* not inherited. A preset that is part of an inheritance cycle, or inherits
|
|
243
|
+
* one that does not exist, is dropped.
|
|
244
|
+
*
|
|
245
|
+
* @param {Array<{file: string, fileDir: string, document: Object}>} documents
|
|
246
|
+
* Parsed documents in reading order (`CMakePresets.json` first, then its
|
|
247
|
+
* includes, then `CMakeUserPresets.json`)
|
|
248
|
+
* @param {Object} context `sourceDir`, `hostSystemName`, `pathListSep`, and
|
|
249
|
+
* `penv` (a function reading the process environment)
|
|
250
|
+
* @returns {Object[]} Visible configure presets: `name`, `displayName`,
|
|
251
|
+
* `file`, `inherits`, `generator`, `binaryDir` (absolute), `toolchainFile`,
|
|
252
|
+
* `cacheVariables` (expanded strings), `environment` (expanded strings),
|
|
253
|
+
* `hasCondition`, and `conditionMet` (true, false or undefined)
|
|
254
|
+
*/
|
|
255
|
+
export function resolveConfigurePresets(documents, context = {}) {
|
|
256
|
+
const byName = new Map();
|
|
257
|
+
for (const doc of documents || []) {
|
|
258
|
+
for (const preset of doc?.document?.configurePresets || []) {
|
|
259
|
+
if (!byName.has(preset.name)) {
|
|
260
|
+
byName.set(preset.name, { preset, doc });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const merged = new Map();
|
|
265
|
+
const merging = new Set();
|
|
266
|
+
const mergedOf = (name, depth) => {
|
|
267
|
+
if (merged.has(name)) {
|
|
268
|
+
return merged.get(name);
|
|
269
|
+
}
|
|
270
|
+
const entry = byName.get(name);
|
|
271
|
+
if (!entry || merging.has(name) || depth > MAX_INHERITANCE_DEPTH) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
merging.add(name);
|
|
275
|
+
const own = entry.preset;
|
|
276
|
+
const parents =
|
|
277
|
+
typeof own.inherits === "string"
|
|
278
|
+
? [own.inherits]
|
|
279
|
+
: Array.isArray(own.inherits)
|
|
280
|
+
? own.inherits.filter((p) => typeof p === "string")
|
|
281
|
+
: [];
|
|
282
|
+
const result = {};
|
|
283
|
+
for (const [field, value] of Object.entries(own)) {
|
|
284
|
+
if (MAP_FIELDS.has(field)) {
|
|
285
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
286
|
+
result[field] = { ...value };
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
result[field] = value;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
let broken = false;
|
|
293
|
+
for (const parentName of parents) {
|
|
294
|
+
const parent = mergedOf(parentName, depth + 1);
|
|
295
|
+
if (!parent) {
|
|
296
|
+
broken = true;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
for (const [field, value] of Object.entries(parent.fields)) {
|
|
300
|
+
if (NOT_INHERITED.has(field)) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (MAP_FIELDS.has(field)) {
|
|
304
|
+
result[field] = { ...value, ...(result[field] || {}) };
|
|
305
|
+
} else if (result[field] === undefined) {
|
|
306
|
+
result[field] = value;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
merging.delete(name);
|
|
311
|
+
const resolved = broken ? null : { fields: result, doc: entry.doc };
|
|
312
|
+
merged.set(name, resolved);
|
|
313
|
+
return resolved;
|
|
314
|
+
};
|
|
315
|
+
const presets = [];
|
|
316
|
+
for (const name of byName.keys()) {
|
|
317
|
+
const resolved = mergedOf(name, 0);
|
|
318
|
+
if (!resolved || resolved.fields.hidden === true) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
presets.push(expandPreset(name, resolved, context));
|
|
322
|
+
}
|
|
323
|
+
return presets;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function expandPreset(name, resolved, context) {
|
|
327
|
+
const { fields, doc } = resolved;
|
|
328
|
+
const sourceDir = context.sourceDir || "";
|
|
329
|
+
const generator =
|
|
330
|
+
typeof fields.generator === "string" ? fields.generator : "";
|
|
331
|
+
const base = {
|
|
332
|
+
sourceDir,
|
|
333
|
+
sourceParentDir: context.sourceParentDir ?? "",
|
|
334
|
+
sourceDirName: context.sourceDirName ?? "",
|
|
335
|
+
hostSystemName: context.hostSystemName ?? "",
|
|
336
|
+
pathListSep: context.pathListSep ?? ":",
|
|
337
|
+
presetName: name,
|
|
338
|
+
generator,
|
|
339
|
+
fileDir: doc?.fileDir ?? sourceDir,
|
|
340
|
+
penv: context.penv,
|
|
341
|
+
};
|
|
342
|
+
// An environment entry may refer to the process environment and to the
|
|
343
|
+
// other entries; a few rounds settle any chain a real preset writes.
|
|
344
|
+
const rawEnvironment = {};
|
|
345
|
+
for (const [key, value] of Object.entries(fields.environment || {})) {
|
|
346
|
+
if (typeof value === "string") {
|
|
347
|
+
rawEnvironment[key] = value;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
let environment = { ...rawEnvironment };
|
|
351
|
+
for (let round = 0; round < 4; round++) {
|
|
352
|
+
const next = {};
|
|
353
|
+
for (const [key, value] of Object.entries(rawEnvironment)) {
|
|
354
|
+
next[key] = expandPresetMacros(value, {
|
|
355
|
+
...base,
|
|
356
|
+
env: { ...environment, [key]: base.penv ? (base.penv(key) ?? "") : "" },
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
environment = next;
|
|
360
|
+
}
|
|
361
|
+
const expandContext = { ...base, env: environment };
|
|
362
|
+
const expand = (v) => expandPresetMacros(v, expandContext);
|
|
363
|
+
const cacheVariables = {};
|
|
364
|
+
for (const [key, entry] of Object.entries(fields.cacheVariables || {})) {
|
|
365
|
+
const value = cacheValue(entry);
|
|
366
|
+
if (typeof value === "string") {
|
|
367
|
+
cacheVariables[key] = expand(value);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
let binaryDir;
|
|
371
|
+
if (typeof fields.binaryDir === "string" && fields.binaryDir.length) {
|
|
372
|
+
const dir = expand(fields.binaryDir);
|
|
373
|
+
binaryDir =
|
|
374
|
+
isAbsolute(dir) || !sourceDir ? normalize(dir) : join(sourceDir, dir);
|
|
375
|
+
}
|
|
376
|
+
const toolchainFile =
|
|
377
|
+
typeof fields.toolchainFile === "string" && fields.toolchainFile.length
|
|
378
|
+
? expand(fields.toolchainFile)
|
|
379
|
+
: cacheVariables.CMAKE_TOOLCHAIN_FILE;
|
|
380
|
+
const inherits =
|
|
381
|
+
typeof fields.inherits === "string"
|
|
382
|
+
? [fields.inherits]
|
|
383
|
+
: Array.isArray(fields.inherits)
|
|
384
|
+
? fields.inherits.filter((p) => typeof p === "string")
|
|
385
|
+
: [];
|
|
386
|
+
return {
|
|
387
|
+
name,
|
|
388
|
+
displayName:
|
|
389
|
+
typeof fields.displayName === "string" ? fields.displayName : undefined,
|
|
390
|
+
file: doc?.file,
|
|
391
|
+
inherits,
|
|
392
|
+
generator: generator || undefined,
|
|
393
|
+
binaryDir,
|
|
394
|
+
toolchainFile: toolchainFile || undefined,
|
|
395
|
+
cacheVariables,
|
|
396
|
+
environment,
|
|
397
|
+
hasCondition: fields.condition !== undefined && fields.condition !== null,
|
|
398
|
+
conditionMet: evaluatePresetCondition(fields.condition, expand),
|
|
399
|
+
};
|
|
400
|
+
}
|