@cdxgen/cdxgen 13.5.0 → 13.7.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 +17 -10
- package/bin/audit.js +7 -4
- package/bin/cdxgen.js +260 -37
- package/bin/convert.js +146 -22
- package/bin/evinse.js +28 -3
- package/bin/repl.js +47 -3
- package/bin/sign.js +211 -34
- package/bin/tracebom.js +18 -6
- package/bin/validate.js +24 -3
- package/bin/verify.js +113 -5
- package/data/behavior-taxonomy.schema.json +1491 -0
- package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
- package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
- package/data/license-aliases.json +24 -2
- package/data/pqc-migration.json +239 -0
- package/data/remediations.json +176 -0
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +4 -3
- package/data/rules/package-integrity.yaml +28 -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 +25 -3
- package/lib/cli/bomAssembly.js +172 -4
- package/lib/cli/cliOptions.js +121 -17
- package/lib/cli/index.js +720 -902
- package/lib/cli/jsBom.js +156 -64
- package/lib/cli/jvmBom.js +602 -86
- package/lib/cli/managedBom.js +161 -19
- package/lib/cli/nativeBom.js +52 -5
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +34 -0
- package/lib/core/fs.js +138 -3
- package/lib/core/globPatterns.js +218 -0
- package/lib/core/httpClient.js +98 -1
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +100 -8
- package/lib/core/projectConfig.js +332 -25
- package/lib/core/toolRegistry.js +184 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/denoutils.js +2 -2
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +3 -8
- package/lib/ecosystems/gradleutils.js +1909 -229
- package/lib/ecosystems/jsEvidence.js +90 -38
- package/lib/ecosystems/kosi.js +3 -5
- package/lib/ecosystems/npmVersionResolution.js +376 -0
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-misc.js +209 -20
- package/lib/ecosystems/parsers-python.js +178 -30
- package/lib/ecosystems/parsers-rust.js +117 -15
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/remote/huggingface.js +22 -0
- package/lib/ecosystems/rubyutils.js +538 -31
- package/lib/ecosystems/rusi.js +2 -4
- package/lib/ecosystems/scalacliutils.js +2 -0
- package/lib/ecosystems/scalasem.js +798 -152
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +536 -71
- package/lib/evinser/scalasem.js +5 -1
- package/lib/helpers/agenticToolutils.js +525 -94
- package/lib/helpers/bomSigner.js +43 -9
- package/lib/helpers/jssSigner.js +1276 -0
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentBlueprint.js +193 -0
- package/lib/inventory/agentToolNames.js +145 -0
- package/lib/inventory/aiCollector.js +153 -7
- package/lib/inventory/aiInventory.js +44 -8
- package/lib/inventory/aiProviders.js +324 -0
- package/lib/inventory/atomUtils.js +77 -0
- package/lib/inventory/bomUtils.js +8 -1
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
- package/lib/inventory/citations.js +31 -2
- package/lib/inventory/communityAiConfigParser.js +978 -80
- package/lib/inventory/cyclonedx20.js +152 -0
- package/lib/inventory/cyclonedx20Common.js +286 -0
- package/lib/inventory/cyclonedx20Derived.js +159 -0
- package/lib/inventory/cyclonedx20Parties.js +552 -0
- package/lib/inventory/cyclonedx20Read.js +768 -0
- package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
- package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
- package/lib/inventory/cyclonedx20ReadContext.js +380 -0
- package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
- package/lib/inventory/cyclonedx20ReadSections.js +599 -0
- package/lib/inventory/cyclonedx20Render.js +766 -0
- package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
- package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
- package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
- package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
- package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
- package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
- package/lib/inventory/cyclonedx20RenderSections.js +499 -0
- package/lib/inventory/cyclonedx20Tables.js +594 -0
- package/lib/inventory/deps.js +141 -13
- package/lib/inventory/dosai.js +375 -6
- package/lib/inventory/dosaiParsers.js +3 -6
- package/lib/inventory/dotnetRuntime.js +367 -0
- package/lib/inventory/ecosystemFormulationParsers.js +979 -0
- package/lib/inventory/envcontext.js +436 -48
- package/lib/inventory/evidenceUtils.js +13 -1
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +124 -14
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +45 -6
- package/lib/inventory/hbomLoader.js +166 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/mcpConfigParser.js +5 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/occurrenceKey.js +90 -0
- package/lib/inventory/osPackageResolver.js +182 -0
- package/lib/inventory/phpBuildInfo.js +10 -59
- package/lib/inventory/phpHostProbe.js +32 -488
- package/lib/inventory/pqcMigration.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/rustFormulationParser.js +21 -10
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +114 -8
- package/lib/managers/binary.js +337 -3
- package/lib/managers/docker.js +79 -0
- package/lib/parsers/huggingfaceManifest.js +9 -1
- package/lib/parsers/huggingfaceUtils.js +18 -0
- package/lib/parsers/kiroPermissions.js +166 -0
- package/lib/parsers/largeJson.js +28 -11
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +48 -35
- package/lib/stages/postgen/postgen.js +41 -1
- package/lib/stages/postgen/ruleEngine.js +13 -5
- package/lib/stages/postgen/specVersionCompat.js +76 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +114 -57
- package/lib/validator/bomValidator.js +14 -2
- package/lib/validator/complianceEngine.js +30 -3
- package/lib/validator/complianceRules.js +1416 -4
- package/lib/validator/generated/validate-1.6.mjs +1 -1
- package/lib/validator/generated/validate-1.7.mjs +1 -1
- package/lib/validator/generated/validate-2.0.mjs +57554 -13851
- package/lib/validator/index.js +49 -8
- package/lib/validator/reporters/json.js +6 -0
- package/package.json +11 -10
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +6 -2
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +29 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +6 -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 +3 -18
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +15 -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 +100 -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 +14 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +4 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/globPatterns.d.ts +70 -0
- package/types/lib/core/globPatterns.d.ts.map +1 -0
- 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/paths.d.ts +9 -0
- package/types/lib/core/paths.d.ts.map +1 -1
- package/types/lib/core/processTree.d.ts +17 -4
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts +47 -8
- package/types/lib/core/projectConfig.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.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +294 -20
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +14 -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/npmVersionResolution.d.ts +119 -0
- package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +10 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-rust.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/remote/huggingface.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 +58 -16
- 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 +120 -13
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/scalasem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +53 -19
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +20 -3
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/helpers/jssSigner.d.ts +288 -0
- package/types/lib/helpers/jssSigner.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +303 -19
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/inventory/agentBlueprint.d.ts +70 -0
- package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
- package/types/lib/inventory/agentToolNames.d.ts +51 -0
- package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/aiProviders.d.ts +85 -0
- package/types/lib/inventory/aiProviders.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +19 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/bomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +5 -0
- package/types/lib/inventory/citations.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/cyclonedx20.d.ts +99 -0
- package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +35 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +36 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +74 -12
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts +11 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomLoader.d.ts +54 -0
- package/types/lib/inventory/hbomLoader.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/jvmLocalRepos.d.ts +5 -1
- package/types/lib/inventory/jvmLocalRepos.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/mcpConfigParser.d.ts.map +1 -1
- 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/occurrenceKey.d.ts +52 -0
- package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +38 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
- package/types/lib/inventory/pqcMigration.d.ts +84 -0
- package/types/lib/inventory/pqcMigration.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/rustFormulationParser.d.ts +7 -2
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
- package/types/lib/inventory/scalaDedupe.d.ts +43 -0
- package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +25 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/kiroPermissions.d.ts +62 -0
- package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +4 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +7 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
- 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 +12 -8
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts +5 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceEngine.d.ts +4 -4
- package/types/lib/validator/complianceEngine.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts +14 -2
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.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,10 +19,12 @@ import {
|
|
|
19
19
|
recordLedgerEvent,
|
|
20
20
|
} from "../core/buildLedger.js";
|
|
21
21
|
import {
|
|
22
|
+
BUNDLE_CMD,
|
|
22
23
|
CARGO_CMD,
|
|
23
24
|
COMPOSER_CMD,
|
|
24
25
|
DOTNET_CMD,
|
|
25
26
|
GCC_CMD,
|
|
27
|
+
GEM_CMD,
|
|
26
28
|
GO_CMD,
|
|
27
29
|
getJavaCommand,
|
|
28
30
|
getPythonCommand,
|
|
@@ -44,12 +46,23 @@ import {
|
|
|
44
46
|
import { diagnosticStream } from "../core/logger.js";
|
|
45
47
|
import { dirNameStr, isMac, isWin } from "../core/paths.js";
|
|
46
48
|
import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
49
|
+
import { brotliDecoderProperties, readBrotliDecoder } from "./brotliDecoder.js";
|
|
50
|
+
import {
|
|
51
|
+
createHostDotnetRuntimeComponent,
|
|
52
|
+
parseDotnetListRuntimes,
|
|
53
|
+
} from "./dotnetRuntime.js";
|
|
47
54
|
import { isValidSdkmanVersion } from "./jvmToolEnv.js";
|
|
55
|
+
import { createNodeRuntimeComponent } from "./nodeBuildInfo.js";
|
|
48
56
|
import {
|
|
49
57
|
createPhpRuntimeComponent,
|
|
58
|
+
packageStoreOf,
|
|
50
59
|
parsePhpReportedVersion,
|
|
51
60
|
} from "./phpBuildInfo.js";
|
|
52
61
|
import { applyPurl, tryBuildPurl } from "./purl.js";
|
|
62
|
+
import {
|
|
63
|
+
createRubyRuntimeComponent,
|
|
64
|
+
parseRubyDescription,
|
|
65
|
+
} from "./rubyBuildInfo.js";
|
|
53
66
|
import {
|
|
54
67
|
classifySpawnRestriction,
|
|
55
68
|
describeSpawnRestriction,
|
|
@@ -137,6 +150,11 @@ export const SDKMAN_JAVA_TOOL_ALIASES = {
|
|
|
137
150
|
java24: readEnvironmentVariable("JAVA24_TOOL") || "24.0.2-tem",
|
|
138
151
|
java25: readEnvironmentVariable("JAVA25_TOOL") || "25.0.4-tem",
|
|
139
152
|
java26: readEnvironmentVariable("JAVA26_TOOL") || "26.0.2-tem",
|
|
153
|
+
// The broker serves no Java 27 build yet (every vendor id 404s), so java27
|
|
154
|
+
// has an alias only when JAVA27_TOOL names one that is downloadable.
|
|
155
|
+
...(readEnvironmentVariable("JAVA27_TOOL")
|
|
156
|
+
? { java27: readEnvironmentVariable("JAVA27_TOOL") }
|
|
157
|
+
: {}),
|
|
140
158
|
};
|
|
141
159
|
|
|
142
160
|
/**
|
|
@@ -165,7 +183,8 @@ export function getOriginUrl(dir) {
|
|
|
165
183
|
* @param {string} configKey Git config key
|
|
166
184
|
* @param {string} dir repo directory
|
|
167
185
|
*
|
|
168
|
-
* @returns
|
|
186
|
+
* @returns {string|undefined} The branch name, or undefined when git fails,
|
|
187
|
+
* for example when the directory is not a git working tree or has no commit
|
|
169
188
|
*/
|
|
170
189
|
export function getBranch(_configKey, dir) {
|
|
171
190
|
return execGitCommand(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
@@ -198,20 +217,20 @@ export function gitTreeHashes(dir) {
|
|
|
198
217
|
}
|
|
199
218
|
|
|
200
219
|
/**
|
|
201
|
-
* Retrieves the files
|
|
202
|
-
*
|
|
220
|
+
* Retrieves the files git tracks under a directory at HEAD. Only the
|
|
221
|
+
* directory's own subtree is listed, with names relative to it, so a scan of
|
|
222
|
+
* one directory of a larger repository does not record the rest of that
|
|
223
|
+
* repository.
|
|
203
224
|
*
|
|
204
|
-
* @
|
|
225
|
+
* @param {string} dir directory inside a git working tree
|
|
226
|
+
*
|
|
227
|
+
* @returns {Object[]} files with their blob hash, name, OmniBOR id and SWHID;
|
|
228
|
+
* empty when git fails, for example when the directory is not a git working
|
|
229
|
+
* tree or has no commit
|
|
205
230
|
*/
|
|
206
231
|
export function listFiles(dir) {
|
|
207
232
|
const filesList = [];
|
|
208
|
-
const output = execGitCommand(dir, [
|
|
209
|
-
"ls-tree",
|
|
210
|
-
"-l",
|
|
211
|
-
"-r",
|
|
212
|
-
"--full-tree",
|
|
213
|
-
"HEAD",
|
|
214
|
-
]);
|
|
233
|
+
const output = execGitCommand(dir, ["ls-tree", "-l", "-r", "HEAD"]);
|
|
215
234
|
if (output) {
|
|
216
235
|
output.split("\n").forEach((l) => {
|
|
217
236
|
l = l.replaceAll("\r", "");
|
|
@@ -239,7 +258,10 @@ export function listFiles(dir) {
|
|
|
239
258
|
* @param {string} dir Repo directory
|
|
240
259
|
* @param {Array} args arguments to git command
|
|
241
260
|
*
|
|
242
|
-
* @returns
|
|
261
|
+
* @returns {string|undefined} git's standard output, or undefined when git
|
|
262
|
+
* could not run or exited with a non-zero status. Text git writes to standard
|
|
263
|
+
* error, including warnings of a successful command, is never part of the
|
|
264
|
+
* result.
|
|
243
265
|
*/
|
|
244
266
|
export function execGitCommand(dir, args) {
|
|
245
267
|
// Prepend hardening `-c` overrides before the subcommand and run git with a
|
|
@@ -256,6 +278,8 @@ export function execGitCommand(dir, args) {
|
|
|
256
278
|
{
|
|
257
279
|
env: hardenedGitEnv(),
|
|
258
280
|
shell: false,
|
|
281
|
+
requireSuccess: true,
|
|
282
|
+
includeStderr: false,
|
|
259
283
|
},
|
|
260
284
|
);
|
|
261
285
|
}
|
|
@@ -393,6 +417,22 @@ function recordToolProbeFailure(tool, ecosystem, command, detail) {
|
|
|
393
417
|
}
|
|
394
418
|
}
|
|
395
419
|
|
|
420
|
+
/**
|
|
421
|
+
* Collapse command output to one line. The `\r` of a Windows line ending goes
|
|
422
|
+
* with the break it belongs to, and the empty lines of trailing output are
|
|
423
|
+
* dropped.
|
|
424
|
+
*
|
|
425
|
+
* @param {string} output command output
|
|
426
|
+
* @param {string} separator what to join the lines with
|
|
427
|
+
* @returns {string} the non-empty lines joined into one line
|
|
428
|
+
*/
|
|
429
|
+
function collapseOutputLines(output, separator) {
|
|
430
|
+
return `${output || ""}`
|
|
431
|
+
.split(/\r?\n/)
|
|
432
|
+
.filter((line) => line !== "")
|
|
433
|
+
.join(separator);
|
|
434
|
+
}
|
|
435
|
+
|
|
396
436
|
/**
|
|
397
437
|
* Collect Java version and installed modules
|
|
398
438
|
*
|
|
@@ -400,9 +440,9 @@ function recordToolProbeFailure(tool, ecosystem, command, detail) {
|
|
|
400
440
|
* @returns Object containing the java details
|
|
401
441
|
*/
|
|
402
442
|
export function collectJavaInfo(dir) {
|
|
403
|
-
const versionDesc =
|
|
443
|
+
const versionDesc = probeCommandOutput(getJavaCommand(), dir, ["--version"]);
|
|
404
444
|
const moduleDesc =
|
|
405
|
-
|
|
445
|
+
probeCommandOutput(getJavaCommand(), dir, ["--list-modules"]) || "";
|
|
406
446
|
if (versionDesc) {
|
|
407
447
|
const info = {
|
|
408
448
|
type: "platform",
|
|
@@ -412,7 +452,7 @@ export function collectJavaInfo(dir) {
|
|
|
412
452
|
properties: [
|
|
413
453
|
{
|
|
414
454
|
name: "java:modules",
|
|
415
|
-
value: moduleDesc
|
|
455
|
+
value: collapseOutputLines(moduleDesc, ", "),
|
|
416
456
|
},
|
|
417
457
|
],
|
|
418
458
|
};
|
|
@@ -426,20 +466,41 @@ export function collectJavaInfo(dir) {
|
|
|
426
466
|
/**
|
|
427
467
|
* Collect dotnet version
|
|
428
468
|
*
|
|
469
|
+
* `version` is the version `dotnet --version` prints, which is the SDK's. .NET
|
|
470
|
+
* advisories name runtime versions, so the component itself carries no purl
|
|
471
|
+
* and no CPE. Each shared framework `dotnet --list-runtimes` reports is a
|
|
472
|
+
* nested component built by createHostDotnetRuntimeComponent, without a
|
|
473
|
+
* bom-ref like the other toolchains.
|
|
474
|
+
*
|
|
429
475
|
* @param {string} dir Working directory
|
|
430
476
|
* @returns Object containing dotnet details
|
|
431
477
|
*/
|
|
432
478
|
export function collectDotnetInfo(dir) {
|
|
433
|
-
const versionDesc =
|
|
479
|
+
const versionDesc = probeCommandOutput(DOTNET_CMD, dir, ["--version"]);
|
|
434
480
|
const moduleDesc =
|
|
435
|
-
|
|
481
|
+
probeCommandOutput(DOTNET_CMD, dir, ["--list-runtimes"]) || "";
|
|
436
482
|
if (versionDesc) {
|
|
437
483
|
const info = {
|
|
438
484
|
type: "platform",
|
|
439
485
|
name: "dotnet",
|
|
440
486
|
version: versionDesc.trim(),
|
|
441
|
-
description: moduleDesc
|
|
487
|
+
description: collapseOutputLines(moduleDesc, "\\n"),
|
|
442
488
|
};
|
|
489
|
+
const components = [];
|
|
490
|
+
const seen = new Set();
|
|
491
|
+
for (const entry of parseDotnetListRuntimes(moduleDesc)) {
|
|
492
|
+
const key = `${entry.framework} ${entry.version}`;
|
|
493
|
+
if (seen.has(key)) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
seen.add(key);
|
|
497
|
+
components.push(
|
|
498
|
+
formulationToolchain(createHostDotnetRuntimeComponent(entry)),
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
if (components.length) {
|
|
502
|
+
info.components = components;
|
|
503
|
+
}
|
|
443
504
|
recordToolProbeResolved("dotnet", "csharp", info.version);
|
|
444
505
|
return info;
|
|
445
506
|
}
|
|
@@ -455,15 +516,15 @@ export function collectDotnetInfo(dir) {
|
|
|
455
516
|
*/
|
|
456
517
|
export function collectPythonInfo(dir) {
|
|
457
518
|
const pythonCmd = getPythonCommand();
|
|
458
|
-
const versionDesc =
|
|
519
|
+
const versionDesc = probeCommandOutput(pythonCmd, dir, ["-S", "--version"]);
|
|
459
520
|
const moduleDesc =
|
|
460
|
-
|
|
521
|
+
probeCommandOutput(pythonCmd, dir, ["-I", "-m", "pip", "--version"]) || "";
|
|
461
522
|
if (versionDesc) {
|
|
462
523
|
const info = {
|
|
463
524
|
type: "platform",
|
|
464
525
|
name: "python",
|
|
465
526
|
version: versionDesc.replace("Python ", ""),
|
|
466
|
-
description: moduleDesc
|
|
527
|
+
description: collapseOutputLines(moduleDesc, "\\n"),
|
|
467
528
|
};
|
|
468
529
|
recordToolProbeResolved("python", "python", info.version);
|
|
469
530
|
return info;
|
|
@@ -486,7 +547,17 @@ export function collectNodeInfo(dir) {
|
|
|
486
547
|
version: runtimeInfo.version,
|
|
487
548
|
components: runtimeInfo.components,
|
|
488
549
|
};
|
|
489
|
-
|
|
550
|
+
if (runtimeInfo.runtime === "Node.js" && runtimeInfo.version) {
|
|
551
|
+
// The same identity a scanned image's Node.js gets, without a bom-ref, as
|
|
552
|
+
// for the other toolchains.
|
|
553
|
+
const runtime = formulationToolchain(
|
|
554
|
+
createNodeRuntimeComponent(runtimeInfo.version),
|
|
555
|
+
);
|
|
556
|
+
nodeInfo.purl = runtime.purl;
|
|
557
|
+
nodeInfo.cpe = runtime.cpe;
|
|
558
|
+
annotateNodeBrotli(nodeInfo.components);
|
|
559
|
+
}
|
|
560
|
+
const moduleDesc = probeCommandOutput(NPM_CMD, dir, ["--version"]);
|
|
490
561
|
if (moduleDesc) {
|
|
491
562
|
nodeInfo.description = `npm: ${moduleDesc}`;
|
|
492
563
|
recordToolProbeResolved("npm", "npm", moduleDesc);
|
|
@@ -496,6 +567,36 @@ export function collectNodeInfo(dir) {
|
|
|
496
567
|
return nodeInfo;
|
|
497
568
|
}
|
|
498
569
|
|
|
570
|
+
/**
|
|
571
|
+
* Record whether the Brotli decoder the running Node.js uses carries the
|
|
572
|
+
* CVE-2026-111497 fix. process.versions.brotli cannot say: Node.js backports
|
|
573
|
+
* the fix without changing it. The decoder is read where it lives, in the node
|
|
574
|
+
* binary or in the shared libbrotlidec a `--shared-brotli` build loads.
|
|
575
|
+
*
|
|
576
|
+
* @param {Object[]|undefined} components bundled components of the runtime
|
|
577
|
+
*/
|
|
578
|
+
function annotateNodeBrotli(components) {
|
|
579
|
+
const brotli = (components || []).find(
|
|
580
|
+
(component) => component.name === "brotli",
|
|
581
|
+
);
|
|
582
|
+
if (!brotli) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
let decoderFile = globalThis.process?.execPath;
|
|
586
|
+
if (nodeComponentLinkage("brotli") === "shared") {
|
|
587
|
+
decoderFile = (
|
|
588
|
+
globalThis.process?.report?.getReport?.()?.sharedObjects || []
|
|
589
|
+
).find((path) => basename(path).startsWith("libbrotlidec"));
|
|
590
|
+
}
|
|
591
|
+
const decoder = decoderFile ? readBrotliDecoder(decoderFile) : undefined;
|
|
592
|
+
if (decoder) {
|
|
593
|
+
brotli.properties = [
|
|
594
|
+
...(brotli.properties || []),
|
|
595
|
+
...brotliDecoderProperties(decoder),
|
|
596
|
+
];
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
499
600
|
/**
|
|
500
601
|
* Collect gcc version
|
|
501
602
|
*
|
|
@@ -503,14 +604,14 @@ export function collectNodeInfo(dir) {
|
|
|
503
604
|
* @returns Object containing gcc details
|
|
504
605
|
*/
|
|
505
606
|
export function collectGccInfo(dir) {
|
|
506
|
-
const versionDesc =
|
|
507
|
-
const moduleDesc =
|
|
607
|
+
const versionDesc = probeCommandOutput(GCC_CMD, dir, ["--version"]);
|
|
608
|
+
const moduleDesc = probeCommandOutput(GCC_CMD, dir, ["-print-search-dirs"]);
|
|
508
609
|
if (versionDesc) {
|
|
509
610
|
const info = {
|
|
510
611
|
type: "platform",
|
|
511
612
|
name: "gcc",
|
|
512
613
|
version: versionDesc.split("\n")[0],
|
|
513
|
-
description: (moduleDesc
|
|
614
|
+
description: collapseOutputLines(moduleDesc, "\\n"),
|
|
514
615
|
};
|
|
515
616
|
recordToolProbeResolved("gcc", "c", info.version);
|
|
516
617
|
return info;
|
|
@@ -526,8 +627,8 @@ export function collectGccInfo(dir) {
|
|
|
526
627
|
* @returns Object containing rust details
|
|
527
628
|
*/
|
|
528
629
|
export function collectRustInfo(dir) {
|
|
529
|
-
const versionDesc =
|
|
530
|
-
const moduleDesc =
|
|
630
|
+
const versionDesc = probeCommandOutput(RUSTC_CMD, dir, ["--version"]);
|
|
631
|
+
const moduleDesc = probeCommandOutput(CARGO_CMD, dir, ["--version"]);
|
|
531
632
|
if (versionDesc) {
|
|
532
633
|
const info = {
|
|
533
634
|
type: "platform",
|
|
@@ -549,7 +650,7 @@ export function collectRustInfo(dir) {
|
|
|
549
650
|
* @returns Object containing go details
|
|
550
651
|
*/
|
|
551
652
|
export function collectGoInfo(dir) {
|
|
552
|
-
const versionDesc =
|
|
653
|
+
const versionDesc = probeCommandOutput(GO_CMD, dir, ["version"]);
|
|
553
654
|
if (versionDesc) {
|
|
554
655
|
const info = {
|
|
555
656
|
type: "platform",
|
|
@@ -570,7 +671,7 @@ export function collectGoInfo(dir) {
|
|
|
570
671
|
* @returns Object containing swift details
|
|
571
672
|
*/
|
|
572
673
|
export function collectSwiftInfo(dir) {
|
|
573
|
-
const versionDesc =
|
|
674
|
+
const versionDesc = probeCommandOutput(SWIFT_CMD, dir, ["--version"]);
|
|
574
675
|
if (versionDesc) {
|
|
575
676
|
const info = {
|
|
576
677
|
type: "platform",
|
|
@@ -585,23 +686,217 @@ export function collectSwiftInfo(dir) {
|
|
|
585
686
|
}
|
|
586
687
|
|
|
587
688
|
/**
|
|
588
|
-
*
|
|
689
|
+
* The real path of the executable a command name runs, looked up on PATH as
|
|
690
|
+
* the shell would, or undefined when it cannot be found.
|
|
691
|
+
*
|
|
692
|
+
* @param {string} command command name or path
|
|
693
|
+
* @returns {string|undefined}
|
|
694
|
+
*/
|
|
695
|
+
function resolveExecutable(command) {
|
|
696
|
+
const name = `${command || ""}`.trim().split(" ")[0];
|
|
697
|
+
if (!name) {
|
|
698
|
+
return undefined;
|
|
699
|
+
}
|
|
700
|
+
const extensions = isWin
|
|
701
|
+
? ["", ...`${process.env.PATHEXT || ".EXE;.CMD;.BAT"}`.split(";")]
|
|
702
|
+
: [""];
|
|
703
|
+
const directories = isAbsolute(name)
|
|
704
|
+
? [dirname(name)]
|
|
705
|
+
: `${process.env.PATH || ""}`.split(delimiter).filter(Boolean);
|
|
706
|
+
const base = isAbsolute(name) ? basename(name) : name;
|
|
707
|
+
for (const directory of directories) {
|
|
708
|
+
for (const extension of extensions) {
|
|
709
|
+
const candidate = join(directory, `${base}${extension}`);
|
|
710
|
+
try {
|
|
711
|
+
if (statSync(candidate).isFile()) {
|
|
712
|
+
return realpathSync(candidate);
|
|
713
|
+
}
|
|
714
|
+
} catch {
|
|
715
|
+
// not here
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return undefined;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Whether a Ruby executable is one the operating system or a package manager
|
|
724
|
+
* that patches it owns. Distros backport fixes under the old upstream version,
|
|
725
|
+
* so its version must not be matched against upstream advisories by CPE.
|
|
726
|
+
*
|
|
727
|
+
* @param {string|undefined} realPath real path of the executable
|
|
728
|
+
* @returns {boolean}
|
|
729
|
+
*/
|
|
730
|
+
export function isPackagedRubyPath(realPath) {
|
|
731
|
+
if (!realPath || isWin) {
|
|
732
|
+
return false;
|
|
733
|
+
}
|
|
734
|
+
// Homebrew builds the upstream release, so it keeps the CPE, as it does in
|
|
735
|
+
// an OBOM; Nix and Guix patch theirs.
|
|
736
|
+
const store = packageStoreOf(realPath);
|
|
737
|
+
if (store) {
|
|
738
|
+
return store !== "homebrew";
|
|
739
|
+
}
|
|
740
|
+
return ["/usr/bin/", "/bin/", "/usr/lib/", "/usr/libexec/", "/System/"].some(
|
|
741
|
+
(prefix) => realPath.startsWith(prefix),
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// The shims of rbenv, asdf and mise run whichever Ruby is selected, which can
|
|
746
|
+
// be the distro's (`rbenv global system`).
|
|
747
|
+
function isVersionManagerShim(realPath) {
|
|
748
|
+
return `${realPath}`.split(/[\\/]/).includes("shims");
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Whether the Ruby `ruby --version` described may carry its release's CPE.
|
|
752
|
+
// A shim is followed to the interpreter it runs; one that cannot be followed
|
|
753
|
+
// keeps no CPE, since it may be the distro's.
|
|
754
|
+
function rubyKeepsCpe(dir) {
|
|
755
|
+
let executable = resolveExecutable(RUBY_CMD);
|
|
756
|
+
if (executable && isVersionManagerShim(executable)) {
|
|
757
|
+
const target = isWin
|
|
758
|
+
? ""
|
|
759
|
+
: firstOutputLine(
|
|
760
|
+
probeCommandOutput(RUBY_CMD, dir, ["-e", "print RbConfig.ruby"]),
|
|
761
|
+
);
|
|
762
|
+
if (!isAbsolute(target)) {
|
|
763
|
+
return false;
|
|
764
|
+
}
|
|
765
|
+
try {
|
|
766
|
+
executable = realpathSync(target);
|
|
767
|
+
} catch {
|
|
768
|
+
executable = target;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return !isPackagedRubyPath(executable);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Collect the Ruby on the PATH.
|
|
776
|
+
*
|
|
777
|
+
* `ruby --version` prints the interpreter's description, such as
|
|
778
|
+
* `ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [x86_64-linux]`, which is kept
|
|
779
|
+
* as the component description. The identity is `pkg:generic/ruby@3.3.6`
|
|
780
|
+
* (or jruby, truffleruby), with the CPE of the release unless a package
|
|
781
|
+
* manager owns the executable: a distro backports fixes under the old upstream
|
|
782
|
+
* version.
|
|
589
783
|
*
|
|
590
784
|
* @param {string} dir Working directory
|
|
591
785
|
* @returns Object containing Ruby details
|
|
592
786
|
*/
|
|
593
787
|
export function collectRubyInfo(dir) {
|
|
594
|
-
const versionDesc =
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
version
|
|
600
|
-
|
|
601
|
-
|
|
788
|
+
const versionDesc = probeCommandOutput(RUBY_CMD, dir, ["--version"]);
|
|
789
|
+
const banner = firstOutputLine(versionDesc);
|
|
790
|
+
const parsed = parseRubyDescription(banner);
|
|
791
|
+
if (parsed) {
|
|
792
|
+
const info = formulationToolchain(
|
|
793
|
+
createRubyRuntimeComponent(parsed.version, {
|
|
794
|
+
engine: parsed.engine,
|
|
795
|
+
withCpe: rubyKeepsCpe(dir),
|
|
796
|
+
}),
|
|
797
|
+
);
|
|
798
|
+
info.description = banner;
|
|
799
|
+
const properties = [];
|
|
800
|
+
if (parsed.patchlevel !== undefined) {
|
|
801
|
+
properties.push({
|
|
802
|
+
name: "cdx:ruby:patchlevel",
|
|
803
|
+
value: parsed.patchlevel,
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
if (parsed.rubyVersion) {
|
|
807
|
+
properties.push({
|
|
808
|
+
name: "cdx:ruby:languageVersion",
|
|
809
|
+
value: parsed.rubyVersion,
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
if (parsed.platform) {
|
|
813
|
+
properties.push({ name: "cdx:ruby:platform", value: parsed.platform });
|
|
814
|
+
}
|
|
815
|
+
if (properties.length) {
|
|
816
|
+
info.properties = properties;
|
|
817
|
+
}
|
|
818
|
+
recordToolProbeResolved("ruby", "ruby", banner);
|
|
602
819
|
return info;
|
|
603
820
|
}
|
|
604
|
-
recordToolProbeFailure(
|
|
821
|
+
recordToolProbeFailure(
|
|
822
|
+
"ruby",
|
|
823
|
+
"ruby",
|
|
824
|
+
RUBY_CMD,
|
|
825
|
+
versionDesc
|
|
826
|
+
? "The ruby version probe did not print a Ruby version banner."
|
|
827
|
+
: undefined,
|
|
828
|
+
);
|
|
829
|
+
return undefined;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Whether the Ruby collectRubyInfo found is the MRI release a project needs.
|
|
834
|
+
*
|
|
835
|
+
* @param {Object|undefined} info result of collectRubyInfo
|
|
836
|
+
* @param {string} version wanted MRI version
|
|
837
|
+
* @returns {boolean}
|
|
838
|
+
*/
|
|
839
|
+
export function isRubyVersionActive(info, version) {
|
|
840
|
+
return Boolean(info && info.name === "ruby" && info.version === version);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Collect the RubyGems version. `gem --version` prints the bare version.
|
|
845
|
+
*
|
|
846
|
+
* @param {string} dir Working directory
|
|
847
|
+
* @returns {Object|undefined} the RubyGems component
|
|
848
|
+
*/
|
|
849
|
+
export function collectRubyGemsInfo(dir) {
|
|
850
|
+
const token = firstOutputLine(
|
|
851
|
+
probeCommandOutput(GEM_CMD, dir, ["--version"]),
|
|
852
|
+
);
|
|
853
|
+
if (/^\d+\.\d+\.\d+$/.test(token)) {
|
|
854
|
+
recordToolProbeResolved("gem", "ruby", token);
|
|
855
|
+
return formulationToolchain(
|
|
856
|
+
applyPurl(
|
|
857
|
+
{
|
|
858
|
+
type: "platform",
|
|
859
|
+
name: "rubygems",
|
|
860
|
+
version: token,
|
|
861
|
+
cpe: `cpe:2.3:a:rubygems:rubygems:${token}:*:*:*:*:*:*:*`,
|
|
862
|
+
},
|
|
863
|
+
tryBuildPurl({ type: "generic", name: "rubygems", version: token }),
|
|
864
|
+
),
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
recordToolProbeFailure("gem", "ruby", GEM_CMD);
|
|
868
|
+
return undefined;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Collect the Bundler version. `bundle --version` prints `Bundler version
|
|
873
|
+
* 2.5.22`, or the bare version from Bundler 2.6 on.
|
|
874
|
+
*
|
|
875
|
+
* @param {string} dir Working directory
|
|
876
|
+
* @returns {Object|undefined} the Bundler component
|
|
877
|
+
*/
|
|
878
|
+
export function collectBundlerInfo(dir) {
|
|
879
|
+
const line = firstOutputLine(
|
|
880
|
+
probeCommandOutput(BUNDLE_CMD, dir, ["--version"]),
|
|
881
|
+
);
|
|
882
|
+
const token = line.startsWith("Bundler version ")
|
|
883
|
+
? line.slice("Bundler version ".length).trim()
|
|
884
|
+
: line;
|
|
885
|
+
if (/^\d+\.\d+\.\d+$/.test(token)) {
|
|
886
|
+
recordToolProbeResolved("bundler", "ruby", token);
|
|
887
|
+
return formulationToolchain(
|
|
888
|
+
applyPurl(
|
|
889
|
+
{
|
|
890
|
+
type: "platform",
|
|
891
|
+
name: "bundler",
|
|
892
|
+
version: token,
|
|
893
|
+
cpe: `cpe:2.3:a:bundler:bundler:${token}:*:*:*:*:*:*:*`,
|
|
894
|
+
},
|
|
895
|
+
tryBuildPurl({ type: "gem", name: "bundler", version: token }),
|
|
896
|
+
),
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
recordToolProbeFailure("bundler", "ruby", BUNDLE_CMD);
|
|
605
900
|
return undefined;
|
|
606
901
|
}
|
|
607
902
|
|
|
@@ -646,7 +941,7 @@ function formulationToolchain(component) {
|
|
|
646
941
|
* @returns Object containing the PHP details
|
|
647
942
|
*/
|
|
648
943
|
export function collectPhpInfo(dir) {
|
|
649
|
-
const output =
|
|
944
|
+
const output = probeCommandOutput(PHP_CMD, dir, ["-n", "-v"]);
|
|
650
945
|
const banner = firstOutputLine(output);
|
|
651
946
|
const reported = banner.startsWith("PHP ")
|
|
652
947
|
? parsePhpReportedVersion(banner.slice("PHP ".length))
|
|
@@ -688,7 +983,7 @@ export function collectPhpInfo(dir) {
|
|
|
688
983
|
* @returns Object containing the Composer details
|
|
689
984
|
*/
|
|
690
985
|
export function collectComposerInfo(dir) {
|
|
691
|
-
const output =
|
|
986
|
+
const output = probeCommandOutput(COMPOSER_CMD, dir, [
|
|
692
987
|
"--version",
|
|
693
988
|
"--no-plugins",
|
|
694
989
|
"--no-scripts",
|
|
@@ -787,6 +1082,14 @@ export function collectEnvInfo(dir, options = undefined) {
|
|
|
787
1082
|
cmp = collectRubyInfo(dir);
|
|
788
1083
|
if (cmp) {
|
|
789
1084
|
infoComponents.push(cmp);
|
|
1085
|
+
cmp = collectRubyGemsInfo(dir);
|
|
1086
|
+
if (cmp) {
|
|
1087
|
+
infoComponents.push(cmp);
|
|
1088
|
+
}
|
|
1089
|
+
cmp = collectBundlerInfo(dir);
|
|
1090
|
+
if (cmp) {
|
|
1091
|
+
infoComponents.push(cmp);
|
|
1092
|
+
}
|
|
790
1093
|
}
|
|
791
1094
|
cmp = collectPhpInfo(dir);
|
|
792
1095
|
if (cmp) {
|
|
@@ -799,16 +1102,55 @@ export function collectEnvInfo(dir, options = undefined) {
|
|
|
799
1102
|
return infoComponents;
|
|
800
1103
|
}
|
|
801
1104
|
|
|
1105
|
+
/**
|
|
1106
|
+
* Longest a toolchain version probe may run. A `--version` call answers in
|
|
1107
|
+
* well under a second; a tool that sets itself up on first use, such as
|
|
1108
|
+
* dotnet or gem in a fresh home directory, or one that waits on a prompt,
|
|
1109
|
+
* must not hold up a scan for the general spawn timeout.
|
|
1110
|
+
*/
|
|
1111
|
+
const VERSION_PROBE_TIMEOUT_MS = 60000;
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Run a toolchain version probe with VERSION_PROBE_TIMEOUT_MS as its limit.
|
|
1115
|
+
*
|
|
1116
|
+
* A probe that fails gives no output. Its text is then an error message, not
|
|
1117
|
+
* a version: `dotnet --version` under a global.json that pins an SDK the host
|
|
1118
|
+
* lacks exits with an error and lists every installed SDK, which would
|
|
1119
|
+
* otherwise become the version of the dotnet component in the formulation.
|
|
1120
|
+
*
|
|
1121
|
+
* @param {string} cmd Command to execute
|
|
1122
|
+
* @param {string} dir Working directory
|
|
1123
|
+
* @param {string[]} args Arguments
|
|
1124
|
+
* @returns {string|undefined} Output of the command, or undefined when it
|
|
1125
|
+
* could not run or exited with a non-zero status
|
|
1126
|
+
*/
|
|
1127
|
+
const probeCommandOutput = (cmd, dir, args) =>
|
|
1128
|
+
getCommandOutput(cmd, dir, args, {
|
|
1129
|
+
requireSuccess: true,
|
|
1130
|
+
timeout: VERSION_PROBE_TIMEOUT_MS,
|
|
1131
|
+
});
|
|
1132
|
+
|
|
802
1133
|
/**
|
|
803
1134
|
* Execute any command to retrieve the output
|
|
804
1135
|
*
|
|
805
1136
|
* @param {*} cmd Command to execute
|
|
806
1137
|
* @param {*} dir working directory
|
|
807
1138
|
* @param {*} args arguments
|
|
808
|
-
* @param {Object} [
|
|
809
|
-
*
|
|
1139
|
+
* @param {Object} [options] extra options merged into spawnSync (e.g. env),
|
|
1140
|
+
* plus `requireSuccess`, which gives undefined for a command that exits with
|
|
1141
|
+
* a non-zero status, and `includeStderr`, which joins the command's standard
|
|
1142
|
+
* error into the result (the default). With `includeStderr` false only the
|
|
1143
|
+
* standard output is returned, so text a command writes to standard error
|
|
1144
|
+
* cannot reach a parser of its output.
|
|
1145
|
+
* @returns {string|undefined} Output of the command, or undefined when it
|
|
1146
|
+
* could not run or printed nothing
|
|
810
1147
|
*/
|
|
811
|
-
const getCommandOutput = (cmd, dir, args,
|
|
1148
|
+
const getCommandOutput = (cmd, dir, args, options = {}) => {
|
|
1149
|
+
const {
|
|
1150
|
+
requireSuccess = false,
|
|
1151
|
+
includeStderr = true,
|
|
1152
|
+
...spawnOverrides
|
|
1153
|
+
} = options;
|
|
812
1154
|
let commandToUse = cmd;
|
|
813
1155
|
// If the command includes space, automatically move it to the front of the args.
|
|
814
1156
|
if (cmd?.trim().includes(" ")) {
|
|
@@ -837,7 +1179,13 @@ const getCommandOutput = (cmd, dir, args, spawnOverrides = {}) => {
|
|
|
837
1179
|
maxBuffer: MAX_BUFFER * 2,
|
|
838
1180
|
...spawnOverrides,
|
|
839
1181
|
});
|
|
1182
|
+
if (requireSuccess && (result.error || result.status !== 0)) {
|
|
1183
|
+
return undefined;
|
|
1184
|
+
}
|
|
840
1185
|
const stdout = result.stdout ? result.stdout.toString() : "";
|
|
1186
|
+
if (!includeStderr) {
|
|
1187
|
+
return stdout.trim() || undefined;
|
|
1188
|
+
}
|
|
841
1189
|
const stderr = result.stderr ? result.stderr.toString() : "";
|
|
842
1190
|
return `${stdout}\n${stderr}`.trim() || undefined;
|
|
843
1191
|
};
|
|
@@ -1218,7 +1566,7 @@ export function installRubyVersion(rubyVersion, filePath) {
|
|
|
1218
1566
|
return { fullToolBinDir: undefined, status: false };
|
|
1219
1567
|
}
|
|
1220
1568
|
const existingRuby = collectRubyInfo(filePath);
|
|
1221
|
-
if (existingRuby
|
|
1569
|
+
if (isRubyVersionActive(existingRuby, rubyVersion)) {
|
|
1222
1570
|
return { fullToolBinDir: undefined, status: true };
|
|
1223
1571
|
}
|
|
1224
1572
|
const fullToolBinDir = rubyVersionDir(rubyVersion);
|
|
@@ -1984,6 +2332,36 @@ export function gitRevertsAndHotfixes(dir, maxCount = 20) {
|
|
|
1984
2332
|
return entries;
|
|
1985
2333
|
}
|
|
1986
2334
|
|
|
2335
|
+
// process.versions keys whose configure flag is named differently.
|
|
2336
|
+
const NODE_SHARED_FLAG_NAMES = {
|
|
2337
|
+
ares: "cares",
|
|
2338
|
+
libffi: "ffi",
|
|
2339
|
+
llhttp: "http_parser",
|
|
2340
|
+
uv: "libuv",
|
|
2341
|
+
};
|
|
2342
|
+
|
|
2343
|
+
/**
|
|
2344
|
+
* Whether the running Node.js links a bundled dependency as a shared library,
|
|
2345
|
+
* from the `node_shared_<name>` configure variables it reports.
|
|
2346
|
+
*
|
|
2347
|
+
* @param {string} name key of process.versions
|
|
2348
|
+
* @param {Object} [variables] configure variables, process.config.variables
|
|
2349
|
+
* by default
|
|
2350
|
+
* @returns {string|undefined} `shared`, `bundled`, or undefined when the build
|
|
2351
|
+
* does not say
|
|
2352
|
+
*/
|
|
2353
|
+
export function nodeComponentLinkage(
|
|
2354
|
+
name,
|
|
2355
|
+
variables = globalThis.process?.config?.variables,
|
|
2356
|
+
) {
|
|
2357
|
+
const flag = `node_shared_${NODE_SHARED_FLAG_NAMES[name] || name}`;
|
|
2358
|
+
if (!variables || !(flag in variables)) {
|
|
2359
|
+
return undefined;
|
|
2360
|
+
}
|
|
2361
|
+
const value = variables[flag];
|
|
2362
|
+
return value === true || value === "true" ? "shared" : "bundled";
|
|
2363
|
+
}
|
|
2364
|
+
|
|
1987
2365
|
/**
|
|
1988
2366
|
* Get information about the runtime.
|
|
1989
2367
|
*
|
|
@@ -2016,12 +2394,22 @@ export function getRuntimeInformation() {
|
|
|
2016
2394
|
name,
|
|
2017
2395
|
version: version || null,
|
|
2018
2396
|
});
|
|
2397
|
+
// A distro or Homebrew build links some of these as shared libraries
|
|
2398
|
+
// (`configure --shared-brotli`); the version is then the shared
|
|
2399
|
+
// library's, and updating Node.js alone does not update it.
|
|
2400
|
+
const linkage = nodeComponentLinkage(name);
|
|
2019
2401
|
const apkg = {
|
|
2020
2402
|
name,
|
|
2021
2403
|
version,
|
|
2022
|
-
description:
|
|
2404
|
+
description:
|
|
2405
|
+
linkage === "shared"
|
|
2406
|
+
? `Linked by Node.js ${runtimeInfo.version} as a shared library`
|
|
2407
|
+
: `Bundled with Node.js ${runtimeInfo.version}`,
|
|
2023
2408
|
type: "library",
|
|
2024
2409
|
scope: "excluded",
|
|
2410
|
+
...(linkage
|
|
2411
|
+
? { properties: [{ name: "cdx:node:linkage", value: linkage }] }
|
|
2412
|
+
: {}),
|
|
2025
2413
|
};
|
|
2026
2414
|
applyPurl(apkg, bundledPurl);
|
|
2027
2415
|
if (nodeSourceUrl) {
|