@cdxgen/cdxgen 13.3.0 → 13.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +115 -31
- package/bin/evinse.js +23 -1
- package/bin/hbom.js +15 -7
- package/bin/repl.js +115 -0
- package/bin/sign.js +45 -15
- package/bin/tracebom.js +5 -1
- package/bin/validate.js +84 -18
- package/bin/verify.js +155 -86
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/helpers/init.gradle +46 -21
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +344 -1
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/dependency-sources.yaml +67 -0
- 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/scala-evidence.yaml +115 -0
- package/lib/audit/index.js +52 -6
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +186 -58
- package/lib/cli/jsBom.js +50 -29
- package/lib/cli/jvmBom.js +779 -146
- package/lib/cli/managedBom.js +1021 -261
- package/lib/cli/nativeBom.js +364 -58
- package/lib/core/activity.js +12 -0
- package/lib/core/env.js +47 -17
- package/lib/core/fs.js +31 -21
- package/lib/core/httpClient.js +233 -69
- package/lib/core/pluginRun.js +184 -0
- package/lib/core/processTree.js +100 -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/runState.js +39 -0
- package/lib/core/toml.js +72 -0
- package/lib/ecosystems/asarutils.js +4 -2
- package/lib/ecosystems/bunutils.js +5 -7
- package/lib/ecosystems/cargoCache.js +231 -8
- package/lib/ecosystems/cmakeResolver.js +10 -21
- package/lib/ecosystems/cppBuildContext.js +631 -0
- package/lib/ecosystems/cppEvidence.js +337 -22
- package/lib/ecosystems/cppIncludeResolver.js +294 -0
- package/lib/ecosystems/denoutils.js +93 -66
- package/lib/ecosystems/ecosystems.js +1967 -788
- package/lib/ecosystems/golem.js +578 -18
- package/lib/ecosystems/gradleutils.js +340 -46
- package/lib/ecosystems/jsEvidence.js +85 -24
- package/lib/ecosystems/kosi.js +21 -4
- package/lib/ecosystems/npmutils.js +64 -0
- package/lib/ecosystems/parsers-dotnet.js +668 -153
- package/lib/ecosystems/parsers-elm.js +46 -28
- package/lib/ecosystems/parsers-gleam.js +3 -4
- package/lib/ecosystems/parsers-go.js +1283 -297
- package/lib/ecosystems/parsers-js.js +92 -26
- package/lib/ecosystems/parsers-julia.js +2 -3
- package/lib/ecosystems/parsers-jvm.js +463 -29
- package/lib/ecosystems/parsers-misc.js +405 -93
- package/lib/ecosystems/parsers-python.js +152 -20
- package/lib/ecosystems/parsers-rust.js +4 -4
- package/lib/ecosystems/parsers-terraform.js +1573 -19
- package/lib/ecosystems/pythonutils.js +102 -6
- package/lib/ecosystems/remote/huggingface.js +3 -0
- package/lib/ecosystems/rubyutils.js +73 -20
- package/lib/ecosystems/rusi.js +32 -9
- package/lib/ecosystems/sbtutils.js +243 -187
- package/lib/ecosystems/scalacliutils.js +343 -0
- package/lib/ecosystems/scalasem.js +2620 -0
- package/lib/ecosystems/terraformRegistry.js +288 -0
- package/lib/ecosystems/utils.js +2 -0
- package/lib/ecosystems/vendoredCode.js +156 -0
- package/lib/evinser/evinser.js +695 -78
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +2 -2
- package/lib/helpers/bomSigner.js +576 -128
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/aiCollector.js +4 -1
- package/lib/inventory/analyzer.js +110 -127
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +204 -48
- package/lib/inventory/auditCategories.js +10 -3
- package/lib/inventory/buildToolRateLimit.js +144 -0
- package/lib/inventory/cacheCommands.js +2 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/cmakeBuildDirs.js +254 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +507 -128
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +747 -101
- package/lib/inventory/dosaiParsers.js +310 -15
- package/lib/inventory/dynamic.js +96 -8
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +590 -132
- package/lib/inventory/fetchBatch.js +574 -38
- package/lib/inventory/fetchDiskCache.js +597 -0
- package/lib/inventory/forgeEnricher.js +14 -5
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +917 -0
- package/lib/inventory/mcpConfigParser.js +2 -3
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/parentSelection.js +146 -0
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rustFormulationParser.js +3 -4
- package/lib/inventory/scalaCoords.js +153 -0
- package/lib/inventory/source.js +215 -11
- package/lib/inventory/spdx.js +245 -0
- package/lib/inventory/traceRunner.js +93 -8
- package/lib/inventory/tracedCrypto.js +423 -0
- package/lib/managers/binary.js +529 -183
- package/lib/managers/docker.js +199 -44
- package/lib/managers/oci.js +24 -2
- package/lib/parsers/cmakeCache.js +69 -0
- package/lib/parsers/cmakeLists.js +16 -2
- package/lib/parsers/cmakePresets.js +400 -0
- package/lib/parsers/compileCommands.js +557 -0
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/parsers/strictJson.js +322 -0
- package/lib/parsers/terraformConfig.js +1073 -0
- package/lib/parsers/terraformSource.js +652 -0
- package/lib/server/server.js +209 -1
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/markers.js +1 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +20 -6
- package/lib/stages/postgen/ruleEngine.js +58 -1
- package/lib/stages/postgen/specVersionCompat.js +62 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/lib/validator/index.js +25 -10
- package/lib/validator/reporters/json.js +1 -0
- package/package.json +23 -23
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +9 -2
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +44 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +7 -4
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +3 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +27 -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 +13 -8
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/pluginRun.d.ts +97 -0
- package/types/lib/core/pluginRun.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +36 -0
- package/types/lib/core/processTree.d.ts.map +1 -0
- package/types/lib/core/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/runState.d.ts +29 -0
- package/types/lib/core/runState.d.ts.map +1 -0
- package/types/lib/core/toml.d.ts +20 -0
- package/types/lib/core/toml.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +12 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
- package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +19 -3
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +9 -3
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +62 -13
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +59 -7
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmutils.d.ts +15 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +155 -5
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +119 -5
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +6 -1
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +74 -3
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +21 -59
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +57 -6
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +26 -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 +21 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/sbtutils.d.ts +88 -2
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
- package/types/lib/ecosystems/scalasem.d.ts +311 -0
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +2 -2
- package/types/lib/ecosystems/utils.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +100 -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/helpers/bomSigner.d.ts +80 -4
- package/types/lib/helpers/bomSigner.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/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- 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 +96 -10
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +3 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
- package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +2 -1
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +61 -2
- 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 +202 -14
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts +53 -7
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +16 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +40 -2
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +48 -14
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +83 -14
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
- package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +6 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/parentSelection.d.ts +34 -0
- package/types/lib/inventory/parentSelection.d.ts.map +1 -0
- 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/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts +80 -0
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +28 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +24 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +16 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +64 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +3 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeCache.d.ts +16 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +2 -1
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
- package/types/lib/parsers/cmakePresets.d.ts +78 -0
- package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
- package/types/lib/parsers/compileCommands.d.ts +115 -0
- package/types/lib/parsers/compileCommands.d.ts.map +1 -0
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +13 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/strictJson.d.ts +46 -0
- package/types/lib/parsers/strictJson.d.ts.map +1 -0
- package/types/lib/parsers/terraformConfig.d.ts +70 -0
- package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
- package/types/lib/parsers/terraformSource.d.ts +66 -0
- package/types/lib/parsers/terraformSource.d.ts.map +1 -0
- package/types/lib/server/server.d.ts +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/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +8 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { delimiter, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { DEBUG_MODE } from "../core/activity.js";
|
|
5
|
+
import { commandOutputText } from "../core/buildLedger.js";
|
|
6
|
+
import { getAllFiles, safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
7
|
+
import { isWin } from "../core/paths.js";
|
|
8
|
+
import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
9
|
+
import { noteBuildToolRateLimit } from "../inventory/buildToolRateLimit.js";
|
|
10
|
+
import { parseScalaArtifact } from "../inventory/scalaCoords.js";
|
|
11
|
+
import { completeComponent } from "./parsers-jvm.js";
|
|
12
|
+
|
|
13
|
+
// The scala-cli directive syntax, at the top of project.scala or any
|
|
14
|
+
// .scala/.sc file: //> using <key> <values...>
|
|
15
|
+
const DIRECTIVE_REGEX = /^\s*\/\/>\s*using\s+(\S+)\s+(.+)$/;
|
|
16
|
+
const DEP_KEYS = new Set([
|
|
17
|
+
"dep",
|
|
18
|
+
"deps",
|
|
19
|
+
"dependency",
|
|
20
|
+
"dependencies",
|
|
21
|
+
"test.dep",
|
|
22
|
+
"test.deps",
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
function scalaBinaryVersion(scalaVersion) {
|
|
26
|
+
if (!scalaVersion) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (scalaVersion.startsWith("3")) {
|
|
30
|
+
return "3";
|
|
31
|
+
}
|
|
32
|
+
if (scalaVersion.startsWith("2.13")) {
|
|
33
|
+
return "2.13";
|
|
34
|
+
}
|
|
35
|
+
if (scalaVersion.startsWith("2.12")) {
|
|
36
|
+
return "2.12";
|
|
37
|
+
}
|
|
38
|
+
const match = scalaVersion.match(/^2\.(\d+)/);
|
|
39
|
+
return match ? `2.${match[1]}` : null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Parse the `//> using` directives of a scala-cli source file.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} sourceFile Path of the source file
|
|
46
|
+
* @returns {{ scalaVersion: string|null, platform: string|null, nativeVersion: string|null, deps: Object[] }}
|
|
47
|
+
* The declared scala version and platform, and the declared dependencies as
|
|
48
|
+
* `{ group, artifact, version, cross, test }` entries, where `cross` is
|
|
49
|
+
* `::`, `:::` or `none`
|
|
50
|
+
*/
|
|
51
|
+
export function parseScalaCliDirectives(sourceFile) {
|
|
52
|
+
const result = {
|
|
53
|
+
scalaVersion: null,
|
|
54
|
+
platform: null,
|
|
55
|
+
nativeVersion: null,
|
|
56
|
+
deps: [],
|
|
57
|
+
};
|
|
58
|
+
let content;
|
|
59
|
+
try {
|
|
60
|
+
content = readFileSync(sourceFile, "utf-8");
|
|
61
|
+
} catch (_err) {
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
for (const line of content.split(/\r?\n/)) {
|
|
65
|
+
const match = DIRECTIVE_REGEX.exec(line);
|
|
66
|
+
if (!match) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const key = match[1].toLowerCase();
|
|
70
|
+
const values = match[2]
|
|
71
|
+
.match(/"[^"]*"|\S+/g)
|
|
72
|
+
?.map((v) => v.replaceAll('"', ""))
|
|
73
|
+
.filter(Boolean);
|
|
74
|
+
if (!values?.length) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (key === "scala") {
|
|
78
|
+
result.scalaVersion = values[0];
|
|
79
|
+
} else if (key === "platform") {
|
|
80
|
+
result.platform = values[0];
|
|
81
|
+
} else if (key === "scalanativeversion" || key === "nativeversion") {
|
|
82
|
+
result.nativeVersion = values[0];
|
|
83
|
+
} else if (DEP_KEYS.has(key)) {
|
|
84
|
+
for (const value of values) {
|
|
85
|
+
// group:artifact:version, group::artifact:version (binary version)
|
|
86
|
+
// and group:::artifact:version (full cross version)
|
|
87
|
+
const depMatch = /^([^:]+)(:::|::|:)([^:]+):(.+)$/.exec(value);
|
|
88
|
+
if (depMatch) {
|
|
89
|
+
result.deps.push({
|
|
90
|
+
group: depMatch[1],
|
|
91
|
+
artifact: depMatch[3],
|
|
92
|
+
version: depMatch[4],
|
|
93
|
+
cross: depMatch[2] === ":" ? "none" : depMatch[2],
|
|
94
|
+
test: key.startsWith("test."),
|
|
95
|
+
});
|
|
96
|
+
} else if (DEBUG_MODE) {
|
|
97
|
+
console.log(`Skipping the malformed scala-cli dependency ${value}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Build a component for a scala-cli dependency in the sbt purl form: the
|
|
107
|
+
* Scala binary suffix is not part of the name, the platform suffix of the
|
|
108
|
+
* declared platform is, and the Scala binary version is recorded as
|
|
109
|
+
* cdx:scala:compilerVersion.
|
|
110
|
+
*
|
|
111
|
+
* @param {Object} dep Parsed dependency declaration
|
|
112
|
+
* @param {Object} project Directives of the file the dependency was declared in
|
|
113
|
+
* @param {string} sourceFile File the dependency was declared in
|
|
114
|
+
* @returns {Object|null} The component, or null for malformed declarations
|
|
115
|
+
*/
|
|
116
|
+
export function scalaCliComponent(dep, project, sourceFile) {
|
|
117
|
+
let platformSuffix = "";
|
|
118
|
+
if (project.platform === "scala-js") {
|
|
119
|
+
platformSuffix = "_sjs1";
|
|
120
|
+
} else if (project.platform === "scala-native" && project.nativeVersion) {
|
|
121
|
+
const nativeMatch = project.nativeVersion.match(/^(0\.\d+)/);
|
|
122
|
+
if (nativeMatch) {
|
|
123
|
+
platformSuffix = `_native${nativeMatch[1]}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// `::` lets the tool append the binary suffix, which the sbt form drops;
|
|
127
|
+
// `:::` appends the full Scala version, which the sbt form keeps. A single
|
|
128
|
+
// colon names the published artifact as is, so an explicit `_3` suffix is
|
|
129
|
+
// stripped like the sbt purls do.
|
|
130
|
+
let name = `${dep.artifact}${platformSuffix}`;
|
|
131
|
+
let binaryVersion = scalaBinaryVersion(project.scalaVersion);
|
|
132
|
+
if (dep.cross === ":::" && project.scalaVersion) {
|
|
133
|
+
name = `${name}_${project.scalaVersion}`;
|
|
134
|
+
} else if (dep.cross === "none") {
|
|
135
|
+
const scalaInfo = parseScalaArtifact(dep.artifact);
|
|
136
|
+
name = scalaInfo.purlName;
|
|
137
|
+
binaryVersion = scalaInfo.binaryVersion;
|
|
138
|
+
}
|
|
139
|
+
const component = completeComponent({
|
|
140
|
+
group: dep.group,
|
|
141
|
+
name,
|
|
142
|
+
version: dep.version,
|
|
143
|
+
});
|
|
144
|
+
component.scope = dep.test ? "optional" : undefined;
|
|
145
|
+
component.evidence = {
|
|
146
|
+
identity: {
|
|
147
|
+
field: "purl",
|
|
148
|
+
confidence: 1,
|
|
149
|
+
methods: [
|
|
150
|
+
{
|
|
151
|
+
technique: "manifest-analysis",
|
|
152
|
+
confidence: 1,
|
|
153
|
+
value: sourceFile,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
// Only the Scala-published artifacts carry the compiler version; a plain
|
|
159
|
+
// Java artifact declared with a single colon does not.
|
|
160
|
+
if (binaryVersion) {
|
|
161
|
+
component.properties = [
|
|
162
|
+
{
|
|
163
|
+
name: "cdx:scala:compilerVersion",
|
|
164
|
+
value: binaryVersion,
|
|
165
|
+
},
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
return component;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Map a jar path of the Coursier cache to its Maven coordinates.
|
|
173
|
+
*
|
|
174
|
+
* Only the https cache layout with a well-known repository path segment is
|
|
175
|
+
* parsed; anything else returns null rather than guessing a group id.
|
|
176
|
+
*
|
|
177
|
+
* @param {string} jarPath Path of a jar in the Coursier cache
|
|
178
|
+
* @returns {{ group: string, name: string, version: string }|null} The coordinates
|
|
179
|
+
*/
|
|
180
|
+
export function coordinatesFromCoursierPath(jarPath) {
|
|
181
|
+
if (!jarPath) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
const segments = jarPath.split(/[\\/]/).filter(Boolean);
|
|
185
|
+
const repoMarkerIndex = segments.findIndex((segment) =>
|
|
186
|
+
["maven2", "maven", "releases", "snapshots", "central"].includes(segment),
|
|
187
|
+
);
|
|
188
|
+
if (repoMarkerIndex === -1) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const version = segments[segments.length - 2];
|
|
192
|
+
const artifactDir = segments[segments.length - 3];
|
|
193
|
+
const jarName = segments[segments.length - 1].replace(/\.jar$/, "");
|
|
194
|
+
const name = jarName.endsWith(`-${version}`)
|
|
195
|
+
? jarName.slice(0, -`-${version}`.length)
|
|
196
|
+
: artifactDir;
|
|
197
|
+
if (!name || !version) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const groupSegments = segments.slice(
|
|
201
|
+
repoMarkerIndex + 1,
|
|
202
|
+
segments.length - 3,
|
|
203
|
+
);
|
|
204
|
+
if (!groupSegments.length) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
group: groupSegments.join("."),
|
|
209
|
+
name,
|
|
210
|
+
version,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function scalaCliCommandArgs() {
|
|
215
|
+
// scala-cli is the standalone tool; the scala runner of the same toolchain
|
|
216
|
+
// wraps it behind --power. Without --server=false the compile goes through
|
|
217
|
+
// a Bloop daemon that outlives the scan. The project is the working
|
|
218
|
+
// directory, so its path never reaches the shell that starts the tool on
|
|
219
|
+
// Windows.
|
|
220
|
+
const compileArgs = ["compile", "--server=false", "--print-class-path", "."];
|
|
221
|
+
const scalaCliProbe = safeSpawnSync(
|
|
222
|
+
"scala-cli",
|
|
223
|
+
["version", "--cli-version"],
|
|
224
|
+
{
|
|
225
|
+
shell: isWin,
|
|
226
|
+
},
|
|
227
|
+
);
|
|
228
|
+
if (!scalaCliProbe.error && scalaCliProbe.status === 0) {
|
|
229
|
+
return { cmd: "scala-cli", args: compileArgs };
|
|
230
|
+
}
|
|
231
|
+
return { cmd: "scala", args: ["--power", ...compileArgs] };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Collect the components a scala-cli project declares through its
|
|
236
|
+
* `//> using` directives.
|
|
237
|
+
*
|
|
238
|
+
* Transitive dependencies are added from the class path of
|
|
239
|
+
* `scala-cli compile --print-class-path` when dependency installation is
|
|
240
|
+
* allowed, by mapping the Coursier cache paths back to coordinates.
|
|
241
|
+
*
|
|
242
|
+
* @param {string} dirPath Directory of the scala-cli project
|
|
243
|
+
* @param {Object} options CLI options
|
|
244
|
+
* @returns {Object[]} Component list, empty when the project declares no
|
|
245
|
+
* scala-cli directives
|
|
246
|
+
*/
|
|
247
|
+
export function collectScalaCliComponents(dirPath, options = {}) {
|
|
248
|
+
const sourceFiles = [
|
|
249
|
+
join(dirPath, "project.scala"),
|
|
250
|
+
...getAllFiles(dirPath, "*.scala"),
|
|
251
|
+
...getAllFiles(dirPath, "*.sc"),
|
|
252
|
+
].filter((file) => safeExistsSync(file));
|
|
253
|
+
const seenFiles = new Set();
|
|
254
|
+
const projects = [];
|
|
255
|
+
for (const file of sourceFiles) {
|
|
256
|
+
if (seenFiles.has(file)) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
seenFiles.add(file);
|
|
260
|
+
const directives = parseScalaCliDirectives(file);
|
|
261
|
+
if (directives.deps.length || directives.scalaVersion) {
|
|
262
|
+
projects.push({ file, directives });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (!projects.length) {
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
const pkgList = [];
|
|
269
|
+
const seenPurls = new Set();
|
|
270
|
+
const addComponent = (component) => {
|
|
271
|
+
if (component?.purl && !seenPurls.has(component.purl)) {
|
|
272
|
+
seenPurls.add(component.purl);
|
|
273
|
+
pkgList.push(component);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
for (const { file, directives } of projects) {
|
|
277
|
+
for (const dep of directives.deps) {
|
|
278
|
+
addComponent(scalaCliComponent(dep, directives, file));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (!pkgList.length) {
|
|
282
|
+
return pkgList;
|
|
283
|
+
}
|
|
284
|
+
// The transitive dependencies of the declared ones come from the class
|
|
285
|
+
// path the tool itself resolves; the compile requires installs to be
|
|
286
|
+
// allowed.
|
|
287
|
+
if (!isProjectToolingAllowed(options)) {
|
|
288
|
+
console.log(
|
|
289
|
+
"Skipping the scala-cli class path resolution since dependency installation is disabled.",
|
|
290
|
+
);
|
|
291
|
+
return pkgList;
|
|
292
|
+
}
|
|
293
|
+
const { cmd, args } = scalaCliCommandArgs();
|
|
294
|
+
console.log(`Executing '${cmd} ${args.join(" ")}' in`, dirPath);
|
|
295
|
+
const result = safeSpawnSync(cmd, args, {
|
|
296
|
+
cwd: dirPath,
|
|
297
|
+
shell: isWin,
|
|
298
|
+
maxBuffer: 100 * 1024 * 1024,
|
|
299
|
+
timeout: 600_000,
|
|
300
|
+
});
|
|
301
|
+
// scala-cli resolves through Coursier, so the class path fails with its
|
|
302
|
+
// downloader message when the repository rate limits the machine.
|
|
303
|
+
noteBuildToolRateLimit("scala-cli", commandOutputText(result), {
|
|
304
|
+
command: `${cmd} ${args.join(" ")}`,
|
|
305
|
+
exitCode: typeof result.status === "number" ? result.status : undefined,
|
|
306
|
+
});
|
|
307
|
+
const classPath = (result.stdout || "")
|
|
308
|
+
.trim()
|
|
309
|
+
.split("\n")
|
|
310
|
+
.filter((line) => line.includes(".jar"))
|
|
311
|
+
.pop();
|
|
312
|
+
if (!classPath) {
|
|
313
|
+
if (DEBUG_MODE) {
|
|
314
|
+
console.log("The scala-cli class path could not be determined.");
|
|
315
|
+
}
|
|
316
|
+
return pkgList;
|
|
317
|
+
}
|
|
318
|
+
for (const jarPath of classPath.split(delimiter)) {
|
|
319
|
+
if (!jarPath.endsWith(".jar")) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const coordinates = coordinatesFromCoursierPath(jarPath);
|
|
323
|
+
if (!coordinates) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const scalaInfo = parseScalaArtifact(coordinates.name);
|
|
327
|
+
const component = completeComponent({
|
|
328
|
+
group: coordinates.group,
|
|
329
|
+
name: scalaInfo.purlName,
|
|
330
|
+
version: coordinates.version,
|
|
331
|
+
});
|
|
332
|
+
if (scalaInfo.binaryVersion) {
|
|
333
|
+
component.properties = [
|
|
334
|
+
{
|
|
335
|
+
name: "cdx:scala:compilerVersion",
|
|
336
|
+
value: scalaInfo.binaryVersion,
|
|
337
|
+
},
|
|
338
|
+
];
|
|
339
|
+
}
|
|
340
|
+
addComponent(component);
|
|
341
|
+
}
|
|
342
|
+
return pkgList;
|
|
343
|
+
}
|