@cdxgen/cdxgen 0.0.1 → 13.0.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 +921 -87
- package/bin/audit.js +239 -0
- package/bin/cdxgen.js +2324 -0
- package/bin/convert.js +213 -0
- package/bin/evinse.js +353 -0
- package/bin/hbom.js +495 -0
- package/bin/repl.js +2224 -0
- package/bin/sign.js +195 -0
- package/bin/tracebom.js +295 -0
- package/bin/validate.js +268 -0
- package/bin/verify.js +189 -0
- package/data/README.md +307 -0
- package/data/bom-1.4.schema.json +1605 -0
- package/data/bom-1.5.schema.json +3660 -0
- package/data/bom-1.6.schema.json +5511 -0
- package/data/bom-1.7.schema.json +6700 -0
- package/data/cbomosdb-queries.json +68 -0
- package/data/component-tags.json +339 -0
- package/data/container-knowledge-index.json +125 -0
- package/data/cosdb-queries.json +17 -0
- package/data/crypto-oid.json +1998 -0
- package/data/cryptography-defs.json +3793 -0
- package/data/cryptography-defs.schema.json +576 -0
- package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
- package/data/frameworks-list.json +219 -0
- package/data/glibc-stdlib.json +117 -0
- package/data/gtfobins-index.json +6296 -0
- package/data/helpers/init.gradle +71 -0
- package/data/jsf-0.82.schema.json +211 -0
- package/data/known-licenses.json +82 -0
- package/data/lic-mapping.json +338 -0
- package/data/license-aliases.json +6624 -0
- package/data/license-db.json +39059 -0
- package/data/license-deprecations.json +302 -0
- package/data/lolbas-index.json +150 -0
- package/data/predictive-audit-allowlist.json +11 -0
- package/data/pypi-pkg-aliases.json +1199 -0
- package/data/python-stdlib.json +308 -0
- package/data/queries-darwin.json +193 -0
- package/data/queries-win.json +257 -0
- package/data/queries.json +268 -0
- package/data/ruby-known-modules.json +281 -0
- package/data/rules/ai-agent-governance.yaml +323 -0
- package/data/rules/ai-bom.yaml +268 -0
- package/data/rules/ai-oversight.yaml +186 -0
- package/data/rules/ai-provenance.yaml +92 -0
- package/data/rules/asar-archives.yaml +150 -0
- package/data/rules/cbom-security.yaml +165 -0
- package/data/rules/chrome-extensions.yaml +248 -0
- package/data/rules/ci-permissions.yaml +802 -0
- package/data/rules/container-risk.yaml +353 -0
- package/data/rules/dependency-sources.yaml +236 -0
- package/data/rules/golem-go.yaml +229 -0
- package/data/rules/hbom-compliance.yaml +325 -0
- package/data/rules/hbom-performance.yaml +307 -0
- package/data/rules/hbom-security.yaml +248 -0
- package/data/rules/host-topology.yaml +165 -0
- package/data/rules/mcp-servers.yaml +388 -0
- package/data/rules/obom-runtime.yaml +1776 -0
- package/data/rules/package-integrity.yaml +364 -0
- package/data/rules/rootfs-hardening.yaml +179 -0
- package/data/rules/vscode-extensions.yaml +237 -0
- package/data/spdx-export.schema.json +6794 -0
- package/data/spdx-license-list.json +7449 -0
- package/data/spdx-licenses.json +759 -0
- package/data/spdx.schema.json +819 -0
- package/data/templates/README.md +3 -0
- package/data/templates/asvs-4.0.3.cdx.json +2943 -0
- package/data/templates/asvs-5.0.cdx.json +3046 -0
- package/data/templates/bsimm-v13.cdx.json +1008 -0
- package/data/templates/masvs-2.0.0.cdx.json +225 -0
- package/data/templates/nist-ssdf-1.1.cdx.json +828 -0
- package/data/templates/pcissc-secure-slc-1.1.cdx.json +1027 -0
- package/data/templates/scvs-1.0.0.cdx.json +813 -0
- package/data/templates/ssaf-DRAFT-2023-11.cdx.json +127 -0
- package/data/vendor-alias.json +41967 -0
- package/data/wrapdb-releases.json +4227 -0
- package/index.cjs +15 -0
- package/lib/audit/index.js +2800 -0
- package/lib/audit/progress.js +114 -0
- package/lib/audit/reporters.js +937 -0
- package/lib/audit/scoring.js +560 -0
- package/lib/audit/targets.js +798 -0
- package/lib/cli/bomAssembly.js +1833 -0
- package/lib/cli/cliOptions.js +513 -0
- package/lib/cli/index.js +2759 -0
- package/lib/cli/jsBom.js +2087 -0
- package/lib/cli/jvmBom.js +1858 -0
- package/lib/cli/managedBom.js +2083 -0
- package/lib/cli/nativeBom.js +2125 -0
- package/lib/core/activity.js +1087 -0
- package/lib/core/env.js +719 -0
- package/lib/core/fs.js +1058 -0
- package/lib/core/httpClient.js +730 -0
- package/lib/core/logger.js +142 -0
- package/lib/core/parallel.js +323 -0
- package/lib/core/paths.js +70 -0
- package/lib/core/projectConfig.js +122 -0
- package/lib/core/propertySanitizer.js +174 -0
- package/lib/core/spdx.js +5 -0
- package/lib/core/state.js +59 -0
- package/lib/core/text.js +207 -0
- package/lib/core/ui.js +876 -0
- package/lib/core/urls.js +84 -0
- package/lib/ecosystems/asarutils.js +1636 -0
- package/lib/ecosystems/bunutils.js +402 -0
- package/lib/ecosystems/caxa.js +77 -0
- package/lib/ecosystems/chromextutils.js +1174 -0
- package/lib/ecosystems/cmakeResolver.js +587 -0
- package/lib/ecosystems/cppEvidence.js +305 -0
- package/lib/ecosystems/denoutils.js +1094 -0
- package/lib/ecosystems/dotnetutils.js +132 -0
- package/lib/ecosystems/ecosystems.js +2772 -0
- package/lib/ecosystems/golem.js +1807 -0
- package/lib/ecosystems/gradleutils.js +1048 -0
- package/lib/ecosystems/jsEvidence.js +317 -0
- package/lib/ecosystems/npmutils.js +586 -0
- package/lib/ecosystems/parsers-bazel.js +875 -0
- package/lib/ecosystems/parsers-dotnet.js +1430 -0
- package/lib/ecosystems/parsers-gleam.js +302 -0
- package/lib/ecosystems/parsers-go.js +818 -0
- package/lib/ecosystems/parsers-js.js +4222 -0
- package/lib/ecosystems/parsers-jvm.js +948 -0
- package/lib/ecosystems/parsers-misc.js +3191 -0
- package/lib/ecosystems/parsers-python.js +2070 -0
- package/lib/ecosystems/parsers-rust.js +1294 -0
- package/lib/ecosystems/parsers-zig.js +861 -0
- package/lib/ecosystems/pep770.js +341 -0
- package/lib/ecosystems/pylockutils.js +427 -0
- package/lib/ecosystems/pythonutils.js +1281 -0
- package/lib/ecosystems/registryProvenance.js +1003 -0
- package/lib/ecosystems/remote/huggingface.js +1343 -0
- package/lib/ecosystems/rubyutils.js +1629 -0
- package/lib/ecosystems/rusi.js +820 -0
- package/lib/ecosystems/sbtutils.js +972 -0
- package/lib/ecosystems/tea.js +607 -0
- package/lib/ecosystems/utils.js +575 -0
- package/lib/ecosystems/zigResolver.js +410 -0
- package/lib/evinser/db.js +145 -0
- package/lib/evinser/evinser.js +2362 -0
- package/lib/evinser/scalasem.js +65 -0
- package/lib/evinser/swiftsem.js +767 -0
- package/lib/helpers/annotationFormatter.js +84 -0
- package/lib/helpers/bomSigner.js +312 -0
- package/lib/helpers/exportUtils.js +160 -0
- package/lib/helpers/remote/dependency-track.js +117 -0
- package/lib/helpers/versutils.js +202 -0
- package/lib/helpers/vsixutils.js +1069 -0
- package/lib/inventory/agentFormulationParser.js +322 -0
- package/lib/inventory/aiCollector.js +2140 -0
- package/lib/inventory/aiInventory.js +414 -0
- package/lib/inventory/aiModelVariants.js +121 -0
- package/lib/inventory/aiOversightCollector.js +661 -0
- package/lib/inventory/aiProvenanceCollector.js +822 -0
- package/lib/inventory/analyzer.js +6089 -0
- package/lib/inventory/analyzerScope.js +807 -0
- package/lib/inventory/astWorker.js +20 -0
- package/lib/inventory/atomUtils.js +1092 -0
- package/lib/inventory/auditCategories.js +192 -0
- package/lib/inventory/bomUtils.js +369 -0
- package/lib/inventory/cacheCommands.js +182 -0
- package/lib/inventory/cacheDir.js +104 -0
- package/lib/inventory/cbomutils.js +590 -0
- package/lib/inventory/cdxrs.js +434 -0
- package/lib/inventory/ciParsers/azurePipelines.js +295 -0
- package/lib/inventory/ciParsers/circleCi.js +286 -0
- package/lib/inventory/ciParsers/common.js +24 -0
- package/lib/inventory/ciParsers/githubActions.js +2434 -0
- package/lib/inventory/ciParsers/gitlabCi.js +213 -0
- package/lib/inventory/ciParsers/jenkins.js +180 -0
- package/lib/inventory/citations.js +234 -0
- package/lib/inventory/communityAiConfigParser.js +756 -0
- package/lib/inventory/containerRisk.js +204 -0
- package/lib/inventory/cryptoAlgorithmFamily.js +258 -0
- package/lib/inventory/deps.js +807 -0
- package/lib/inventory/depsUtils.js +588 -0
- package/lib/inventory/display.js +2128 -0
- package/lib/inventory/dosai.js +601 -0
- package/lib/inventory/dosaiParsers.js +154 -0
- package/lib/inventory/dynamic.js +145 -0
- package/lib/inventory/envcontext.js +1789 -0
- package/lib/inventory/evidenceUtils.js +774 -0
- package/lib/inventory/fetchBatch.js +779 -0
- package/lib/inventory/fetchRate.js +255 -0
- package/lib/inventory/forgeEnricher.js +300 -0
- package/lib/inventory/formulationParsers.js +422 -0
- package/lib/inventory/gtfobins.js +339 -0
- package/lib/inventory/hbom.js +719 -0
- package/lib/inventory/hbomAnalysis.js +310 -0
- package/lib/inventory/hbomLoader.js +35 -0
- package/lib/inventory/hostTopology.js +835 -0
- package/lib/inventory/inventoryStats.js +100 -0
- package/lib/inventory/jsonLike.js +121 -0
- package/lib/inventory/licenseEnhancer.js +918 -0
- package/lib/inventory/lolbas.js +285 -0
- package/lib/inventory/mcp.js +253 -0
- package/lib/inventory/mcpConfigParser.js +683 -0
- package/lib/inventory/mcpDiscovery.js +112 -0
- package/lib/inventory/mcpPinning.js +209 -0
- package/lib/inventory/osPackageResolver.js +493 -0
- package/lib/inventory/osinfo.js +277 -0
- package/lib/inventory/osqueryTransform.js +274 -0
- package/lib/inventory/plugins.js +466 -0
- package/lib/inventory/protobom.js +231 -0
- package/lib/inventory/protobomLoader.js +43 -0
- package/lib/inventory/provenanceUtils.js +224 -0
- package/lib/inventory/purl.js +749 -0
- package/lib/inventory/rustFormulationParser.js +339 -0
- package/lib/inventory/sbomDocument.js +340 -0
- package/lib/inventory/source.js +1488 -0
- package/lib/inventory/spdx.js +361 -0
- package/lib/inventory/spdxExpression.js +512 -0
- package/lib/inventory/spdxUtils.js +107 -0
- package/lib/inventory/table.js +263 -0
- package/lib/inventory/traceRunner.js +439 -0
- package/lib/inventory/unicodeScan.js +147 -0
- package/lib/managers/binary.js +3307 -0
- package/lib/managers/containerutils.js +125 -0
- package/lib/managers/docker.js +2145 -0
- package/lib/managers/dockerConnection.js +162 -0
- package/lib/managers/oci.js +704 -0
- package/lib/managers/piptree.js +267 -0
- package/lib/parsers/cmakeCache.js +199 -0
- package/lib/parsers/gguf.js +492 -0
- package/lib/parsers/gitAiNotes.js +233 -0
- package/lib/parsers/gitmodules.js +239 -0
- package/lib/parsers/htmlExtract.js +610 -0
- package/lib/parsers/huggingfaceManifest.js +551 -0
- package/lib/parsers/huggingfaceUtils.js +506 -0
- package/lib/parsers/iri.js +618 -0
- package/lib/parsers/npmrc.js +99 -0
- package/lib/parsers/ollama.js +101 -0
- package/lib/parsers/xml.js +841 -0
- package/lib/server/openapi.yaml +433 -0
- package/lib/server/server.js +616 -0
- package/lib/stages/postgen/annotator.js +977 -0
- package/lib/stages/postgen/auditBom.js +468 -0
- package/lib/stages/postgen/postgen.js +1239 -0
- package/lib/stages/postgen/ruleEngine.js +731 -0
- package/lib/stages/postgen/sortBom.js +195 -0
- package/lib/stages/postgen/spdxConverter.js +796 -0
- package/lib/stages/postgen/specVersionCompat.js +703 -0
- package/lib/stages/pregen/envAudit.js +388 -0
- package/lib/stages/pregen/pregen.js +637 -0
- package/lib/third-party/README.md +9 -0
- package/lib/third-party/arborist/CHANGELOG.md +1109 -0
- package/lib/third-party/arborist/LICENSE.md +20 -0
- package/lib/third-party/arborist/README.md +315 -0
- package/lib/third-party/arborist/lib/arborist/index.js +258 -0
- package/lib/third-party/arborist/lib/arborist/load-actual.js +605 -0
- package/lib/third-party/arborist/lib/arborist/load-virtual.js +300 -0
- package/lib/third-party/arborist/lib/bin-links.js +120 -0
- package/lib/third-party/arborist/lib/calc-dep-flags.js +130 -0
- package/lib/third-party/arborist/lib/case-insensitive-map.js +51 -0
- package/lib/third-party/arborist/lib/consistent-resolve.js +42 -0
- package/lib/third-party/arborist/lib/debug.js +50 -0
- package/lib/third-party/arborist/lib/dep-valid.js +190 -0
- package/lib/third-party/arborist/lib/edge.js +417 -0
- package/lib/third-party/arborist/lib/from-path.js +36 -0
- package/lib/third-party/arborist/lib/gather-dep-set.js +43 -0
- package/lib/third-party/arborist/lib/index.js +22 -0
- package/lib/third-party/arborist/lib/inventory.js +138 -0
- package/lib/third-party/arborist/lib/link.js +169 -0
- package/lib/third-party/arborist/lib/node.js +1673 -0
- package/lib/third-party/arborist/lib/npm-extension.js +45 -0
- package/lib/third-party/arborist/lib/override-resolves.js +11 -0
- package/lib/third-party/arborist/lib/override-set.js +319 -0
- package/lib/third-party/arborist/lib/package-extensions.js +289 -0
- package/lib/third-party/arborist/lib/printable.js +210 -0
- package/lib/third-party/arborist/lib/proc-log.js +30 -0
- package/lib/third-party/arborist/lib/realpath.js +100 -0
- package/lib/third-party/arborist/lib/relpath.js +4 -0
- package/lib/third-party/arborist/lib/shrinkwrap.js +1291 -0
- package/lib/third-party/arborist/lib/spec-from-lock.js +34 -0
- package/lib/third-party/arborist/lib/tree-check.js +165 -0
- package/lib/third-party/arborist/lib/validate-npm-package-name.js +107 -0
- package/lib/third-party/arborist/lib/version-from-tgz.js +51 -0
- package/lib/third-party/arborist/lib/yarn-lock.js +397 -0
- package/lib/validator/bomValidator.js +985 -0
- package/lib/validator/complianceEngine.js +241 -0
- package/lib/validator/complianceRules.js +1680 -0
- package/lib/validator/generated/runtime.mjs +17 -0
- package/lib/validator/generated/validate-1.6.mjs +21258 -0
- package/lib/validator/generated/validate-1.7.mjs +24803 -0
- package/lib/validator/generated/validate-2.0.mjs +22931 -0
- package/lib/validator/index.js +246 -0
- package/lib/validator/reporters/annotations.js +142 -0
- package/lib/validator/reporters/console.js +160 -0
- package/lib/validator/reporters/index.js +41 -0
- package/lib/validator/reporters/json.js +37 -0
- package/lib/validator/reporters/sarif.js +184 -0
- package/package.json +209 -26
- package/types/bin/audit.d.ts +3 -0
- package/types/bin/audit.d.ts.map +1 -0
- package/types/bin/cdxgen.d.ts +3 -0
- package/types/bin/cdxgen.d.ts.map +1 -0
- package/types/bin/convert.d.ts +3 -0
- package/types/bin/convert.d.ts.map +1 -0
- package/types/bin/evinse.d.ts +3 -0
- package/types/bin/evinse.d.ts.map +1 -0
- package/types/bin/hbom.d.ts +3 -0
- package/types/bin/hbom.d.ts.map +1 -0
- package/types/bin/repl.d.ts +3 -0
- package/types/bin/repl.d.ts.map +1 -0
- package/types/bin/sign.d.ts +3 -0
- package/types/bin/sign.d.ts.map +1 -0
- package/types/bin/tracebom.d.ts +3 -0
- package/types/bin/tracebom.d.ts.map +1 -0
- package/types/bin/validate.d.ts +14 -0
- package/types/bin/validate.d.ts.map +1 -0
- package/types/bin/verify.d.ts +3 -0
- package/types/bin/verify.d.ts.map +1 -0
- package/types/lib/audit/index.d.ts +153 -0
- package/types/lib/audit/index.d.ts.map +1 -0
- package/types/lib/audit/progress.d.ts +31 -0
- package/types/lib/audit/progress.d.ts.map +1 -0
- package/types/lib/audit/reporters.d.ts +62 -0
- package/types/lib/audit/reporters.d.ts.map +1 -0
- package/types/lib/audit/scoring.d.ts +36 -0
- package/types/lib/audit/scoring.d.ts.map +1 -0
- package/types/lib/audit/targets.d.ts +77 -0
- package/types/lib/audit/targets.d.ts.map +1 -0
- package/types/lib/cli/bomAssembly.d.ts +315 -0
- package/types/lib/cli/bomAssembly.d.ts.map +1 -0
- package/types/lib/cli/cliOptions.d.ts +156 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -0
- package/types/lib/cli/index.d.ts +107 -0
- package/types/lib/cli/index.d.ts.map +1 -0
- package/types/lib/cli/jsBom.d.ts +94 -0
- package/types/lib/cli/jsBom.d.ts.map +1 -0
- package/types/lib/cli/jvmBom.d.ts +54 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -0
- package/types/lib/cli/managedBom.d.ts +105 -0
- package/types/lib/cli/managedBom.d.ts.map +1 -0
- package/types/lib/cli/nativeBom.d.ts +143 -0
- package/types/lib/cli/nativeBom.d.ts.map +1 -0
- package/types/lib/core/activity.d.ts +178 -0
- package/types/lib/core/activity.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +192 -0
- package/types/lib/core/env.d.ts.map +1 -0
- package/types/lib/core/fs.d.ts +158 -0
- package/types/lib/core/fs.d.ts.map +1 -0
- package/types/lib/core/httpClient.d.ts +149 -0
- package/types/lib/core/httpClient.d.ts.map +1 -0
- package/types/lib/core/logger.d.ts +28 -0
- package/types/lib/core/logger.d.ts.map +1 -0
- package/types/lib/core/parallel.d.ts +95 -0
- package/types/lib/core/parallel.d.ts.map +1 -0
- package/types/lib/core/paths.d.ts +36 -0
- package/types/lib/core/paths.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts +23 -0
- package/types/lib/core/projectConfig.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +23 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -0
- package/types/lib/core/spdx.d.ts +5 -0
- package/types/lib/core/spdx.d.ts.map +1 -0
- package/types/lib/core/state.d.ts +20 -0
- package/types/lib/core/state.d.ts.map +1 -0
- package/types/lib/core/text.d.ts +78 -0
- package/types/lib/core/text.d.ts.map +1 -0
- package/types/lib/core/ui.d.ts +87 -0
- package/types/lib/core/ui.d.ts.map +1 -0
- package/types/lib/core/urls.d.ts +43 -0
- package/types/lib/core/urls.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts +71 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -0
- package/types/lib/ecosystems/bunutils.d.ts +38 -0
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -0
- package/types/lib/ecosystems/caxa.d.ts +8 -0
- package/types/lib/ecosystems/caxa.d.ts.map +1 -0
- package/types/lib/ecosystems/chromextutils.d.ts +97 -0
- package/types/lib/ecosystems/chromextutils.d.ts.map +1 -0
- package/types/lib/ecosystems/cmakeResolver.d.ts +176 -0
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +35 -0
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +76 -0
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -0
- package/types/lib/ecosystems/dotnetutils.d.ts +45 -0
- package/types/lib/ecosystems/dotnetutils.d.ts.map +1 -0
- package/types/lib/ecosystems/ecosystems.d.ts +279 -0
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts +60 -0
- package/types/lib/ecosystems/golem.d.ts.map +1 -0
- package/types/lib/ecosystems/gradleutils.d.ts +139 -0
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -0
- package/types/lib/ecosystems/jsEvidence.d.ts +17 -0
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -0
- package/types/lib/ecosystems/npmutils.d.ts +183 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts +36 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts +116 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-gleam.d.ts +33 -0
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-go.d.ts +92 -0
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-js.d.ts +242 -0
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-jvm.d.ts +100 -0
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-misc.d.ts +450 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts +145 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rust.d.ts +56 -0
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-zig.d.ts +83 -0
- package/types/lib/ecosystems/parsers-zig.d.ts.map +1 -0
- package/types/lib/ecosystems/pep770.d.ts +38 -0
- package/types/lib/ecosystems/pep770.d.ts.map +1 -0
- package/types/lib/ecosystems/pylockutils.d.ts +68 -0
- package/types/lib/ecosystems/pylockutils.d.ts.map +1 -0
- package/types/lib/ecosystems/pythonutils.d.ts +70 -0
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -0
- package/types/lib/ecosystems/registryProvenance.d.ts +26 -0
- package/types/lib/ecosystems/registryProvenance.d.ts.map +1 -0
- package/types/lib/ecosystems/remote/huggingface.d.ts +31 -0
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -0
- package/types/lib/ecosystems/rubyutils.d.ts +182 -0
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -0
- package/types/lib/ecosystems/rusi.d.ts +40 -0
- package/types/lib/ecosystems/rusi.d.ts.map +1 -0
- package/types/lib/ecosystems/sbtutils.d.ts +179 -0
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -0
- package/types/lib/ecosystems/tea.d.ts +180 -0
- package/types/lib/ecosystems/tea.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +41 -0
- package/types/lib/ecosystems/utils.d.ts.map +1 -0
- package/types/lib/ecosystems/zigResolver.d.ts +70 -0
- package/types/lib/ecosystems/zigResolver.d.ts.map +1 -0
- package/types/lib/evinser/db.d.ts +17 -0
- package/types/lib/evinser/db.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +354 -0
- package/types/lib/evinser/evinser.d.ts.map +1 -0
- package/types/lib/evinser/scalasem.d.ts +15 -0
- package/types/lib/evinser/scalasem.d.ts.map +1 -0
- package/types/lib/evinser/swiftsem.d.ts +103 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -0
- package/types/lib/helpers/annotationFormatter.d.ts +23 -0
- package/types/lib/helpers/annotationFormatter.d.ts.map +1 -0
- package/types/lib/helpers/bomSigner.d.ts +28 -0
- package/types/lib/helpers/bomSigner.d.ts.map +1 -0
- package/types/lib/helpers/exportUtils.d.ts +52 -0
- package/types/lib/helpers/exportUtils.d.ts.map +1 -0
- package/types/lib/helpers/remote/dependency-track.d.ts +23 -0
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
- package/types/lib/helpers/versutils.d.ts +8 -0
- package/types/lib/helpers/versutils.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +130 -0
- package/types/lib/helpers/vsixutils.d.ts.map +1 -0
- package/types/lib/inventory/agentFormulationParser.d.ts +21 -0
- package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts +61 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -0
- package/types/lib/inventory/aiInventory.d.ts +103 -0
- package/types/lib/inventory/aiInventory.d.ts.map +1 -0
- package/types/lib/inventory/aiModelVariants.d.ts +31 -0
- package/types/lib/inventory/aiModelVariants.d.ts.map +1 -0
- package/types/lib/inventory/aiOversightCollector.d.ts +28 -0
- package/types/lib/inventory/aiOversightCollector.d.ts.map +1 -0
- package/types/lib/inventory/aiProvenanceCollector.d.ts +13 -0
- package/types/lib/inventory/aiProvenanceCollector.d.ts.map +1 -0
- package/types/lib/inventory/analyzer.d.ts +157 -0
- package/types/lib/inventory/analyzer.d.ts.map +1 -0
- package/types/lib/inventory/analyzerScope.d.ts +106 -0
- package/types/lib/inventory/analyzerScope.d.ts.map +1 -0
- package/types/lib/inventory/astWorker.d.ts +9 -0
- package/types/lib/inventory/astWorker.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +159 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -0
- package/types/lib/inventory/auditCategories.d.ts +80 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -0
- package/types/lib/inventory/bomUtils.d.ts +145 -0
- package/types/lib/inventory/bomUtils.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +28 -0
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -0
- package/types/lib/inventory/cacheDir.d.ts +55 -0
- package/types/lib/inventory/cacheDir.d.ts.map +1 -0
- package/types/lib/inventory/cbomutils.d.ts +37 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -0
- package/types/lib/inventory/cdxrs.d.ts +90 -0
- package/types/lib/inventory/cdxrs.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/azurePipelines.d.ts +27 -0
- package/types/lib/inventory/ciParsers/azurePipelines.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/circleCi.d.ts +27 -0
- package/types/lib/inventory/ciParsers/circleCi.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/common.d.ts +11 -0
- package/types/lib/inventory/ciParsers/common.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/githubActions.d.ts +38 -0
- package/types/lib/inventory/ciParsers/githubActions.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/gitlabCi.d.ts +26 -0
- package/types/lib/inventory/ciParsers/gitlabCi.d.ts.map +1 -0
- package/types/lib/inventory/ciParsers/jenkins.d.ts +26 -0
- package/types/lib/inventory/ciParsers/jenkins.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +90 -0
- package/types/lib/inventory/citations.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts +14 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -0
- package/types/lib/inventory/containerRisk.d.ts +20 -0
- package/types/lib/inventory/containerRisk.d.ts.map +1 -0
- package/types/lib/inventory/cryptoAlgorithmFamily.d.ts +37 -0
- package/types/lib/inventory/cryptoAlgorithmFamily.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +140 -0
- package/types/lib/inventory/deps.d.ts.map +1 -0
- package/types/lib/inventory/depsUtils.d.ts +74 -0
- package/types/lib/inventory/depsUtils.d.ts.map +1 -0
- package/types/lib/inventory/display.d.ts +227 -0
- package/types/lib/inventory/display.d.ts.map +1 -0
- package/types/lib/inventory/dosai.d.ts +130 -0
- package/types/lib/inventory/dosai.d.ts.map +1 -0
- package/types/lib/inventory/dosaiParsers.d.ts +59 -0
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -0
- package/types/lib/inventory/dynamic.d.ts +25 -0
- package/types/lib/inventory/dynamic.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +377 -0
- package/types/lib/inventory/envcontext.d.ts.map +1 -0
- package/types/lib/inventory/evidenceUtils.d.ts +74 -0
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -0
- package/types/lib/inventory/fetchBatch.d.ts +127 -0
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -0
- package/types/lib/inventory/fetchRate.d.ts +118 -0
- package/types/lib/inventory/fetchRate.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts +31 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -0
- package/types/lib/inventory/formulationParsers.d.ts +50 -0
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/gtfobins.d.ts +27 -0
- package/types/lib/inventory/gtfobins.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts +58 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -0
- package/types/lib/inventory/hbomAnalysis.d.ts +56 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -0
- package/types/lib/inventory/hbomLoader.d.ts +7 -0
- package/types/lib/inventory/hbomLoader.d.ts.map +1 -0
- package/types/lib/inventory/hostTopology.d.ts +47 -0
- package/types/lib/inventory/hostTopology.d.ts.map +1 -0
- package/types/lib/inventory/inventoryStats.d.ts +42 -0
- package/types/lib/inventory/inventoryStats.d.ts.map +1 -0
- package/types/lib/inventory/jsonLike.d.ts +23 -0
- package/types/lib/inventory/jsonLike.d.ts.map +1 -0
- package/types/lib/inventory/licenseEnhancer.d.ts +70 -0
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -0
- package/types/lib/inventory/lolbas.d.ts +16 -0
- package/types/lib/inventory/lolbas.d.ts.map +1 -0
- package/types/lib/inventory/mcp.d.ts +29 -0
- package/types/lib/inventory/mcp.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts +20 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -0
- package/types/lib/inventory/mcpDiscovery.d.ts +33 -0
- package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -0
- package/types/lib/inventory/mcpPinning.d.ts +11 -0
- package/types/lib/inventory/mcpPinning.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +49 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -0
- package/types/lib/inventory/osinfo.d.ts +120 -0
- package/types/lib/inventory/osinfo.d.ts.map +1 -0
- package/types/lib/inventory/osqueryTransform.d.ts +84 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -0
- package/types/lib/inventory/plugins.d.ts +58 -0
- package/types/lib/inventory/plugins.d.ts.map +1 -0
- package/types/lib/inventory/protobom.d.ts +71 -0
- package/types/lib/inventory/protobom.d.ts.map +1 -0
- package/types/lib/inventory/protobomLoader.d.ts +17 -0
- package/types/lib/inventory/protobomLoader.d.ts.map +1 -0
- package/types/lib/inventory/provenanceUtils.d.ts +98 -0
- package/types/lib/inventory/provenanceUtils.d.ts.map +1 -0
- package/types/lib/inventory/purl.d.ts +313 -0
- package/types/lib/inventory/purl.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts +17 -0
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -0
- package/types/lib/inventory/sbomDocument.d.ts +59 -0
- package/types/lib/inventory/sbomDocument.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +163 -0
- package/types/lib/inventory/source.d.ts.map +1 -0
- package/types/lib/inventory/spdx.d.ts +66 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -0
- package/types/lib/inventory/spdxExpression.d.ts +58 -0
- package/types/lib/inventory/spdxExpression.d.ts.map +1 -0
- package/types/lib/inventory/spdxUtils.d.ts +12 -0
- package/types/lib/inventory/spdxUtils.d.ts.map +1 -0
- package/types/lib/inventory/table.d.ts +19 -0
- package/types/lib/inventory/table.d.ts.map +1 -0
- package/types/lib/inventory/traceRunner.d.ts +80 -0
- package/types/lib/inventory/traceRunner.d.ts.map +1 -0
- package/types/lib/inventory/unicodeScan.d.ts +46 -0
- package/types/lib/inventory/unicodeScan.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts +76 -0
- package/types/lib/managers/binary.d.ts.map +1 -0
- package/types/lib/managers/containerutils.d.ts +30 -0
- package/types/lib/managers/containerutils.d.ts.map +1 -0
- package/types/lib/managers/docker.d.ts +157 -0
- package/types/lib/managers/docker.d.ts.map +1 -0
- package/types/lib/managers/dockerConnection.d.ts +42 -0
- package/types/lib/managers/dockerConnection.d.ts.map +1 -0
- package/types/lib/managers/oci.d.ts +21 -0
- package/types/lib/managers/oci.d.ts.map +1 -0
- package/types/lib/managers/piptree.d.ts +13 -0
- package/types/lib/managers/piptree.d.ts.map +1 -0
- package/types/lib/parsers/cmakeCache.d.ts +70 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -0
- package/types/lib/parsers/gguf.d.ts +39 -0
- package/types/lib/parsers/gguf.d.ts.map +1 -0
- package/types/lib/parsers/gitAiNotes.d.ts +15 -0
- package/types/lib/parsers/gitAiNotes.d.ts.map +1 -0
- package/types/lib/parsers/gitmodules.d.ts +88 -0
- package/types/lib/parsers/gitmodules.d.ts.map +1 -0
- package/types/lib/parsers/htmlExtract.d.ts +34 -0
- package/types/lib/parsers/htmlExtract.d.ts.map +1 -0
- package/types/lib/parsers/huggingfaceManifest.d.ts +153 -0
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts +155 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -0
- package/types/lib/parsers/iri.d.ts +68 -0
- package/types/lib/parsers/iri.d.ts.map +1 -0
- package/types/lib/parsers/npmrc.d.ts +33 -0
- package/types/lib/parsers/npmrc.d.ts.map +1 -0
- package/types/lib/parsers/ollama.d.ts +22 -0
- package/types/lib/parsers/ollama.d.ts.map +1 -0
- package/types/lib/parsers/xml.d.ts +47 -0
- package/types/lib/parsers/xml.d.ts.map +1 -0
- package/types/lib/server/server.d.ts +51 -0
- package/types/lib/server/server.d.ts.map +1 -0
- package/types/lib/stages/postgen/annotator.d.ts +36 -0
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -0
- package/types/lib/stages/postgen/auditBom.d.ts +92 -0
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
- package/types/lib/stages/postgen/postgen.d.ts +59 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -0
- package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
- package/types/lib/stages/postgen/sortBom.d.ts +34 -0
- package/types/lib/stages/postgen/sortBom.d.ts.map +1 -0
- package/types/lib/stages/postgen/spdxConverter.d.ts +11 -0
- package/types/lib/stages/postgen/spdxConverter.d.ts.map +1 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts +71 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -0
- package/types/lib/stages/pregen/envAudit.d.ts +14 -0
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
- package/types/lib/stages/pregen/pregen.d.ts +59 -0
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/arborist/index.d.ts +47 -0
- package/types/lib/third-party/arborist/lib/arborist/index.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts +4 -0
- package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts +4 -0
- package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/bin-links.d.ts +18 -0
- package/types/lib/third-party/arborist/lib/bin-links.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts +9 -0
- package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/debug.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/debug.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/dep-valid.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/dep-valid.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/edge.d.ts +46 -0
- package/types/lib/third-party/arborist/lib/edge.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/from-path.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/from-path.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/index.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/index.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/inventory.d.ts +14 -0
- package/types/lib/third-party/arborist/lib/inventory.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/link.d.ts +18 -0
- package/types/lib/third-party/arborist/lib/link.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/node.d.ts +112 -0
- package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/npm-extension.d.ts +18 -0
- package/types/lib/third-party/arborist/lib/npm-extension.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/override-resolves.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/override-resolves.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/override-set.d.ts +27 -0
- package/types/lib/third-party/arborist/lib/override-set.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/package-extensions.d.ts +36 -0
- package/types/lib/third-party/arborist/lib/package-extensions.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/printable.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/printable.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/proc-log.d.ts +20 -0
- package/types/lib/third-party/arborist/lib/proc-log.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/realpath.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/realpath.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/relpath.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/relpath.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts +54 -0
- package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/tree-check.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/tree-check.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts +13 -0
- package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts +6 -0
- package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/yarn-lock.d.ts +35 -0
- package/types/lib/third-party/arborist/lib/yarn-lock.d.ts.map +1 -0
- package/types/lib/validator/bomValidator.d.ts +40 -0
- package/types/lib/validator/bomValidator.d.ts.map +1 -0
- package/types/lib/validator/complianceEngine.d.ts +72 -0
- package/types/lib/validator/complianceEngine.d.ts.map +1 -0
- package/types/lib/validator/complianceRules.d.ts +61 -0
- package/types/lib/validator/complianceRules.d.ts.map +1 -0
- package/types/lib/validator/index.d.ts +101 -0
- package/types/lib/validator/index.d.ts.map +1 -0
- package/types/lib/validator/reporters/annotations.d.ts +37 -0
- package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
- package/types/lib/validator/reporters/console.d.ts +34 -0
- package/types/lib/validator/reporters/console.d.ts.map +1 -0
- package/types/lib/validator/reporters/index.d.ts +30 -0
- package/types/lib/validator/reporters/index.d.ts.map +1 -0
- package/types/lib/validator/reporters/json.d.ts +11 -0
- package/types/lib/validator/reporters/json.d.ts.map +1 -0
- package/types/lib/validator/reporters/sarif.d.ts +22 -0
- package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
- package/mod.d.ts +0 -7
- package/mod.js +0 -22
|
@@ -0,0 +1,972 @@
|
|
|
1
|
+
import { constants, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
|
|
5
|
+
import { build } from "@cdxgen/cdx-purl";
|
|
6
|
+
import { valid } from "semver";
|
|
7
|
+
|
|
8
|
+
import { applyPurl, mavenPurl } from "../inventory/purl.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A lightweight parser for Java .properties files, replacing the properties-reader library.
|
|
12
|
+
* Reads the file, parses key-value pairs separated by '=' or ':', and ignores comments.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} filePath Path to the properties file
|
|
15
|
+
* @returns {{ get: (key: string) => string | null }} An object containing a get method
|
|
16
|
+
*/
|
|
17
|
+
function propertiesReader(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
const content = readFileSync(filePath, "utf-8");
|
|
20
|
+
const props = {};
|
|
21
|
+
const lines = content.split(/\r?\n/);
|
|
22
|
+
for (let line of lines) {
|
|
23
|
+
line = line.trim();
|
|
24
|
+
// Skip empty lines and comments starting with '#' or '!'
|
|
25
|
+
if (!line || line.startsWith("#") || line.startsWith("!")) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const eqIdx = line.indexOf("=");
|
|
29
|
+
const colIdx = line.indexOf(":");
|
|
30
|
+
let sepIdx = -1;
|
|
31
|
+
if (eqIdx !== -1 && colIdx !== -1) {
|
|
32
|
+
sepIdx = Math.min(eqIdx, colIdx);
|
|
33
|
+
} else if (eqIdx !== -1) {
|
|
34
|
+
sepIdx = eqIdx;
|
|
35
|
+
} else if (colIdx !== -1) {
|
|
36
|
+
sepIdx = colIdx;
|
|
37
|
+
}
|
|
38
|
+
if (sepIdx !== -1) {
|
|
39
|
+
const key = line.substring(0, sepIdx).trim();
|
|
40
|
+
const val = line.substring(sepIdx + 1).trim();
|
|
41
|
+
props[key] = val;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
get: (key) => props[key] ?? null,
|
|
46
|
+
};
|
|
47
|
+
} catch (_err) {
|
|
48
|
+
return {
|
|
49
|
+
get: () => null,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
import {
|
|
55
|
+
cdxgenAgent,
|
|
56
|
+
DEBUG_MODE,
|
|
57
|
+
readEnvironmentVariable,
|
|
58
|
+
} from "../core/activity.js";
|
|
59
|
+
import {
|
|
60
|
+
getAllFiles,
|
|
61
|
+
multiChecksumFile,
|
|
62
|
+
safeCopyFileSync,
|
|
63
|
+
safeExistsSync,
|
|
64
|
+
safeUnlinkSync,
|
|
65
|
+
safeWriteSync,
|
|
66
|
+
} from "../core/fs.js";
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns a default location of the plugins file.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} projectPath Path to the SBT project
|
|
72
|
+
*/
|
|
73
|
+
export function sbtPluginsPath(projectPath) {
|
|
74
|
+
return join(projectPath, "project", "plugins.sbt");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Determine the version of SBT used in compilation of this project.
|
|
79
|
+
* By default it looks into a standard SBT location i.e.
|
|
80
|
+
* <path-project>/project/build.properties
|
|
81
|
+
* Returns `null` if the version cannot be determined.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} projectPath Path to the SBT project
|
|
84
|
+
*/
|
|
85
|
+
export function determineSbtVersion(projectPath) {
|
|
86
|
+
const buildPropFile = join(projectPath, "project", "build.properties");
|
|
87
|
+
if (DEBUG_MODE) {
|
|
88
|
+
console.log("Looking for", buildPropFile);
|
|
89
|
+
}
|
|
90
|
+
if (safeExistsSync(buildPropFile)) {
|
|
91
|
+
const properties = propertiesReader(buildPropFile);
|
|
92
|
+
const property = properties.get("sbt.version");
|
|
93
|
+
if (property != null && valid(property)) {
|
|
94
|
+
return property;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Adds a new plugin to the SBT project by amending its plugins list.
|
|
102
|
+
* Only recommended for SBT < 1.2.0 or otherwise use `addPluginSbtFile`
|
|
103
|
+
* parameter.
|
|
104
|
+
* The change manipulates the existing plugins' file by creating a copy of it
|
|
105
|
+
* and returning a path where it is moved to.
|
|
106
|
+
* Once the SBT task is complete one must always call `cleanupPlugin` to remove
|
|
107
|
+
* the modifications made in place.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} projectPath Path to the SBT project
|
|
110
|
+
* @param {string} plugin Name of the plugin to add
|
|
111
|
+
*/
|
|
112
|
+
export function addPlugin(projectPath, plugin) {
|
|
113
|
+
const pluginsFile = sbtPluginsPath(projectPath);
|
|
114
|
+
let originalPluginsFile = null;
|
|
115
|
+
if (safeExistsSync(pluginsFile)) {
|
|
116
|
+
originalPluginsFile = `${pluginsFile}.cdxgen`;
|
|
117
|
+
safeCopyFileSync(
|
|
118
|
+
pluginsFile,
|
|
119
|
+
originalPluginsFile,
|
|
120
|
+
constants.COPYFILE_FICLONE,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
safeWriteSync(pluginsFile, plugin, { flag: "a" });
|
|
125
|
+
return originalPluginsFile;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Cleans up modifications to the project's plugins' file made by the
|
|
130
|
+
* `addPlugin` function.
|
|
131
|
+
*
|
|
132
|
+
* @param {string} projectPath Path to the SBT project
|
|
133
|
+
* @param {string} originalPluginsFile Location of the original plugins file, if any
|
|
134
|
+
*/
|
|
135
|
+
export function cleanupPlugin(projectPath, originalPluginsFile) {
|
|
136
|
+
const pluginsFile = sbtPluginsPath(projectPath);
|
|
137
|
+
if (safeExistsSync(pluginsFile)) {
|
|
138
|
+
if (!originalPluginsFile) {
|
|
139
|
+
// just remove the file, it was never there
|
|
140
|
+
safeUnlinkSync(pluginsFile);
|
|
141
|
+
return !safeExistsSync(pluginsFile);
|
|
142
|
+
}
|
|
143
|
+
// Bring back the original file
|
|
144
|
+
safeCopyFileSync(
|
|
145
|
+
originalPluginsFile,
|
|
146
|
+
pluginsFile,
|
|
147
|
+
constants.COPYFILE_FICLONE,
|
|
148
|
+
);
|
|
149
|
+
safeUnlinkSync(originalPluginsFile);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Returns the root directory of the local Coursier cache, or null when it
|
|
157
|
+
* cannot be determined or does not exist.
|
|
158
|
+
*
|
|
159
|
+
* @returns {string|null} Absolute path to the cache root
|
|
160
|
+
*/
|
|
161
|
+
function coursierCacheRoot() {
|
|
162
|
+
const configured = readEnvironmentVariable("COURSIER_CACHE");
|
|
163
|
+
let cacheRoot = configured;
|
|
164
|
+
if (!cacheRoot) {
|
|
165
|
+
const home =
|
|
166
|
+
readEnvironmentVariable("HOME") || readEnvironmentVariable("USERPROFILE");
|
|
167
|
+
if (!home) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
if (process.platform === "darwin") {
|
|
171
|
+
cacheRoot = join(home, "Library", "Caches", "Coursier", "v1");
|
|
172
|
+
} else if (process.platform === "win32") {
|
|
173
|
+
const localAppData = readEnvironmentVariable("LOCALAPPDATA");
|
|
174
|
+
if (localAppData) {
|
|
175
|
+
cacheRoot = join(localAppData, "Coursier", "Cache", "v1");
|
|
176
|
+
} else {
|
|
177
|
+
cacheRoot = join(home, "AppData", "Local", "Coursier", "Cache", "v1");
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
cacheRoot = join(home, ".cache", "coursier", "v1");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return safeExistsSync(cacheRoot) ? cacheRoot : null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Coursier stores an artifact at
|
|
187
|
+
// <cacheRoot>/<protocol>/<host>/<repo path...>/<groupPath>/<name>/<version>/,
|
|
188
|
+
// so the only unknown part of the path is the repository prefix. Those prefixes
|
|
189
|
+
// are enumerated once per cache root with a shallow, depth-bounded scan and then
|
|
190
|
+
// probed directly. The previous implementation instead ran a recursive `**` glob
|
|
191
|
+
// across the whole cache for every single coordinate - twice, once for the
|
|
192
|
+
// registry URL and once for the jar - which costs O(cache size) per lookup
|
|
193
|
+
// regardless of whether the artifact is present. On a large shared CI cache that
|
|
194
|
+
// turned a few hundred packages into tens of minutes of directory walking.
|
|
195
|
+
// See https://github.com/cdxgen/cdxgen/issues/4291
|
|
196
|
+
const _repoRootsCache = new Map();
|
|
197
|
+
|
|
198
|
+
// A repository prefix always starts with <protocol>/<host>, and in practice adds
|
|
199
|
+
// at most a couple of path segments ("maven2", "content/repositories/releases").
|
|
200
|
+
// The scan stops at this depth so that it never descends into the group-id
|
|
201
|
+
// directories, which is where the bulk of a cache lives.
|
|
202
|
+
const MAX_REPO_PREFIX_DEPTH = 5;
|
|
203
|
+
|
|
204
|
+
function coursierRepoRoots(cacheRoot) {
|
|
205
|
+
if (_repoRootsCache.has(cacheRoot)) {
|
|
206
|
+
return _repoRootsCache.get(cacheRoot);
|
|
207
|
+
}
|
|
208
|
+
const roots = [];
|
|
209
|
+
// Breadth-first so that shallower prefixes, which are the more common ones,
|
|
210
|
+
// are probed first.
|
|
211
|
+
let frontier = [[]];
|
|
212
|
+
for (let depth = 1; depth <= MAX_REPO_PREFIX_DEPTH; depth++) {
|
|
213
|
+
const next = [];
|
|
214
|
+
for (const parts of frontier) {
|
|
215
|
+
let entries;
|
|
216
|
+
try {
|
|
217
|
+
entries = readdirSync(join(cacheRoot, ...parts), {
|
|
218
|
+
withFileTypes: true,
|
|
219
|
+
});
|
|
220
|
+
} catch (_err) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
for (const entry of entries) {
|
|
224
|
+
if (!entry.isDirectory()) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const childParts = [...parts, entry.name];
|
|
228
|
+
// <protocol>/<host> is the shortest thing that can be a repository.
|
|
229
|
+
if (depth >= 2) {
|
|
230
|
+
roots.push(childParts);
|
|
231
|
+
}
|
|
232
|
+
next.push(childParts);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
frontier = next;
|
|
236
|
+
if (!frontier.length) {
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
_repoRootsCache.set(cacheRoot, roots);
|
|
241
|
+
return roots;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Converts a repository prefix in the Coursier cache layout into a URL.
|
|
246
|
+
*
|
|
247
|
+
* @param {string[]} parts Path segments of the prefix, relative to the cache root
|
|
248
|
+
* @returns {string|null} The repository URL
|
|
249
|
+
*/
|
|
250
|
+
function repoPrefixToUrl(parts) {
|
|
251
|
+
if (!parts || parts.length < 2) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
const protocol = parts[0];
|
|
255
|
+
if (protocol === "file") {
|
|
256
|
+
let localPath = parts.slice(1).join("/");
|
|
257
|
+
if (!localPath.startsWith("/")) {
|
|
258
|
+
localPath = `/${localPath}`;
|
|
259
|
+
}
|
|
260
|
+
return `file://${localPath}`;
|
|
261
|
+
}
|
|
262
|
+
const host = parts[1];
|
|
263
|
+
const repoPath = parts.slice(2).join("/");
|
|
264
|
+
let repoUrl = `${protocol}://${host}`;
|
|
265
|
+
if (repoPath) {
|
|
266
|
+
repoUrl += `/${repoPath}`;
|
|
267
|
+
}
|
|
268
|
+
if (repoUrl.endsWith("/")) {
|
|
269
|
+
repoUrl = repoUrl.substring(0, repoUrl.length - 1);
|
|
270
|
+
}
|
|
271
|
+
return repoUrl;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Memoized so that the registry URL and the jar path for one coordinate cost a
|
|
275
|
+
// single lookup between them.
|
|
276
|
+
const _coursierLocationCache = new Map();
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Locate a Maven coordinate in the local Coursier cache.
|
|
280
|
+
*
|
|
281
|
+
* @param {string} group Maven groupId
|
|
282
|
+
* @param {string} name Maven artifactId (original name with suffix if applicable)
|
|
283
|
+
* @param {string} version Package version
|
|
284
|
+
* @returns {{ repoUrl: string, dir: string }|null} The repository URL and the artifact directory
|
|
285
|
+
*/
|
|
286
|
+
function locateInCoursierCache(group, name, version) {
|
|
287
|
+
if (!group || !name || !version) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const cacheRoot = coursierCacheRoot();
|
|
291
|
+
if (!cacheRoot) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
// The cache root is part of the key so that a changed COURSIER_CACHE is never
|
|
295
|
+
// answered from a memo built against the previous one.
|
|
296
|
+
const cacheKey = `${cacheRoot}|${group}:${name}:${version}`;
|
|
297
|
+
if (_coursierLocationCache.has(cacheKey)) {
|
|
298
|
+
return _coursierLocationCache.get(cacheKey);
|
|
299
|
+
}
|
|
300
|
+
const groupParts = group.split(".");
|
|
301
|
+
const roots = coursierRepoRoots(cacheRoot);
|
|
302
|
+
let result = null;
|
|
303
|
+
for (let i = 0; i < roots.length; i++) {
|
|
304
|
+
const dir = join(cacheRoot, ...roots[i], ...groupParts, name, version);
|
|
305
|
+
if (safeExistsSync(dir)) {
|
|
306
|
+
const repoUrl = repoPrefixToUrl(roots[i]);
|
|
307
|
+
if (repoUrl) {
|
|
308
|
+
result = { repoUrl, dir };
|
|
309
|
+
// Most coordinates in a build come from the same handful of
|
|
310
|
+
// repositories, so keeping the one that just matched at the front makes
|
|
311
|
+
// the common case a single stat call.
|
|
312
|
+
if (i > 0) {
|
|
313
|
+
roots.unshift(roots.splice(i, 1)[0]);
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
_coursierLocationCache.set(cacheKey, result);
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Find the repository URL from the local Coursier cache for a given Maven package.
|
|
325
|
+
*
|
|
326
|
+
* @param {string} group Maven groupId
|
|
327
|
+
* @param {string} name Maven artifactId (original name with suffix if applicable)
|
|
328
|
+
* @param {string} version Package version
|
|
329
|
+
* @returns {string|null} The repository URL or null if not found
|
|
330
|
+
*/
|
|
331
|
+
export function findCoursierRegistryUrl(group, name, version) {
|
|
332
|
+
return locateInCoursierCache(group, name, version)?.repoUrl || null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Test if a given URL exists (returns 2xx/3xx for http/https, or exists on disk for file)
|
|
337
|
+
*
|
|
338
|
+
* @param {string} url URL to test
|
|
339
|
+
* @returns {Promise<boolean>} true if URL exists
|
|
340
|
+
*/
|
|
341
|
+
export async function testUrlExists(url) {
|
|
342
|
+
if (!url) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
if (url.startsWith("file://")) {
|
|
346
|
+
let localPath = url.substring(7);
|
|
347
|
+
if (process.platform === "win32" && localPath.startsWith("/")) {
|
|
348
|
+
localPath = localPath.substring(1);
|
|
349
|
+
}
|
|
350
|
+
return safeExistsSync(localPath);
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
const response = await cdxgenAgent.head(url, {
|
|
354
|
+
timeout: { request: 3000 },
|
|
355
|
+
retry: { limit: 0 },
|
|
356
|
+
followRedirect: true,
|
|
357
|
+
});
|
|
358
|
+
return response.statusCode >= 200 && response.statusCode < 400;
|
|
359
|
+
} catch (_err) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Find the local jar path in Coursier cache if it exists.
|
|
366
|
+
*
|
|
367
|
+
* @param {string} group Maven groupId
|
|
368
|
+
* @param {string} name Maven artifactId (original name with suffix)
|
|
369
|
+
* @param {string} version Package version
|
|
370
|
+
* @returns {string|null} local jar path or null
|
|
371
|
+
*/
|
|
372
|
+
export function findLocalJarPath(group, name, version) {
|
|
373
|
+
const location = locateInCoursierCache(group, name, version);
|
|
374
|
+
if (!location) {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
// The conventionally named jar is checked first so that the directory only has
|
|
378
|
+
// to be listed for the unusual layouts.
|
|
379
|
+
const conventional = join(location.dir, `${name}-${version}.jar`);
|
|
380
|
+
if (safeExistsSync(conventional)) {
|
|
381
|
+
return conventional;
|
|
382
|
+
}
|
|
383
|
+
let entries;
|
|
384
|
+
try {
|
|
385
|
+
entries = readdirSync(location.dir);
|
|
386
|
+
} catch (_err) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
for (const entry of entries) {
|
|
390
|
+
// A sources or javadoc jar is not the artifact and must not be hashed as if
|
|
391
|
+
// it were.
|
|
392
|
+
if (
|
|
393
|
+
entry.endsWith(".jar") &&
|
|
394
|
+
!entry.endsWith("-sources.jar") &&
|
|
395
|
+
!entry.endsWith("-javadoc.jar")
|
|
396
|
+
) {
|
|
397
|
+
return join(location.dir, entry);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Memoization cache for resolveJarDistribution. The sbt dependency tree
|
|
404
|
+
// repeats the same coordinates many times (thousands of lines resolving to a
|
|
405
|
+
// few hundred unique packages), and each resolution performs recursive globs
|
|
406
|
+
// over the Coursier cache plus jar hashing. Without this cache, parsing a
|
|
407
|
+
// large tree performed the same expensive lookups over and over, which could
|
|
408
|
+
// take many minutes and appear as a hang. See
|
|
409
|
+
// https://github.com/cdxgen/cdxgen/issues/4291
|
|
410
|
+
const _jarDistributionCache = new Map();
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Resolve the repo/jar download URLs and optional hashes for a Maven coordinate.
|
|
414
|
+
*
|
|
415
|
+
* Looks up the Coursier registry URL for the coordinate and, when the jar is
|
|
416
|
+
* present in the local Coursier cache, computes MD5/SHA-1/SHA-256/SHA-512
|
|
417
|
+
* digests. Results are memoized per coordinate.
|
|
418
|
+
*
|
|
419
|
+
* @param {string} group Maven groupId.
|
|
420
|
+
* @param {string} name Maven artifactId.
|
|
421
|
+
* @param {string} version Package version.
|
|
422
|
+
* @returns {Promise<{repoUrl: string, jarUrl: string, hashes?: Array<{alg: string, content: string}>}|null>}
|
|
423
|
+
* Resolved URLs with optional hashes, or null when no registry URL is found.
|
|
424
|
+
*/
|
|
425
|
+
export async function resolveJarDistribution(group, name, version) {
|
|
426
|
+
const cacheKey = `${coursierCacheRoot()}|${group}:${name}:${version}`;
|
|
427
|
+
if (_jarDistributionCache.has(cacheKey)) {
|
|
428
|
+
return _jarDistributionCache.get(cacheKey);
|
|
429
|
+
}
|
|
430
|
+
const repoUrl = findCoursierRegistryUrl(group, name, version);
|
|
431
|
+
if (!repoUrl) {
|
|
432
|
+
_jarDistributionCache.set(cacheKey, null);
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
const groupPath = group.replace(/\./g, "/");
|
|
436
|
+
const jarUrl = `${repoUrl}/${groupPath}/${name}/${version}/${name}-${version}.jar`;
|
|
437
|
+
const result = { repoUrl, jarUrl };
|
|
438
|
+
const localJarPath = findLocalJarPath(group, name, version);
|
|
439
|
+
if (localJarPath) {
|
|
440
|
+
try {
|
|
441
|
+
const hashValues = await multiChecksumFile(
|
|
442
|
+
["md5", "sha1", "sha256", "sha512"],
|
|
443
|
+
localJarPath,
|
|
444
|
+
);
|
|
445
|
+
result.hashes = [
|
|
446
|
+
{ alg: "MD5", content: hashValues["md5"] },
|
|
447
|
+
{ alg: "SHA-1", content: hashValues["sha1"] },
|
|
448
|
+
{ alg: "SHA-256", content: hashValues["sha256"] },
|
|
449
|
+
{ alg: "SHA-512", content: hashValues["sha512"] },
|
|
450
|
+
];
|
|
451
|
+
} catch (_err) {
|
|
452
|
+
// ignore
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
_jarDistributionCache.set(cacheKey, result);
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Parse an sbt dependency tree output file and return the package list and dependency tree.
|
|
461
|
+
*
|
|
462
|
+
* Reads a file produced by the sbt `dependencyTree` command and extracts Maven artifact
|
|
463
|
+
* coordinates, building a hierarchical dependency graph. Evicted packages and ranges are ignored.
|
|
464
|
+
*
|
|
465
|
+
* @param {string} sbtTreeFile Path to the sbt dependency tree output file
|
|
466
|
+
* @returns {{ pkgList: Object[], dependenciesList: Object[] }}
|
|
467
|
+
*/
|
|
468
|
+
export async function parseSbtTree(sbtTreeFile) {
|
|
469
|
+
const pkgList = [];
|
|
470
|
+
const dependenciesList = [];
|
|
471
|
+
const keys_cache = {};
|
|
472
|
+
const level_trees = {};
|
|
473
|
+
const tmpA = readFileSync(sbtTreeFile, { encoding: "utf-8" }).split("\n");
|
|
474
|
+
let last_level = 0;
|
|
475
|
+
let last_purl = "";
|
|
476
|
+
let stack = [];
|
|
477
|
+
let first_purl = "";
|
|
478
|
+
// Depth of the shallowest node whose subtree is being discarded, so that the
|
|
479
|
+
// transitive dependencies of an evicted version are dropped with it rather
|
|
480
|
+
// than being reparented onto whichever node happened to be emitted last.
|
|
481
|
+
let skipBelowLevel = -1;
|
|
482
|
+
for (let l of tmpA) {
|
|
483
|
+
l = l.replaceAll("\r", "");
|
|
484
|
+
if (!l.trim().length) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
let level = 0;
|
|
488
|
+
const tmpB = l.split("+-");
|
|
489
|
+
if (tmpB.length > 1) {
|
|
490
|
+
level = Math.floor(tmpB[0].length / 2);
|
|
491
|
+
} else if (l.trimStart() !== l) {
|
|
492
|
+
// An indented line without a `+-` marker is a cycle back-reference (`#-`)
|
|
493
|
+
// or the blank spacer sbt emits between sibling groups. Neither is a node
|
|
494
|
+
// and neither may disturb the level bookkeeping.
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (skipBelowLevel >= 0) {
|
|
498
|
+
if (level > skipBelowLevel) {
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
skipBelowLevel = -1;
|
|
502
|
+
}
|
|
503
|
+
// Ignore evicted packages: the version that won the conflict is listed
|
|
504
|
+
// separately, so the evicted node and everything under it is noise.
|
|
505
|
+
// | +-org.scala-lang:scala3-library_3:3.1.3 (evicted by: 3.3.0)
|
|
506
|
+
if (l.includes("(evicted")) {
|
|
507
|
+
skipBelowLevel = level;
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
let isLibrary = false;
|
|
511
|
+
if (l.endsWith("[S]")) {
|
|
512
|
+
isLibrary = true;
|
|
513
|
+
}
|
|
514
|
+
const pkgLine = tmpB[tmpB.length - 1].split(" ")[0];
|
|
515
|
+
if (!pkgLine.includes(":")) {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
// A version range rather than a resolved version, and a coordinate that the
|
|
519
|
+
// ascii graph truncated because it did not fit the configured width, are both
|
|
520
|
+
// unusable. Emitting them would produce a component with a bogus version - or,
|
|
521
|
+
// when the truncation cut into the artifact id, an invalid purl.
|
|
522
|
+
// | | | | | | +-org.eclipse.platform:org.eclipse.equinox.common:[3.15.100,4.0...
|
|
523
|
+
// | | | | | +-com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-anno..
|
|
524
|
+
if (
|
|
525
|
+
pkgLine.includes(",") ||
|
|
526
|
+
pkgLine.includes("[") ||
|
|
527
|
+
pkgLine.endsWith("..")
|
|
528
|
+
) {
|
|
529
|
+
skipBelowLevel = level;
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const pkgParts = pkgLine.split(":");
|
|
533
|
+
let group = "";
|
|
534
|
+
let name = "";
|
|
535
|
+
let version = "";
|
|
536
|
+
if (pkgParts.length === 3) {
|
|
537
|
+
group = pkgParts[0];
|
|
538
|
+
name = pkgParts[1];
|
|
539
|
+
version = pkgParts[2];
|
|
540
|
+
}
|
|
541
|
+
// A maven purl requires a namespace, so a coordinate that did not yield all
|
|
542
|
+
// three parts is skipped rather than turned into an invalid component.
|
|
543
|
+
if (!group.length || !name.length || !version.length) {
|
|
544
|
+
if (DEBUG_MODE) {
|
|
545
|
+
console.log(pkgLine, "was not parsed correctly!");
|
|
546
|
+
}
|
|
547
|
+
skipBelowLevel = level;
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
const originalName = name;
|
|
551
|
+
const scalaSuffixRegex = /_(2\.\d+|3)$/;
|
|
552
|
+
const match = name.match(scalaSuffixRegex);
|
|
553
|
+
let compilerVersion = null;
|
|
554
|
+
if (match) {
|
|
555
|
+
compilerVersion = match[1];
|
|
556
|
+
name = name.replace(scalaSuffixRegex, "");
|
|
557
|
+
}
|
|
558
|
+
const distInfo = await resolveJarDistribution(group, originalName, version);
|
|
559
|
+
const qualifiers = { type: "jar" };
|
|
560
|
+
if (distInfo && !distInfo.repoUrl.startsWith("file://")) {
|
|
561
|
+
qualifiers.repository_url = distInfo.repoUrl;
|
|
562
|
+
}
|
|
563
|
+
const purlString = build({
|
|
564
|
+
type: "maven",
|
|
565
|
+
namespace: group || null,
|
|
566
|
+
name: name,
|
|
567
|
+
version: version || null,
|
|
568
|
+
qualifiers: qualifiers || null,
|
|
569
|
+
});
|
|
570
|
+
// The dependency graph has to be keyed on the same string the components use
|
|
571
|
+
// as their `bom-ref`. `repository_url` percent-encodes the `//` of the
|
|
572
|
+
// repository URL, so using the raw purl here left every cached package with a
|
|
573
|
+
// ref that matched no component and the whole tree was dropped downstream.
|
|
574
|
+
// See https://github.com/cdxgen/cdxgen/issues/4291
|
|
575
|
+
const bomRef = decodeURIComponent(purlString);
|
|
576
|
+
// Filter duplicates
|
|
577
|
+
if (!keys_cache[purlString]) {
|
|
578
|
+
const adep = {
|
|
579
|
+
group,
|
|
580
|
+
name,
|
|
581
|
+
version,
|
|
582
|
+
purl: purlString,
|
|
583
|
+
"bom-ref": bomRef,
|
|
584
|
+
evidence: {
|
|
585
|
+
identity: {
|
|
586
|
+
field: "purl",
|
|
587
|
+
confidence: 1,
|
|
588
|
+
concludedValue: purlString,
|
|
589
|
+
methods: [
|
|
590
|
+
{
|
|
591
|
+
technique: "manifest-analysis",
|
|
592
|
+
confidence: 1,
|
|
593
|
+
value: sbtTreeFile,
|
|
594
|
+
},
|
|
595
|
+
],
|
|
596
|
+
},
|
|
597
|
+
},
|
|
598
|
+
};
|
|
599
|
+
if (isLibrary) {
|
|
600
|
+
adep["type"] = "library";
|
|
601
|
+
}
|
|
602
|
+
const props = [];
|
|
603
|
+
if (compilerVersion) {
|
|
604
|
+
props.push({
|
|
605
|
+
name: "cdx:scala:compilerVersion",
|
|
606
|
+
value: compilerVersion,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
if (props.length > 0) {
|
|
610
|
+
adep.properties = props;
|
|
611
|
+
}
|
|
612
|
+
if (distInfo) {
|
|
613
|
+
if (!distInfo.jarUrl.startsWith("file://")) {
|
|
614
|
+
adep.externalReferences = [
|
|
615
|
+
{
|
|
616
|
+
type: "distribution",
|
|
617
|
+
url: distInfo.jarUrl,
|
|
618
|
+
},
|
|
619
|
+
];
|
|
620
|
+
}
|
|
621
|
+
if (distInfo.hashes) {
|
|
622
|
+
adep.hashes = distInfo.hashes;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
pkgList.push(adep);
|
|
626
|
+
keys_cache[purlString] = true;
|
|
627
|
+
}
|
|
628
|
+
// From here the logic is similar to parsing gradle tree
|
|
629
|
+
if (!level_trees[bomRef]) {
|
|
630
|
+
level_trees[bomRef] = [];
|
|
631
|
+
}
|
|
632
|
+
if (level === 0) {
|
|
633
|
+
first_purl = bomRef;
|
|
634
|
+
stack = [bomRef];
|
|
635
|
+
} else if (last_purl === "") {
|
|
636
|
+
stack.push(bomRef);
|
|
637
|
+
} else if (level > last_level) {
|
|
638
|
+
const cnodes = level_trees[last_purl] || [];
|
|
639
|
+
if (!cnodes.includes(bomRef)) {
|
|
640
|
+
cnodes.push(bomRef);
|
|
641
|
+
}
|
|
642
|
+
level_trees[last_purl] = cnodes;
|
|
643
|
+
if (stack[stack.length - 1] !== bomRef) {
|
|
644
|
+
stack.push(bomRef);
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
for (let i = 0; i < last_level - level + 1; i++) {
|
|
648
|
+
stack.pop();
|
|
649
|
+
}
|
|
650
|
+
const last_stack =
|
|
651
|
+
stack.length > 0 ? stack[stack.length - 1] : first_purl;
|
|
652
|
+
const cnodes = level_trees[last_stack] || [];
|
|
653
|
+
if (!cnodes.includes(bomRef)) {
|
|
654
|
+
cnodes.push(bomRef);
|
|
655
|
+
}
|
|
656
|
+
level_trees[last_stack] = cnodes;
|
|
657
|
+
stack.push(bomRef);
|
|
658
|
+
}
|
|
659
|
+
last_level = level;
|
|
660
|
+
last_purl = bomRef;
|
|
661
|
+
}
|
|
662
|
+
for (const lk of Object.keys(level_trees)) {
|
|
663
|
+
dependenciesList.push({
|
|
664
|
+
ref: lk,
|
|
665
|
+
dependsOn: [...new Set(level_trees[lk])].sort(),
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
return { pkgList, dependenciesList };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Parse sbt lock file
|
|
673
|
+
*
|
|
674
|
+
* @param {string} pkgLockFile build.sbt.lock file
|
|
675
|
+
*/
|
|
676
|
+
export async function parseSbtLock(pkgLockFile) {
|
|
677
|
+
const pkgList = [];
|
|
678
|
+
if (safeExistsSync(pkgLockFile)) {
|
|
679
|
+
const lockData = JSON.parse(
|
|
680
|
+
readFileSync(pkgLockFile, { encoding: "utf-8" }),
|
|
681
|
+
);
|
|
682
|
+
if (lockData?.dependencies) {
|
|
683
|
+
for (const pkg of lockData.dependencies) {
|
|
684
|
+
const artifacts = pkg.artifacts || undefined;
|
|
685
|
+
let integrity = "";
|
|
686
|
+
if (artifacts?.length) {
|
|
687
|
+
integrity = artifacts[0].hash.replace("sha1:", "sha1-");
|
|
688
|
+
}
|
|
689
|
+
let compScope;
|
|
690
|
+
if (pkg.configurations) {
|
|
691
|
+
if (pkg.configurations.includes("runtime")) {
|
|
692
|
+
compScope = "required";
|
|
693
|
+
} else {
|
|
694
|
+
compScope = "optional";
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
const originalName = pkg.name;
|
|
698
|
+
let name = pkg.name;
|
|
699
|
+
const scalaSuffixRegex = /_(2\.\d+|3)$/;
|
|
700
|
+
const match = name.match(scalaSuffixRegex);
|
|
701
|
+
let compilerVersion = null;
|
|
702
|
+
if (match) {
|
|
703
|
+
compilerVersion = match[1];
|
|
704
|
+
name = name.replace(scalaSuffixRegex, "");
|
|
705
|
+
}
|
|
706
|
+
const distInfo = await resolveJarDistribution(
|
|
707
|
+
pkg.org,
|
|
708
|
+
originalName,
|
|
709
|
+
pkg.version,
|
|
710
|
+
);
|
|
711
|
+
const props = [
|
|
712
|
+
{
|
|
713
|
+
name: "internal:SrcFile",
|
|
714
|
+
value: pkgLockFile,
|
|
715
|
+
},
|
|
716
|
+
];
|
|
717
|
+
if (compilerVersion) {
|
|
718
|
+
props.push({
|
|
719
|
+
name: "cdx:scala:compilerVersion",
|
|
720
|
+
value: compilerVersion,
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
const qualifiers = { type: "jar" };
|
|
724
|
+
if (distInfo && !distInfo.repoUrl.startsWith("file://")) {
|
|
725
|
+
qualifiers.repository_url = distInfo.repoUrl;
|
|
726
|
+
}
|
|
727
|
+
const purlString = build({
|
|
728
|
+
type: "maven",
|
|
729
|
+
namespace: pkg.org || null,
|
|
730
|
+
name: name,
|
|
731
|
+
version: pkg.version || null,
|
|
732
|
+
qualifiers: qualifiers || null,
|
|
733
|
+
});
|
|
734
|
+
const adep = {
|
|
735
|
+
group: pkg.org,
|
|
736
|
+
name,
|
|
737
|
+
version: pkg.version,
|
|
738
|
+
_integrity: integrity,
|
|
739
|
+
scope: compScope,
|
|
740
|
+
properties: props,
|
|
741
|
+
purl: purlString,
|
|
742
|
+
"bom-ref": decodeURIComponent(purlString),
|
|
743
|
+
evidence: {
|
|
744
|
+
identity: {
|
|
745
|
+
field: "purl",
|
|
746
|
+
confidence: 1,
|
|
747
|
+
concludedValue: purlString,
|
|
748
|
+
methods: [
|
|
749
|
+
{
|
|
750
|
+
technique: "manifest-analysis",
|
|
751
|
+
confidence: 1,
|
|
752
|
+
value: pkgLockFile,
|
|
753
|
+
},
|
|
754
|
+
],
|
|
755
|
+
},
|
|
756
|
+
},
|
|
757
|
+
};
|
|
758
|
+
if (distInfo) {
|
|
759
|
+
if (!distInfo.jarUrl.startsWith("file://")) {
|
|
760
|
+
adep.externalReferences = [
|
|
761
|
+
{
|
|
762
|
+
type: "distribution",
|
|
763
|
+
url: distInfo.jarUrl,
|
|
764
|
+
},
|
|
765
|
+
];
|
|
766
|
+
}
|
|
767
|
+
if (distInfo.hashes) {
|
|
768
|
+
adep.hashes = distInfo.hashes;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
pkgList.push(adep);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return pkgList;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Parse the root build.sbt to extract the aggregate project name, organization, and version.
|
|
780
|
+
*
|
|
781
|
+
* @param {string} projectPath Directory path of the project
|
|
782
|
+
* @returns {{ name: string, group: string, version: string }|null}
|
|
783
|
+
*/
|
|
784
|
+
export function parseSbtRootProject(projectPath) {
|
|
785
|
+
const buildSbt = join(projectPath, "build.sbt");
|
|
786
|
+
if (!safeExistsSync(buildSbt)) {
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
try {
|
|
790
|
+
const content = readFileSync(buildSbt, { encoding: "utf-8" });
|
|
791
|
+
const nameMatch = content.match(/^name\s*:=\s*"([^"]+)"/m);
|
|
792
|
+
const orgMatch = content.match(
|
|
793
|
+
/ThisBuild\s*\/\s*organization\s*:=\s*"([^"]+)"/m,
|
|
794
|
+
);
|
|
795
|
+
const versionMatch = content.match(
|
|
796
|
+
/ThisBuild\s*\/\s*version\s*:=\s*"([^"]+)"/m,
|
|
797
|
+
);
|
|
798
|
+
if (!nameMatch || !versionMatch) {
|
|
799
|
+
return null;
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
name: nameMatch[1],
|
|
803
|
+
group: orgMatch ? orgMatch[1] : "",
|
|
804
|
+
version: versionMatch[1],
|
|
805
|
+
};
|
|
806
|
+
} catch (_err) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Discover SBT subproject names statically by parsing build.sbt and project files.
|
|
813
|
+
*
|
|
814
|
+
* @param {string} projectPath Directory path of the project
|
|
815
|
+
* @returns {string[]} List of discovered subproject names
|
|
816
|
+
*/
|
|
817
|
+
export function discoverSbtProjects(projectPath) {
|
|
818
|
+
const projects = new Set();
|
|
819
|
+
const sbtFiles = getAllFiles(projectPath, "**/*.sbt");
|
|
820
|
+
const scalaFiles = getAllFiles(projectPath, "project/**/*.scala");
|
|
821
|
+
const allFiles = [...sbtFiles, ...scalaFiles];
|
|
822
|
+
|
|
823
|
+
const projectRegex =
|
|
824
|
+
/(?:lazy\s+val|val)\s+([a-zA-Z0-9_-]+)\s*=\s*(?:project|Projects\.|(project\s+in))/g;
|
|
825
|
+
|
|
826
|
+
for (const file of allFiles) {
|
|
827
|
+
try {
|
|
828
|
+
const content = readFileSync(file, { encoding: "utf-8" });
|
|
829
|
+
let match;
|
|
830
|
+
projectRegex.lastIndex = 0;
|
|
831
|
+
while ((match = projectRegex.exec(content)) !== null) {
|
|
832
|
+
const projName = match[1].trim();
|
|
833
|
+
if (projName && projName !== "root") {
|
|
834
|
+
projects.add(projName);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
} catch (_err) {
|
|
838
|
+
// ignore
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return [...projects];
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Parse the output of the sbt `projects` command to extract the real project
|
|
846
|
+
* identifiers as understood by sbt. This is more accurate than scraping the
|
|
847
|
+
* build files with a regex (see {@link discoverSbtProjects}), since it relies
|
|
848
|
+
* on sbt's own project resolution and therefore avoids false positives from
|
|
849
|
+
* commented-out code, examples or values that merely look like project
|
|
850
|
+
* definitions.
|
|
851
|
+
*
|
|
852
|
+
* A typical `sbt projects` output looks like:
|
|
853
|
+
*
|
|
854
|
+
* ```
|
|
855
|
+
* [info] In file:/path/to/build/
|
|
856
|
+
* [info] * chen
|
|
857
|
+
* [info] platform
|
|
858
|
+
* [info] dataflowengineoss
|
|
859
|
+
* ```
|
|
860
|
+
*
|
|
861
|
+
* The project marked with `*` is the currently selected (usually the
|
|
862
|
+
* aggregating root) project.
|
|
863
|
+
*
|
|
864
|
+
* @param {string} stdout Raw stdout captured from `sbt projects`
|
|
865
|
+
* @returns {{projects: string[], root: string | undefined}} The discovered
|
|
866
|
+
* project ids and the currently selected (root) project id, if any.
|
|
867
|
+
*/
|
|
868
|
+
export function parseSbtProjects(stdout) {
|
|
869
|
+
const projects = [];
|
|
870
|
+
let root;
|
|
871
|
+
if (!stdout) {
|
|
872
|
+
return { projects, root };
|
|
873
|
+
}
|
|
874
|
+
const lines = stdout.split(/\r?\n/);
|
|
875
|
+
// Matches lines such as `[info] * name` or `[info] name`.
|
|
876
|
+
// The optional `[info]` prefix is stripped first so we can tolerate
|
|
877
|
+
// different sbt log levels/formats.
|
|
878
|
+
const projectLineRegex = /^(\*)?\s*([a-zA-Z0-9_.-]+)\s*$/;
|
|
879
|
+
let inProjectsBlock = false;
|
|
880
|
+
for (const rawLine of lines) {
|
|
881
|
+
// Strip the leading `[info]`/`[warn]` log prefix, if any.
|
|
882
|
+
const line = rawLine.replace(/^\[[a-z]+\]\s?/i, "");
|
|
883
|
+
if (/^In\s+\S+/.test(line.trim())) {
|
|
884
|
+
inProjectsBlock = true;
|
|
885
|
+
continue;
|
|
886
|
+
}
|
|
887
|
+
if (!inProjectsBlock) {
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
const trimmed = line.trim();
|
|
891
|
+
if (!trimmed) {
|
|
892
|
+
// A blank line terminates the projects listing.
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
const match = projectLineRegex.exec(trimmed);
|
|
896
|
+
if (!match) {
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
const isCurrent = Boolean(match[1]);
|
|
900
|
+
const projName = match[2];
|
|
901
|
+
if (!projName || projName === "info" || projName === "warn") {
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
projects.push(projName);
|
|
905
|
+
if (isCurrent) {
|
|
906
|
+
root = projName;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
return { projects, root };
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Parse plugins.sbt files to extract sbt plugins as development dependencies.
|
|
914
|
+
*
|
|
915
|
+
* @param {string} projectPath Directory path of the project
|
|
916
|
+
* @returns {Object[]} List of parsed dependency components
|
|
917
|
+
*/
|
|
918
|
+
export function parseSbtPlugins(projectPath) {
|
|
919
|
+
const plugins = [];
|
|
920
|
+
const pluginFiles = getAllFiles(projectPath, "**/plugins.sbt");
|
|
921
|
+
|
|
922
|
+
const pluginRegex =
|
|
923
|
+
/addSbtPlugin\(\s*(["'])([^"'\s]+)\1\s*(%%?)\s*(["'])([^"'\s]+)\4\s*%\s*(["'])([^"'\s]+)\6\s*\)/g;
|
|
924
|
+
|
|
925
|
+
for (const file of pluginFiles) {
|
|
926
|
+
try {
|
|
927
|
+
const content = readFileSync(file, { encoding: "utf-8" });
|
|
928
|
+
let match;
|
|
929
|
+
pluginRegex.lastIndex = 0;
|
|
930
|
+
while ((match = pluginRegex.exec(content)) !== null) {
|
|
931
|
+
const group = match[2];
|
|
932
|
+
const name = match[5];
|
|
933
|
+
const version = match[7];
|
|
934
|
+
const purl = mavenPurl(group, name, version, { type: "jar" });
|
|
935
|
+
|
|
936
|
+
const adep = {
|
|
937
|
+
group,
|
|
938
|
+
name,
|
|
939
|
+
version,
|
|
940
|
+
scope: "optional",
|
|
941
|
+
properties: [
|
|
942
|
+
{
|
|
943
|
+
name: "cdx:sbt:package:development",
|
|
944
|
+
value: "true",
|
|
945
|
+
},
|
|
946
|
+
],
|
|
947
|
+
evidence: {
|
|
948
|
+
identity: {
|
|
949
|
+
field: "purl",
|
|
950
|
+
confidence: 1,
|
|
951
|
+
methods: [
|
|
952
|
+
{
|
|
953
|
+
technique: "manifest-analysis",
|
|
954
|
+
confidence: 1,
|
|
955
|
+
value: file,
|
|
956
|
+
},
|
|
957
|
+
],
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
};
|
|
961
|
+
if (purl) {
|
|
962
|
+
adep.evidence.identity.concludedValue = purl;
|
|
963
|
+
}
|
|
964
|
+
applyPurl(adep, purl);
|
|
965
|
+
plugins.push(adep);
|
|
966
|
+
}
|
|
967
|
+
} catch (_err) {
|
|
968
|
+
// ignore
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return plugins;
|
|
972
|
+
}
|