@cdxgen/cdxgen 13.4.0 → 13.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +29 -5
- package/bin/evinse.js +8 -0
- package/bin/hbom.js +15 -7
- package/bin/repl.js +29 -0
- package/bin/validate.js +6 -0
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/license-aliases.json +24 -2
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +407 -1
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/data/rules/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +14 -0
- package/lib/cli/bomAssembly.js +120 -6
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +182 -6
- package/lib/cli/jsBom.js +153 -64
- package/lib/cli/jvmBom.js +363 -66
- package/lib/cli/managedBom.js +853 -87
- package/lib/cli/nativeBom.js +267 -33
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +38 -8
- package/lib/core/fs.js +40 -19
- package/lib/core/httpClient.js +172 -46
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +5 -0
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/core/toolRegistry.js +170 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +550 -6
- package/lib/ecosystems/gradleutils.js +858 -244
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-dotnet.js +117 -18
- package/lib/ecosystems/parsers-go.js +1090 -367
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-jvm.js +259 -17
- package/lib/ecosystems/parsers-misc.js +438 -64
- package/lib/ecosystems/parsers-python.js +100 -12
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/rubyutils.js +544 -34
- package/lib/ecosystems/rusi.js +10 -0
- package/lib/ecosystems/scalacliutils.js +4 -1
- package/lib/ecosystems/scalasem.js +798 -151
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +472 -61
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +413 -93
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +110 -0
- package/lib/inventory/auditCategories.js +3 -3
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +41 -4
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +639 -63
- package/lib/inventory/dotnetRuntime.js +217 -0
- package/lib/inventory/dynamic.js +45 -3
- package/lib/inventory/envcontext.js +475 -18
- package/lib/inventory/evidenceUtils.js +447 -23
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +32 -3
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +271 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/phpBuildInfo.js +438 -0
- package/lib/inventory/phpHostProbe.js +185 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +256 -5
- package/lib/inventory/spdx.js +144 -0
- package/lib/inventory/traceRunner.js +5 -1
- package/lib/inventory/tracedCrypto.js +129 -0
- package/lib/managers/binary.js +866 -186
- package/lib/managers/docker.js +245 -12
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +62 -13
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +198 -2
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +5 -5
- package/lib/stages/postgen/ruleEngine.js +71 -6
- package/lib/stages/postgen/specVersionCompat.js +30 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +231 -62
- package/lib/validator/bomValidator.js +32 -6
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +27 -8
- package/lib/validator/generated/validate-1.7.mjs +32 -13
- package/lib/validator/generated/validate-2.0.mjs +31 -12
- package/lib/validator/index.js +1 -1
- package/package.json +19 -18
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +22 -3
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +1 -17
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +20 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +70 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +22 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +2 -0
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +57 -21
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +40 -4
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +85 -13
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +28 -2
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +37 -58
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +14 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +88 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +33 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +2 -1
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +162 -7
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +44 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/dynamic.d.ts +6 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +92 -8
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +29 -10
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +44 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +38 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +15 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +4 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +22 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +24 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +17 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +8 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +26 -9
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
2
|
import { arch, homedir } from "node:os";
|
|
3
|
-
import { basename, delimiter, dirname, join } from "node:path";
|
|
3
|
+
import { basename, delimiter, dirname, isAbsolute, join } from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
|
|
6
6
|
import { compareLoose } from "semver";
|
|
@@ -19,9 +19,12 @@ import {
|
|
|
19
19
|
recordLedgerEvent,
|
|
20
20
|
} from "../core/buildLedger.js";
|
|
21
21
|
import {
|
|
22
|
+
BUNDLE_CMD,
|
|
22
23
|
CARGO_CMD,
|
|
24
|
+
COMPOSER_CMD,
|
|
23
25
|
DOTNET_CMD,
|
|
24
26
|
GCC_CMD,
|
|
27
|
+
GEM_CMD,
|
|
25
28
|
GO_CMD,
|
|
26
29
|
getJavaCommand,
|
|
27
30
|
getPythonCommand,
|
|
@@ -29,6 +32,7 @@ import {
|
|
|
29
32
|
isDeno,
|
|
30
33
|
isNode,
|
|
31
34
|
NPM_CMD,
|
|
35
|
+
PHP_CMD,
|
|
32
36
|
RUBY_CMD,
|
|
33
37
|
RUSTC_CMD,
|
|
34
38
|
SWIFT_CMD,
|
|
@@ -41,8 +45,20 @@ import {
|
|
|
41
45
|
} from "../core/fs.js";
|
|
42
46
|
import { diagnosticStream } from "../core/logger.js";
|
|
43
47
|
import { dirNameStr, isMac, isWin } from "../core/paths.js";
|
|
48
|
+
import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
49
|
+
import { brotliDecoderProperties, readBrotliDecoder } from "./brotliDecoder.js";
|
|
44
50
|
import { isValidSdkmanVersion } from "./jvmToolEnv.js";
|
|
51
|
+
import { createNodeRuntimeComponent } from "./nodeBuildInfo.js";
|
|
52
|
+
import {
|
|
53
|
+
createPhpRuntimeComponent,
|
|
54
|
+
packageStoreOf,
|
|
55
|
+
parsePhpReportedVersion,
|
|
56
|
+
} from "./phpBuildInfo.js";
|
|
45
57
|
import { applyPurl, tryBuildPurl } from "./purl.js";
|
|
58
|
+
import {
|
|
59
|
+
createRubyRuntimeComponent,
|
|
60
|
+
parseRubyDescription,
|
|
61
|
+
} from "./rubyBuildInfo.js";
|
|
46
62
|
import {
|
|
47
63
|
classifySpawnRestriction,
|
|
48
64
|
describeSpawnRestriction,
|
|
@@ -62,6 +78,9 @@ export const GIT_COMMAND = readEnvironmentVariable("GIT_CMD") || "git";
|
|
|
62
78
|
* - `core.fsmonitor=false` — a repo-set fsmonitor value is a command git runs.
|
|
63
79
|
* - `core.hooksPath=/dev/null` — prevents any hook script from executing.
|
|
64
80
|
* - `safe.bareRepository=explicit` — avoids operating on an embedded bare repo.
|
|
81
|
+
* - `gpg.program`, `gpg.ssh.program`, `gpg.x509.program` — `%G?` in a log
|
|
82
|
+
* format verifies signatures by running these, so pin them to the tools
|
|
83
|
+
* on PATH instead of a program named by the repo.
|
|
65
84
|
* `-c` overrides take precedence over the repo-local config. Diff-producing
|
|
66
85
|
* commands (`git show`/`git diff`) additionally pass `--no-ext-diff`/
|
|
67
86
|
* `--no-textconv` to block `.gitattributes`-driven external diff and textconv
|
|
@@ -74,6 +93,12 @@ const GIT_HARDENING_CONFIG_ARGS = Object.freeze([
|
|
|
74
93
|
"core.hooksPath=/dev/null",
|
|
75
94
|
"-c",
|
|
76
95
|
"safe.bareRepository=explicit",
|
|
96
|
+
"-c",
|
|
97
|
+
"gpg.program=gpg",
|
|
98
|
+
"-c",
|
|
99
|
+
"gpg.ssh.program=ssh-keygen",
|
|
100
|
+
"-c",
|
|
101
|
+
"gpg.x509.program=gpgsm",
|
|
77
102
|
]);
|
|
78
103
|
|
|
79
104
|
/**
|
|
@@ -84,7 +109,15 @@ const GIT_HARDENING_CONFIG_ARGS = Object.freeze([
|
|
|
84
109
|
* @returns {Object} environment for spawning git
|
|
85
110
|
*/
|
|
86
111
|
function hardenedGitEnv() {
|
|
87
|
-
|
|
112
|
+
// These commands only read the local repository. A partial clone would
|
|
113
|
+
// otherwise fetch missing objects through the repo's own remote and
|
|
114
|
+
// core.sshCommand settings, so turn lazy fetching and every transport off.
|
|
115
|
+
const env = {
|
|
116
|
+
...process.env,
|
|
117
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
118
|
+
GIT_NO_LAZY_FETCH: "1",
|
|
119
|
+
GIT_ALLOW_PROTOCOL: "cdxgen-no-network",
|
|
120
|
+
};
|
|
88
121
|
if (isSecureMode) {
|
|
89
122
|
env.GIT_CONFIG_NOSYSTEM = "1";
|
|
90
123
|
env.GIT_CONFIG_GLOBAL = "/dev/null";
|
|
@@ -113,6 +146,11 @@ export const SDKMAN_JAVA_TOOL_ALIASES = {
|
|
|
113
146
|
java24: readEnvironmentVariable("JAVA24_TOOL") || "24.0.2-tem",
|
|
114
147
|
java25: readEnvironmentVariable("JAVA25_TOOL") || "25.0.4-tem",
|
|
115
148
|
java26: readEnvironmentVariable("JAVA26_TOOL") || "26.0.2-tem",
|
|
149
|
+
// The broker serves no Java 27 build yet (every vendor id 404s), so java27
|
|
150
|
+
// has an alias only when JAVA27_TOOL names one that is downloadable.
|
|
151
|
+
...(readEnvironmentVariable("JAVA27_TOOL")
|
|
152
|
+
? { java27: readEnvironmentVariable("JAVA27_TOOL") }
|
|
153
|
+
: {}),
|
|
116
154
|
};
|
|
117
155
|
|
|
118
156
|
/**
|
|
@@ -337,8 +375,10 @@ function recordToolProbeResolved(tool, ecosystem, found) {
|
|
|
337
375
|
* @param {string} tool Tool name
|
|
338
376
|
* @param {string} ecosystem Ecosystem the tool belongs to
|
|
339
377
|
* @param {string} command Probe command that failed
|
|
378
|
+
* @param {string} [detail] What to say when the command is not restricted,
|
|
379
|
+
* instead of the default that no command answered
|
|
340
380
|
*/
|
|
341
|
-
function recordToolProbeFailure(tool, ecosystem, command) {
|
|
381
|
+
function recordToolProbeFailure(tool, ecosystem, command, detail) {
|
|
342
382
|
if (!isLedgerEnabled()) {
|
|
343
383
|
return;
|
|
344
384
|
}
|
|
@@ -362,7 +402,7 @@ function recordToolProbeFailure(tool, ecosystem, command) {
|
|
|
362
402
|
ecosystem,
|
|
363
403
|
tool,
|
|
364
404
|
source: "PATH",
|
|
365
|
-
detail: `No ${tool} command answered the version probe.`,
|
|
405
|
+
detail: detail || `No ${tool} command answered the version probe.`,
|
|
366
406
|
});
|
|
367
407
|
}
|
|
368
408
|
}
|
|
@@ -460,6 +500,16 @@ export function collectNodeInfo(dir) {
|
|
|
460
500
|
version: runtimeInfo.version,
|
|
461
501
|
components: runtimeInfo.components,
|
|
462
502
|
};
|
|
503
|
+
if (runtimeInfo.runtime === "Node.js" && runtimeInfo.version) {
|
|
504
|
+
// The same identity a scanned image's Node.js gets, without a bom-ref, as
|
|
505
|
+
// for the other toolchains.
|
|
506
|
+
const runtime = formulationToolchain(
|
|
507
|
+
createNodeRuntimeComponent(runtimeInfo.version),
|
|
508
|
+
);
|
|
509
|
+
nodeInfo.purl = runtime.purl;
|
|
510
|
+
nodeInfo.cpe = runtime.cpe;
|
|
511
|
+
annotateNodeBrotli(nodeInfo.components);
|
|
512
|
+
}
|
|
463
513
|
const moduleDesc = getCommandOutput(NPM_CMD, dir, ["--version"]);
|
|
464
514
|
if (moduleDesc) {
|
|
465
515
|
nodeInfo.description = `npm: ${moduleDesc}`;
|
|
@@ -470,6 +520,36 @@ export function collectNodeInfo(dir) {
|
|
|
470
520
|
return nodeInfo;
|
|
471
521
|
}
|
|
472
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Record whether the Brotli decoder the running Node.js uses carries the
|
|
525
|
+
* CVE-2026-111497 fix. process.versions.brotli cannot say: Node.js backports
|
|
526
|
+
* the fix without changing it. The decoder is read where it lives, in the node
|
|
527
|
+
* binary or in the shared libbrotlidec a `--shared-brotli` build loads.
|
|
528
|
+
*
|
|
529
|
+
* @param {Object[]|undefined} components bundled components of the runtime
|
|
530
|
+
*/
|
|
531
|
+
function annotateNodeBrotli(components) {
|
|
532
|
+
const brotli = (components || []).find(
|
|
533
|
+
(component) => component.name === "brotli",
|
|
534
|
+
);
|
|
535
|
+
if (!brotli) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
let decoderFile = globalThis.process?.execPath;
|
|
539
|
+
if (nodeComponentLinkage("brotli") === "shared") {
|
|
540
|
+
decoderFile = (
|
|
541
|
+
globalThis.process?.report?.getReport?.()?.sharedObjects || []
|
|
542
|
+
).find((path) => basename(path).startsWith("libbrotlidec"));
|
|
543
|
+
}
|
|
544
|
+
const decoder = decoderFile ? readBrotliDecoder(decoderFile) : undefined;
|
|
545
|
+
if (decoder) {
|
|
546
|
+
brotli.properties = [
|
|
547
|
+
...(brotli.properties || []),
|
|
548
|
+
...brotliDecoderProperties(decoder),
|
|
549
|
+
];
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
473
553
|
/**
|
|
474
554
|
* Collect gcc version
|
|
475
555
|
*
|
|
@@ -559,23 +639,333 @@ export function collectSwiftInfo(dir) {
|
|
|
559
639
|
}
|
|
560
640
|
|
|
561
641
|
/**
|
|
562
|
-
*
|
|
642
|
+
* The real path of the executable a command name runs, looked up on PATH as
|
|
643
|
+
* the shell would, or undefined when it cannot be found.
|
|
644
|
+
*
|
|
645
|
+
* @param {string} command command name or path
|
|
646
|
+
* @returns {string|undefined}
|
|
647
|
+
*/
|
|
648
|
+
function resolveExecutable(command) {
|
|
649
|
+
const name = `${command || ""}`.trim().split(" ")[0];
|
|
650
|
+
if (!name) {
|
|
651
|
+
return undefined;
|
|
652
|
+
}
|
|
653
|
+
const extensions = isWin
|
|
654
|
+
? ["", ...`${process.env.PATHEXT || ".EXE;.CMD;.BAT"}`.split(";")]
|
|
655
|
+
: [""];
|
|
656
|
+
const directories = isAbsolute(name)
|
|
657
|
+
? [dirname(name)]
|
|
658
|
+
: `${process.env.PATH || ""}`.split(delimiter).filter(Boolean);
|
|
659
|
+
const base = isAbsolute(name) ? basename(name) : name;
|
|
660
|
+
for (const directory of directories) {
|
|
661
|
+
for (const extension of extensions) {
|
|
662
|
+
const candidate = join(directory, `${base}${extension}`);
|
|
663
|
+
try {
|
|
664
|
+
if (statSync(candidate).isFile()) {
|
|
665
|
+
return realpathSync(candidate);
|
|
666
|
+
}
|
|
667
|
+
} catch {
|
|
668
|
+
// not here
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return undefined;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Whether a Ruby executable is one the operating system or a package manager
|
|
677
|
+
* that patches it owns. Distros backport fixes under the old upstream version,
|
|
678
|
+
* so its version must not be matched against upstream advisories by CPE.
|
|
679
|
+
*
|
|
680
|
+
* @param {string|undefined} realPath real path of the executable
|
|
681
|
+
* @returns {boolean}
|
|
682
|
+
*/
|
|
683
|
+
export function isPackagedRubyPath(realPath) {
|
|
684
|
+
if (!realPath || isWin) {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
// Homebrew builds the upstream release, so it keeps the CPE, as it does in
|
|
688
|
+
// an OBOM; Nix and Guix patch theirs.
|
|
689
|
+
const store = packageStoreOf(realPath);
|
|
690
|
+
if (store) {
|
|
691
|
+
return store !== "homebrew";
|
|
692
|
+
}
|
|
693
|
+
return ["/usr/bin/", "/bin/", "/usr/lib/", "/usr/libexec/", "/System/"].some(
|
|
694
|
+
(prefix) => realPath.startsWith(prefix),
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// The shims of rbenv, asdf and mise run whichever Ruby is selected, which can
|
|
699
|
+
// be the distro's (`rbenv global system`).
|
|
700
|
+
function isVersionManagerShim(realPath) {
|
|
701
|
+
return `${realPath}`.split(/[\\/]/).includes("shims");
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Whether the Ruby `ruby --version` described may carry its release's CPE.
|
|
705
|
+
// A shim is followed to the interpreter it runs; one that cannot be followed
|
|
706
|
+
// keeps no CPE, since it may be the distro's.
|
|
707
|
+
function rubyKeepsCpe(dir) {
|
|
708
|
+
let executable = resolveExecutable(RUBY_CMD);
|
|
709
|
+
if (executable && isVersionManagerShim(executable)) {
|
|
710
|
+
const target = isWin
|
|
711
|
+
? ""
|
|
712
|
+
: firstOutputLine(
|
|
713
|
+
getCommandOutput(RUBY_CMD, dir, ["-e", "print RbConfig.ruby"]),
|
|
714
|
+
);
|
|
715
|
+
if (!isAbsolute(target)) {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
executable = realpathSync(target);
|
|
720
|
+
} catch {
|
|
721
|
+
executable = target;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return !isPackagedRubyPath(executable);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Collect the Ruby on the PATH.
|
|
729
|
+
*
|
|
730
|
+
* `ruby --version` prints the interpreter's description, such as
|
|
731
|
+
* `ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [x86_64-linux]`, which is kept
|
|
732
|
+
* as the component description. The identity is `pkg:generic/ruby@3.3.6`
|
|
733
|
+
* (or jruby, truffleruby), with the CPE of the release unless a package
|
|
734
|
+
* manager owns the executable: a distro backports fixes under the old upstream
|
|
735
|
+
* version.
|
|
563
736
|
*
|
|
564
737
|
* @param {string} dir Working directory
|
|
565
738
|
* @returns Object containing Ruby details
|
|
566
739
|
*/
|
|
567
740
|
export function collectRubyInfo(dir) {
|
|
568
741
|
const versionDesc = getCommandOutput(RUBY_CMD, dir, ["--version"]);
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
version
|
|
574
|
-
|
|
575
|
-
|
|
742
|
+
const banner = firstOutputLine(versionDesc);
|
|
743
|
+
const parsed = parseRubyDescription(banner);
|
|
744
|
+
if (parsed) {
|
|
745
|
+
const info = formulationToolchain(
|
|
746
|
+
createRubyRuntimeComponent(parsed.version, {
|
|
747
|
+
engine: parsed.engine,
|
|
748
|
+
withCpe: rubyKeepsCpe(dir),
|
|
749
|
+
}),
|
|
750
|
+
);
|
|
751
|
+
info.description = banner;
|
|
752
|
+
const properties = [];
|
|
753
|
+
if (parsed.patchlevel !== undefined) {
|
|
754
|
+
properties.push({
|
|
755
|
+
name: "cdx:ruby:patchlevel",
|
|
756
|
+
value: parsed.patchlevel,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
if (parsed.rubyVersion) {
|
|
760
|
+
properties.push({
|
|
761
|
+
name: "cdx:ruby:languageVersion",
|
|
762
|
+
value: parsed.rubyVersion,
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
if (parsed.platform) {
|
|
766
|
+
properties.push({ name: "cdx:ruby:platform", value: parsed.platform });
|
|
767
|
+
}
|
|
768
|
+
if (properties.length) {
|
|
769
|
+
info.properties = properties;
|
|
770
|
+
}
|
|
771
|
+
recordToolProbeResolved("ruby", "ruby", banner);
|
|
576
772
|
return info;
|
|
577
773
|
}
|
|
578
|
-
recordToolProbeFailure(
|
|
774
|
+
recordToolProbeFailure(
|
|
775
|
+
"ruby",
|
|
776
|
+
"ruby",
|
|
777
|
+
RUBY_CMD,
|
|
778
|
+
versionDesc
|
|
779
|
+
? "The ruby version probe did not print a Ruby version banner."
|
|
780
|
+
: undefined,
|
|
781
|
+
);
|
|
782
|
+
return undefined;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Whether the Ruby collectRubyInfo found is the MRI release a project needs.
|
|
787
|
+
*
|
|
788
|
+
* @param {Object|undefined} info result of collectRubyInfo
|
|
789
|
+
* @param {string} version wanted MRI version
|
|
790
|
+
* @returns {boolean}
|
|
791
|
+
*/
|
|
792
|
+
export function isRubyVersionActive(info, version) {
|
|
793
|
+
return Boolean(info && info.name === "ruby" && info.version === version);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Collect the RubyGems version. `gem --version` prints the bare version.
|
|
798
|
+
*
|
|
799
|
+
* @param {string} dir Working directory
|
|
800
|
+
* @returns {Object|undefined} the RubyGems component
|
|
801
|
+
*/
|
|
802
|
+
export function collectRubyGemsInfo(dir) {
|
|
803
|
+
const token = firstOutputLine(getCommandOutput(GEM_CMD, dir, ["--version"]));
|
|
804
|
+
if (/^\d+\.\d+\.\d+$/.test(token)) {
|
|
805
|
+
recordToolProbeResolved("gem", "ruby", token);
|
|
806
|
+
return formulationToolchain(
|
|
807
|
+
applyPurl(
|
|
808
|
+
{
|
|
809
|
+
type: "platform",
|
|
810
|
+
name: "rubygems",
|
|
811
|
+
version: token,
|
|
812
|
+
cpe: `cpe:2.3:a:rubygems:rubygems:${token}:*:*:*:*:*:*:*`,
|
|
813
|
+
},
|
|
814
|
+
tryBuildPurl({ type: "generic", name: "rubygems", version: token }),
|
|
815
|
+
),
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
recordToolProbeFailure("gem", "ruby", GEM_CMD);
|
|
819
|
+
return undefined;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Collect the Bundler version. `bundle --version` prints `Bundler version
|
|
824
|
+
* 2.5.22`, or the bare version from Bundler 2.6 on.
|
|
825
|
+
*
|
|
826
|
+
* @param {string} dir Working directory
|
|
827
|
+
* @returns {Object|undefined} the Bundler component
|
|
828
|
+
*/
|
|
829
|
+
export function collectBundlerInfo(dir) {
|
|
830
|
+
const line = firstOutputLine(
|
|
831
|
+
getCommandOutput(BUNDLE_CMD, dir, ["--version"]),
|
|
832
|
+
);
|
|
833
|
+
const token = line.startsWith("Bundler version ")
|
|
834
|
+
? line.slice("Bundler version ".length).trim()
|
|
835
|
+
: line;
|
|
836
|
+
if (/^\d+\.\d+\.\d+$/.test(token)) {
|
|
837
|
+
recordToolProbeResolved("bundler", "ruby", token);
|
|
838
|
+
return formulationToolchain(
|
|
839
|
+
applyPurl(
|
|
840
|
+
{
|
|
841
|
+
type: "platform",
|
|
842
|
+
name: "bundler",
|
|
843
|
+
version: token,
|
|
844
|
+
cpe: `cpe:2.3:a:bundler:bundler:${token}:*:*:*:*:*:*:*`,
|
|
845
|
+
},
|
|
846
|
+
tryBuildPurl({ type: "gem", name: "bundler", version: token }),
|
|
847
|
+
),
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
recordToolProbeFailure("bundler", "ruby", BUNDLE_CMD);
|
|
851
|
+
return undefined;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* The first line of a command's output, without its line end.
|
|
856
|
+
*
|
|
857
|
+
* @param {string|undefined} output Output of getCommandOutput
|
|
858
|
+
* @returns {string} First line, or an empty string
|
|
859
|
+
*/
|
|
860
|
+
function firstOutputLine(output) {
|
|
861
|
+
return `${output || ""}`.split(/\r?\n/, 1)[0].trim();
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* A toolchain component for the formulation section. Formulation shares the
|
|
866
|
+
* document's bom-ref namespace with the inventory, which can hold the very same
|
|
867
|
+
* `pkg:generic/php@<version>` runtime (an image scanned with
|
|
868
|
+
* --include-formulation), so like the other toolchains it carries no bom-ref.
|
|
869
|
+
*
|
|
870
|
+
* @param {Object} component component built with applyPurl
|
|
871
|
+
* @returns {Object} the component without its bom-ref
|
|
872
|
+
*/
|
|
873
|
+
function formulationToolchain(component) {
|
|
874
|
+
delete component["bom-ref"];
|
|
875
|
+
return component;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Collect the PHP version of the PHP found on the PATH.
|
|
880
|
+
*
|
|
881
|
+
* `-n` stops PHP loading any php.ini, so a PHPRC or an auto_prepend_file cannot
|
|
882
|
+
* run code, and `-v` is used rather than `-r 'echo PHP_VERSION;'` because the
|
|
883
|
+
* shell on Windows does not quote arguments. The first line is
|
|
884
|
+
* `PHP 8.5.11 (cli) (built: Sep 22 2026 13:32:06) (NTS)`.
|
|
885
|
+
*
|
|
886
|
+
* The identity is `pkg:generic/php`: a probe of the PATH cannot tell which
|
|
887
|
+
* package manager, if any, installed this PHP. A banner with a distro revision,
|
|
888
|
+
* such as Ubuntu 22.04's `PHP 8.1.2-1ubuntu2.14`, is recorded as reported but
|
|
889
|
+
* without a CPE: the distro backports fixes under the old upstream number.
|
|
890
|
+
*
|
|
891
|
+
* @param {string} dir Working directory
|
|
892
|
+
* @returns Object containing the PHP details
|
|
893
|
+
*/
|
|
894
|
+
export function collectPhpInfo(dir) {
|
|
895
|
+
const output = getCommandOutput(PHP_CMD, dir, ["-n", "-v"]);
|
|
896
|
+
const banner = firstOutputLine(output);
|
|
897
|
+
const reported = banner.startsWith("PHP ")
|
|
898
|
+
? parsePhpReportedVersion(banner.slice("PHP ".length))
|
|
899
|
+
: undefined;
|
|
900
|
+
if (reported) {
|
|
901
|
+
recordToolProbeResolved("php", "php", reported.version);
|
|
902
|
+
return formulationToolchain(
|
|
903
|
+
createPhpRuntimeComponent(reported.version, {
|
|
904
|
+
withCpe: !reported.distroRevision,
|
|
905
|
+
}),
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
recordToolProbeFailure(
|
|
909
|
+
"php",
|
|
910
|
+
"php",
|
|
911
|
+
PHP_CMD,
|
|
912
|
+
output
|
|
913
|
+
? "The php version probe did not print a PHP version banner."
|
|
914
|
+
: undefined,
|
|
915
|
+
);
|
|
916
|
+
return undefined;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Collect the Composer version.
|
|
921
|
+
*
|
|
922
|
+
* `--no-plugins` and `--no-scripts` keep the plugins and scripts of the
|
|
923
|
+
* project in the working directory from running, which `composer --version`
|
|
924
|
+
* would otherwise let a plugin do. It needs no network. The banner is
|
|
925
|
+
* `Composer version 2.10.3 2026-08-27 13:34:23`, but an older Composer on a
|
|
926
|
+
* newer PHP prints deprecation notices above it, so the first line that starts
|
|
927
|
+
* with it is read; the line after it names the PHP Composer runs on, with its
|
|
928
|
+
* path, and is never read. The banner must start its line: an indented echo of
|
|
929
|
+
* the project's composer.json in an error block does not count. Only a stable
|
|
930
|
+
* release is recorded: a pre-release or a snapshot has no version a CPE can
|
|
931
|
+
* name.
|
|
932
|
+
*
|
|
933
|
+
* @param {string} dir Working directory
|
|
934
|
+
* @returns Object containing the Composer details
|
|
935
|
+
*/
|
|
936
|
+
export function collectComposerInfo(dir) {
|
|
937
|
+
const output = getCommandOutput(COMPOSER_CMD, dir, [
|
|
938
|
+
"--version",
|
|
939
|
+
"--no-plugins",
|
|
940
|
+
"--no-scripts",
|
|
941
|
+
"--no-interaction",
|
|
942
|
+
]);
|
|
943
|
+
const token =
|
|
944
|
+
/^Composer version (\S+)/m.exec(
|
|
945
|
+
`${output || ""}`.slice(0, 64 * 1024),
|
|
946
|
+
)?.[1] || "";
|
|
947
|
+
if (/^\d+\.\d+\.\d+$/.test(token)) {
|
|
948
|
+
recordToolProbeResolved("composer", "php", token);
|
|
949
|
+
return formulationToolchain(
|
|
950
|
+
applyPurl(
|
|
951
|
+
{
|
|
952
|
+
type: "platform",
|
|
953
|
+
name: "composer",
|
|
954
|
+
version: token,
|
|
955
|
+
cpe: `cpe:2.3:a:getcomposer:composer:${token}:*:*:*:*:*:*:*`,
|
|
956
|
+
},
|
|
957
|
+
tryBuildPurl({ type: "generic", name: "composer", version: token }),
|
|
958
|
+
),
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
recordToolProbeFailure(
|
|
962
|
+
"composer",
|
|
963
|
+
"php",
|
|
964
|
+
COMPOSER_CMD,
|
|
965
|
+
output
|
|
966
|
+
? "The composer version probe did not print a stable Composer version."
|
|
967
|
+
: undefined,
|
|
968
|
+
);
|
|
579
969
|
return undefined;
|
|
580
970
|
}
|
|
581
971
|
|
|
@@ -594,12 +984,23 @@ export function runSwiftCommand(dir, args) {
|
|
|
594
984
|
* Collect toolchain information components for the current environment.
|
|
595
985
|
*
|
|
596
986
|
* Probes the working directory for java, dotnet, python, node, gcc, rust, go,
|
|
597
|
-
* and
|
|
987
|
+
* ruby, php and composer toolchains and returns one component per detected
|
|
988
|
+
* tool.
|
|
598
989
|
*
|
|
599
990
|
* @param {string} dir Working directory to inspect
|
|
991
|
+
* @param {Object} [options] CLI options, which decide whether the project's
|
|
992
|
+
* own toolchain files may choose the tools that run
|
|
600
993
|
* @returns {Object[]} Array of toolchain component objects; empty when nothing is detected
|
|
601
994
|
*/
|
|
602
|
-
export function collectEnvInfo(dir) {
|
|
995
|
+
export function collectEnvInfo(dir, options = undefined) {
|
|
996
|
+
// Version managers pick the toolchain from files in the working directory.
|
|
997
|
+
// rust-toolchain.toml can name an absolute toolchain path and global.json
|
|
998
|
+
// can name SDK paths, so unless the project's tooling may run, the probes
|
|
999
|
+
// run outside the scanned project and report the toolchains installed on
|
|
1000
|
+
// the host.
|
|
1001
|
+
if (!isProjectToolingAllowed(options)) {
|
|
1002
|
+
dir = getTmpDir();
|
|
1003
|
+
}
|
|
603
1004
|
const infoComponents = [];
|
|
604
1005
|
let cmp = collectJavaInfo(dir);
|
|
605
1006
|
if (cmp) {
|
|
@@ -630,6 +1031,22 @@ export function collectEnvInfo(dir) {
|
|
|
630
1031
|
infoComponents.push(cmp);
|
|
631
1032
|
}
|
|
632
1033
|
cmp = collectRubyInfo(dir);
|
|
1034
|
+
if (cmp) {
|
|
1035
|
+
infoComponents.push(cmp);
|
|
1036
|
+
cmp = collectRubyGemsInfo(dir);
|
|
1037
|
+
if (cmp) {
|
|
1038
|
+
infoComponents.push(cmp);
|
|
1039
|
+
}
|
|
1040
|
+
cmp = collectBundlerInfo(dir);
|
|
1041
|
+
if (cmp) {
|
|
1042
|
+
infoComponents.push(cmp);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
cmp = collectPhpInfo(dir);
|
|
1046
|
+
if (cmp) {
|
|
1047
|
+
infoComponents.push(cmp);
|
|
1048
|
+
}
|
|
1049
|
+
cmp = collectComposerInfo(dir);
|
|
633
1050
|
if (cmp) {
|
|
634
1051
|
infoComponents.push(cmp);
|
|
635
1052
|
}
|
|
@@ -1055,7 +1472,7 @@ export function installRubyVersion(rubyVersion, filePath) {
|
|
|
1055
1472
|
return { fullToolBinDir: undefined, status: false };
|
|
1056
1473
|
}
|
|
1057
1474
|
const existingRuby = collectRubyInfo(filePath);
|
|
1058
|
-
if (existingRuby
|
|
1475
|
+
if (isRubyVersionActive(existingRuby, rubyVersion)) {
|
|
1059
1476
|
return { fullToolBinDir: undefined, status: true };
|
|
1060
1477
|
}
|
|
1061
1478
|
const fullToolBinDir = rubyVersionDir(rubyVersion);
|
|
@@ -1821,6 +2238,36 @@ export function gitRevertsAndHotfixes(dir, maxCount = 20) {
|
|
|
1821
2238
|
return entries;
|
|
1822
2239
|
}
|
|
1823
2240
|
|
|
2241
|
+
// process.versions keys whose configure flag is named differently.
|
|
2242
|
+
const NODE_SHARED_FLAG_NAMES = {
|
|
2243
|
+
ares: "cares",
|
|
2244
|
+
libffi: "ffi",
|
|
2245
|
+
llhttp: "http_parser",
|
|
2246
|
+
uv: "libuv",
|
|
2247
|
+
};
|
|
2248
|
+
|
|
2249
|
+
/**
|
|
2250
|
+
* Whether the running Node.js links a bundled dependency as a shared library,
|
|
2251
|
+
* from the `node_shared_<name>` configure variables it reports.
|
|
2252
|
+
*
|
|
2253
|
+
* @param {string} name key of process.versions
|
|
2254
|
+
* @param {Object} [variables] configure variables, process.config.variables
|
|
2255
|
+
* by default
|
|
2256
|
+
* @returns {string|undefined} `shared`, `bundled`, or undefined when the build
|
|
2257
|
+
* does not say
|
|
2258
|
+
*/
|
|
2259
|
+
export function nodeComponentLinkage(
|
|
2260
|
+
name,
|
|
2261
|
+
variables = globalThis.process?.config?.variables,
|
|
2262
|
+
) {
|
|
2263
|
+
const flag = `node_shared_${NODE_SHARED_FLAG_NAMES[name] || name}`;
|
|
2264
|
+
if (!variables || !(flag in variables)) {
|
|
2265
|
+
return undefined;
|
|
2266
|
+
}
|
|
2267
|
+
const value = variables[flag];
|
|
2268
|
+
return value === true || value === "true" ? "shared" : "bundled";
|
|
2269
|
+
}
|
|
2270
|
+
|
|
1824
2271
|
/**
|
|
1825
2272
|
* Get information about the runtime.
|
|
1826
2273
|
*
|
|
@@ -1853,12 +2300,22 @@ export function getRuntimeInformation() {
|
|
|
1853
2300
|
name,
|
|
1854
2301
|
version: version || null,
|
|
1855
2302
|
});
|
|
2303
|
+
// A distro or Homebrew build links some of these as shared libraries
|
|
2304
|
+
// (`configure --shared-brotli`); the version is then the shared
|
|
2305
|
+
// library's, and updating Node.js alone does not update it.
|
|
2306
|
+
const linkage = nodeComponentLinkage(name);
|
|
1856
2307
|
const apkg = {
|
|
1857
2308
|
name,
|
|
1858
2309
|
version,
|
|
1859
|
-
description:
|
|
2310
|
+
description:
|
|
2311
|
+
linkage === "shared"
|
|
2312
|
+
? `Linked by Node.js ${runtimeInfo.version} as a shared library`
|
|
2313
|
+
: `Bundled with Node.js ${runtimeInfo.version}`,
|
|
1860
2314
|
type: "library",
|
|
1861
2315
|
scope: "excluded",
|
|
2316
|
+
...(linkage
|
|
2317
|
+
? { properties: [{ name: "cdx:node:linkage", value: linkage }] }
|
|
2318
|
+
: {}),
|
|
1862
2319
|
};
|
|
1863
2320
|
applyPurl(apkg, bundledPurl);
|
|
1864
2321
|
if (nodeSourceUrl) {
|