@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
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
readEnvironmentVariable,
|
|
19
19
|
} from "../core/activity.js";
|
|
20
20
|
import { PYTHON_CMD, PYTHON_EXCLUDED_COMPONENTS } from "../core/env.js";
|
|
21
|
-
import { safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
21
|
+
import { getAllFiles, safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
22
22
|
import { thoughtLog } from "../core/logger.js";
|
|
23
23
|
import { isWin } from "../core/paths.js";
|
|
24
24
|
import {
|
|
@@ -331,6 +331,70 @@ export function get_python_command_from_env(env) {
|
|
|
331
331
|
return fallbackCmd;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
/** Directories that hold installed packages, not the project's own code. */
|
|
335
|
+
const INSTALLED_PACKAGE_DIRS = [
|
|
336
|
+
"**/site-packages/**",
|
|
337
|
+
"**/dist-packages/**",
|
|
338
|
+
"**/.venv/**",
|
|
339
|
+
"**/venv/**",
|
|
340
|
+
"**/.tox/**",
|
|
341
|
+
"**/.nox/**",
|
|
342
|
+
"**/__pypackages__/**",
|
|
343
|
+
"**/node_modules/**",
|
|
344
|
+
];
|
|
345
|
+
|
|
346
|
+
const projectModuleNamesCache = new Map();
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* The top-level packages and modules a project provides, wherever they sit
|
|
350
|
+
* in its tree: each outermost package directory (one with an `__init__.py`
|
|
351
|
+
* whose parent has none), and the module files beside such packages, since
|
|
352
|
+
* their directory is a source root. Directories of installed packages
|
|
353
|
+
* (virtual environments, `site-packages`) are not the project's.
|
|
354
|
+
*
|
|
355
|
+
* @param {string} src Path to the project being analysed
|
|
356
|
+
* @returns {Set<string>} Module names
|
|
357
|
+
*/
|
|
358
|
+
export function projectModuleNames(src) {
|
|
359
|
+
const root = resolve(src);
|
|
360
|
+
if (projectModuleNamesCache.has(root)) {
|
|
361
|
+
return projectModuleNamesCache.get(root);
|
|
362
|
+
}
|
|
363
|
+
const names = new Set();
|
|
364
|
+
const sourceRoots = new Set();
|
|
365
|
+
const inits = getAllFiles(root, "**/__init__.py", {
|
|
366
|
+
exclude: INSTALLED_PACKAGE_DIRS,
|
|
367
|
+
});
|
|
368
|
+
for (const init of inits) {
|
|
369
|
+
let pkgDir = dirname(resolve(init));
|
|
370
|
+
while (
|
|
371
|
+
dirname(pkgDir) !== root &&
|
|
372
|
+
dirname(pkgDir).startsWith(root) &&
|
|
373
|
+
safeExistsSync(join(dirname(pkgDir), "__init__.py"))
|
|
374
|
+
) {
|
|
375
|
+
pkgDir = dirname(pkgDir);
|
|
376
|
+
}
|
|
377
|
+
if (pkgDir === root) {
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
names.add(basename(pkgDir));
|
|
381
|
+
sourceRoots.add(dirname(pkgDir));
|
|
382
|
+
}
|
|
383
|
+
for (const dir of sourceRoots) {
|
|
384
|
+
try {
|
|
385
|
+
for (const f of readdirSync(dir)) {
|
|
386
|
+
if (f.endsWith(".py") && f !== "__init__.py") {
|
|
387
|
+
names.add(f.slice(0, -3));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} catch {
|
|
391
|
+
// an unreadable directory provides nothing
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
projectModuleNamesCache.set(root, names);
|
|
395
|
+
return names;
|
|
396
|
+
}
|
|
397
|
+
|
|
334
398
|
/**
|
|
335
399
|
* Is this import satisfied by a module that lives in the project itself?
|
|
336
400
|
*
|
|
@@ -344,7 +408,9 @@ export function get_python_command_from_env(env) {
|
|
|
344
408
|
* filesystem whether the module is ours answers it exactly.
|
|
345
409
|
*
|
|
346
410
|
* Checks the project root and a `src/` layout for a module file, a package directory,
|
|
347
|
-
* and a PEP 420 namespace package directory
|
|
411
|
+
* and a PEP 420 namespace package directory, then the top-level packages found
|
|
412
|
+
* anywhere in the project and the modules beside them (tool-heavy repositories
|
|
413
|
+
* keep their Python libraries in places such as `dev_tools/pylibs/`).
|
|
348
414
|
*
|
|
349
415
|
* @param {string} src Path to the project being analysed
|
|
350
416
|
* @param {string} name Imported top-level module name
|
|
@@ -354,6 +420,9 @@ export function isFirstPartyModule(src, name) {
|
|
|
354
420
|
if (!src || !name || name.includes("/") || name.includes("\\")) {
|
|
355
421
|
return false;
|
|
356
422
|
}
|
|
423
|
+
if (projectModuleNames(src).has(name)) {
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
357
426
|
for (const root of [src, join(src, "src")]) {
|
|
358
427
|
if (
|
|
359
428
|
safeExistsSync(join(root, `${name}.py`)) ||
|
|
@@ -378,6 +447,21 @@ export function isFirstPartyModule(src, name) {
|
|
|
378
447
|
return false;
|
|
379
448
|
}
|
|
380
449
|
|
|
450
|
+
/**
|
|
451
|
+
* Whether a directory holds Python sources for atom to parse.
|
|
452
|
+
*
|
|
453
|
+
* The search skips the directories the manifest searches skip, such as
|
|
454
|
+
* node_modules and dot directories, and honours the exclude patterns, so a
|
|
455
|
+
* Python file shipped inside an npm package does not count.
|
|
456
|
+
*
|
|
457
|
+
* @param {string} src directory
|
|
458
|
+
* @param {Object} options CLI options
|
|
459
|
+
* @returns {boolean} true when the directory holds at least one Python file
|
|
460
|
+
*/
|
|
461
|
+
export function hasPythonSources(src, options = {}) {
|
|
462
|
+
return getAllFiles(src, "**/*.py", options).length > 0;
|
|
463
|
+
}
|
|
464
|
+
|
|
381
465
|
/**
|
|
382
466
|
* Method to find python modules by parsing the imports and then checking with PyPI to obtain the latest version
|
|
383
467
|
*
|
|
@@ -390,9 +474,11 @@ export async function getPyModules(src, epkgList, options) {
|
|
|
390
474
|
const allImports = {};
|
|
391
475
|
const dependenciesList = [];
|
|
392
476
|
let modList = [];
|
|
393
|
-
const
|
|
394
|
-
options.depsSlicesFile || options.usagesSlicesFile
|
|
395
|
-
|
|
477
|
+
const requestedSlicesFile =
|
|
478
|
+
options.depsSlicesFile || options.usagesSlicesFile;
|
|
479
|
+
let slicesFile = requestedSlicesFile
|
|
480
|
+
? resolve(requestedSlicesFile)
|
|
481
|
+
: undefined;
|
|
396
482
|
// Issue: 615 fix. Reuse existing slices file
|
|
397
483
|
if (slicesFile && safeExistsSync(slicesFile)) {
|
|
398
484
|
const slicesData = JSON.parse(readFileSync(slicesFile, "utf-8"));
|
|
@@ -401,8 +487,18 @@ export async function getPyModules(src, epkgList, options) {
|
|
|
401
487
|
} else {
|
|
402
488
|
modList = slicesData;
|
|
403
489
|
}
|
|
404
|
-
} else {
|
|
490
|
+
} else if (hasPythonSources(src, options)) {
|
|
491
|
+
// A new slices file is kept where it was asked for only when the evidence
|
|
492
|
+
// step will read it again; otherwise atom writes it to a temporary
|
|
493
|
+
// directory instead of the working directory.
|
|
494
|
+
if (!options.evidence) {
|
|
495
|
+
slicesFile = undefined;
|
|
496
|
+
}
|
|
405
497
|
modList = findAppModules(src, "python", "parsedeps", slicesFile, options);
|
|
498
|
+
} else {
|
|
499
|
+
thoughtLog(
|
|
500
|
+
`There are no Python sources at '${src}', so atom parsedeps has nothing to read.`,
|
|
501
|
+
);
|
|
406
502
|
}
|
|
407
503
|
const pyDefaultModules = new Set(PYTHON_STD_MODULES);
|
|
408
504
|
modList = modList.filter(
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
recordActivity,
|
|
6
6
|
} from "../../core/activity.js";
|
|
7
7
|
import { sanitizeStructuredValueForBom } from "../../core/propertySanitizer.js";
|
|
8
|
+
import { registerRunReset } from "../../core/runState.js";
|
|
8
9
|
import {
|
|
9
10
|
detectAiModelVariants,
|
|
10
11
|
normalizeDetectedVariants,
|
|
@@ -167,6 +168,8 @@ export function resetHuggingFaceRemoteCaches() {
|
|
|
167
168
|
payloadCache.clear();
|
|
168
169
|
}
|
|
169
170
|
|
|
171
|
+
registerRunReset("huggingface:responses", resetHuggingFaceRemoteCaches);
|
|
172
|
+
|
|
170
173
|
const normalizeLicenseFilePath = (licensePath) =>
|
|
171
174
|
String(licensePath || "")
|
|
172
175
|
.trim()
|
|
@@ -15,23 +15,21 @@ import { build, Purl } from "@cdxgen/cdx-purl";
|
|
|
15
15
|
|
|
16
16
|
// utils.js does not import rubyutils.js, so importing from it here is safe and
|
|
17
17
|
// does not introduce a cyclic dependency.
|
|
18
|
-
import {
|
|
19
|
-
cdxgenAgent,
|
|
20
|
-
DEBUG_MODE,
|
|
21
|
-
readEnvironmentVariable,
|
|
22
|
-
} from "../core/activity.js";
|
|
18
|
+
import { DEBUG_MODE, readEnvironmentVariable } from "../core/activity.js";
|
|
23
19
|
import { shouldFetchLicense } from "../core/env.js";
|
|
24
20
|
import { getAllFiles, safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
25
21
|
import { thoughtLog } from "../core/logger.js";
|
|
26
22
|
import { dirNameStr, isWin } from "../core/paths.js";
|
|
27
23
|
import { mergeDependencies } from "../inventory/depsUtils.js";
|
|
28
24
|
import {
|
|
25
|
+
gatedGet,
|
|
29
26
|
prefetchEnabled,
|
|
30
27
|
prefetchedResponse,
|
|
31
28
|
prefetchJson,
|
|
32
29
|
recordPolicyDegradationFromError,
|
|
33
30
|
} from "../inventory/fetchBatch.js";
|
|
34
31
|
import { genericPurl } from "../inventory/purl.js";
|
|
32
|
+
import { isValidIdnEmail } from "../parsers/email.js";
|
|
35
33
|
|
|
36
34
|
// FIXME. This has to get removed, once we improve the module detection one-liner.
|
|
37
35
|
// If you're a Rubyist, please help us improve this code.
|
|
@@ -913,6 +911,9 @@ export async function enrichGemsFromLocalCache(pkgList, options = {}) {
|
|
|
913
911
|
installedPkgs = await parseGemspecData(
|
|
914
912
|
readFileSync(gemspecFile, { encoding: "utf-8" }),
|
|
915
913
|
gemspecFile,
|
|
914
|
+
// The gemspec is read only for the fields it holds; the registry
|
|
915
|
+
// round the caller is about to make answers the rest.
|
|
916
|
+
{ noFetch: true },
|
|
916
917
|
);
|
|
917
918
|
} catch (_err) {
|
|
918
919
|
// pass
|
|
@@ -983,16 +984,21 @@ function applyGemMetadata(p, body) {
|
|
|
983
984
|
p.properties.push({ name, value: `${value}` });
|
|
984
985
|
}
|
|
985
986
|
};
|
|
986
|
-
|
|
987
|
-
|
|
987
|
+
// The registry fills only what the lockfile, the gemspec and the caches on
|
|
988
|
+
// this machine left open, so a local answer survives the round.
|
|
989
|
+
if (!p.description?.length && (body.description || body.summary)) {
|
|
990
|
+
p.description = body.description || body.summary;
|
|
991
|
+
}
|
|
992
|
+
if (body.licenses && !p.license) {
|
|
988
993
|
p.license = body.licenses;
|
|
989
994
|
}
|
|
990
995
|
if (body.metadata) {
|
|
991
|
-
if (body.metadata.source_code_uri) {
|
|
996
|
+
if (body.metadata.source_code_uri && !p.repository) {
|
|
992
997
|
p.repository = { url: body.metadata.source_code_uri };
|
|
993
998
|
if (
|
|
994
999
|
body.homepage_uri &&
|
|
995
|
-
body.homepage_uri !== body.metadata.source_code_uri
|
|
1000
|
+
body.homepage_uri !== body.metadata.source_code_uri &&
|
|
1001
|
+
!p.homepage
|
|
996
1002
|
) {
|
|
997
1003
|
p.homepage = { url: body.homepage_uri };
|
|
998
1004
|
}
|
|
@@ -1033,7 +1039,7 @@ function applyGemMetadata(p, body) {
|
|
|
1033
1039
|
if (!p.externalReferences.length) {
|
|
1034
1040
|
p.externalReferences = undefined;
|
|
1035
1041
|
}
|
|
1036
|
-
if (body.sha) {
|
|
1042
|
+
if (body.sha && !p._integrity && !p.hashes?.length) {
|
|
1037
1043
|
p._integrity = `sha256-${body.sha}`;
|
|
1038
1044
|
}
|
|
1039
1045
|
// RubyGems reports the authors as a comma separated string. It is split into
|
|
@@ -1173,7 +1179,17 @@ export async function getRubyGemsMetadata(pkgList) {
|
|
|
1173
1179
|
for (const [name, pkgs] of Object.entries(pkgsByName)) {
|
|
1174
1180
|
const versionedPkgs = pkgs.filter((p) => p.version);
|
|
1175
1181
|
if (versionedPkgs.length > 1) {
|
|
1182
|
+
// The listing answers every versioned variant of this gem in one
|
|
1183
|
+
// request. A direct URL is asked for only an entry the listing does
|
|
1184
|
+
// not answer, so it is not prefetched here: the serial path below
|
|
1185
|
+
// requests one when the listing misses.
|
|
1176
1186
|
addBatchUrl(`${RUBYGEMS_V1_VERSIONS_URL}${name}.json`);
|
|
1187
|
+
for (const p of pkgs) {
|
|
1188
|
+
if (!p.version) {
|
|
1189
|
+
addBatchUrl(gemDirectUrl(p, RUBYGEMS_V2_URL, RUBYGEMS_V1_URL));
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
continue;
|
|
1177
1193
|
}
|
|
1178
1194
|
for (const p of pkgs) {
|
|
1179
1195
|
addBatchUrl(gemDirectUrl(p, RUBYGEMS_V2_URL, RUBYGEMS_V1_URL));
|
|
@@ -1201,7 +1217,7 @@ export async function getRubyGemsMetadata(pkgList) {
|
|
|
1201
1217
|
}
|
|
1202
1218
|
const res =
|
|
1203
1219
|
prefetchedResponse(prefetched, versionsUrl) ||
|
|
1204
|
-
(await
|
|
1220
|
+
(await gatedGet(versionsUrl, apiOptions));
|
|
1205
1221
|
versions = res.body;
|
|
1206
1222
|
}
|
|
1207
1223
|
if (Array.isArray(versions) && versions.length) {
|
|
@@ -1280,7 +1296,7 @@ async function enrichGemFromVersionEndpoint(
|
|
|
1280
1296
|
}
|
|
1281
1297
|
const res =
|
|
1282
1298
|
prefetchedResponse(prefetched, fullUrl) ||
|
|
1283
|
-
(await
|
|
1299
|
+
(await gatedGet(fullUrl, apiOptions));
|
|
1284
1300
|
let body = res.body;
|
|
1285
1301
|
if (body?.length) {
|
|
1286
1302
|
body = body[0];
|
|
@@ -1565,6 +1581,12 @@ function listGemBindirFiles(gemspecFile, bindir = "bin") {
|
|
|
1565
1581
|
* @param {Object} [options] Parse options
|
|
1566
1582
|
* @param {Object<string, string>} [options.lockedVersions] Locked versions of
|
|
1567
1583
|
* the gems the project directory serves, by gem name
|
|
1584
|
+
* @param {boolean} [options.projectGemspec] The gemspec describes the project
|
|
1585
|
+
* being scanned. No registry holds the project, so its gem is never looked
|
|
1586
|
+
* up and keeps what the gemspec says.
|
|
1587
|
+
* @param {boolean} [options.noFetch] Read the gemspec for the fields it holds
|
|
1588
|
+
* without asking the registry about the gem. The local cache enricher uses
|
|
1589
|
+
* this, since the caller is responsible for the registry round.
|
|
1568
1590
|
*/
|
|
1569
1591
|
export async function parseGemspecData(gemspecData, gemspecFile, options = {}) {
|
|
1570
1592
|
let pkgList = [];
|
|
@@ -1946,9 +1968,11 @@ export async function parseGemspecData(gemspecData, gemspecFile, options = {}) {
|
|
|
1946
1968
|
// `spec.email` holds the contact addresses of the gem, not of an author.
|
|
1947
1969
|
// An address can only be attributed when there is one per author, in the
|
|
1948
1970
|
// same order, or when the gem has a single author.
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
)
|
|
1971
|
+
// Only a valid `idn-email` may reach `organizationalContact.email`; the
|
|
1972
|
+
// schema asserts the format, so anything else fails BOM validation.
|
|
1973
|
+
const emails = (lists.email || [])
|
|
1974
|
+
.map((email) => `${email}`.trim())
|
|
1975
|
+
.filter(isValidIdnEmail);
|
|
1952
1976
|
pkg.authors = lists.authors.map((name, i) => {
|
|
1953
1977
|
let email;
|
|
1954
1978
|
if (emails.length === lists.authors.length) {
|
|
@@ -1983,7 +2007,7 @@ export async function parseGemspecData(gemspecData, gemspecFile, options = {}) {
|
|
|
1983
2007
|
} else {
|
|
1984
2008
|
console.log("Unable to parse", gemspecData, gemspecFile);
|
|
1985
2009
|
}
|
|
1986
|
-
if (shouldFetchLicense()) {
|
|
2010
|
+
if (shouldFetchLicense() && !options.projectGemspec && !options.noFetch) {
|
|
1987
2011
|
return await getRubyGemsMetadata(pkgList);
|
|
1988
2012
|
}
|
|
1989
2013
|
return pkgList;
|
|
@@ -1997,11 +2021,24 @@ export async function parseGemspecData(gemspecData, gemspecFile, options = {}) {
|
|
|
1997
2021
|
* directory (`PATH` with `remote: .`), which is how Bundler records the gem a
|
|
1998
2022
|
* project builds when its Gemfile uses the `gemspec` directive.
|
|
1999
2023
|
*
|
|
2024
|
+
* Gems the lockfile serves from a git remote or from a path outside the
|
|
2025
|
+
* project are never sent to rubygems.org: no public registry holds the release
|
|
2026
|
+
* they pinned. Before the registry round, the caches on this machine are read
|
|
2027
|
+
* first, so a gem whose installed gemspec or compact index entry is present
|
|
2028
|
+
* keeps those answers.
|
|
2029
|
+
*
|
|
2000
2030
|
* @param {object} gemLockData Gemfile.lock data
|
|
2001
2031
|
* @param {string} lockFile Lock file
|
|
2032
|
+
* @param {object} [options] Options
|
|
2033
|
+
* @param {string} [options.gemHome] GEM_HOME to read installed gemspecs from
|
|
2034
|
+
* @param {string} [options.compactIndexCacheDir] Bundler compact index cache
|
|
2002
2035
|
*/
|
|
2003
|
-
export async function parseGemfileLockData(
|
|
2004
|
-
|
|
2036
|
+
export async function parseGemfileLockData(
|
|
2037
|
+
gemLockData,
|
|
2038
|
+
lockFile,
|
|
2039
|
+
options = {},
|
|
2040
|
+
) {
|
|
2041
|
+
const pkgList = [];
|
|
2005
2042
|
const pkgnames = {};
|
|
2006
2043
|
const dependenciesList = [];
|
|
2007
2044
|
const dependenciesMap = {};
|
|
@@ -2207,13 +2244,16 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
|
|
|
2207
2244
|
}
|
|
2208
2245
|
// Bundler locks every gem against exactly one source, so the gem's
|
|
2209
2246
|
// own top-level line is where its remote belongs. A later duplicate
|
|
2210
|
-
// sighting of the same name would be the same release.
|
|
2247
|
+
// sighting of the same name would be the same release. The section
|
|
2248
|
+
// is kept as well: a gem under GIT or PATH is served from a source
|
|
2249
|
+
// no public registry holds.
|
|
2211
2250
|
if (!gemSourceInfo[name]) {
|
|
2212
2251
|
gemSourceInfo[name] = {
|
|
2213
2252
|
remote: lastRemote,
|
|
2214
2253
|
revision: lastRevision,
|
|
2215
2254
|
branch: lastBranch,
|
|
2216
2255
|
tag: lastTag,
|
|
2256
|
+
section: lastSection,
|
|
2217
2257
|
};
|
|
2218
2258
|
}
|
|
2219
2259
|
}
|
|
@@ -2369,7 +2409,20 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
|
|
|
2369
2409
|
});
|
|
2370
2410
|
}
|
|
2371
2411
|
if (shouldFetchLicense()) {
|
|
2372
|
-
|
|
2412
|
+
// The caches on this machine answer first: the installed gemspec holds
|
|
2413
|
+
// the licence the registry would be asked for, and the compact index the
|
|
2414
|
+
// checksum, so the registry round below only fills what is still missing.
|
|
2415
|
+
await enrichGemsFromLocalCache(pkgList, options);
|
|
2416
|
+
// The gem the lockfile serves from the project's own directory is the
|
|
2417
|
+
// project itself, and a gem under GIT or PATH is served from a source no
|
|
2418
|
+
// public registry holds; only the rest are looked up.
|
|
2419
|
+
const lookupList = pkgList.filter(
|
|
2420
|
+
(p) =>
|
|
2421
|
+
!projectGemRefs.includes(p["bom-ref"]) &&
|
|
2422
|
+
gemSourceInfo[p.name]?.section !== "GIT" &&
|
|
2423
|
+
gemSourceInfo[p.name]?.section !== "PATH",
|
|
2424
|
+
);
|
|
2425
|
+
await getRubyGemsMetadata(lookupList);
|
|
2373
2426
|
}
|
|
2374
2427
|
return { pkgList, dependenciesList, rootList, projectGemRefs };
|
|
2375
2428
|
}
|
package/lib/ecosystems/rusi.js
CHANGED
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
safeSpawnSync,
|
|
11
11
|
} from "../core/fs.js";
|
|
12
12
|
import { dirNameStr } from "../core/paths.js";
|
|
13
|
+
import {
|
|
14
|
+
reportPluginRunFailure,
|
|
15
|
+
resolvePluginSourceDir,
|
|
16
|
+
} from "../core/pluginRun.js";
|
|
17
|
+
import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
13
18
|
import { applyAlgorithmProperties } from "../inventory/cryptoAlgorithmFamily.js";
|
|
14
19
|
import { resolvePluginBinary } from "../inventory/plugins.js";
|
|
15
20
|
|
|
@@ -817,9 +822,24 @@ export function runRusiAnalysis(src, outputFile, options = {}) {
|
|
|
817
822
|
if (!executable || !src || !outputFile) {
|
|
818
823
|
return false;
|
|
819
824
|
}
|
|
825
|
+
// rusi runs cargo and rustc on the project, which follow its
|
|
826
|
+
// `.cargo/config.toml` and `rust-toolchain.toml` and can compile its build
|
|
827
|
+
// scripts, so it waits for permission to run the project's tooling.
|
|
828
|
+
if (!isProjectToolingAllowed(options)) {
|
|
829
|
+
console.log(
|
|
830
|
+
"Skipping rusi since dependency installation is disabled. Rust evidence needs cargo to run on the project.",
|
|
831
|
+
);
|
|
832
|
+
return false;
|
|
833
|
+
}
|
|
820
834
|
|
|
835
|
+
// cdxgen may run with its working directory already inside the project
|
|
836
|
+
// while the source argument is relative to a repository root; a plain
|
|
837
|
+
// resolve would join the two into a directory that does not exist. The
|
|
838
|
+
// helper checks the result and falls back to the working directory when it
|
|
839
|
+
// is itself the cargo project under analysis.
|
|
840
|
+
const analysisDir = resolvePluginSourceDir(src, ["Cargo.toml"]);
|
|
821
841
|
const rusiMode = options.rusiMode === "cryptos" ? "cryptos" : "analyze";
|
|
822
|
-
const args = [rusiMode, "--dir",
|
|
842
|
+
const args = [rusiMode, "--dir", analysisDir, "--out", resolve(outputFile)];
|
|
823
843
|
|
|
824
844
|
// Set callgraph and data-flow args
|
|
825
845
|
args.push("--callgraph", options.rusiCallgraph || "static");
|
|
@@ -850,18 +870,21 @@ export function runRusiAnalysis(src, outputFile, options = {}) {
|
|
|
850
870
|
}
|
|
851
871
|
|
|
852
872
|
const result = safeSpawnSync(executable, args, {
|
|
853
|
-
cwd:
|
|
873
|
+
cwd: analysisDir,
|
|
854
874
|
shell: false,
|
|
855
875
|
});
|
|
856
876
|
|
|
857
877
|
if (result?.status !== 0 || result?.error || !safeExistsSync(outputFile)) {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
878
|
+
reportPluginRunFailure({
|
|
879
|
+
tool: "rusi",
|
|
880
|
+
ecosystem: "rust",
|
|
881
|
+
executable,
|
|
882
|
+
args,
|
|
883
|
+
dir: analysisDir,
|
|
884
|
+
result,
|
|
885
|
+
outputFile,
|
|
886
|
+
options,
|
|
887
|
+
});
|
|
865
888
|
return false;
|
|
866
889
|
}
|
|
867
890
|
return true;
|