@cdxgen/cdxgen 13.1.0 → 13.3.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 +32 -15
- package/bin/cdxgen.js +243 -122
- package/bin/evinse.js +7 -0
- package/bin/sign.js +88 -14
- package/bin/tracebom.js +64 -4
- package/bin/validate.js +29 -7
- package/bin/verify.js +79 -39
- package/data/crypto-oid.json +88 -12
- package/data/remediations.json +47 -0
- package/data/rules/ai-bom.yaml +78 -0
- package/data/rules/cargo-rust.yaml +132 -0
- package/data/rules/mcp-servers.yaml +122 -0
- package/lib/audit/targets.js +6 -1
- package/lib/cli/bomAssembly.js +117 -15
- package/lib/cli/cliOptions.js +93 -1
- package/lib/cli/index.js +235 -5
- package/lib/cli/jsBom.js +108 -26
- package/lib/cli/jvmBom.js +68 -12
- package/lib/cli/managedBom.js +264 -41
- package/lib/cli/nativeBom.js +923 -15
- package/lib/core/activity.js +120 -2
- package/lib/core/env.js +44 -7
- package/lib/core/fs.js +174 -6
- package/lib/core/metadataProperties.js +97 -0
- package/lib/core/projectConfig.js +31 -4
- package/lib/core/userAgent.js +151 -0
- package/lib/ecosystems/bunutils.js +269 -101
- package/lib/ecosystems/cargoCache.js +364 -0
- package/lib/ecosystems/caxa.js +447 -7
- package/lib/ecosystems/cmakeResolver.js +66 -0
- package/lib/ecosystems/cppEvidence.js +104 -33
- package/lib/ecosystems/ecosystems.js +260 -99
- package/lib/ecosystems/golem.js +11 -1
- package/lib/ecosystems/gradleutils.js +185 -9
- package/lib/ecosystems/jsEvidence.js +19 -20
- package/lib/ecosystems/kosi.js +1263 -0
- package/lib/ecosystems/npmutils.js +110 -9
- package/lib/ecosystems/parsers-crystal.js +179 -0
- package/lib/ecosystems/parsers-dotnet.js +120 -49
- package/lib/ecosystems/parsers-elm.js +816 -0
- package/lib/ecosystems/parsers-gleam.js +1 -1
- package/lib/ecosystems/parsers-go.js +47 -9
- package/lib/ecosystems/parsers-js.js +171 -50
- package/lib/ecosystems/parsers-julia.js +268 -0
- package/lib/ecosystems/parsers-lua.js +218 -0
- package/lib/ecosystems/parsers-misc.js +919 -161
- package/lib/ecosystems/parsers-nim.js +221 -0
- package/lib/ecosystems/parsers-opam.js +180 -0
- package/lib/ecosystems/parsers-perl.js +277 -0
- package/lib/ecosystems/parsers-python.js +27 -15
- package/lib/ecosystems/parsers-r.js +148 -0
- package/lib/ecosystems/parsers-rebar.js +411 -0
- package/lib/ecosystems/parsers-rust.js +954 -33
- package/lib/ecosystems/parsers-spack.js +204 -0
- package/lib/ecosystems/parsers-stack.js +264 -0
- package/lib/ecosystems/parsers-terraform.js +194 -0
- package/lib/ecosystems/rubyutils.js +1426 -166
- package/lib/ecosystems/rusi.js +158 -7
- package/lib/evinser/evinser.js +547 -129
- package/lib/evinser/swiftsem.js +1914 -302
- package/lib/helpers/agenticToolutils.js +925 -0
- package/lib/helpers/bomSigner.js +652 -221
- package/lib/inventory/agentFormulationParser.js +57 -4
- package/lib/inventory/aiCollector.js +504 -10
- package/lib/inventory/aiInventory.js +12 -0
- package/lib/inventory/analyzer.js +488 -30
- package/lib/inventory/astWorker.js +6 -0
- package/lib/inventory/atomUtils.js +568 -31
- package/lib/inventory/auditCategories.js +8 -0
- package/lib/inventory/cbomutils.js +30 -0
- package/lib/inventory/cdxrs.js +110 -14
- package/lib/inventory/communityAiConfigParser.js +215 -2
- package/lib/inventory/depsUtils.js +183 -11
- package/lib/inventory/display.js +4 -5
- package/lib/inventory/dosai.js +627 -13
- package/lib/inventory/dynamic.js +39 -1
- package/lib/inventory/envcontext.js +9 -6
- package/lib/inventory/evidenceUtils.js +26 -5
- package/lib/inventory/fetchBatch.js +190 -19
- package/lib/inventory/fetchRate.js +74 -11
- package/lib/inventory/forgeEnricher.js +3 -2
- package/lib/inventory/jvmToolEnv.js +6 -5
- package/lib/inventory/mcpConfigParser.js +166 -2
- package/lib/inventory/mcpDiscovery.js +11 -0
- package/lib/inventory/mcpServerManifest.js +389 -0
- package/lib/inventory/mcpbBundle.js +419 -0
- package/lib/inventory/plugins.js +3 -0
- package/lib/inventory/protobom.js +62 -89
- package/lib/inventory/protobomLoader.js +4 -0
- package/lib/inventory/purl.js +152 -3
- package/lib/inventory/rustFormulationParser.js +1 -1
- package/lib/inventory/sbomDocument.js +2 -70
- package/lib/inventory/source.js +47 -23
- package/lib/inventory/stylePackageRefs.js +41 -0
- package/lib/inventory/svelteUtils.js +524 -0
- package/lib/inventory/traceRunner.js +210 -21
- package/lib/managers/binary.js +115 -24
- package/lib/managers/docker.js +440 -20
- package/lib/managers/oci.js +39 -1
- package/lib/parsers/cmakeLists.js +452 -0
- package/lib/parsers/huggingfaceUtils.js +15 -7
- package/lib/parsers/largeJson.js +454 -0
- package/lib/parsers/npmrc.js +19 -1
- package/lib/parsers/onnx.js +294 -0
- package/lib/parsers/safetensors.js +114 -0
- package/lib/stages/postgen/introspection/markers.js +29 -6
- package/lib/stages/postgen/postgen.js +237 -16
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
- package/lib/validator/bomValidator.js +6 -16
- package/lib/validator/index.js +48 -10
- package/lib/validator/reporters/console.js +3 -0
- package/lib/validator/reporters/json.js +1 -0
- package/lib/validator/reporters/sarif.js +7 -0
- package/package.json +27 -27
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +2 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +33 -1
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +2 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +23 -0
- 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 +33 -0
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +88 -8
- 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 +21 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +55 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/metadataProperties.d.ts +39 -0
- package/types/lib/core/metadataProperties.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts +6 -2
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/userAgent.d.ts +56 -0
- package/types/lib/core/userAgent.d.ts.map +1 -0
- package/types/lib/ecosystems/bunutils.d.ts +12 -5
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +75 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
- package/types/lib/ecosystems/caxa.d.ts +14 -0
- package/types/lib/ecosystems/caxa.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +23 -0
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts +2 -2
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +15 -1
- 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 +40 -4
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +5 -2
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts +86 -0
- package/types/lib/ecosystems/kosi.d.ts.map +1 -0
- package/types/lib/ecosystems/npmutils.d.ts +42 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-go.d.ts +10 -0
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +10 -4
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
- package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-misc.d.ts +90 -3
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
- package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
- package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
- package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-r.d.ts +35 -0
- package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
- package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
- package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
- package/types/lib/ecosystems/pythonutils.d.ts +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +143 -2
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts +13 -0
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +81 -2
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +280 -15
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +87 -0
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
- package/types/lib/helpers/bomSigner.d.ts +106 -13
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/atomUtils.d.ts +145 -3
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +4 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/cdxrs.d.ts +8 -3
- package/types/lib/inventory/cdxrs.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/depsUtils.d.ts +15 -0
- package/types/lib/inventory/depsUtils.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +87 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +34 -0
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchRate.d.ts +9 -6
- package/types/lib/inventory/fetchRate.d.ts.map +1 -1
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +5 -4
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
- package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
- package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
- package/types/lib/inventory/mcpbBundle.d.ts +19 -0
- package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
- package/types/lib/inventory/plugins.d.ts.map +1 -1
- package/types/lib/inventory/protobom.d.ts +18 -13
- package/types/lib/inventory/protobom.d.ts.map +1 -1
- package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
- package/types/lib/inventory/purl.d.ts +71 -2
- package/types/lib/inventory/purl.d.ts.map +1 -1
- package/types/lib/inventory/sbomDocument.d.ts.map +1 -1
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
- package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
- package/types/lib/inventory/svelteUtils.d.ts +124 -0
- package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
- package/types/lib/inventory/traceRunner.d.ts +47 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +30 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +29 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +14 -0
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +76 -0
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/largeJson.d.ts +52 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -0
- package/types/lib/parsers/npmrc.d.ts +5 -0
- package/types/lib/parsers/npmrc.d.ts.map +1 -1
- package/types/lib/parsers/onnx.d.ts +28 -0
- package/types/lib/parsers/onnx.d.ts.map +1 -0
- package/types/lib/parsers/safetensors.d.ts +22 -0
- package/types/lib/parsers/safetensors.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts +3 -2
- package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +33 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -1
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/console.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/types/lib/validator/reporters/sarif.d.ts.map +1 -1
package/lib/cli/cliOptions.js
CHANGED
|
@@ -15,6 +15,10 @@ import { join, resolve } from "node:path";
|
|
|
15
15
|
|
|
16
16
|
import { isSecureMode, readEnvironmentVariable } from "../core/activity.js";
|
|
17
17
|
import { PROJECT_TYPE_ALIASES } from "../core/env.js";
|
|
18
|
+
import {
|
|
19
|
+
METADATA_PROPERTY_CONFIG_KEYS,
|
|
20
|
+
parseMetadataProperties,
|
|
21
|
+
} from "../core/metadataProperties.js";
|
|
18
22
|
import {
|
|
19
23
|
DEFAULT_CDX_SPEC_VERSION,
|
|
20
24
|
normalizeCycloneDxComponentTypeFilter,
|
|
@@ -120,6 +124,80 @@ export function isUserProvided(value, yaDefault) {
|
|
|
120
124
|
return value !== undefined && value !== yaDefault;
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Combine the custom metadata properties of every source (discussion 4391):
|
|
129
|
+
* the `--metadata-property` flag, the CDXGEN_METADATA_PROPERTY and
|
|
130
|
+
* CDXGEN_METADATA_PROPERTIES environment variables, and a config file's
|
|
131
|
+
* `metadata-property` or `metadataProperties` entry.
|
|
132
|
+
*
|
|
133
|
+
* yargs would let the highest-precedence source replace the others outright,
|
|
134
|
+
* so each is read on its own and they are merged instead. A name set by more
|
|
135
|
+
* than one source takes its values from the one that wins in the usual order
|
|
136
|
+
* — the command line, then the environment, then the config file — while a
|
|
137
|
+
* source may repeat a name for a multi-valued property.
|
|
138
|
+
*
|
|
139
|
+
* @param {object} args Parsed yargs argv
|
|
140
|
+
* @param {object} [context]
|
|
141
|
+
* @param {string[]} [context.argv] Raw command-line arguments, which tell a
|
|
142
|
+
* flag on the command line from one yargs filled in from elsewhere
|
|
143
|
+
* @param {object} [context.projectConfig] The sanitized config file contents.
|
|
144
|
+
* Without it, a programmatic caller's `args` are taken as the config.
|
|
145
|
+
* @returns {{name: string, value: string}[]} The merged properties
|
|
146
|
+
*/
|
|
147
|
+
export function resolveMetadataProperties(
|
|
148
|
+
args,
|
|
149
|
+
{ argv = process.argv, projectConfig } = {},
|
|
150
|
+
) {
|
|
151
|
+
const flagGiven = argv.some((argument) =>
|
|
152
|
+
["--metadata-property", "--metadataProperty"].includes(
|
|
153
|
+
`${argument}`.split("=")[0],
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
const fromConfig = projectConfig
|
|
157
|
+
? METADATA_PROPERTY_CONFIG_KEYS.flatMap((key) =>
|
|
158
|
+
parseMetadataProperties(projectConfig[key]),
|
|
159
|
+
)
|
|
160
|
+
: flagGiven
|
|
161
|
+
? []
|
|
162
|
+
: [
|
|
163
|
+
...parseMetadataProperties(args?.metadataProperty),
|
|
164
|
+
...parseMetadataProperties(args?.metadataProperties),
|
|
165
|
+
];
|
|
166
|
+
const sources = [
|
|
167
|
+
flagGiven ? parseMetadataProperties(args?.metadataProperty) : [],
|
|
168
|
+
[
|
|
169
|
+
...parseMetadataProperties(
|
|
170
|
+
readEnvironmentVariable("CDXGEN_METADATA_PROPERTY"),
|
|
171
|
+
),
|
|
172
|
+
...parseMetadataProperties(
|
|
173
|
+
readEnvironmentVariable("CDXGEN_METADATA_PROPERTIES"),
|
|
174
|
+
),
|
|
175
|
+
],
|
|
176
|
+
fromConfig,
|
|
177
|
+
];
|
|
178
|
+
const properties = [];
|
|
179
|
+
const claimedNames = new Set();
|
|
180
|
+
for (const source of sources) {
|
|
181
|
+
const sourceNames = new Set();
|
|
182
|
+
for (const aprop of source) {
|
|
183
|
+
if (
|
|
184
|
+
claimedNames.has(aprop.name) ||
|
|
185
|
+
properties.some(
|
|
186
|
+
(prop) => prop.name === aprop.name && prop.value === aprop.value,
|
|
187
|
+
)
|
|
188
|
+
) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
properties.push(aprop);
|
|
192
|
+
sourceNames.add(aprop.name);
|
|
193
|
+
}
|
|
194
|
+
for (const name of sourceNames) {
|
|
195
|
+
claimedNames.add(name);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return properties;
|
|
199
|
+
}
|
|
200
|
+
|
|
123
201
|
/**
|
|
124
202
|
* Apply command-name-based defaults to the raw parsed args. When cdxgen is
|
|
125
203
|
* invoked via a symlink or alias (e.g. `obom`, `cbom`, `spdxgen`, `aibom`),
|
|
@@ -162,6 +240,8 @@ export function applyCommandNameDefaults(args, invokedCommandName) {
|
|
|
162
240
|
* @param {object} context
|
|
163
241
|
* @param {string} context.filePath Resolved source path
|
|
164
242
|
* @param {boolean} context.isRemoteOrPurl True when source is a URL or purl
|
|
243
|
+
* @param {string[]} [context.argv] Raw command-line arguments
|
|
244
|
+
* @param {object} [context.projectConfig] Sanitized config file contents
|
|
165
245
|
* @returns {object} The initial options object
|
|
166
246
|
*/
|
|
167
247
|
/**
|
|
@@ -221,8 +301,12 @@ function resolveIntrospectOption(args, argv) {
|
|
|
221
301
|
|
|
222
302
|
export function buildInitialOptions(
|
|
223
303
|
args,
|
|
224
|
-
{ filePath, isRemoteOrPurl, argv = process.argv },
|
|
304
|
+
{ filePath, isRemoteOrPurl, argv = process.argv, projectConfig },
|
|
225
305
|
) {
|
|
306
|
+
const metadataProperties = resolveMetadataProperties(args, {
|
|
307
|
+
argv,
|
|
308
|
+
projectConfig,
|
|
309
|
+
});
|
|
226
310
|
const res = Object.assign({}, args, {
|
|
227
311
|
projectType: args.type,
|
|
228
312
|
multiProject: args.recurse,
|
|
@@ -235,6 +319,9 @@ export function buildInitialOptions(
|
|
|
235
319
|
include: args.include || args.includeRegex,
|
|
236
320
|
noIgnore: args.noIgnore,
|
|
237
321
|
gitAiNotesRef: args.gitAiNotesRef || "refs/notes/ai",
|
|
322
|
+
metadataProperties: metadataProperties.length
|
|
323
|
+
? metadataProperties
|
|
324
|
+
: undefined,
|
|
238
325
|
// Introspection: the flag or the documented environment opt-in. An
|
|
239
326
|
// explicit --no-introspect stays `false` and beats both, while an
|
|
240
327
|
// unmentioned flag stays undefined so a profile can still enable it.
|
|
@@ -598,6 +685,9 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
598
685
|
* passed `--spec-version`
|
|
599
686
|
* @param {boolean} [context.isDryRun=false] Dry-run mode
|
|
600
687
|
* @param {boolean} [context.isSecureMode] Secure mode
|
|
688
|
+
* @param {object} [context.projectConfig] Sanitized config file contents,
|
|
689
|
+
* whose metadata properties merge
|
|
690
|
+
* with the other sources'
|
|
601
691
|
* @returns {{ options: object, warnings: OptionsWarning[] }}
|
|
602
692
|
*/
|
|
603
693
|
export function buildOptionsFromArgs(args, context) {
|
|
@@ -607,12 +697,14 @@ export function buildOptionsFromArgs(args, context) {
|
|
|
607
697
|
isRemoteOrPurl,
|
|
608
698
|
userSetSpecVersion,
|
|
609
699
|
isDryRun = false,
|
|
700
|
+
projectConfig,
|
|
610
701
|
} = context;
|
|
611
702
|
|
|
612
703
|
const expandedArgs = applyCommandNameDefaults(args, invokedCommandName);
|
|
613
704
|
const options = buildInitialOptions(expandedArgs, {
|
|
614
705
|
filePath,
|
|
615
706
|
isRemoteOrPurl,
|
|
707
|
+
projectConfig,
|
|
616
708
|
});
|
|
617
709
|
const phase3Warnings = applyPostConstructionOverrides(options, {
|
|
618
710
|
invokedCommandName,
|
package/lib/cli/index.js
CHANGED
|
@@ -32,6 +32,11 @@ import { thoughtLog } from "../core/logger.js";
|
|
|
32
32
|
import { mapWithConcurrency } from "../core/parallel.js";
|
|
33
33
|
import { dirNameStr } from "../core/paths.js";
|
|
34
34
|
import { ui } from "../core/ui.js";
|
|
35
|
+
import { isElmProjectFile } from "../ecosystems/parsers-elm.js";
|
|
36
|
+
import {
|
|
37
|
+
isJuliaManifestFile,
|
|
38
|
+
isJuliaProjectFile,
|
|
39
|
+
} from "../ecosystems/parsers-julia.js";
|
|
35
40
|
import {
|
|
36
41
|
parseBitbucketPipelinesFile,
|
|
37
42
|
parseContainerFile,
|
|
@@ -79,6 +84,7 @@ import {
|
|
|
79
84
|
exportArchive,
|
|
80
85
|
exportImage,
|
|
81
86
|
getPkgPathList,
|
|
87
|
+
isImageReference,
|
|
82
88
|
parseImageName,
|
|
83
89
|
} from "../managers/docker.js";
|
|
84
90
|
import {
|
|
@@ -90,6 +96,7 @@ import {
|
|
|
90
96
|
determineParentComponent,
|
|
91
97
|
} from "./bomAssembly.js";
|
|
92
98
|
import {
|
|
99
|
+
createAgenticBom,
|
|
93
100
|
createAsarBom,
|
|
94
101
|
createCaxaBom,
|
|
95
102
|
createChromeExtensionBom,
|
|
@@ -126,24 +133,36 @@ import {
|
|
|
126
133
|
createGitHubBom,
|
|
127
134
|
createHelmBom,
|
|
128
135
|
createJenkinsBom,
|
|
136
|
+
createPerlBom,
|
|
129
137
|
createPHPBom,
|
|
130
138
|
createPythonBom,
|
|
139
|
+
createRBom,
|
|
131
140
|
createRubyBom,
|
|
141
|
+
createTerraformBom,
|
|
132
142
|
} from "./managedBom.js";
|
|
133
143
|
import {
|
|
134
144
|
createCargoCacheBom,
|
|
135
145
|
createClojureBom,
|
|
136
146
|
createCocoaBom,
|
|
137
147
|
createCppBom,
|
|
148
|
+
createCrystalBom,
|
|
138
149
|
createDartBom,
|
|
139
150
|
createElixirBom,
|
|
151
|
+
createElmBom,
|
|
152
|
+
createErlangBom,
|
|
140
153
|
createGleamBom,
|
|
141
154
|
createGoBom,
|
|
142
155
|
createHaskellBom,
|
|
156
|
+
createJuliaBom,
|
|
157
|
+
createLuaBom,
|
|
158
|
+
createNimBom,
|
|
143
159
|
createNixBom,
|
|
160
|
+
createOCamlBom,
|
|
144
161
|
createRustBom,
|
|
162
|
+
createSpackBom,
|
|
145
163
|
createSwiftBom,
|
|
146
164
|
createZigBom,
|
|
165
|
+
findStackLockFiles,
|
|
147
166
|
getCargoCacheDir,
|
|
148
167
|
} from "./nativeBom.js";
|
|
149
168
|
|
|
@@ -154,22 +173,33 @@ export {
|
|
|
154
173
|
createGitHubBom,
|
|
155
174
|
createHelmBom,
|
|
156
175
|
createJenkinsBom,
|
|
176
|
+
createPerlBom,
|
|
157
177
|
createPHPBom,
|
|
158
178
|
createPixiBom,
|
|
159
179
|
createPythonBom,
|
|
180
|
+
createRBom,
|
|
160
181
|
createRubyBom,
|
|
182
|
+
createTerraformBom,
|
|
161
183
|
} from "./managedBom.js";
|
|
162
184
|
export {
|
|
163
185
|
createClojureBom,
|
|
164
186
|
createCocoaBom,
|
|
165
187
|
createCppBom,
|
|
188
|
+
createCrystalBom,
|
|
166
189
|
createDartBom,
|
|
167
190
|
createElixirBom,
|
|
191
|
+
createElmBom,
|
|
192
|
+
createErlangBom,
|
|
168
193
|
createGleamBom,
|
|
169
194
|
createGoBom,
|
|
170
195
|
createHaskellBom,
|
|
196
|
+
createJuliaBom,
|
|
197
|
+
createLuaBom,
|
|
198
|
+
createNimBom,
|
|
171
199
|
createNixBom,
|
|
200
|
+
createOCamlBom,
|
|
172
201
|
createRustBom,
|
|
202
|
+
createSpackBom,
|
|
173
203
|
createSwiftBom,
|
|
174
204
|
createZigBom,
|
|
175
205
|
} from "./nativeBom.js";
|
|
@@ -1871,17 +1901,49 @@ export async function createDynamicBom(path, options) {
|
|
|
1871
1901
|
blockExec: options.traceBlockExec,
|
|
1872
1902
|
traceCrypto: options.traceCrypto,
|
|
1873
1903
|
cbom: options.cbom,
|
|
1904
|
+
proxyEgress: options.traceProxyEgress,
|
|
1905
|
+
allowLoopback: options.traceAllowLoopback,
|
|
1906
|
+
dryRun: options.traceDryRun,
|
|
1907
|
+
policy: options.tracePolicy,
|
|
1908
|
+
policyFile: options.tracePolicyFile,
|
|
1909
|
+
blockInterpreters: options.traceBlockInterpreters,
|
|
1910
|
+
denyPersistenceWrites: options.traceDenyPersistenceWrites,
|
|
1911
|
+
privateTmp: options.tracePrivateTmp,
|
|
1912
|
+
protectHome: options.traceProtectHome,
|
|
1874
1913
|
};
|
|
1875
1914
|
|
|
1876
|
-
const {
|
|
1877
|
-
|
|
1915
|
+
const {
|
|
1916
|
+
components: pkgList,
|
|
1917
|
+
services: traceServices,
|
|
1918
|
+
dryRunSummary,
|
|
1919
|
+
} = await buildDynamicComponents(commandStr, workingDir, traceOptions);
|
|
1878
1920
|
|
|
1879
|
-
|
|
1921
|
+
const bomNSData = buildBomNSData(options, pkgList, "generic", {
|
|
1880
1922
|
src: workingDir,
|
|
1881
1923
|
projectType: "dynamic",
|
|
1882
1924
|
filename: commandStr,
|
|
1883
1925
|
services: traceServices,
|
|
1884
1926
|
});
|
|
1927
|
+
// A dry run denies every side effect, so the attempted-operation counts are
|
|
1928
|
+
// the result. Only counts are recorded, never the paths or targets.
|
|
1929
|
+
if (dryRunSummary && bomNSData?.bomJson?.metadata) {
|
|
1930
|
+
const metadata = bomNSData.bomJson.metadata;
|
|
1931
|
+
metadata.properties = metadata.properties || [];
|
|
1932
|
+
metadata.properties.push({ name: "cdx:dynamic:dryRun", value: "true" });
|
|
1933
|
+
metadata.properties.push({
|
|
1934
|
+
name: "cdx:dynamic:dryRun:captured",
|
|
1935
|
+
value: dryRunSummary.captured === false ? "false" : "true",
|
|
1936
|
+
});
|
|
1937
|
+
for (const [key, value] of Object.entries(dryRunSummary)) {
|
|
1938
|
+
if (Number.isInteger(value)) {
|
|
1939
|
+
metadata.properties.push({
|
|
1940
|
+
name: `cdx:dynamic:dryRun:${key}`,
|
|
1941
|
+
value: String(value),
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
return bomNSData;
|
|
1885
1947
|
}
|
|
1886
1948
|
|
|
1887
1949
|
/**
|
|
@@ -2060,7 +2122,8 @@ export async function createXBom(path, options) {
|
|
|
2060
2122
|
`${options.multiProject ? "**/" : ""}cabal.project.freeze`,
|
|
2061
2123
|
options,
|
|
2062
2124
|
);
|
|
2063
|
-
|
|
2125
|
+
const stackLockDetectFiles = findStackLockFiles(path, options);
|
|
2126
|
+
if (hackageFiles.length || stackLockDetectFiles.length) {
|
|
2064
2127
|
return createHaskellBom(path, options);
|
|
2065
2128
|
}
|
|
2066
2129
|
|
|
@@ -2285,6 +2348,131 @@ export async function createXBom(path, options) {
|
|
|
2285
2348
|
if (gleamTomlFiles.length) {
|
|
2286
2349
|
return await createGleamBom(path, options);
|
|
2287
2350
|
}
|
|
2351
|
+
|
|
2352
|
+
// Julia
|
|
2353
|
+
const juliaProjectFiles = getAllFiles(
|
|
2354
|
+
path,
|
|
2355
|
+
`${options.multiProject ? "**/" : ""}Project.toml`,
|
|
2356
|
+
options,
|
|
2357
|
+
);
|
|
2358
|
+
const juliaManifestFiles = getAllFiles(
|
|
2359
|
+
path,
|
|
2360
|
+
`${options.multiProject ? "**/" : ""}Manifest.toml`,
|
|
2361
|
+
options,
|
|
2362
|
+
);
|
|
2363
|
+
// `Project.toml` is not a name Julia owns — Cloud Native Buildpacks use it
|
|
2364
|
+
// too — so dispatch only when a file actually declares a Julia environment.
|
|
2365
|
+
if (
|
|
2366
|
+
juliaManifestFiles.some(isJuliaManifestFile) ||
|
|
2367
|
+
juliaProjectFiles.some(isJuliaProjectFile)
|
|
2368
|
+
) {
|
|
2369
|
+
return await createJuliaBom(path, options);
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
// Erlang with rebar3
|
|
2373
|
+
const rebarLockFiles = getAllFiles(
|
|
2374
|
+
path,
|
|
2375
|
+
`${options.multiProject ? "**/" : ""}rebar.lock`,
|
|
2376
|
+
options,
|
|
2377
|
+
);
|
|
2378
|
+
if (rebarLockFiles.length) {
|
|
2379
|
+
return await createErlangBom(path, options);
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
// OCaml with opam
|
|
2383
|
+
const opamLockedFiles = getAllFiles(
|
|
2384
|
+
path,
|
|
2385
|
+
`${options.multiProject ? "**/" : ""}*.opam.locked`,
|
|
2386
|
+
options,
|
|
2387
|
+
);
|
|
2388
|
+
if (opamLockedFiles.length) {
|
|
2389
|
+
return await createOCamlBom(path, options);
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
// Elm with elm.json (0.19) or elm-package.json (0.18)
|
|
2393
|
+
const elmJsonFiles = getAllFiles(
|
|
2394
|
+
path,
|
|
2395
|
+
`${options.multiProject ? "**/" : ""}elm.json`,
|
|
2396
|
+
options,
|
|
2397
|
+
).filter(isElmProjectFile);
|
|
2398
|
+
const legacyElmFiles = getAllFiles(
|
|
2399
|
+
path,
|
|
2400
|
+
`${options.multiProject ? "**/" : ""}elm-package.json`,
|
|
2401
|
+
options,
|
|
2402
|
+
);
|
|
2403
|
+
if (elmJsonFiles.length || legacyElmFiles.length) {
|
|
2404
|
+
return await createElmBom(path, options);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
// Crystal with shards
|
|
2408
|
+
const shardYmlFiles = getAllFiles(
|
|
2409
|
+
path,
|
|
2410
|
+
`${options.multiProject ? "**/" : ""}shard.yml`,
|
|
2411
|
+
options,
|
|
2412
|
+
);
|
|
2413
|
+
if (shardYmlFiles.length) {
|
|
2414
|
+
return await createCrystalBom(path, options);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
// Nim with nimble
|
|
2418
|
+
const nimbleFiles = getAllFiles(
|
|
2419
|
+
path,
|
|
2420
|
+
`${options.multiProject ? "**/" : ""}*.nimble`,
|
|
2421
|
+
options,
|
|
2422
|
+
);
|
|
2423
|
+
if (nimbleFiles.length) {
|
|
2424
|
+
return await createNimBom(path, options);
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
// Lua with LuaRocks
|
|
2428
|
+
const rockspecFiles = getAllFiles(
|
|
2429
|
+
path,
|
|
2430
|
+
`${options.multiProject ? "**/" : ""}*.rockspec`,
|
|
2431
|
+
options,
|
|
2432
|
+
);
|
|
2433
|
+
if (rockspecFiles.length) {
|
|
2434
|
+
return await createLuaBom(path, options);
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
// Spack environments
|
|
2438
|
+
const spackLockFiles = getAllFiles(
|
|
2439
|
+
path,
|
|
2440
|
+
`${options.multiProject ? "**/" : ""}spack.lock`,
|
|
2441
|
+
options,
|
|
2442
|
+
);
|
|
2443
|
+
if (spackLockFiles.length) {
|
|
2444
|
+
return await createSpackBom(path, options);
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
// R with renv
|
|
2448
|
+
const renvLockFiles = getAllFiles(
|
|
2449
|
+
path,
|
|
2450
|
+
`${options.multiProject ? "**/" : ""}renv.lock`,
|
|
2451
|
+
options,
|
|
2452
|
+
);
|
|
2453
|
+
if (renvLockFiles.length) {
|
|
2454
|
+
return createRBom(path, options);
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
// Perl with Carton
|
|
2458
|
+
const cpanSnapshotFiles = getAllFiles(
|
|
2459
|
+
path,
|
|
2460
|
+
`${options.multiProject ? "**/" : ""}cpanfile.snapshot`,
|
|
2461
|
+
options,
|
|
2462
|
+
);
|
|
2463
|
+
if (cpanSnapshotFiles.length) {
|
|
2464
|
+
return createPerlBom(path, options);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
// Terraform and OpenTofu providers
|
|
2468
|
+
const tfLockFiles = getAllFiles(
|
|
2469
|
+
path,
|
|
2470
|
+
`${options.multiProject ? "**/" : ""}.terraform.lock.hcl`,
|
|
2471
|
+
options,
|
|
2472
|
+
);
|
|
2473
|
+
if (tfLockFiles.length) {
|
|
2474
|
+
return createTerraformBom(path, options);
|
|
2475
|
+
}
|
|
2288
2476
|
}
|
|
2289
2477
|
|
|
2290
2478
|
/**
|
|
@@ -2406,7 +2594,13 @@ async function createBomForPath(path, options) {
|
|
|
2406
2594
|
} else if (
|
|
2407
2595
|
(options.projectType &&
|
|
2408
2596
|
!options.projectType?.includes("universal") &&
|
|
2409
|
-
hasAnyProjectType(["oci"], options, false)
|
|
2597
|
+
hasAnyProjectType(["oci"], options, false) &&
|
|
2598
|
+
// Explicit container types accept every documented image reference
|
|
2599
|
+
// style (postgres:15-alpine, shiftleft/scan-slim, registry:5000/ns/img),
|
|
2600
|
+
// but only for inputs that cannot be a local path: existing files and
|
|
2601
|
+
// directories keep flowing to the tar, oci-dir and source scanners.
|
|
2602
|
+
!safeExistsSync(path) &&
|
|
2603
|
+
isImageReference(path)) ||
|
|
2410
2604
|
path.startsWith("docker.io") ||
|
|
2411
2605
|
path.startsWith("quay.io") ||
|
|
2412
2606
|
path.startsWith("ghcr.io") ||
|
|
@@ -2636,6 +2830,39 @@ async function createBomForPath(path, options) {
|
|
|
2636
2830
|
if (PROJECT_TYPE_ALIASES["gleam"].includes(projectType[0])) {
|
|
2637
2831
|
return await createGleamBom(path, options);
|
|
2638
2832
|
}
|
|
2833
|
+
if (PROJECT_TYPE_ALIASES["julia"].includes(projectType[0])) {
|
|
2834
|
+
return await createJuliaBom(path, options);
|
|
2835
|
+
}
|
|
2836
|
+
if (PROJECT_TYPE_ALIASES["erlang"].includes(projectType[0])) {
|
|
2837
|
+
return await createErlangBom(path, options);
|
|
2838
|
+
}
|
|
2839
|
+
if (PROJECT_TYPE_ALIASES["ocaml"].includes(projectType[0])) {
|
|
2840
|
+
return await createOCamlBom(path, options);
|
|
2841
|
+
}
|
|
2842
|
+
if (PROJECT_TYPE_ALIASES["elm"].includes(projectType[0])) {
|
|
2843
|
+
return await createElmBom(path, options);
|
|
2844
|
+
}
|
|
2845
|
+
if (PROJECT_TYPE_ALIASES["crystal"].includes(projectType[0])) {
|
|
2846
|
+
return await createCrystalBom(path, options);
|
|
2847
|
+
}
|
|
2848
|
+
if (PROJECT_TYPE_ALIASES["nim"].includes(projectType[0])) {
|
|
2849
|
+
return await createNimBom(path, options);
|
|
2850
|
+
}
|
|
2851
|
+
if (PROJECT_TYPE_ALIASES["lua"].includes(projectType[0])) {
|
|
2852
|
+
return await createLuaBom(path, options);
|
|
2853
|
+
}
|
|
2854
|
+
if (PROJECT_TYPE_ALIASES["spack"].includes(projectType[0])) {
|
|
2855
|
+
return await createSpackBom(path, options);
|
|
2856
|
+
}
|
|
2857
|
+
if (PROJECT_TYPE_ALIASES["r"].includes(projectType[0])) {
|
|
2858
|
+
return createRBom(path, options);
|
|
2859
|
+
}
|
|
2860
|
+
if (PROJECT_TYPE_ALIASES["perl"].includes(projectType[0])) {
|
|
2861
|
+
return createPerlBom(path, options);
|
|
2862
|
+
}
|
|
2863
|
+
if (PROJECT_TYPE_ALIASES["terraform"].includes(projectType[0])) {
|
|
2864
|
+
return createTerraformBom(path, options);
|
|
2865
|
+
}
|
|
2639
2866
|
if (PROJECT_TYPE_ALIASES["caxa"].includes(projectType[0])) {
|
|
2640
2867
|
return await createCaxaBom(path, options);
|
|
2641
2868
|
}
|
|
@@ -2645,6 +2872,9 @@ async function createBomForPath(path, options) {
|
|
|
2645
2872
|
if (PROJECT_TYPE_ALIASES["vscode-extension"].includes(projectType[0])) {
|
|
2646
2873
|
return await createVscodeExtensionBom(path, options);
|
|
2647
2874
|
}
|
|
2875
|
+
if (PROJECT_TYPE_ALIASES["agentic"].includes(projectType[0])) {
|
|
2876
|
+
return await createAgenticBom(path, options);
|
|
2877
|
+
}
|
|
2648
2878
|
if (PROJECT_TYPE_ALIASES["chrome-extension"].includes(projectType[0])) {
|
|
2649
2879
|
return await createChromeExtensionBom(path, options);
|
|
2650
2880
|
}
|