@cdxgen/cdxgen 0.0.1 → 13.0.1

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.
Files changed (722) hide show
  1. package/README.md +921 -87
  2. package/bin/audit.js +239 -0
  3. package/bin/cdxgen.js +2335 -0
  4. package/bin/convert.js +220 -0
  5. package/bin/evinse.js +353 -0
  6. package/bin/hbom.js +504 -0
  7. package/bin/repl.js +2224 -0
  8. package/bin/sign.js +195 -0
  9. package/bin/tracebom.js +303 -0
  10. package/bin/validate.js +268 -0
  11. package/bin/verify.js +189 -0
  12. package/data/README.md +307 -0
  13. package/data/bom-1.4.schema.json +1605 -0
  14. package/data/bom-1.5.schema.json +3660 -0
  15. package/data/bom-1.6.schema.json +5511 -0
  16. package/data/bom-1.7.schema.json +6700 -0
  17. package/data/cbomosdb-queries.json +68 -0
  18. package/data/component-tags.json +339 -0
  19. package/data/container-knowledge-index.json +125 -0
  20. package/data/cosdb-queries.json +17 -0
  21. package/data/crypto-oid.json +1998 -0
  22. package/data/cryptography-defs.json +3793 -0
  23. package/data/cryptography-defs.schema.json +576 -0
  24. package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
  25. package/data/frameworks-list.json +219 -0
  26. package/data/glibc-stdlib.json +117 -0
  27. package/data/gtfobins-index.json +6296 -0
  28. package/data/helpers/init.gradle +71 -0
  29. package/data/jsf-0.82.schema.json +211 -0
  30. package/data/known-licenses.json +82 -0
  31. package/data/lic-mapping.json +338 -0
  32. package/data/license-aliases.json +6624 -0
  33. package/data/license-db.json +39059 -0
  34. package/data/license-deprecations.json +302 -0
  35. package/data/lolbas-index.json +150 -0
  36. package/data/predictive-audit-allowlist.json +11 -0
  37. package/data/pypi-pkg-aliases.json +1199 -0
  38. package/data/python-stdlib.json +308 -0
  39. package/data/queries-darwin.json +193 -0
  40. package/data/queries-win.json +257 -0
  41. package/data/queries.json +268 -0
  42. package/data/ruby-known-modules.json +281 -0
  43. package/data/rules/ai-agent-governance.yaml +323 -0
  44. package/data/rules/ai-bom.yaml +268 -0
  45. package/data/rules/ai-oversight.yaml +186 -0
  46. package/data/rules/ai-provenance.yaml +92 -0
  47. package/data/rules/asar-archives.yaml +150 -0
  48. package/data/rules/cbom-security.yaml +165 -0
  49. package/data/rules/chrome-extensions.yaml +248 -0
  50. package/data/rules/ci-permissions.yaml +802 -0
  51. package/data/rules/container-risk.yaml +353 -0
  52. package/data/rules/dependency-sources.yaml +236 -0
  53. package/data/rules/golem-go.yaml +229 -0
  54. package/data/rules/hbom-compliance.yaml +325 -0
  55. package/data/rules/hbom-performance.yaml +307 -0
  56. package/data/rules/hbom-security.yaml +248 -0
  57. package/data/rules/host-topology.yaml +165 -0
  58. package/data/rules/mcp-servers.yaml +388 -0
  59. package/data/rules/obom-runtime.yaml +1776 -0
  60. package/data/rules/package-integrity.yaml +364 -0
  61. package/data/rules/rootfs-hardening.yaml +179 -0
  62. package/data/rules/vscode-extensions.yaml +237 -0
  63. package/data/spdx-export.schema.json +6794 -0
  64. package/data/spdx-license-list.json +7449 -0
  65. package/data/spdx-licenses.json +759 -0
  66. package/data/spdx.schema.json +819 -0
  67. package/data/templates/README.md +3 -0
  68. package/data/templates/asvs-4.0.3.cdx.json +2943 -0
  69. package/data/templates/asvs-5.0.cdx.json +3046 -0
  70. package/data/templates/bsimm-v13.cdx.json +1008 -0
  71. package/data/templates/masvs-2.0.0.cdx.json +225 -0
  72. package/data/templates/nist-ssdf-1.1.cdx.json +828 -0
  73. package/data/templates/pcissc-secure-slc-1.1.cdx.json +1027 -0
  74. package/data/templates/scvs-1.0.0.cdx.json +813 -0
  75. package/data/templates/ssaf-DRAFT-2023-11.cdx.json +127 -0
  76. package/data/vendor-alias.json +41967 -0
  77. package/data/wrapdb-releases.json +4227 -0
  78. package/index.cjs +15 -0
  79. package/lib/audit/index.js +2800 -0
  80. package/lib/audit/progress.js +114 -0
  81. package/lib/audit/reporters.js +937 -0
  82. package/lib/audit/scoring.js +560 -0
  83. package/lib/audit/targets.js +798 -0
  84. package/lib/cli/bomAssembly.js +1882 -0
  85. package/lib/cli/cliOptions.js +543 -0
  86. package/lib/cli/index.js +2759 -0
  87. package/lib/cli/jsBom.js +2087 -0
  88. package/lib/cli/jvmBom.js +1858 -0
  89. package/lib/cli/managedBom.js +2083 -0
  90. package/lib/cli/nativeBom.js +2125 -0
  91. package/lib/core/activity.js +1087 -0
  92. package/lib/core/env.js +719 -0
  93. package/lib/core/fs.js +1058 -0
  94. package/lib/core/httpClient.js +730 -0
  95. package/lib/core/logger.js +280 -0
  96. package/lib/core/parallel.js +323 -0
  97. package/lib/core/paths.js +70 -0
  98. package/lib/core/projectConfig.js +122 -0
  99. package/lib/core/propertySanitizer.js +174 -0
  100. package/lib/core/spdx.js +5 -0
  101. package/lib/core/state.js +59 -0
  102. package/lib/core/text.js +207 -0
  103. package/lib/core/ui.js +920 -0
  104. package/lib/core/urls.js +84 -0
  105. package/lib/ecosystems/asarutils.js +1636 -0
  106. package/lib/ecosystems/bunutils.js +402 -0
  107. package/lib/ecosystems/caxa.js +77 -0
  108. package/lib/ecosystems/chromextutils.js +1174 -0
  109. package/lib/ecosystems/cmakeResolver.js +587 -0
  110. package/lib/ecosystems/cppEvidence.js +305 -0
  111. package/lib/ecosystems/denoutils.js +1094 -0
  112. package/lib/ecosystems/dotnetutils.js +132 -0
  113. package/lib/ecosystems/ecosystems.js +2772 -0
  114. package/lib/ecosystems/golem.js +1807 -0
  115. package/lib/ecosystems/gradleutils.js +1048 -0
  116. package/lib/ecosystems/jsEvidence.js +317 -0
  117. package/lib/ecosystems/npmutils.js +586 -0
  118. package/lib/ecosystems/parsers-bazel.js +875 -0
  119. package/lib/ecosystems/parsers-dotnet.js +1430 -0
  120. package/lib/ecosystems/parsers-gleam.js +302 -0
  121. package/lib/ecosystems/parsers-go.js +818 -0
  122. package/lib/ecosystems/parsers-js.js +4222 -0
  123. package/lib/ecosystems/parsers-jvm.js +948 -0
  124. package/lib/ecosystems/parsers-misc.js +3191 -0
  125. package/lib/ecosystems/parsers-python.js +2070 -0
  126. package/lib/ecosystems/parsers-rust.js +1294 -0
  127. package/lib/ecosystems/parsers-zig.js +861 -0
  128. package/lib/ecosystems/pep770.js +341 -0
  129. package/lib/ecosystems/pylockutils.js +427 -0
  130. package/lib/ecosystems/pythonutils.js +1281 -0
  131. package/lib/ecosystems/registryProvenance.js +1003 -0
  132. package/lib/ecosystems/remote/huggingface.js +1343 -0
  133. package/lib/ecosystems/rubyutils.js +1629 -0
  134. package/lib/ecosystems/rusi.js +820 -0
  135. package/lib/ecosystems/sbtutils.js +972 -0
  136. package/lib/ecosystems/tea.js +607 -0
  137. package/lib/ecosystems/utils.js +583 -0
  138. package/lib/ecosystems/zigResolver.js +410 -0
  139. package/lib/evinser/db.js +145 -0
  140. package/lib/evinser/evinser.js +2362 -0
  141. package/lib/evinser/scalasem.js +65 -0
  142. package/lib/evinser/swiftsem.js +767 -0
  143. package/lib/helpers/annotationFormatter.js +84 -0
  144. package/lib/helpers/bomSigner.js +312 -0
  145. package/lib/helpers/exportUtils.js +160 -0
  146. package/lib/helpers/remote/dependency-track.js +117 -0
  147. package/lib/helpers/versutils.js +202 -0
  148. package/lib/helpers/vsixutils.js +1069 -0
  149. package/lib/inventory/agentFormulationParser.js +322 -0
  150. package/lib/inventory/aiCollector.js +2140 -0
  151. package/lib/inventory/aiInventory.js +414 -0
  152. package/lib/inventory/aiModelVariants.js +121 -0
  153. package/lib/inventory/aiOversightCollector.js +661 -0
  154. package/lib/inventory/aiProvenanceCollector.js +822 -0
  155. package/lib/inventory/analyzer.js +6089 -0
  156. package/lib/inventory/analyzerScope.js +807 -0
  157. package/lib/inventory/astWorker.js +20 -0
  158. package/lib/inventory/atomUtils.js +1092 -0
  159. package/lib/inventory/auditCategories.js +192 -0
  160. package/lib/inventory/bomUtils.js +369 -0
  161. package/lib/inventory/cacheCommands.js +182 -0
  162. package/lib/inventory/cacheDir.js +104 -0
  163. package/lib/inventory/cbomutils.js +590 -0
  164. package/lib/inventory/cdxrs.js +434 -0
  165. package/lib/inventory/ciParsers/azurePipelines.js +295 -0
  166. package/lib/inventory/ciParsers/circleCi.js +286 -0
  167. package/lib/inventory/ciParsers/common.js +24 -0
  168. package/lib/inventory/ciParsers/githubActions.js +2434 -0
  169. package/lib/inventory/ciParsers/gitlabCi.js +213 -0
  170. package/lib/inventory/ciParsers/jenkins.js +180 -0
  171. package/lib/inventory/citations.js +234 -0
  172. package/lib/inventory/communityAiConfigParser.js +756 -0
  173. package/lib/inventory/containerRisk.js +204 -0
  174. package/lib/inventory/cryptoAlgorithmFamily.js +258 -0
  175. package/lib/inventory/deps.js +807 -0
  176. package/lib/inventory/depsUtils.js +588 -0
  177. package/lib/inventory/display.js +2128 -0
  178. package/lib/inventory/dosai.js +601 -0
  179. package/lib/inventory/dosaiParsers.js +154 -0
  180. package/lib/inventory/dynamic.js +145 -0
  181. package/lib/inventory/envcontext.js +1793 -0
  182. package/lib/inventory/evidenceUtils.js +774 -0
  183. package/lib/inventory/fetchBatch.js +779 -0
  184. package/lib/inventory/fetchRate.js +255 -0
  185. package/lib/inventory/forgeEnricher.js +300 -0
  186. package/lib/inventory/formulationParsers.js +422 -0
  187. package/lib/inventory/gtfobins.js +339 -0
  188. package/lib/inventory/hbom.js +719 -0
  189. package/lib/inventory/hbomAnalysis.js +310 -0
  190. package/lib/inventory/hbomLoader.js +35 -0
  191. package/lib/inventory/hostTopology.js +835 -0
  192. package/lib/inventory/inventoryStats.js +100 -0
  193. package/lib/inventory/jsonLike.js +121 -0
  194. package/lib/inventory/licenseEnhancer.js +918 -0
  195. package/lib/inventory/lolbas.js +285 -0
  196. package/lib/inventory/mcp.js +253 -0
  197. package/lib/inventory/mcpConfigParser.js +683 -0
  198. package/lib/inventory/mcpDiscovery.js +112 -0
  199. package/lib/inventory/mcpPinning.js +209 -0
  200. package/lib/inventory/osPackageResolver.js +493 -0
  201. package/lib/inventory/osinfo.js +383 -0
  202. package/lib/inventory/osqueryTransform.js +274 -0
  203. package/lib/inventory/plugins.js +466 -0
  204. package/lib/inventory/protobom.js +231 -0
  205. package/lib/inventory/protobomLoader.js +43 -0
  206. package/lib/inventory/provenanceUtils.js +224 -0
  207. package/lib/inventory/purl.js +749 -0
  208. package/lib/inventory/rustFormulationParser.js +339 -0
  209. package/lib/inventory/sbomDocument.js +340 -0
  210. package/lib/inventory/source.js +1488 -0
  211. package/lib/inventory/spdx.js +361 -0
  212. package/lib/inventory/spdxExpression.js +512 -0
  213. package/lib/inventory/spdxUtils.js +107 -0
  214. package/lib/inventory/table.js +267 -0
  215. package/lib/inventory/traceRunner.js +439 -0
  216. package/lib/inventory/unicodeScan.js +147 -0
  217. package/lib/managers/binary.js +3459 -0
  218. package/lib/managers/containerutils.js +125 -0
  219. package/lib/managers/docker.js +2145 -0
  220. package/lib/managers/dockerConnection.js +162 -0
  221. package/lib/managers/oci.js +704 -0
  222. package/lib/managers/piptree.js +267 -0
  223. package/lib/parsers/cmakeCache.js +199 -0
  224. package/lib/parsers/gguf.js +492 -0
  225. package/lib/parsers/gitAiNotes.js +233 -0
  226. package/lib/parsers/gitmodules.js +239 -0
  227. package/lib/parsers/htmlExtract.js +610 -0
  228. package/lib/parsers/huggingfaceManifest.js +551 -0
  229. package/lib/parsers/huggingfaceUtils.js +506 -0
  230. package/lib/parsers/iri.js +618 -0
  231. package/lib/parsers/npmrc.js +99 -0
  232. package/lib/parsers/ollama.js +101 -0
  233. package/lib/parsers/xml.js +841 -0
  234. package/lib/server/openapi.yaml +433 -0
  235. package/lib/server/server.js +616 -0
  236. package/lib/stages/postgen/annotator.js +977 -0
  237. package/lib/stages/postgen/auditBom.js +468 -0
  238. package/lib/stages/postgen/postgen.js +1239 -0
  239. package/lib/stages/postgen/ruleEngine.js +731 -0
  240. package/lib/stages/postgen/sortBom.js +195 -0
  241. package/lib/stages/postgen/spdxConverter.js +796 -0
  242. package/lib/stages/postgen/specVersionCompat.js +703 -0
  243. package/lib/stages/pregen/envAudit.js +388 -0
  244. package/lib/stages/pregen/pregen.js +637 -0
  245. package/lib/third-party/README.md +9 -0
  246. package/lib/third-party/arborist/CHANGELOG.md +1109 -0
  247. package/lib/third-party/arborist/LICENSE.md +20 -0
  248. package/lib/third-party/arborist/README.md +315 -0
  249. package/lib/third-party/arborist/lib/arborist/index.js +258 -0
  250. package/lib/third-party/arborist/lib/arborist/load-actual.js +605 -0
  251. package/lib/third-party/arborist/lib/arborist/load-virtual.js +300 -0
  252. package/lib/third-party/arborist/lib/bin-links.js +120 -0
  253. package/lib/third-party/arborist/lib/calc-dep-flags.js +130 -0
  254. package/lib/third-party/arborist/lib/case-insensitive-map.js +51 -0
  255. package/lib/third-party/arborist/lib/consistent-resolve.js +42 -0
  256. package/lib/third-party/arborist/lib/debug.js +50 -0
  257. package/lib/third-party/arborist/lib/dep-valid.js +190 -0
  258. package/lib/third-party/arborist/lib/edge.js +417 -0
  259. package/lib/third-party/arborist/lib/from-path.js +36 -0
  260. package/lib/third-party/arborist/lib/gather-dep-set.js +43 -0
  261. package/lib/third-party/arborist/lib/index.js +22 -0
  262. package/lib/third-party/arborist/lib/inventory.js +138 -0
  263. package/lib/third-party/arborist/lib/link.js +169 -0
  264. package/lib/third-party/arborist/lib/node.js +1673 -0
  265. package/lib/third-party/arborist/lib/npm-extension.js +45 -0
  266. package/lib/third-party/arborist/lib/override-resolves.js +11 -0
  267. package/lib/third-party/arborist/lib/override-set.js +319 -0
  268. package/lib/third-party/arborist/lib/package-extensions.js +289 -0
  269. package/lib/third-party/arborist/lib/printable.js +210 -0
  270. package/lib/third-party/arborist/lib/proc-log.js +30 -0
  271. package/lib/third-party/arborist/lib/realpath.js +100 -0
  272. package/lib/third-party/arborist/lib/relpath.js +4 -0
  273. package/lib/third-party/arborist/lib/shrinkwrap.js +1291 -0
  274. package/lib/third-party/arborist/lib/spec-from-lock.js +34 -0
  275. package/lib/third-party/arborist/lib/tree-check.js +165 -0
  276. package/lib/third-party/arborist/lib/validate-npm-package-name.js +107 -0
  277. package/lib/third-party/arborist/lib/version-from-tgz.js +51 -0
  278. package/lib/third-party/arborist/lib/yarn-lock.js +397 -0
  279. package/lib/validator/bomValidator.js +985 -0
  280. package/lib/validator/complianceEngine.js +241 -0
  281. package/lib/validator/complianceRules.js +1680 -0
  282. package/lib/validator/generated/runtime.mjs +17 -0
  283. package/lib/validator/generated/validate-1.6.mjs +21258 -0
  284. package/lib/validator/generated/validate-1.7.mjs +24803 -0
  285. package/lib/validator/generated/validate-2.0.mjs +22931 -0
  286. package/lib/validator/index.js +246 -0
  287. package/lib/validator/reporters/annotations.js +142 -0
  288. package/lib/validator/reporters/console.js +160 -0
  289. package/lib/validator/reporters/index.js +41 -0
  290. package/lib/validator/reporters/json.js +37 -0
  291. package/lib/validator/reporters/sarif.js +184 -0
  292. package/package.json +209 -26
  293. package/types/bin/audit.d.ts +3 -0
  294. package/types/bin/audit.d.ts.map +1 -0
  295. package/types/bin/cdxgen.d.ts +3 -0
  296. package/types/bin/cdxgen.d.ts.map +1 -0
  297. package/types/bin/convert.d.ts +3 -0
  298. package/types/bin/convert.d.ts.map +1 -0
  299. package/types/bin/evinse.d.ts +3 -0
  300. package/types/bin/evinse.d.ts.map +1 -0
  301. package/types/bin/hbom.d.ts +3 -0
  302. package/types/bin/hbom.d.ts.map +1 -0
  303. package/types/bin/repl.d.ts +3 -0
  304. package/types/bin/repl.d.ts.map +1 -0
  305. package/types/bin/sign.d.ts +3 -0
  306. package/types/bin/sign.d.ts.map +1 -0
  307. package/types/bin/tracebom.d.ts +3 -0
  308. package/types/bin/tracebom.d.ts.map +1 -0
  309. package/types/bin/validate.d.ts +14 -0
  310. package/types/bin/validate.d.ts.map +1 -0
  311. package/types/bin/verify.d.ts +3 -0
  312. package/types/bin/verify.d.ts.map +1 -0
  313. package/types/lib/audit/index.d.ts +153 -0
  314. package/types/lib/audit/index.d.ts.map +1 -0
  315. package/types/lib/audit/progress.d.ts +31 -0
  316. package/types/lib/audit/progress.d.ts.map +1 -0
  317. package/types/lib/audit/reporters.d.ts +62 -0
  318. package/types/lib/audit/reporters.d.ts.map +1 -0
  319. package/types/lib/audit/scoring.d.ts +36 -0
  320. package/types/lib/audit/scoring.d.ts.map +1 -0
  321. package/types/lib/audit/targets.d.ts +77 -0
  322. package/types/lib/audit/targets.d.ts.map +1 -0
  323. package/types/lib/cli/bomAssembly.d.ts +329 -0
  324. package/types/lib/cli/bomAssembly.d.ts.map +1 -0
  325. package/types/lib/cli/cliOptions.d.ts +156 -0
  326. package/types/lib/cli/cliOptions.d.ts.map +1 -0
  327. package/types/lib/cli/index.d.ts +107 -0
  328. package/types/lib/cli/index.d.ts.map +1 -0
  329. package/types/lib/cli/jsBom.d.ts +94 -0
  330. package/types/lib/cli/jsBom.d.ts.map +1 -0
  331. package/types/lib/cli/jvmBom.d.ts +54 -0
  332. package/types/lib/cli/jvmBom.d.ts.map +1 -0
  333. package/types/lib/cli/managedBom.d.ts +105 -0
  334. package/types/lib/cli/managedBom.d.ts.map +1 -0
  335. package/types/lib/cli/nativeBom.d.ts +143 -0
  336. package/types/lib/cli/nativeBom.d.ts.map +1 -0
  337. package/types/lib/core/activity.d.ts +178 -0
  338. package/types/lib/core/activity.d.ts.map +1 -0
  339. package/types/lib/core/env.d.ts +192 -0
  340. package/types/lib/core/env.d.ts.map +1 -0
  341. package/types/lib/core/fs.d.ts +158 -0
  342. package/types/lib/core/fs.d.ts.map +1 -0
  343. package/types/lib/core/httpClient.d.ts +149 -0
  344. package/types/lib/core/httpClient.d.ts.map +1 -0
  345. package/types/lib/core/logger.d.ts +50 -0
  346. package/types/lib/core/logger.d.ts.map +1 -0
  347. package/types/lib/core/parallel.d.ts +95 -0
  348. package/types/lib/core/parallel.d.ts.map +1 -0
  349. package/types/lib/core/paths.d.ts +36 -0
  350. package/types/lib/core/paths.d.ts.map +1 -0
  351. package/types/lib/core/projectConfig.d.ts +23 -0
  352. package/types/lib/core/projectConfig.d.ts.map +1 -0
  353. package/types/lib/core/propertySanitizer.d.ts +23 -0
  354. package/types/lib/core/propertySanitizer.d.ts.map +1 -0
  355. package/types/lib/core/spdx.d.ts +5 -0
  356. package/types/lib/core/spdx.d.ts.map +1 -0
  357. package/types/lib/core/state.d.ts +20 -0
  358. package/types/lib/core/state.d.ts.map +1 -0
  359. package/types/lib/core/text.d.ts +78 -0
  360. package/types/lib/core/text.d.ts.map +1 -0
  361. package/types/lib/core/ui.d.ts +87 -0
  362. package/types/lib/core/ui.d.ts.map +1 -0
  363. package/types/lib/core/urls.d.ts +43 -0
  364. package/types/lib/core/urls.d.ts.map +1 -0
  365. package/types/lib/ecosystems/asarutils.d.ts +71 -0
  366. package/types/lib/ecosystems/asarutils.d.ts.map +1 -0
  367. package/types/lib/ecosystems/bunutils.d.ts +38 -0
  368. package/types/lib/ecosystems/bunutils.d.ts.map +1 -0
  369. package/types/lib/ecosystems/caxa.d.ts +8 -0
  370. package/types/lib/ecosystems/caxa.d.ts.map +1 -0
  371. package/types/lib/ecosystems/chromextutils.d.ts +97 -0
  372. package/types/lib/ecosystems/chromextutils.d.ts.map +1 -0
  373. package/types/lib/ecosystems/cmakeResolver.d.ts +176 -0
  374. package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -0
  375. package/types/lib/ecosystems/cppEvidence.d.ts +35 -0
  376. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -0
  377. package/types/lib/ecosystems/denoutils.d.ts +76 -0
  378. package/types/lib/ecosystems/denoutils.d.ts.map +1 -0
  379. package/types/lib/ecosystems/dotnetutils.d.ts +45 -0
  380. package/types/lib/ecosystems/dotnetutils.d.ts.map +1 -0
  381. package/types/lib/ecosystems/ecosystems.d.ts +279 -0
  382. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -0
  383. package/types/lib/ecosystems/golem.d.ts +60 -0
  384. package/types/lib/ecosystems/golem.d.ts.map +1 -0
  385. package/types/lib/ecosystems/gradleutils.d.ts +139 -0
  386. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -0
  387. package/types/lib/ecosystems/jsEvidence.d.ts +17 -0
  388. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -0
  389. package/types/lib/ecosystems/npmutils.d.ts +183 -0
  390. package/types/lib/ecosystems/npmutils.d.ts.map +1 -0
  391. package/types/lib/ecosystems/parsers-bazel.d.ts +36 -0
  392. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -0
  393. package/types/lib/ecosystems/parsers-dotnet.d.ts +116 -0
  394. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -0
  395. package/types/lib/ecosystems/parsers-gleam.d.ts +33 -0
  396. package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -0
  397. package/types/lib/ecosystems/parsers-go.d.ts +92 -0
  398. package/types/lib/ecosystems/parsers-go.d.ts.map +1 -0
  399. package/types/lib/ecosystems/parsers-js.d.ts +242 -0
  400. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -0
  401. package/types/lib/ecosystems/parsers-jvm.d.ts +100 -0
  402. package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -0
  403. package/types/lib/ecosystems/parsers-misc.d.ts +450 -0
  404. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -0
  405. package/types/lib/ecosystems/parsers-python.d.ts +145 -0
  406. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -0
  407. package/types/lib/ecosystems/parsers-rust.d.ts +56 -0
  408. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -0
  409. package/types/lib/ecosystems/parsers-zig.d.ts +83 -0
  410. package/types/lib/ecosystems/parsers-zig.d.ts.map +1 -0
  411. package/types/lib/ecosystems/pep770.d.ts +38 -0
  412. package/types/lib/ecosystems/pep770.d.ts.map +1 -0
  413. package/types/lib/ecosystems/pylockutils.d.ts +68 -0
  414. package/types/lib/ecosystems/pylockutils.d.ts.map +1 -0
  415. package/types/lib/ecosystems/pythonutils.d.ts +70 -0
  416. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -0
  417. package/types/lib/ecosystems/registryProvenance.d.ts +26 -0
  418. package/types/lib/ecosystems/registryProvenance.d.ts.map +1 -0
  419. package/types/lib/ecosystems/remote/huggingface.d.ts +31 -0
  420. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -0
  421. package/types/lib/ecosystems/rubyutils.d.ts +182 -0
  422. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -0
  423. package/types/lib/ecosystems/rusi.d.ts +40 -0
  424. package/types/lib/ecosystems/rusi.d.ts.map +1 -0
  425. package/types/lib/ecosystems/sbtutils.d.ts +179 -0
  426. package/types/lib/ecosystems/sbtutils.d.ts.map +1 -0
  427. package/types/lib/ecosystems/tea.d.ts +180 -0
  428. package/types/lib/ecosystems/tea.d.ts.map +1 -0
  429. package/types/lib/ecosystems/utils.d.ts +41 -0
  430. package/types/lib/ecosystems/utils.d.ts.map +1 -0
  431. package/types/lib/ecosystems/zigResolver.d.ts +70 -0
  432. package/types/lib/ecosystems/zigResolver.d.ts.map +1 -0
  433. package/types/lib/evinser/db.d.ts +17 -0
  434. package/types/lib/evinser/db.d.ts.map +1 -0
  435. package/types/lib/evinser/evinser.d.ts +354 -0
  436. package/types/lib/evinser/evinser.d.ts.map +1 -0
  437. package/types/lib/evinser/scalasem.d.ts +15 -0
  438. package/types/lib/evinser/scalasem.d.ts.map +1 -0
  439. package/types/lib/evinser/swiftsem.d.ts +103 -0
  440. package/types/lib/evinser/swiftsem.d.ts.map +1 -0
  441. package/types/lib/helpers/annotationFormatter.d.ts +23 -0
  442. package/types/lib/helpers/annotationFormatter.d.ts.map +1 -0
  443. package/types/lib/helpers/bomSigner.d.ts +28 -0
  444. package/types/lib/helpers/bomSigner.d.ts.map +1 -0
  445. package/types/lib/helpers/exportUtils.d.ts +52 -0
  446. package/types/lib/helpers/exportUtils.d.ts.map +1 -0
  447. package/types/lib/helpers/remote/dependency-track.d.ts +23 -0
  448. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
  449. package/types/lib/helpers/versutils.d.ts +8 -0
  450. package/types/lib/helpers/versutils.d.ts.map +1 -0
  451. package/types/lib/helpers/vsixutils.d.ts +130 -0
  452. package/types/lib/helpers/vsixutils.d.ts.map +1 -0
  453. package/types/lib/inventory/agentFormulationParser.d.ts +21 -0
  454. package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -0
  455. package/types/lib/inventory/aiCollector.d.ts +61 -0
  456. package/types/lib/inventory/aiCollector.d.ts.map +1 -0
  457. package/types/lib/inventory/aiInventory.d.ts +103 -0
  458. package/types/lib/inventory/aiInventory.d.ts.map +1 -0
  459. package/types/lib/inventory/aiModelVariants.d.ts +31 -0
  460. package/types/lib/inventory/aiModelVariants.d.ts.map +1 -0
  461. package/types/lib/inventory/aiOversightCollector.d.ts +28 -0
  462. package/types/lib/inventory/aiOversightCollector.d.ts.map +1 -0
  463. package/types/lib/inventory/aiProvenanceCollector.d.ts +13 -0
  464. package/types/lib/inventory/aiProvenanceCollector.d.ts.map +1 -0
  465. package/types/lib/inventory/analyzer.d.ts +157 -0
  466. package/types/lib/inventory/analyzer.d.ts.map +1 -0
  467. package/types/lib/inventory/analyzerScope.d.ts +106 -0
  468. package/types/lib/inventory/analyzerScope.d.ts.map +1 -0
  469. package/types/lib/inventory/astWorker.d.ts +9 -0
  470. package/types/lib/inventory/astWorker.d.ts.map +1 -0
  471. package/types/lib/inventory/atomUtils.d.ts +159 -0
  472. package/types/lib/inventory/atomUtils.d.ts.map +1 -0
  473. package/types/lib/inventory/auditCategories.d.ts +80 -0
  474. package/types/lib/inventory/auditCategories.d.ts.map +1 -0
  475. package/types/lib/inventory/bomUtils.d.ts +145 -0
  476. package/types/lib/inventory/bomUtils.d.ts.map +1 -0
  477. package/types/lib/inventory/cacheCommands.d.ts +28 -0
  478. package/types/lib/inventory/cacheCommands.d.ts.map +1 -0
  479. package/types/lib/inventory/cacheDir.d.ts +55 -0
  480. package/types/lib/inventory/cacheDir.d.ts.map +1 -0
  481. package/types/lib/inventory/cbomutils.d.ts +37 -0
  482. package/types/lib/inventory/cbomutils.d.ts.map +1 -0
  483. package/types/lib/inventory/cdxrs.d.ts +90 -0
  484. package/types/lib/inventory/cdxrs.d.ts.map +1 -0
  485. package/types/lib/inventory/ciParsers/azurePipelines.d.ts +27 -0
  486. package/types/lib/inventory/ciParsers/azurePipelines.d.ts.map +1 -0
  487. package/types/lib/inventory/ciParsers/circleCi.d.ts +27 -0
  488. package/types/lib/inventory/ciParsers/circleCi.d.ts.map +1 -0
  489. package/types/lib/inventory/ciParsers/common.d.ts +11 -0
  490. package/types/lib/inventory/ciParsers/common.d.ts.map +1 -0
  491. package/types/lib/inventory/ciParsers/githubActions.d.ts +38 -0
  492. package/types/lib/inventory/ciParsers/githubActions.d.ts.map +1 -0
  493. package/types/lib/inventory/ciParsers/gitlabCi.d.ts +26 -0
  494. package/types/lib/inventory/ciParsers/gitlabCi.d.ts.map +1 -0
  495. package/types/lib/inventory/ciParsers/jenkins.d.ts +26 -0
  496. package/types/lib/inventory/ciParsers/jenkins.d.ts.map +1 -0
  497. package/types/lib/inventory/citations.d.ts +90 -0
  498. package/types/lib/inventory/citations.d.ts.map +1 -0
  499. package/types/lib/inventory/communityAiConfigParser.d.ts +14 -0
  500. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -0
  501. package/types/lib/inventory/containerRisk.d.ts +20 -0
  502. package/types/lib/inventory/containerRisk.d.ts.map +1 -0
  503. package/types/lib/inventory/cryptoAlgorithmFamily.d.ts +37 -0
  504. package/types/lib/inventory/cryptoAlgorithmFamily.d.ts.map +1 -0
  505. package/types/lib/inventory/deps.d.ts +140 -0
  506. package/types/lib/inventory/deps.d.ts.map +1 -0
  507. package/types/lib/inventory/depsUtils.d.ts +74 -0
  508. package/types/lib/inventory/depsUtils.d.ts.map +1 -0
  509. package/types/lib/inventory/display.d.ts +227 -0
  510. package/types/lib/inventory/display.d.ts.map +1 -0
  511. package/types/lib/inventory/dosai.d.ts +130 -0
  512. package/types/lib/inventory/dosai.d.ts.map +1 -0
  513. package/types/lib/inventory/dosaiParsers.d.ts +59 -0
  514. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -0
  515. package/types/lib/inventory/dynamic.d.ts +25 -0
  516. package/types/lib/inventory/dynamic.d.ts.map +1 -0
  517. package/types/lib/inventory/envcontext.d.ts +377 -0
  518. package/types/lib/inventory/envcontext.d.ts.map +1 -0
  519. package/types/lib/inventory/evidenceUtils.d.ts +74 -0
  520. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -0
  521. package/types/lib/inventory/fetchBatch.d.ts +127 -0
  522. package/types/lib/inventory/fetchBatch.d.ts.map +1 -0
  523. package/types/lib/inventory/fetchRate.d.ts +118 -0
  524. package/types/lib/inventory/fetchRate.d.ts.map +1 -0
  525. package/types/lib/inventory/forgeEnricher.d.ts +31 -0
  526. package/types/lib/inventory/forgeEnricher.d.ts.map +1 -0
  527. package/types/lib/inventory/formulationParsers.d.ts +50 -0
  528. package/types/lib/inventory/formulationParsers.d.ts.map +1 -0
  529. package/types/lib/inventory/gtfobins.d.ts +27 -0
  530. package/types/lib/inventory/gtfobins.d.ts.map +1 -0
  531. package/types/lib/inventory/hbom.d.ts +58 -0
  532. package/types/lib/inventory/hbom.d.ts.map +1 -0
  533. package/types/lib/inventory/hbomAnalysis.d.ts +56 -0
  534. package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -0
  535. package/types/lib/inventory/hbomLoader.d.ts +7 -0
  536. package/types/lib/inventory/hbomLoader.d.ts.map +1 -0
  537. package/types/lib/inventory/hostTopology.d.ts +47 -0
  538. package/types/lib/inventory/hostTopology.d.ts.map +1 -0
  539. package/types/lib/inventory/inventoryStats.d.ts +42 -0
  540. package/types/lib/inventory/inventoryStats.d.ts.map +1 -0
  541. package/types/lib/inventory/jsonLike.d.ts +23 -0
  542. package/types/lib/inventory/jsonLike.d.ts.map +1 -0
  543. package/types/lib/inventory/licenseEnhancer.d.ts +70 -0
  544. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -0
  545. package/types/lib/inventory/lolbas.d.ts +16 -0
  546. package/types/lib/inventory/lolbas.d.ts.map +1 -0
  547. package/types/lib/inventory/mcp.d.ts +29 -0
  548. package/types/lib/inventory/mcp.d.ts.map +1 -0
  549. package/types/lib/inventory/mcpConfigParser.d.ts +20 -0
  550. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -0
  551. package/types/lib/inventory/mcpDiscovery.d.ts +33 -0
  552. package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -0
  553. package/types/lib/inventory/mcpPinning.d.ts +11 -0
  554. package/types/lib/inventory/mcpPinning.d.ts.map +1 -0
  555. package/types/lib/inventory/osPackageResolver.d.ts +49 -0
  556. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -0
  557. package/types/lib/inventory/osinfo.d.ts +201 -0
  558. package/types/lib/inventory/osinfo.d.ts.map +1 -0
  559. package/types/lib/inventory/osqueryTransform.d.ts +84 -0
  560. package/types/lib/inventory/osqueryTransform.d.ts.map +1 -0
  561. package/types/lib/inventory/plugins.d.ts +58 -0
  562. package/types/lib/inventory/plugins.d.ts.map +1 -0
  563. package/types/lib/inventory/protobom.d.ts +71 -0
  564. package/types/lib/inventory/protobom.d.ts.map +1 -0
  565. package/types/lib/inventory/protobomLoader.d.ts +17 -0
  566. package/types/lib/inventory/protobomLoader.d.ts.map +1 -0
  567. package/types/lib/inventory/provenanceUtils.d.ts +98 -0
  568. package/types/lib/inventory/provenanceUtils.d.ts.map +1 -0
  569. package/types/lib/inventory/purl.d.ts +313 -0
  570. package/types/lib/inventory/purl.d.ts.map +1 -0
  571. package/types/lib/inventory/rustFormulationParser.d.ts +17 -0
  572. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -0
  573. package/types/lib/inventory/sbomDocument.d.ts +59 -0
  574. package/types/lib/inventory/sbomDocument.d.ts.map +1 -0
  575. package/types/lib/inventory/source.d.ts +163 -0
  576. package/types/lib/inventory/source.d.ts.map +1 -0
  577. package/types/lib/inventory/spdx.d.ts +66 -0
  578. package/types/lib/inventory/spdx.d.ts.map +1 -0
  579. package/types/lib/inventory/spdxExpression.d.ts +58 -0
  580. package/types/lib/inventory/spdxExpression.d.ts.map +1 -0
  581. package/types/lib/inventory/spdxUtils.d.ts +12 -0
  582. package/types/lib/inventory/spdxUtils.d.ts.map +1 -0
  583. package/types/lib/inventory/table.d.ts +22 -0
  584. package/types/lib/inventory/table.d.ts.map +1 -0
  585. package/types/lib/inventory/traceRunner.d.ts +80 -0
  586. package/types/lib/inventory/traceRunner.d.ts.map +1 -0
  587. package/types/lib/inventory/unicodeScan.d.ts +46 -0
  588. package/types/lib/inventory/unicodeScan.d.ts.map +1 -0
  589. package/types/lib/managers/binary.d.ts +147 -0
  590. package/types/lib/managers/binary.d.ts.map +1 -0
  591. package/types/lib/managers/containerutils.d.ts +30 -0
  592. package/types/lib/managers/containerutils.d.ts.map +1 -0
  593. package/types/lib/managers/docker.d.ts +157 -0
  594. package/types/lib/managers/docker.d.ts.map +1 -0
  595. package/types/lib/managers/dockerConnection.d.ts +42 -0
  596. package/types/lib/managers/dockerConnection.d.ts.map +1 -0
  597. package/types/lib/managers/oci.d.ts +21 -0
  598. package/types/lib/managers/oci.d.ts.map +1 -0
  599. package/types/lib/managers/piptree.d.ts +13 -0
  600. package/types/lib/managers/piptree.d.ts.map +1 -0
  601. package/types/lib/parsers/cmakeCache.d.ts +70 -0
  602. package/types/lib/parsers/cmakeCache.d.ts.map +1 -0
  603. package/types/lib/parsers/gguf.d.ts +39 -0
  604. package/types/lib/parsers/gguf.d.ts.map +1 -0
  605. package/types/lib/parsers/gitAiNotes.d.ts +15 -0
  606. package/types/lib/parsers/gitAiNotes.d.ts.map +1 -0
  607. package/types/lib/parsers/gitmodules.d.ts +88 -0
  608. package/types/lib/parsers/gitmodules.d.ts.map +1 -0
  609. package/types/lib/parsers/htmlExtract.d.ts +34 -0
  610. package/types/lib/parsers/htmlExtract.d.ts.map +1 -0
  611. package/types/lib/parsers/huggingfaceManifest.d.ts +153 -0
  612. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -0
  613. package/types/lib/parsers/huggingfaceUtils.d.ts +155 -0
  614. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -0
  615. package/types/lib/parsers/iri.d.ts +68 -0
  616. package/types/lib/parsers/iri.d.ts.map +1 -0
  617. package/types/lib/parsers/npmrc.d.ts +33 -0
  618. package/types/lib/parsers/npmrc.d.ts.map +1 -0
  619. package/types/lib/parsers/ollama.d.ts +22 -0
  620. package/types/lib/parsers/ollama.d.ts.map +1 -0
  621. package/types/lib/parsers/xml.d.ts +47 -0
  622. package/types/lib/parsers/xml.d.ts.map +1 -0
  623. package/types/lib/server/server.d.ts +51 -0
  624. package/types/lib/server/server.d.ts.map +1 -0
  625. package/types/lib/stages/postgen/annotator.d.ts +36 -0
  626. package/types/lib/stages/postgen/annotator.d.ts.map +1 -0
  627. package/types/lib/stages/postgen/auditBom.d.ts +92 -0
  628. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
  629. package/types/lib/stages/postgen/postgen.d.ts +59 -0
  630. package/types/lib/stages/postgen/postgen.d.ts.map +1 -0
  631. package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
  632. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
  633. package/types/lib/stages/postgen/sortBom.d.ts +34 -0
  634. package/types/lib/stages/postgen/sortBom.d.ts.map +1 -0
  635. package/types/lib/stages/postgen/spdxConverter.d.ts +11 -0
  636. package/types/lib/stages/postgen/spdxConverter.d.ts.map +1 -0
  637. package/types/lib/stages/postgen/specVersionCompat.d.ts +71 -0
  638. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -0
  639. package/types/lib/stages/pregen/envAudit.d.ts +14 -0
  640. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
  641. package/types/lib/stages/pregen/pregen.d.ts +59 -0
  642. package/types/lib/stages/pregen/pregen.d.ts.map +1 -0
  643. package/types/lib/third-party/arborist/lib/arborist/index.d.ts +47 -0
  644. package/types/lib/third-party/arborist/lib/arborist/index.d.ts.map +1 -0
  645. package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts +4 -0
  646. package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts.map +1 -0
  647. package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts +4 -0
  648. package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts.map +1 -0
  649. package/types/lib/third-party/arborist/lib/bin-links.d.ts +18 -0
  650. package/types/lib/third-party/arborist/lib/bin-links.d.ts.map +1 -0
  651. package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts +3 -0
  652. package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts.map +1 -0
  653. package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts +9 -0
  654. package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts.map +1 -0
  655. package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts +3 -0
  656. package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts.map +1 -0
  657. package/types/lib/third-party/arborist/lib/debug.d.ts +3 -0
  658. package/types/lib/third-party/arborist/lib/debug.d.ts.map +1 -0
  659. package/types/lib/third-party/arborist/lib/dep-valid.d.ts +3 -0
  660. package/types/lib/third-party/arborist/lib/dep-valid.d.ts.map +1 -0
  661. package/types/lib/third-party/arborist/lib/edge.d.ts +46 -0
  662. package/types/lib/third-party/arborist/lib/edge.d.ts.map +1 -0
  663. package/types/lib/third-party/arborist/lib/from-path.d.ts +3 -0
  664. package/types/lib/third-party/arborist/lib/from-path.d.ts.map +1 -0
  665. package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts +3 -0
  666. package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts.map +1 -0
  667. package/types/lib/third-party/arborist/lib/index.d.ts +3 -0
  668. package/types/lib/third-party/arborist/lib/index.d.ts.map +1 -0
  669. package/types/lib/third-party/arborist/lib/inventory.d.ts +14 -0
  670. package/types/lib/third-party/arborist/lib/inventory.d.ts.map +1 -0
  671. package/types/lib/third-party/arborist/lib/link.d.ts +18 -0
  672. package/types/lib/third-party/arborist/lib/link.d.ts.map +1 -0
  673. package/types/lib/third-party/arborist/lib/node.d.ts +112 -0
  674. package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -0
  675. package/types/lib/third-party/arborist/lib/npm-extension.d.ts +18 -0
  676. package/types/lib/third-party/arborist/lib/npm-extension.d.ts.map +1 -0
  677. package/types/lib/third-party/arborist/lib/override-resolves.d.ts +3 -0
  678. package/types/lib/third-party/arborist/lib/override-resolves.d.ts.map +1 -0
  679. package/types/lib/third-party/arborist/lib/override-set.d.ts +27 -0
  680. package/types/lib/third-party/arborist/lib/override-set.d.ts.map +1 -0
  681. package/types/lib/third-party/arborist/lib/package-extensions.d.ts +36 -0
  682. package/types/lib/third-party/arborist/lib/package-extensions.d.ts.map +1 -0
  683. package/types/lib/third-party/arborist/lib/printable.d.ts +3 -0
  684. package/types/lib/third-party/arborist/lib/printable.d.ts.map +1 -0
  685. package/types/lib/third-party/arborist/lib/proc-log.d.ts +20 -0
  686. package/types/lib/third-party/arborist/lib/proc-log.d.ts.map +1 -0
  687. package/types/lib/third-party/arborist/lib/realpath.d.ts +3 -0
  688. package/types/lib/third-party/arborist/lib/realpath.d.ts.map +1 -0
  689. package/types/lib/third-party/arborist/lib/relpath.d.ts +3 -0
  690. package/types/lib/third-party/arborist/lib/relpath.d.ts.map +1 -0
  691. package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts +54 -0
  692. package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts.map +1 -0
  693. package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts +3 -0
  694. package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts.map +1 -0
  695. package/types/lib/third-party/arborist/lib/tree-check.d.ts +3 -0
  696. package/types/lib/third-party/arborist/lib/tree-check.d.ts.map +1 -0
  697. package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts +13 -0
  698. package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts.map +1 -0
  699. package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts +6 -0
  700. package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts.map +1 -0
  701. package/types/lib/third-party/arborist/lib/yarn-lock.d.ts +35 -0
  702. package/types/lib/third-party/arborist/lib/yarn-lock.d.ts.map +1 -0
  703. package/types/lib/validator/bomValidator.d.ts +40 -0
  704. package/types/lib/validator/bomValidator.d.ts.map +1 -0
  705. package/types/lib/validator/complianceEngine.d.ts +72 -0
  706. package/types/lib/validator/complianceEngine.d.ts.map +1 -0
  707. package/types/lib/validator/complianceRules.d.ts +61 -0
  708. package/types/lib/validator/complianceRules.d.ts.map +1 -0
  709. package/types/lib/validator/index.d.ts +101 -0
  710. package/types/lib/validator/index.d.ts.map +1 -0
  711. package/types/lib/validator/reporters/annotations.d.ts +37 -0
  712. package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
  713. package/types/lib/validator/reporters/console.d.ts +34 -0
  714. package/types/lib/validator/reporters/console.d.ts.map +1 -0
  715. package/types/lib/validator/reporters/index.d.ts +30 -0
  716. package/types/lib/validator/reporters/index.d.ts.map +1 -0
  717. package/types/lib/validator/reporters/json.d.ts +11 -0
  718. package/types/lib/validator/reporters/json.d.ts.map +1 -0
  719. package/types/lib/validator/reporters/sarif.d.ts +22 -0
  720. package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
  721. package/mod.d.ts +0 -7
  722. package/mod.js +0 -22
@@ -0,0 +1,1858 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { readFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { basename, dirname, join, resolve, sep } from "node:path";
5
+ import process from "node:process";
6
+
7
+ import { build } from "@cdxgen/cdx-purl";
8
+ import { gte, lte } from "semver";
9
+
10
+ import { DEBUG_MODE, readEnvironmentVariable } from "../core/activity.js";
11
+ import {
12
+ hasAnyProjectType,
13
+ includeMavenTestScope,
14
+ isFeatureEnabled,
15
+ isPackageManagerAllowed,
16
+ PREFER_MAVEN_DEPS_TREE,
17
+ parseMavenArgs,
18
+ } from "../core/env.js";
19
+ import {
20
+ getAllFiles,
21
+ getTmpDir,
22
+ MAX_BUFFER,
23
+ safeExistsSync,
24
+ safeMkdirSync,
25
+ safeMkdtempSync,
26
+ safeRmSync,
27
+ safeSpawnSync,
28
+ safeUnlinkSync,
29
+ safeWriteSync,
30
+ } from "../core/fs.js";
31
+ import { thoughtLog } from "../core/logger.js";
32
+ import { dirNameStr } from "../core/paths.js";
33
+ import { extractJarArchive, getMvnMetadata } from "../ecosystems/ecosystems.js";
34
+ import {
35
+ buildGradleCommandArguments,
36
+ buildObjectForGradleModule,
37
+ collectGradleDependencies,
38
+ executeParallelGradleProperties,
39
+ getGradleCommand,
40
+ getMavenCommand,
41
+ getMillCommand,
42
+ parseGradleDep,
43
+ parseGradleInfoLogsForUrls,
44
+ parseGradleProperties,
45
+ parseGradleResolvedDistributions,
46
+ splitOutputByGradleProjects,
47
+ } from "../ecosystems/gradleutils.js";
48
+ import {
49
+ parseModuleBazel,
50
+ parseModuleBazelLock,
51
+ } from "../ecosystems/parsers-bazel.js";
52
+ import {
53
+ parseBazelActionGraph,
54
+ parseBazelSkyframe,
55
+ parseMavenTree,
56
+ parseMavenTreeJson,
57
+ parseMillDependency,
58
+ parsePom,
59
+ } from "../ecosystems/parsers-jvm.js";
60
+ import {
61
+ addPlugin,
62
+ cleanupPlugin,
63
+ determineSbtVersion,
64
+ discoverSbtProjects,
65
+ parseSbtLock,
66
+ parseSbtProjects,
67
+ parseSbtRootProject,
68
+ parseSbtTree,
69
+ } from "../ecosystems/sbtutils.js";
70
+ import {
71
+ collectJarNS,
72
+ collectMvnDependencies,
73
+ convertJarNSToPackages,
74
+ } from "../inventory/deps.js";
75
+ import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
76
+ import {
77
+ attachIdentityTools,
78
+ extractToolRefs,
79
+ } from "../inventory/evidenceUtils.js";
80
+ import { applyPurl, mavenPurl } from "../inventory/purl.js";
81
+ import {
82
+ buildBomNSData,
83
+ createDefaultParentComponent,
84
+ shouldIncludeNodeModulesDir,
85
+ } from "./bomAssembly.js";
86
+
87
+ const isWin = process.platform === "win32";
88
+
89
+ /**
90
+ * Resolved path to the Gradle modules cache directory, derived from
91
+ * `GRADLE_CACHE_DIR`, `GRADLE_USER_HOME`, or `~/.gradle/caches/modules-2/files-2.1`.
92
+ *
93
+ * @type {string}
94
+ */
95
+ export let GRADLE_CACHE_DIR =
96
+ readEnvironmentVariable("GRADLE_CACHE_DIR") ||
97
+ join(homedir(), ".gradle", "caches", "modules-2", "files-2.1");
98
+ if (readEnvironmentVariable("GRADLE_USER_HOME")) {
99
+ GRADLE_CACHE_DIR = join(
100
+ readEnvironmentVariable("GRADLE_USER_HOME"),
101
+ "caches",
102
+ "modules-2",
103
+ "files-2.1",
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Absolute path to the bundled `init.gradle` helper script under `data/helpers`.
109
+ *
110
+ * @type {string}
111
+ */
112
+ // Construct path to gradle init script
113
+ export const GRADLE_INIT_SCRIPT = resolve(
114
+ dirNameStr,
115
+ "data",
116
+ "helpers",
117
+ "init.gradle",
118
+ );
119
+
120
+ /**
121
+ * Resolved path to the sbt/Ivy2 cache directory, derived from `SBT_CACHE_DIR`
122
+ * or `~/.ivy2/cache`.
123
+ *
124
+ * @type {string}
125
+ */
126
+ // Construct sbt cache directory
127
+ export const SBT_CACHE_DIR =
128
+ readEnvironmentVariable("SBT_CACHE_DIR") || join(homedir(), ".ivy2", "cache");
129
+
130
+ /**
131
+ * Function to create bom string for Java jars
132
+ *
133
+ * @param {string} path to the project
134
+ * @param {Object} options Parse options from the cli
135
+ *
136
+ * @returns {Object} BOM with namespace mapping
137
+ */
138
+ export async function createJarBom(path, options) {
139
+ let pkgList = [];
140
+ let jarFiles;
141
+ let nsMapping = {};
142
+ const searchOptions = {
143
+ ...options,
144
+ exclude: [...(options.exclude || [])],
145
+ };
146
+ if (typeof searchOptions.includeNodeModulesDir === "undefined") {
147
+ searchOptions.includeNodeModulesDir = shouldIncludeNodeModulesDir(options, [
148
+ "jar",
149
+ "war",
150
+ "ear",
151
+ ]);
152
+ }
153
+ // Exclude certain directories during oci sbom generation
154
+ if (hasAnyProjectType(["oci"], options, false)) {
155
+ searchOptions.exclude.push("**/android-sdk*/**");
156
+ searchOptions.exclude.push("**/.sdkman/**");
157
+ }
158
+ const parentComponent = createDefaultParentComponent(path, "maven", options);
159
+ if (options.useGradleCache) {
160
+ nsMapping = await collectGradleDependencies(
161
+ getGradleCommand(path, null),
162
+ path,
163
+ false,
164
+ true,
165
+ );
166
+ } else if (options.useMavenCache) {
167
+ nsMapping = await collectMvnDependencies(
168
+ getMavenCommand(path, null),
169
+ null,
170
+ false,
171
+ true,
172
+ );
173
+ }
174
+ if (path.endsWith(".jar")) {
175
+ jarFiles = [resolve(path)];
176
+ } else {
177
+ jarFiles = getAllFiles(
178
+ path,
179
+ `${options.multiProject ? "**/" : ""}*.[jw]ar`,
180
+ searchOptions,
181
+ );
182
+ }
183
+ // Jenkins plugins
184
+ const hpiFiles = getAllFiles(
185
+ path,
186
+ `${options.multiProject ? "**/" : ""}*.hpi`,
187
+ searchOptions,
188
+ );
189
+ if (hpiFiles.length) {
190
+ jarFiles = jarFiles.concat(hpiFiles);
191
+ }
192
+ for (const jar of jarFiles) {
193
+ const tempDir = safeMkdtempSync(join(getTmpDir(), "jar-deps-"));
194
+ if (DEBUG_MODE) {
195
+ console.log(`Parsing ${jar}`);
196
+ }
197
+ const dlist = await extractJarArchive(jar, tempDir);
198
+ if (dlist?.length) {
199
+ pkgList = pkgList.concat(dlist);
200
+ }
201
+ if (pkgList.length) {
202
+ pkgList = await getMvnMetadata(pkgList);
203
+ }
204
+ // Clean up
205
+ if (tempDir?.startsWith(getTmpDir())) {
206
+ safeRmSync(tempDir, { recursive: true, force: true });
207
+ }
208
+ }
209
+ pkgList = pkgList.concat(await convertJarNSToPackages(nsMapping));
210
+ return buildBomNSData(options, pkgList, "maven", {
211
+ src: path,
212
+ parentComponent,
213
+ });
214
+ }
215
+
216
+ /**
217
+ * Discover the real sbt project ids for a build by invoking sbt's own
218
+ * `projects` command. This is more reliable than scraping the build files with
219
+ * a regex, since it uses sbt's project resolution and avoids false positives
220
+ * (commented-out code, examples, values that merely resemble project defs) that
221
+ * can lead to hangs when those bogus scopes are later passed to `dependencyTree`.
222
+ *
223
+ * Falls back to the regex-based {@link discoverSbtProjects} heuristic when the
224
+ * sbt invocation fails or yields nothing useful.
225
+ *
226
+ * @param {string} basePath Directory of the sbt build
227
+ * @param {string} sbtCmd sbt executable
228
+ * @param {Object} env Environment for the spawned process
229
+ * @returns {string[]} List of sbt project ids
230
+ */
231
+ export function discoverSbtProjectsFromCmd(basePath, sbtCmd, env) {
232
+ try {
233
+ const result = safeSpawnSync(
234
+ sbtCmd,
235
+ ["-batch", "-no-colors", '"projects"'],
236
+ {
237
+ cwd: basePath,
238
+ shell: true,
239
+ env,
240
+ encoding: "utf-8",
241
+ },
242
+ );
243
+ if (result.status === 0 && !result.error) {
244
+ const { projects, root } = parseSbtProjects(result.stdout || "");
245
+ // Exclude the aggregating root project - its own dependencyTree is
246
+ // usually a subset of the aggregated subprojects and re-resolving it
247
+ // only adds noise/time.
248
+ const subprojects = projects.filter((p) => p !== root);
249
+ if (subprojects.length > 0) {
250
+ if (DEBUG_MODE) {
251
+ console.log(
252
+ `Discovered sbt projects via sbt: ${subprojects.join(", ")}`,
253
+ );
254
+ }
255
+ return subprojects;
256
+ }
257
+ // Single-project builds (root only): resolve at the root scope.
258
+ if (projects.length > 0) {
259
+ return [];
260
+ }
261
+ } else if (DEBUG_MODE) {
262
+ console.log(
263
+ "sbt projects command did not succeed. Falling back to heuristic project discovery.",
264
+ );
265
+ }
266
+ } catch (err) {
267
+ if (DEBUG_MODE) {
268
+ console.log("Unable to run sbt projects command.", err);
269
+ }
270
+ }
271
+ // Fallback to the regex-based heuristic.
272
+ return discoverSbtProjects(basePath);
273
+ }
274
+
275
+ /**
276
+ * Function to create bom string for Java projects
277
+ *
278
+ * @param {string} path to the project
279
+ * @param {Object} options Parse options from the cli
280
+ * @returns {Promise<Object>} Promise resolving to BOM object
281
+ */
282
+ export async function createJavaBom(path, options) {
283
+ let jarNSMapping = {};
284
+ let pkgList = [];
285
+ let dependencies = [];
286
+ // cyclone-dx-maven plugin creates a component for the app under metadata
287
+ // This is subsequently referred to in the dependencies list
288
+ let parentComponent = {};
289
+ // Support for tracking all the tools that created the BOM
290
+ // For java, this would correctly include the cyclonedx maven plugin.
291
+ let tools;
292
+ let possible_misses = false;
293
+ let parallelPropTaskOut = "";
294
+ // war/ear mode
295
+ if (path.endsWith(".war") || path.endsWith(".jar")) {
296
+ // Check if the file exists
297
+ if (safeExistsSync(path)) {
298
+ if (DEBUG_MODE) {
299
+ console.log(`Retrieving packages from ${path}`);
300
+ }
301
+ const tempDir = safeMkdtempSync(join(getTmpDir(), "war-deps-"));
302
+ jarNSMapping = await collectJarNS(tempDir);
303
+ pkgList = await extractJarArchive(path, tempDir, jarNSMapping);
304
+ if (pkgList.length) {
305
+ pkgList = await getMvnMetadata(pkgList);
306
+ }
307
+ // Clean up
308
+ if (tempDir?.startsWith(getTmpDir())) {
309
+ console.log(`Cleaning up ${tempDir}`);
310
+ safeRmSync(tempDir, { recursive: true, force: true });
311
+ }
312
+ } else {
313
+ console.log(`${path} doesn't exist`);
314
+ }
315
+ return buildBomNSData(options, pkgList, "maven", {
316
+ src: dirname(path),
317
+ filename: path,
318
+ nsMapping: jarNSMapping,
319
+ dependencies,
320
+ parentComponent,
321
+ });
322
+ }
323
+ // -t quarkus is supported
324
+ let isQuarkus = options?.projectType?.includes("quarkus");
325
+ let useMavenDepsTree = isQuarkus ? false : PREFER_MAVEN_DEPS_TREE;
326
+ // Is this a multi-module project
327
+ let rootModules;
328
+ // maven - pom.xml
329
+ const pomFiles = getAllFiles(
330
+ path,
331
+ `${options.multiProject ? "**/" : ""}pom.xml`,
332
+ options,
333
+ );
334
+ // gradle
335
+ const gradleFiles = getAllFiles(
336
+ path,
337
+ `${options.multiProject ? "**/" : ""}build.gradle*`,
338
+ options,
339
+ );
340
+ // mill
341
+ const millFiles = getAllFiles(
342
+ path,
343
+ `${options.multiProject ? "**/" : ""}build.mill`,
344
+ options,
345
+ );
346
+ let bomJsonFiles = [];
347
+ if (
348
+ pomFiles?.length &&
349
+ isPackageManagerAllowed(
350
+ "maven",
351
+ ["bazel", "sbt", "gradle", "mill"],
352
+ options,
353
+ )
354
+ ) {
355
+ if (gradleFiles.length) {
356
+ thoughtLog(
357
+ `Is this a Gradle project? I recommend invoking cdxgen with the "-t gradle" option if you're encountering build errors.`,
358
+ );
359
+ }
360
+ if (!isQuarkus) {
361
+ // Quarkus projects require special treatment. To detect quarkus, we parse the first 3 maven file to look for a hit
362
+ for (const pf of pomFiles.slice(0, 3)) {
363
+ const pomMap = parsePom(pf);
364
+ if (!rootModules && pomMap?.modules?.length) {
365
+ rootModules = pomMap.modules;
366
+ }
367
+ // In quarkus mode, we cannot use the maven deps tree
368
+ if (pomMap.isQuarkus) {
369
+ isQuarkus = true;
370
+ useMavenDepsTree = false;
371
+ break;
372
+ }
373
+ }
374
+ }
375
+ let result;
376
+ let mvnArgs;
377
+ // FIXME: How do we motivate everyone to upgrade to 1.7?
378
+ const toolsSpecVersion = 1.6;
379
+ if (isQuarkus) {
380
+ thoughtLog(
381
+ "This appears to be a Quarkus project. Let's use the right Maven plugin.",
382
+ );
383
+ // disable analytics. See: https://quarkus.io/usage/
384
+ mvnArgs = [
385
+ "-fn",
386
+ "quarkus:dependency-sbom",
387
+ "-Dquarkus.analytics.disabled=true",
388
+ ];
389
+ if (options.specVersion >= 1.6) {
390
+ mvnArgs = mvnArgs.concat(
391
+ `-Dquarkus.dependency.sbom.schema-version=${toolsSpecVersion}`,
392
+ );
393
+ }
394
+ } else {
395
+ // FIXME: The last maven plugin release was on November 28th, 2024.
396
+ // Should we fork this repo and maintain it ourselves?
397
+ const cdxMavenPlugin =
398
+ readEnvironmentVariable("CDX_MAVEN_PLUGIN") ||
399
+ "org.cyclonedx:cyclonedx-maven-plugin:2.9.1";
400
+ const cdxMavenGoal =
401
+ readEnvironmentVariable("CDX_MAVEN_GOAL") || "makeAggregateBom";
402
+ mvnArgs = [
403
+ "-fn",
404
+ `${cdxMavenPlugin}:${cdxMavenGoal}`,
405
+ "-DoutputName=bom",
406
+ ];
407
+ if (includeMavenTestScope) {
408
+ mvnArgs.push("-DincludeTestScope=true");
409
+ }
410
+ // By using quiet mode we can reduce the maxBuffer used and avoid crashes
411
+ if (!DEBUG_MODE) {
412
+ mvnArgs.push("-q");
413
+ }
414
+ // Support for passing additional settings and profile to maven
415
+ if (readEnvironmentVariable("MVN_ARGS")) {
416
+ const addArgs = parseMavenArgs(readEnvironmentVariable("MVN_ARGS"));
417
+ mvnArgs = mvnArgs.concat(addArgs);
418
+ }
419
+ // specVersion 1.4 doesn't support externalReferences.type=distribution-intake
420
+ // so we need to run the plugin with the correct version
421
+ if (options.specVersion >= 1.6) {
422
+ mvnArgs = mvnArgs.concat(`-DschemaVersion=${toolsSpecVersion}`);
423
+ } else if (options.specVersion > 1.4) {
424
+ mvnArgs = mvnArgs.concat(`-DschemaVersion=${options.specVersion}`);
425
+ }
426
+ }
427
+ const firstPom = pomFiles.length ? pomFiles[0] : undefined;
428
+ let mavenCmd = getMavenCommand(path, path);
429
+ for (const f of pomFiles) {
430
+ const basePath = dirname(f);
431
+ if (
432
+ isQuarkus &&
433
+ !options.deep &&
434
+ rootModules?.includes(basename(basePath))
435
+ ) {
436
+ if (DEBUG_MODE) {
437
+ console.log("Skipped sub-module", basePath);
438
+ }
439
+ continue;
440
+ }
441
+ const settingsXml = join(basePath, "settings.xml");
442
+ if (safeExistsSync(settingsXml)) {
443
+ console.log(
444
+ `maven settings.xml found in ${basePath}. Please set the MVN_ARGS environment variable based on the full mvn build command used for this project.\nExample: MVN_ARGS='--settings ${settingsXml}'`,
445
+ );
446
+ }
447
+ if (mavenCmd?.endsWith("mvn")) {
448
+ mavenCmd = getMavenCommand(basePath, path);
449
+ }
450
+ // Should we attempt to resolve class names
451
+ if (options.resolveClass || options.deep) {
452
+ const tmpjarNSMapping = await collectMvnDependencies(
453
+ mavenCmd,
454
+ basePath,
455
+ true,
456
+ false,
457
+ );
458
+ if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
459
+ jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
460
+ }
461
+ }
462
+ // Use the cyclonedx maven plugin if there is no preference for maven deps tree
463
+ if (!useMavenDepsTree) {
464
+ thoughtLog("The user wants me to use the cyclonedx-maven plugin.");
465
+ console.log(`Executing '${mavenCmd}' in`, basePath);
466
+ result = safeSpawnSync(mavenCmd, mvnArgs, {
467
+ cwd: basePath,
468
+ shell: isWin,
469
+ });
470
+ // Check if the cyclonedx plugin created the required bom.json file
471
+ // Sometimes the plugin fails silently for complex maven projects
472
+ bomJsonFiles = getAllFiles(
473
+ path,
474
+ "**/target/*{cdx,bom,cyclonedx}*.json",
475
+ options,
476
+ );
477
+ // Check if the bom json files got created in a directory other than target
478
+ if (!bomJsonFiles.length) {
479
+ bomJsonFiles = getAllFiles(
480
+ path,
481
+ "target/**/*{cdx,bom,cyclonedx}*.json",
482
+ options,
483
+ );
484
+ }
485
+ }
486
+ // Also check if the user has a preference for maven deps tree command
487
+ if (
488
+ useMavenDepsTree ||
489
+ !bomJsonFiles.length ||
490
+ result?.status !== 0 ||
491
+ result?.error
492
+ ) {
493
+ const tempRoot = getTmpDir();
494
+ const tempDir = safeMkdtempSync(join(tempRoot, "cdxgen-mvn-"));
495
+ const tempMvnTree = join(tempDir, "cdxgen-mvn-tree.json");
496
+ const tempMvnTreeText = join(tempDir, "cdxgen-mvn-tree.txt");
497
+ const tempMvnParentTree = join(tempDir, "cdxgen-mvn-parent-tree.json");
498
+ const tempMvnParentTreeText = join(
499
+ tempDir,
500
+ "cdxgen-mvn-parent-tree.txt",
501
+ );
502
+ try {
503
+ let mvnTreeArgs = [
504
+ "dependency:tree",
505
+ `-DoutputFile=${tempMvnTree}`,
506
+ "-DoutputType=json",
507
+ ];
508
+ let addArgs = [];
509
+ if (readEnvironmentVariable("MVN_ARGS")) {
510
+ addArgs = parseMavenArgs(readEnvironmentVariable("MVN_ARGS"));
511
+ mvnTreeArgs = mvnTreeArgs.concat(addArgs);
512
+ }
513
+ // Automatically use settings.xml to improve the success for fallback
514
+ if (safeExistsSync(settingsXml)) {
515
+ mvnTreeArgs.push("-s");
516
+ mvnTreeArgs.push(settingsXml);
517
+ }
518
+ // For the first pom alone, we need to execute first in non-recursive mode to capture
519
+ // the parent component. Then, we execute all of them in recursive mode
520
+ if (f === firstPom) {
521
+ thoughtLog(
522
+ "What is the parent component here? Let's use maven command to find out.",
523
+ );
524
+ let findParentComponentArgs = [
525
+ "dependency:tree",
526
+ "-N",
527
+ `-DoutputFile=${tempMvnParentTree}`,
528
+ "-DoutputType=json",
529
+ ];
530
+ if (addArgs.length) {
531
+ findParentComponentArgs = findParentComponentArgs.concat(addArgs);
532
+ }
533
+ result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
534
+ cwd: basePath,
535
+ shell: isWin,
536
+ });
537
+ // If json is empty or unparseable, fallback to text parsing
538
+ let emptyJson = !safeExistsSync(tempMvnParentTree);
539
+ if (safeExistsSync(tempMvnParentTree)) {
540
+ const mvnTreeString = readFileSync(tempMvnParentTree, {
541
+ encoding: "utf-8",
542
+ });
543
+ const parsedList = parseMavenTreeJson(mvnTreeString, f);
544
+ if (!parsedList?.pkgList?.length) {
545
+ emptyJson = true;
546
+ // Remove the invalid json file so text output is preferred below.
547
+ if (safeExistsSync(tempMvnParentTree)) {
548
+ safeUnlinkSync(tempMvnParentTree);
549
+ }
550
+ }
551
+ }
552
+ if (result.status !== 0 || result.error || emptyJson) {
553
+ findParentComponentArgs = [
554
+ "dependency:tree",
555
+ "-N",
556
+ `-DoutputFile=${tempMvnParentTreeText}`,
557
+ ];
558
+ if (addArgs.length) {
559
+ findParentComponentArgs =
560
+ findParentComponentArgs.concat(addArgs);
561
+ }
562
+ result = safeSpawnSync(mavenCmd, findParentComponentArgs, {
563
+ cwd: basePath,
564
+ shell: isWin,
565
+ });
566
+ }
567
+ if (result.status === 0) {
568
+ const parentTreeFile = safeExistsSync(tempMvnParentTreeText)
569
+ ? tempMvnParentTreeText
570
+ : tempMvnParentTree;
571
+ if (safeExistsSync(parentTreeFile)) {
572
+ const mvnTreeString = readFileSync(parentTreeFile, {
573
+ encoding: "utf-8",
574
+ });
575
+ const parsedList = parentTreeFile.endsWith(".json")
576
+ ? parseMavenTreeJson(mvnTreeString, f)
577
+ : parseMavenTree(mvnTreeString, f);
578
+ const dlist = parsedList.pkgList || [];
579
+ if (dlist.length) {
580
+ const tmpParentComponent = dlist.splice(0, 1)[0];
581
+ tmpParentComponent.type = "application";
582
+ parentComponent = tmpParentComponent;
583
+ parentComponent.components = [];
584
+ if (parentComponent.name) {
585
+ thoughtLog(
586
+ `Parent component is called ${parentComponent.name}!`,
587
+ );
588
+ }
589
+ }
590
+ }
591
+ }
592
+ }
593
+ thoughtLog(
594
+ `**MAVEN**: Let's use Maven to collect packages from ${basePath}.`,
595
+ );
596
+ if (DEBUG_MODE) {
597
+ console.log(
598
+ `Executing '${basename(mavenCmd)} dependency:tree ...' in ${basePath}`,
599
+ );
600
+ }
601
+ result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
602
+ cwd: basePath,
603
+ shell: isWin,
604
+ });
605
+ let emptyJson = !safeExistsSync(tempMvnTree);
606
+ if (safeExistsSync(tempMvnTree)) {
607
+ const mvnTreeString = readFileSync(tempMvnTree, {
608
+ encoding: "utf-8",
609
+ });
610
+ const parsedList = parseMavenTreeJson(mvnTreeString, f);
611
+ if (!parsedList?.pkgList?.length) {
612
+ emptyJson = true;
613
+ // Remove the invalid json file so text output is preferred below.
614
+ if (safeExistsSync(tempMvnTree)) {
615
+ safeUnlinkSync(tempMvnTree);
616
+ }
617
+ }
618
+ }
619
+ if (result.status !== 0 || result.error || emptyJson) {
620
+ mvnTreeArgs = [
621
+ "dependency:tree",
622
+ `-DoutputFile=${tempMvnTreeText}`,
623
+ ];
624
+ if (addArgs.length) {
625
+ mvnTreeArgs = mvnTreeArgs.concat(addArgs);
626
+ }
627
+ if (safeExistsSync(settingsXml)) {
628
+ mvnTreeArgs.push("-s");
629
+ mvnTreeArgs.push(settingsXml);
630
+ }
631
+ result = safeSpawnSync(mavenCmd, mvnTreeArgs, {
632
+ cwd: basePath,
633
+ shell: isWin,
634
+ });
635
+ }
636
+ if (result.status !== 0 || result.error) {
637
+ possible_misses = true;
638
+ // Our approach to recursively invoking the maven plugin for each sub-module is bound to result in failures
639
+ // These could be due to a range of reasons that are covered below.
640
+ if (pomFiles.length === 1 || DEBUG_MODE || PREFER_MAVEN_DEPS_TREE) {
641
+ if (result.stdout) {
642
+ console.log(result.stdout);
643
+ }
644
+ if (result.stderr) {
645
+ console.log(result.stderr);
646
+ console.log("The above build errors could be due to:\n");
647
+ }
648
+ if (
649
+ result.stdout &&
650
+ (result.stdout.includes("Non-resolvable parent POM") ||
651
+ result.stdout.includes("points at wrong local POM"))
652
+ ) {
653
+ console.log(
654
+ "1. Check if the pom.xml contains valid settings for parent and modules. Some projects can be built only from a specific directory.",
655
+ );
656
+ } else if (
657
+ result.stdout &&
658
+ (result.stdout.includes("Could not resolve dependencies") ||
659
+ result.stdout.includes(
660
+ "no dependency information available",
661
+ ) ||
662
+ result.stdout.includes(
663
+ "The following artifacts could not be resolved",
664
+ ))
665
+ ) {
666
+ console.log(
667
+ "1. Try building the project with 'mvn package -Dmaven.test.skip=true' using the correct version of Java and maven before invoking cdxgen.",
668
+ );
669
+ } else if (
670
+ result.stdout?.includes(
671
+ "Could not resolve target platform specification",
672
+ )
673
+ ) {
674
+ console.log(
675
+ "1. Some projects can be built only from the root directory. Invoke cdxgen with --no-recurse option",
676
+ );
677
+ } else {
678
+ console.log(
679
+ "1. Java version requirement: cdxgen container image bundles Java 24 with maven 3.9 which might be incompatible. Try running cdxgen with the custom JDK11-based image `ghcr.io/cdxgen/cdxgen-java11:v13`.",
680
+ );
681
+ }
682
+ console.log(
683
+ "2. Private dependencies cannot be downloaded: Check if any additional arguments must be passed to maven and set them via MVN_ARGS environment variable.",
684
+ );
685
+ console.log(
686
+ "3. Check if all required environment variables including any maven profile arguments are passed correctly to this tool.",
687
+ );
688
+ }
689
+ // Do not fall back to methods that can produce incomplete results when failOnError is set
690
+ options.failOnError && process.exit(1);
691
+ console.log(
692
+ "\nFalling back to parsing pom.xml files. Only direct dependencies would get included!",
693
+ );
694
+ thoughtLog(
695
+ "**MAVEN**: There appear to be build errors, so the SBOM will be incomplete.",
696
+ );
697
+ const pomMap = parsePom(f);
698
+ const dlist = pomMap?.dependencies || [];
699
+ if (dlist.length) {
700
+ pkgList = pkgList.concat(dlist);
701
+ }
702
+ } else {
703
+ const treeFile = safeExistsSync(tempMvnTreeText)
704
+ ? tempMvnTreeText
705
+ : tempMvnTree;
706
+ if (safeExistsSync(treeFile)) {
707
+ const mvnTreeString = readFileSync(treeFile, {
708
+ encoding: "utf-8",
709
+ });
710
+ const parsedList = treeFile.endsWith(".json")
711
+ ? parseMavenTreeJson(mvnTreeString, f)
712
+ : parseMavenTree(mvnTreeString, f);
713
+ const dlist = parsedList.pkgList || [];
714
+ const tmpParentComponent = dlist.splice(0, 1)[0];
715
+ if (tmpParentComponent) {
716
+ tmpParentComponent.type = "application";
717
+ }
718
+ if (dlist.length) {
719
+ pkgList = pkgList.concat(dlist);
720
+ if (dlist.length > 1) {
721
+ thoughtLog(`Obtained ${dlist.length} components from maven.`);
722
+ } else {
723
+ thoughtLog(
724
+ `"Received very few components from the maven dependency tree command for ${basePath}."`,
725
+ );
726
+ }
727
+ }
728
+ // Retain the parent hierarchy
729
+ if (!tmpParentComponent) {
730
+ thoughtLog(
731
+ `No parseable components were found after executing '${basename(mavenCmd)}'.`,
732
+ );
733
+ } else if (!Object.keys(parentComponent).length) {
734
+ parentComponent = tmpParentComponent;
735
+ parentComponent.components = [];
736
+ } else {
737
+ parentComponent.components.push(tmpParentComponent);
738
+ }
739
+ if (parsedList?.dependenciesList?.length) {
740
+ dependencies = mergeDependencies(
741
+ dependencies,
742
+ parsedList.dependenciesList,
743
+ tmpParentComponent,
744
+ );
745
+ } else {
746
+ if (dlist?.length) {
747
+ thoughtLog(
748
+ `Hmm, I didn't find any dependencies after executing '${basename(mavenCmd)}'. However, I did get ${dlist.length} components, which is confusing.`,
749
+ );
750
+ }
751
+ }
752
+ }
753
+ }
754
+ } finally {
755
+ if (!DEBUG_MODE && tempDir?.startsWith(tempRoot)) {
756
+ safeRmSync(tempDir, { recursive: true, force: true });
757
+ }
758
+ }
759
+ }
760
+ } // for
761
+ // Locate and parse all bom.json files from the maven plugin
762
+ if (!useMavenDepsTree) {
763
+ for (const abjson of bomJsonFiles) {
764
+ let bomJsonObj;
765
+ try {
766
+ if (DEBUG_MODE) {
767
+ console.log(`Extracting data from generated bom file ${abjson}`);
768
+ }
769
+ bomJsonObj = JSON.parse(
770
+ readFileSync(abjson, {
771
+ encoding: "utf-8",
772
+ }),
773
+ );
774
+ if (bomJsonObj) {
775
+ if (
776
+ !tools &&
777
+ bomJsonObj.metadata &&
778
+ bomJsonObj.metadata.tools &&
779
+ (Array.isArray(bomJsonObj.metadata.tools) ||
780
+ bomJsonObj.metadata.tools.components ||
781
+ bomJsonObj.metadata.tools.services)
782
+ ) {
783
+ tools = bomJsonObj.metadata.tools;
784
+ }
785
+ const toolRefs = extractToolRefs(
786
+ bomJsonObj?.metadata?.tools,
787
+ (tool) => tool?.name !== "cdxgen",
788
+ );
789
+ if (
790
+ bomJsonObj.metadata?.component &&
791
+ !Object.keys(parentComponent).length
792
+ ) {
793
+ parentComponent = bomJsonObj.metadata.component;
794
+ options.parentComponent = parentComponent;
795
+ }
796
+ if (bomJsonObj.components) {
797
+ // Inject evidence into the components. #994
798
+ if (options.specVersion >= 1.5) {
799
+ // maven would usually generate a target directory closest to the pom.xml
800
+ // I am sure there would be cases where this assumption is not true :)
801
+ const srcPomFile = join(dirname(abjson), "..", "pom.xml");
802
+ for (const acomp of bomJsonObj.components) {
803
+ if (!acomp.evidence) {
804
+ acomp.evidence = {
805
+ identity: {
806
+ field: "purl",
807
+ confidence: 0.8,
808
+ methods: [
809
+ {
810
+ technique: "manifest-analysis",
811
+ confidence: 0.8,
812
+ value: srcPomFile,
813
+ },
814
+ ],
815
+ },
816
+ };
817
+ }
818
+ if (!acomp.properties) {
819
+ acomp.properties = [];
820
+ }
821
+ acomp.properties.push({
822
+ name: "internal:SrcFile",
823
+ value: srcPomFile,
824
+ });
825
+ attachIdentityTools(acomp, toolRefs);
826
+ }
827
+ }
828
+ pkgList = pkgList.concat(bomJsonObj.components);
829
+ }
830
+ if (bomJsonObj.dependencies) {
831
+ dependencies = mergeDependencies(
832
+ dependencies,
833
+ bomJsonObj.dependencies,
834
+ parentComponent,
835
+ );
836
+ }
837
+ }
838
+ } catch (err) {
839
+ if (options.failOnError || DEBUG_MODE) {
840
+ console.log(err);
841
+ options.failOnError && process.exit(1);
842
+ }
843
+ }
844
+ }
845
+ }
846
+ if (possible_misses) {
847
+ if (gradleFiles.length) {
848
+ console.log(
849
+ "Is this a gradle project? Try running cdxgen with `-t gradle`.",
850
+ );
851
+ } else if (!DEBUG_MODE) {
852
+ console.warn(
853
+ "Multiple errors occurred while building this project with maven. The SBOM is therefore incomplete!",
854
+ );
855
+ }
856
+ }
857
+ }
858
+ const allProjects = [];
859
+ const allProjectsAddedPurls = [];
860
+ const rootDependsOn = new Set();
861
+ const gradleModules = new Map();
862
+ // Determine the root path for gradle
863
+ // Fixes gradle invocation for microservices-demo
864
+ let gradleRootPath = path;
865
+ if (
866
+ gradleFiles?.length &&
867
+ !safeExistsSync(join(path, "settings.gradle")) &&
868
+ !safeExistsSync(join(path, "settings.gradle.kts")) &&
869
+ !safeExistsSync(join(path, "build.gradle")) &&
870
+ !safeExistsSync(join(path, "build.gradle.kts"))
871
+ ) {
872
+ gradleRootPath = dirname(gradleFiles[0]);
873
+ }
874
+ if (safeExistsSync(join(gradleRootPath, "gradle.properties"))) {
875
+ thoughtLog(
876
+ "Hmm, there is a gradle.properties file. Do we need any private modules or custom JVM arguments for this project 🤔?",
877
+ );
878
+ }
879
+ // Execute gradle properties
880
+ if (
881
+ gradleFiles?.length &&
882
+ isPackageManagerAllowed(
883
+ "gradle",
884
+ ["maven", "bazel", "sbt", "mill"],
885
+ options,
886
+ )
887
+ ) {
888
+ const wrapperPropPath = join(
889
+ gradleRootPath,
890
+ "gradle",
891
+ "wrapper",
892
+ "gradle-wrapper.properties",
893
+ );
894
+ if (safeExistsSync(wrapperPropPath)) {
895
+ try {
896
+ const propContent = readFileSync(wrapperPropPath, "utf-8");
897
+ const distUrlLine = propContent
898
+ .split("\n")
899
+ .find((l) => l.startsWith("distributionUrl="));
900
+ if (distUrlLine) {
901
+ const distributionUrl = distUrlLine
902
+ .split("=")[1]
903
+ .trim()
904
+ .replace(/\\:/g, ":");
905
+ const versionMatch = distributionUrl.match(
906
+ /gradle-(.*?)-(bin|all)\.zip/,
907
+ );
908
+ const gradleVersion = versionMatch ? versionMatch[1] : "unknown";
909
+ thoughtLog(
910
+ `Found Gradle wrapper with distributionUrl: ${distributionUrl}, version: ${gradleVersion}`,
911
+ );
912
+ if (!tools) {
913
+ tools = [];
914
+ }
915
+ let toolsArr = tools;
916
+ if (!Array.isArray(toolsArr)) {
917
+ if (toolsArr.components) {
918
+ toolsArr = toolsArr.components;
919
+ } else {
920
+ toolsArr = [];
921
+ }
922
+ }
923
+ if (!toolsArr.find((c) => c.name === "gradle")) {
924
+ const distShaLine = propContent
925
+ .split("\n")
926
+ .find((l) => l.startsWith("distributionSha256Sum="));
927
+ let hashes;
928
+ if (distShaLine) {
929
+ const sha256Sum = distShaLine.split("=")[1].trim();
930
+ if (sha256Sum) {
931
+ hashes = [
932
+ {
933
+ alg: "SHA-256",
934
+ content: sha256Sum,
935
+ },
936
+ ];
937
+ }
938
+ }
939
+ const gradleComponent = {
940
+ type: "application",
941
+ group: "org.gradle",
942
+ name: "gradle",
943
+ version: gradleVersion,
944
+ externalReferences: [
945
+ {
946
+ type: "distribution",
947
+ url: distributionUrl,
948
+ },
949
+ ],
950
+ isExternal: true,
951
+ };
952
+ applyPurl(
953
+ gradleComponent,
954
+ mavenPurl("org.gradle", "gradle", gradleVersion, {
955
+ type: "bin",
956
+ }),
957
+ );
958
+ if (hashes) {
959
+ gradleComponent.hashes = hashes;
960
+ }
961
+ toolsArr.push(gradleComponent);
962
+ }
963
+ if (Array.isArray(tools)) {
964
+ tools = toolsArr;
965
+ } else {
966
+ tools.components = toolsArr;
967
+ }
968
+ }
969
+ } catch (_err) {
970
+ // ignore
971
+ }
972
+ }
973
+ let includedBuilds = [];
974
+ let allProjectsStr = [];
975
+ if (readEnvironmentVariable("GRADLE_INCLUDED_BUILDS")) {
976
+ includedBuilds = readEnvironmentVariable("GRADLE_INCLUDED_BUILDS")
977
+ .split(",")
978
+ .map((b) => (!b.startsWith(":") ? `:${b}` : b));
979
+ }
980
+ const resolveGradleDistribution = isFeatureEnabled(
981
+ options,
982
+ "resolve-gradle-distribution",
983
+ );
984
+ const gradleInitArgs = readEnvironmentVariable("GRADLE_INCLUDED_BUILDS")
985
+ ? []
986
+ : ["--init-script", GRADLE_INIT_SCRIPT];
987
+ if (resolveGradleDistribution && gradleInitArgs.length) {
988
+ gradleInitArgs.push("-PcdxgenResolveDistribution=true");
989
+ }
990
+ parallelPropTaskOut = executeParallelGradleProperties(
991
+ gradleRootPath,
992
+ [null].concat(includedBuilds),
993
+ gradleInitArgs,
994
+ );
995
+ if (readEnvironmentVariable("GRADLE_INCLUDED_BUILDS") === undefined) {
996
+ const outputLines = parallelPropTaskOut.split("\n");
997
+ for (const [_i, line] of outputLines.entries()) {
998
+ if (line.startsWith("Root project '") || line.startsWith("Project '")) {
999
+ break;
1000
+ }
1001
+ if (line.startsWith("<CDXGEN:includedBuild>")) {
1002
+ const includedBuild = line.split(">");
1003
+ if (!includedBuilds.includes(includedBuild[1].trim())) {
1004
+ includedBuilds.push(includedBuild[1].trim());
1005
+ }
1006
+ }
1007
+ }
1008
+ if (includedBuilds.length > 0) {
1009
+ thoughtLog(
1010
+ `Wait, this gradle project uses composite builds. I must carefully process these ${includedBuilds.length} projects, in addition to the root.`,
1011
+ );
1012
+ if (DEBUG_MODE) {
1013
+ console.log(`Composite builds: ${includedBuilds.join(" ").trim()}.`);
1014
+ }
1015
+ parallelPropTaskOut = parallelPropTaskOut.concat(
1016
+ "\n",
1017
+ executeParallelGradleProperties(gradleRootPath, includedBuilds),
1018
+ );
1019
+ }
1020
+ }
1021
+ const splitPropTaskOut = splitOutputByGradleProjects(parallelPropTaskOut, [
1022
+ "properties",
1023
+ ]);
1024
+ for (const [key, propTaskOut] of splitPropTaskOut.entries()) {
1025
+ const retMap = parseGradleProperties(propTaskOut);
1026
+ const rootProject = retMap.rootProject;
1027
+ if (rootProject) {
1028
+ const rootComponent = await buildObjectForGradleModule(
1029
+ rootProject,
1030
+ retMap.metadata,
1031
+ );
1032
+ if (!includedBuilds.includes(key)) {
1033
+ parentComponent = rootComponent;
1034
+ }
1035
+ gradleModules.set(key, rootComponent);
1036
+ if (!allProjectsAddedPurls.includes(rootComponent["purl"])) {
1037
+ allProjects.push(rootComponent);
1038
+ rootDependsOn.add(rootComponent["bom-ref"]);
1039
+ allProjectsAddedPurls.push(rootComponent["purl"]);
1040
+ }
1041
+ allProjectsStr = allProjectsStr.concat(retMap.projects);
1042
+ }
1043
+ }
1044
+ // Get the sub-project properties and set the root dependencies
1045
+ if (allProjectsStr?.length) {
1046
+ const modulesToSkip = readEnvironmentVariable("GRADLE_SKIP_MODULES")
1047
+ ? readEnvironmentVariable("GRADLE_SKIP_MODULES").split(",")
1048
+ : [];
1049
+ if (modulesToSkip.length) {
1050
+ thoughtLog(
1051
+ `Good news. I know there are ${allProjectsStr.length} gradle modules at ${gradleRootPath}. I must skip ${modulesToSkip.length} out of these.`,
1052
+ );
1053
+ }
1054
+ parallelPropTaskOut = executeParallelGradleProperties(
1055
+ gradleRootPath,
1056
+ allProjectsStr.filter((module) => !modulesToSkip.includes(module)),
1057
+ );
1058
+ const splitPropTaskOut = splitOutputByGradleProjects(
1059
+ parallelPropTaskOut,
1060
+ ["properties"],
1061
+ );
1062
+
1063
+ for (const subProject of allProjectsStr) {
1064
+ const retMap = parseGradleProperties(
1065
+ splitPropTaskOut.get(subProject),
1066
+ subProject,
1067
+ );
1068
+ const rootSubProject = retMap.rootProject;
1069
+ if (rootSubProject) {
1070
+ const rootSubProjectObj = await buildObjectForGradleModule(
1071
+ rootSubProject === "root" ? subProject : rootSubProject,
1072
+ retMap.metadata,
1073
+ );
1074
+ if (!allProjectsAddedPurls.includes(rootSubProjectObj["purl"])) {
1075
+ allProjects.push(rootSubProjectObj);
1076
+ rootDependsOn.add(rootSubProjectObj["bom-ref"]);
1077
+ allProjectsAddedPurls.push(rootSubProjectObj["purl"]);
1078
+ }
1079
+ gradleModules.set(subProject, rootSubProjectObj);
1080
+ }
1081
+ }
1082
+ // Bug #317 fix
1083
+ parentComponent.components = allProjects.flatMap((s) => {
1084
+ delete s.qualifiers;
1085
+ delete s.evidence;
1086
+ return s;
1087
+ });
1088
+ dependencies.push({
1089
+ ref: parentComponent["bom-ref"],
1090
+ dependsOn: [...rootDependsOn].sort(),
1091
+ });
1092
+ }
1093
+ }
1094
+ if (
1095
+ gradleFiles?.length &&
1096
+ options.installDeps &&
1097
+ isPackageManagerAllowed(
1098
+ "gradle",
1099
+ ["maven", "bazel", "sbt", "mill"],
1100
+ options,
1101
+ )
1102
+ ) {
1103
+ allProjects.push(parentComponent);
1104
+ const gradleCmd = getGradleCommand(gradleRootPath, null);
1105
+ const gradleDepTask = readEnvironmentVariable("GRADLE_DEPENDENCY_TASK")
1106
+ ? readEnvironmentVariable("GRADLE_DEPENDENCY_TASK")
1107
+ : "dependencies";
1108
+
1109
+ const gradleSubCommands = [];
1110
+ let modulesToSkip = readEnvironmentVariable("GRADLE_SKIP_MODULES")
1111
+ ? readEnvironmentVariable("GRADLE_SKIP_MODULES").split(",")
1112
+ : [];
1113
+ if (readEnvironmentVariable("GRADLE_SKIP_MODULE_DEPENDENCIES")) {
1114
+ modulesToSkip = modulesToSkip.concat(
1115
+ readEnvironmentVariable("GRADLE_SKIP_MODULE_DEPENDENCIES").split(","),
1116
+ );
1117
+ }
1118
+ if (!modulesToSkip.includes("root")) {
1119
+ gradleSubCommands.push(gradleDepTask);
1120
+ }
1121
+ for (const [key, sp] of gradleModules) {
1122
+ //create single command for dependencies tasks on all subprojects
1123
+ if (sp.purl !== parentComponent.purl && !modulesToSkip.includes(key)) {
1124
+ gradleSubCommands.push(`${key}:${gradleDepTask}`);
1125
+ }
1126
+ }
1127
+ const gradleArguments = buildGradleCommandArguments(
1128
+ readEnvironmentVariable("GRADLE_ARGS")
1129
+ ? readEnvironmentVariable("GRADLE_ARGS").split(" ")
1130
+ : [],
1131
+ gradleSubCommands,
1132
+ readEnvironmentVariable("GRADLE_ARGS_DEPENDENCIES")
1133
+ ? readEnvironmentVariable("GRADLE_ARGS_DEPENDENCIES").split(" ")
1134
+ : [],
1135
+ gradleCmd.length,
1136
+ );
1137
+ const allOutputs = [];
1138
+ for (const gradleArg of gradleArguments) {
1139
+ if (DEBUG_MODE) {
1140
+ console.log(
1141
+ `Executing ${gradleCmd} with arguments ${gradleArg.join(" ").substring(0, 150)}... in ${gradleRootPath}`,
1142
+ );
1143
+ }
1144
+ thoughtLog(
1145
+ `Let's invoke '${basename(gradleCmd)}' with the arguments '${gradleArg.join(" ").substring(0, 100)} ...'.`,
1146
+ );
1147
+ const finalGradleArg = gradleArg.includes("--info")
1148
+ ? gradleArg
1149
+ : gradleArg.concat(["--info"]);
1150
+ const sresult = safeSpawnSync(gradleCmd, finalGradleArg, {
1151
+ cwd: gradleRootPath,
1152
+ shell: isWin,
1153
+ });
1154
+ if (sresult.status !== 0 || sresult.error) {
1155
+ if (options.failOnError || DEBUG_MODE) {
1156
+ console.error(sresult.stdout, sresult.stderr);
1157
+ }
1158
+ options.failOnError && process.exit(1);
1159
+ }
1160
+ if (sresult.stdout !== null) {
1161
+ allOutputs.push(sresult.stdout);
1162
+ }
1163
+ }
1164
+ const sstdout = allOutputs.join("\n");
1165
+ if (sstdout) {
1166
+ const cmdOutput = Buffer.from(sstdout).toString();
1167
+ const perProjectOutput = splitOutputByGradleProjects(cmdOutput, [
1168
+ gradleDepTask,
1169
+ ]);
1170
+ for (const key of gradleModules.keys()) {
1171
+ const parsedList = await parseGradleDep(
1172
+ perProjectOutput.has(key) ? perProjectOutput.get(key) : "",
1173
+ key,
1174
+ gradleModules,
1175
+ gradleRootPath,
1176
+ );
1177
+ const dlist = parsedList.pkgList;
1178
+ if (parsedList?.dependenciesList?.length) {
1179
+ dependencies = mergeDependencies(
1180
+ dependencies,
1181
+ parsedList.dependenciesList,
1182
+ parentComponent,
1183
+ );
1184
+ } else {
1185
+ if (dlist?.length) {
1186
+ thoughtLog(
1187
+ `Hmm, I didn't find any dependencies after executing '${basename(gradleCmd)}' for the project ${key}. However, I did get ${dlist.length} components, which is confusing.`,
1188
+ );
1189
+ }
1190
+ }
1191
+ if (dlist?.length) {
1192
+ pkgList = pkgList.concat(dlist);
1193
+ }
1194
+ }
1195
+ }
1196
+ if (pkgList.length) {
1197
+ const fileToUrlMap = parseGradleInfoLogsForUrls(sstdout);
1198
+ // When the `resolve-gradle-distribution` feature flag is enabled, the init script
1199
+ // probes each repository for the actual artifact and emits the resolved URL keyed
1200
+ // by `group:name:version`. This is more accurate than guessing the first repository.
1201
+ const resolvedDistributions =
1202
+ parseGradleResolvedDistributions(parallelPropTaskOut);
1203
+
1204
+ for (const p of pkgList) {
1205
+ if (!p.externalReferences) {
1206
+ p.externalReferences = [];
1207
+ }
1208
+ if (!p.externalReferences.find((r) => r.type === "distribution")) {
1209
+ const groupPath = p.group.replace(/\./g, "/");
1210
+ const matchPath = `${groupPath}/${p.name}/${p.version}/`;
1211
+ let matchedUrl = Object.values(fileToUrlMap).find((url) =>
1212
+ url.includes(matchPath),
1213
+ );
1214
+ if (!matchedUrl) {
1215
+ matchedUrl =
1216
+ resolvedDistributions[`${p.group}:${p.name}:${p.version}`];
1217
+ }
1218
+ if (matchedUrl) {
1219
+ p.externalReferences.push({
1220
+ type: "distribution",
1221
+ url: matchedUrl,
1222
+ });
1223
+ }
1224
+ }
1225
+ }
1226
+ if (parentComponent.components?.length) {
1227
+ for (const subProj of parentComponent.components) {
1228
+ pkgList = pkgList.filter(
1229
+ (pkg) =>
1230
+ pkg["bom-ref"] !== subProj["bom-ref"] &&
1231
+ pkg["bom-ref"] !== parentComponent["bom-ref"],
1232
+ );
1233
+ }
1234
+ }
1235
+ thoughtLog(
1236
+ `Obtained ${pkgList.length} components by executing the '${basename(gradleCmd)}' command.`,
1237
+ );
1238
+ if (DEBUG_MODE) {
1239
+ console.log("Obtained", pkgList.length, "from this gradle project.");
1240
+ }
1241
+ } else {
1242
+ thoughtLog(
1243
+ "**GRADLE:** SBOM is incomplete. I recommend troubleshooting the issue to improve the BOM precision.",
1244
+ );
1245
+ if (!DEBUG_MODE) {
1246
+ console.log(
1247
+ "No packages found. Set the environment variable 'CDXGEN_DEBUG_MODE=debug' to troubleshoot any gradle related errors.",
1248
+ );
1249
+ }
1250
+ options.failOnError && process.exit(1);
1251
+ }
1252
+ if (
1253
+ (!readEnvironmentVariable("GRADLE_STOP_DAEMON") &&
1254
+ (!readEnvironmentVariable("GRADLE_USE_DAEMON") ||
1255
+ ["true", "1"].includes(
1256
+ readEnvironmentVariable("GRADLE_USE_DAEMON"),
1257
+ ))) ||
1258
+ ["true", "1"].includes(readEnvironmentVariable("GRADLE_STOP_DAEMON"))
1259
+ ) {
1260
+ if (DEBUG_MODE) {
1261
+ console.log("Stopping gradle daemon...");
1262
+ }
1263
+ const sresult = safeSpawnSync(gradleCmd, ["--stop"], {
1264
+ cwd: gradleRootPath,
1265
+ shell: isWin,
1266
+ });
1267
+ if (sresult.status !== 0 || sresult.error) {
1268
+ if (options.failOnError || DEBUG_MODE) {
1269
+ console.error(sresult.stdout, sresult.stderr);
1270
+ }
1271
+ options.failOnError && process.exit(1);
1272
+ }
1273
+ }
1274
+ // Should we attempt to resolve class names
1275
+ if (options.resolveClass || options.deep) {
1276
+ const tmpjarNSMapping = await collectJarNS(GRADLE_CACHE_DIR);
1277
+ if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
1278
+ jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ // Bazel
1284
+ // Look for the BUILD file only in the root directory
1285
+ // NOTE: This can match BUILD files used by perl, so could lead to errors in some projects
1286
+ const bazelFiles = getAllFiles(
1287
+ path,
1288
+ `${options.multiProject ? "**/" : ""}{WORKSPACE{,.bazel},MODULE.bazel}`,
1289
+ options,
1290
+ );
1291
+ if (
1292
+ bazelFiles?.length &&
1293
+ !hasAnyProjectType(["docker", "oci", "container", "os"], options, false) &&
1294
+ isPackageManagerAllowed(
1295
+ "bazel",
1296
+ ["maven", "gradle", "sbt", "mill"],
1297
+ options,
1298
+ )
1299
+ ) {
1300
+ let BAZEL_CMD = "bazel";
1301
+ const bazelHome = readEnvironmentVariable("BAZEL_HOME");
1302
+ if (bazelHome) {
1303
+ BAZEL_CMD = join(bazelHome, "bin", "bazel");
1304
+ }
1305
+
1306
+ // bzlmod: parse MODULE.bazel and MODULE.bazel.lock for BCR modules and
1307
+ // ecosystem dependencies (Maven, etc.). This works from the manifest and
1308
+ // lock alone, so BCR/Maven packages are extracted even when the bazel
1309
+ // toolchain is absent. Resolved third-party deps map to their true
1310
+ // ecosystem purl (pkg:maven, ...); only BCR modules use pkg:bazel.
1311
+ const moduleBazelFiles = bazelFiles.filter(
1312
+ (f) => basename(f) === "MODULE.bazel",
1313
+ );
1314
+ for (const moduleFile of moduleBazelFiles) {
1315
+ const baseDir = dirname(moduleFile);
1316
+ const moduleResult = parseModuleBazel(moduleFile);
1317
+ if (moduleResult.pkgList?.length) {
1318
+ pkgList = pkgList.concat(moduleResult.pkgList);
1319
+ }
1320
+ if (moduleResult.parentComponent?.name) {
1321
+ parentComponent = moduleResult.parentComponent;
1322
+ }
1323
+ const lockFile = join(baseDir, "MODULE.bazel.lock");
1324
+ if (safeExistsSync(lockFile)) {
1325
+ const lockResult = parseModuleBazelLock(lockFile);
1326
+ if (lockResult.pkgList?.length) {
1327
+ pkgList = pkgList.concat(lockResult.pkgList);
1328
+ }
1329
+ if (lockResult.dependencies?.length) {
1330
+ dependencies = mergeDependencies(
1331
+ dependencies,
1332
+ lockResult.dependencies,
1333
+ );
1334
+ }
1335
+ }
1336
+ }
1337
+
1338
+ // Querying bazel means building the project first, which is the most
1339
+ // expensive thing cdxgen can do and needs network access. Like every other
1340
+ // package-manager invocation it therefore runs only when dependency
1341
+ // installation is permitted; `--lifecycle pre-build` and secure mode both
1342
+ // turn it off, leaving the manifest and lock as the inventory source.
1343
+ for (const f of options.installDeps ? bazelFiles : []) {
1344
+ const basePath = dirname(f);
1345
+ // Invoke bazel build first
1346
+ const bazelTarget = readEnvironmentVariable("BAZEL_TARGET") || "//...";
1347
+ let bArgs = [
1348
+ ...(readEnvironmentVariable("BAZEL_ARGS")?.split(" ") || []),
1349
+ "build",
1350
+ bazelTarget,
1351
+ ];
1352
+ // Automatically load any bazelrc file
1353
+ if (
1354
+ !readEnvironmentVariable("BAZEL_ARGS") &&
1355
+ safeExistsSync(join(basePath, ".bazelrc"))
1356
+ ) {
1357
+ bArgs = ["--bazelrc=.bazelrc", "build", bazelTarget];
1358
+ }
1359
+ console.log("Executing", BAZEL_CMD, "in", basePath);
1360
+ let result = safeSpawnSync(BAZEL_CMD, bArgs, {
1361
+ cwd: basePath,
1362
+ shell: isWin,
1363
+ });
1364
+ if (result.status !== 0 || result.error) {
1365
+ if (result.stderr) {
1366
+ console.error(result.stdout, result.stderr);
1367
+ }
1368
+ console.log(
1369
+ "1. Check if bazel is installed and available in PATH.\n2. Try building your app with bazel prior to invoking cdxgen",
1370
+ );
1371
+ options.failOnError && process.exit(1);
1372
+ } else {
1373
+ const target = readEnvironmentVariable("BAZEL_TARGET") || "//...";
1374
+ let query = [
1375
+ ...(readEnvironmentVariable("BAZEL_ARGS")?.split(" ") || []),
1376
+ ];
1377
+ let bazelParser;
1378
+ // Automatically load any bazelrc file
1379
+ if (
1380
+ !readEnvironmentVariable("BAZEL_ARGS") &&
1381
+ safeExistsSync(join(basePath, ".bazelrc"))
1382
+ ) {
1383
+ query = ["--bazelrc=.bazelrc"];
1384
+ }
1385
+ if (
1386
+ ["true", "1"].includes(
1387
+ readEnvironmentVariable("BAZEL_USE_ACTION_GRAPH"),
1388
+ )
1389
+ ) {
1390
+ query = query.concat(["query", `deps(${target})`, "--output=label"]);
1391
+ bazelParser = parseBazelActionGraph;
1392
+ } else {
1393
+ query = query.concat([
1394
+ "aquery",
1395
+ "--output=textproto",
1396
+ "--skyframe_state",
1397
+ ]);
1398
+ bazelParser = parseBazelSkyframe;
1399
+ }
1400
+ console.log("Executing", BAZEL_CMD, `${query.join(" ")} in`, basePath);
1401
+ result = safeSpawnSync(BAZEL_CMD, query, {
1402
+ cwd: basePath,
1403
+ });
1404
+ if (result.status !== 0 || result.error) {
1405
+ console.error(result.stdout, result.stderr);
1406
+ options.failOnError && process.exit(1);
1407
+ }
1408
+ const stdout = result.stdout;
1409
+ if (stdout) {
1410
+ const cmdOutput = Buffer.from(stdout).toString();
1411
+ const dlist = bazelParser(cmdOutput);
1412
+ if (dlist?.length) {
1413
+ pkgList = pkgList.concat(dlist);
1414
+ } else {
1415
+ console.log(
1416
+ "No packages were detected.\n1. Build your project using bazel build command before running cdxgen\n2. Try running the bazel aquery command manually to see if skyframe state can be retrieved.",
1417
+ );
1418
+ console.log(
1419
+ "If your project requires a different query, please file a bug at cyclonedx/cdxgen repo!",
1420
+ );
1421
+ options.failOnError && process.exit(1);
1422
+ }
1423
+ } else {
1424
+ console.log("Bazel unexpectedly didn't produce any output");
1425
+ options.failOnError && process.exit(1);
1426
+ }
1427
+ }
1428
+ }
1429
+ }
1430
+
1431
+ // scala sbt
1432
+ // Identify sbt projects via its `project` directory:
1433
+ // - all SBT project _should_ define build.properties file with sbt version info
1434
+ // - SBT projects _typically_ have some configs/plugins defined in .sbt files
1435
+ // - SBT projects that are still on 0.13.x, can still use the old approach,
1436
+ // where configs are defined via Scala files
1437
+ // Detecting one of those should be enough to determine an SBT project.
1438
+ let sbtProjectFiles = getAllFiles(
1439
+ path,
1440
+ `${
1441
+ options.multiProject ? "**/" : ""
1442
+ }project/{build.properties,*.sbt,*.scala}`,
1443
+ options,
1444
+ );
1445
+
1446
+ let sbtProjects = [];
1447
+ for (const i in sbtProjectFiles) {
1448
+ // parent dir of sbtProjectFile is the `project` directory
1449
+ // parent dir of `project` is the sbt root project directory
1450
+ const baseDir = dirname(dirname(sbtProjectFiles[i]));
1451
+ sbtProjects = sbtProjects.concat(baseDir);
1452
+ }
1453
+
1454
+ // Fallback in case sbt's project directory is non-existent
1455
+ if (!sbtProjects.length) {
1456
+ sbtProjectFiles = getAllFiles(
1457
+ path,
1458
+ `${options.multiProject ? "**/" : ""}*.sbt`,
1459
+ options,
1460
+ );
1461
+ for (const i in sbtProjectFiles) {
1462
+ const baseDir = dirname(sbtProjectFiles[i]);
1463
+ sbtProjects = sbtProjects.concat(baseDir);
1464
+ }
1465
+ }
1466
+ // eliminate duplicates and ignore project directories
1467
+ sbtProjects = [...new Set(sbtProjects)].filter(
1468
+ (p) => !p.endsWith(`${sep}project`) && !p.includes(`target${sep}`),
1469
+ );
1470
+ const sbtLockFiles = getAllFiles(
1471
+ path,
1472
+ `${options.multiProject ? "**/" : ""}build.sbt.lock`,
1473
+ options,
1474
+ );
1475
+ const tempCacheDir = safeMkdtempSync(join(getTmpDir(), "sbt-cache-"));
1476
+ safeMkdirSync(tempCacheDir, { recursive: true });
1477
+ if (
1478
+ sbtProjects?.length &&
1479
+ isPackageManagerAllowed(
1480
+ "sbt",
1481
+ ["bazel", "maven", "gradle", "mill"],
1482
+ options,
1483
+ )
1484
+ ) {
1485
+ // If the project use sbt lock files
1486
+ if (sbtLockFiles?.length) {
1487
+ for (const f of sbtLockFiles) {
1488
+ const dlist = await parseSbtLock(f);
1489
+ if (dlist?.length) {
1490
+ pkgList = pkgList.concat(dlist);
1491
+ }
1492
+ }
1493
+ } else {
1494
+ const SBT_CMD = readEnvironmentVariable("SBT_CMD") || "sbt";
1495
+ let sbtVersion = determineSbtVersion(path);
1496
+ // If can't find sbt version at the root of repository then search in
1497
+ // sbt project array too because sometimes the project folder isn't at
1498
+ // root of repository
1499
+ if (sbtVersion == null) {
1500
+ for (const i in sbtProjects) {
1501
+ sbtVersion = determineSbtVersion(sbtProjects[i]);
1502
+ if (sbtVersion != null) {
1503
+ break;
1504
+ }
1505
+ }
1506
+ }
1507
+ if (DEBUG_MODE) {
1508
+ console.log(`Detected sbt version: ${sbtVersion}`);
1509
+ }
1510
+ // Introduced in 1.2.0 https://www.scala-sbt.org/1.x/docs/sbt-1.2-Release-Notes.html#addPluginSbtFile+command,
1511
+ // however working properly for real only since 1.3.4: https://github.com/sbt/sbt/releases/tag/v1.3.4
1512
+ const standalonePluginFile =
1513
+ sbtVersion != null &&
1514
+ gte(sbtVersion, "1.3.4") &&
1515
+ lte(sbtVersion, "1.4.0");
1516
+ const useSlashSyntax = !sbtVersion || gte(sbtVersion, "1.5.0");
1517
+ const isDependencyTreeBuiltIn =
1518
+ sbtVersion != null && gte(sbtVersion, "1.4.0");
1519
+ const tempDir = safeMkdtempSync(join(getTmpDir(), "cdxsbt-"));
1520
+ const tempSbtgDir = safeMkdtempSync(join(getTmpDir(), "cdxsbtg-"));
1521
+ safeMkdirSync(tempSbtgDir, { recursive: true });
1522
+ // Create temporary plugins file
1523
+ const tempSbtPlugins = join(tempSbtgDir, "dep-plugins.sbt");
1524
+
1525
+ // Requires a custom version of `sbt-dependency-graph` that
1526
+ // supports `--append` for `toFile` subtask.
1527
+ let sbtPluginDefinition = `\naddSbtPlugin("io.shiftleft" % "sbt-dependency-graph" % "0.10.0-append-to-file3")\n`;
1528
+ if (isDependencyTreeBuiltIn) {
1529
+ sbtPluginDefinition = "\naddDependencyTreePlugin\n";
1530
+ if (DEBUG_MODE) {
1531
+ console.log("Using addDependencyTreePlugin as the custom plugin");
1532
+ }
1533
+ }
1534
+ safeWriteSync(tempSbtPlugins, sbtPluginDefinition);
1535
+ let sbtExtraArgs = "";
1536
+ const env = { ...process.env };
1537
+ // We need to collect the jars from the cache
1538
+ if (options.deep) {
1539
+ sbtExtraArgs = " updateClassifiers";
1540
+ env["COURSIER_CACHE"] = tempCacheDir;
1541
+ env["SBT_IVY_HOME"] = tempCacheDir;
1542
+ }
1543
+ for (const i in sbtProjects) {
1544
+ const basePath = sbtProjects[i];
1545
+ const dlFile = join(tempDir, `dl-${i}.tmp`);
1546
+ let sbtArgs = [];
1547
+ let pluginFile = null;
1548
+ const subDlFiles = [];
1549
+ if (standalonePluginFile) {
1550
+ sbtArgs = [
1551
+ `-addPluginSbtFile=${tempSbtPlugins}`,
1552
+ `"dependencyList::toFile ${dlFile} --force"`,
1553
+ ];
1554
+ subDlFiles.push(dlFile);
1555
+ } else {
1556
+ // write to the existing plugins file
1557
+ // Discover the real sbt project ids by asking sbt itself, falling
1558
+ // back to the regex-based heuristic if that fails. A per-subproject
1559
+ // `dependencyTree` fan-out yields a far more complete tree than a
1560
+ // single root resolution (which only captures the root project's own
1561
+ // libraryDependencies). See https://github.com/cdxgen/cdxgen/issues/4291
1562
+ const subprojects = discoverSbtProjectsFromCmd(
1563
+ basePath,
1564
+ SBT_CMD,
1565
+ env,
1566
+ );
1567
+ if (subprojects.length > 0 && useSlashSyntax) {
1568
+ sbtArgs = [
1569
+ `'set ThisBuild / asciiGraphWidth := 800'${sbtExtraArgs}`,
1570
+ ];
1571
+ for (const sp of subprojects) {
1572
+ const subDlFile = join(tempDir, `dl-${i}-${sp}.tmp`);
1573
+ subDlFiles.push(subDlFile);
1574
+ sbtArgs.push(
1575
+ `"${sp}/dependencyTree / toFile ${subDlFile} --force"`,
1576
+ );
1577
+ }
1578
+ } else if (useSlashSyntax) {
1579
+ sbtArgs = [
1580
+ `'set ThisBuild / asciiGraphWidth := 800'${sbtExtraArgs} "dependencyTree / toFile ${dlFile} --force"`,
1581
+ ];
1582
+ subDlFiles.push(dlFile);
1583
+ } else {
1584
+ sbtArgs = [
1585
+ `'set asciiGraphWidth in ThisBuild := 800'${sbtExtraArgs} "dependencyTree::toFile ${dlFile} --force"`,
1586
+ ];
1587
+ subDlFiles.push(dlFile);
1588
+ }
1589
+ pluginFile = addPlugin(basePath, sbtPluginDefinition);
1590
+ }
1591
+ // Run sbt in non-interactive batch mode so it never blocks waiting for
1592
+ // input on stdin (which can otherwise appear as an indefinite hang) and
1593
+ // does not emit ANSI colour codes into the dependency tree output.
1594
+ sbtArgs = ["-batch", "-no-colors", ...sbtArgs];
1595
+ console.log(
1596
+ "Executing",
1597
+ SBT_CMD,
1598
+ sbtArgs.join(" "),
1599
+ "in",
1600
+ basePath,
1601
+ "using plugins",
1602
+ tempSbtgDir,
1603
+ );
1604
+ // Note that the command has to be invoked with `shell: true` to properly execut sbt
1605
+ const result = safeSpawnSync(SBT_CMD, sbtArgs, {
1606
+ cwd: basePath,
1607
+ shell: true,
1608
+ env,
1609
+ });
1610
+ if (result.status !== 0 || result.error) {
1611
+ console.error(result.stdout, result.stderr);
1612
+ console.log(
1613
+ "1. Check if scala and sbt is installed and available in PATH. Only scala 2.10 + sbt 0.13.6+ and 2.12 + sbt 1.0+ is supported for now.",
1614
+ );
1615
+ console.log(
1616
+ "2. Check if the plugin net.virtual-void:sbt-dependency-graph 0.10.0-RC1 can be used in the environment",
1617
+ );
1618
+ console.log(
1619
+ "3. Consider creating a lockfile using sbt-dependency-lock plugin. See https://github.com/stringbean/sbt-dependency-lock",
1620
+ );
1621
+ options.failOnError && process.exit(1);
1622
+ }
1623
+ if (!standalonePluginFile) {
1624
+ cleanupPlugin(basePath, pluginFile);
1625
+ }
1626
+ const sbtSubprojectRoots = [];
1627
+ for (const subDlFile of subDlFiles) {
1628
+ if (safeExistsSync(subDlFile)) {
1629
+ const retMap = await parseSbtTree(subDlFile);
1630
+ if (retMap.pkgList?.length) {
1631
+ const tmpParentComponent = retMap.pkgList.splice(0, 1)[0];
1632
+ tmpParentComponent.type = "application";
1633
+ pkgList = pkgList.concat(retMap.pkgList);
1634
+ pkgList.push(tmpParentComponent);
1635
+ sbtSubprojectRoots.push(tmpParentComponent);
1636
+ }
1637
+ if (retMap.dependenciesList) {
1638
+ dependencies = mergeDependencies(
1639
+ dependencies,
1640
+ retMap.dependenciesList,
1641
+ parentComponent,
1642
+ );
1643
+ }
1644
+ } else {
1645
+ if (options.failOnError || DEBUG_MODE) {
1646
+ console.log(`sbt dependencyList did not yield ${subDlFile}`);
1647
+ }
1648
+ options.failOnError && process.exit(1);
1649
+ }
1650
+ }
1651
+ // Construct a synthetic root component from build.sbt name/org/version
1652
+ // that aggregates all subproject roots as its direct dependencies.
1653
+ const sbtRoot = parseSbtRootProject(basePath);
1654
+ if (sbtRoot && sbtSubprojectRoots.length > 0) {
1655
+ const rootPurl = build({
1656
+ type: "maven",
1657
+ namespace: sbtRoot.group || null,
1658
+ name: sbtRoot.name,
1659
+ version: sbtRoot.version || null,
1660
+ qualifiers: { type: "jar" } || null,
1661
+ });
1662
+ const rootComponent = {
1663
+ group: sbtRoot.group,
1664
+ name: sbtRoot.name,
1665
+ version: sbtRoot.version,
1666
+ type: "application",
1667
+ purl: rootPurl,
1668
+ "bom-ref": decodeURIComponent(rootPurl),
1669
+ };
1670
+ parentComponent = rootComponent;
1671
+ dependencies.push({
1672
+ ref: decodeURIComponent(rootPurl),
1673
+ dependsOn: sbtSubprojectRoots
1674
+ .map((c) => c["bom-ref"])
1675
+ .filter(Boolean),
1676
+ });
1677
+ } else if (sbtSubprojectRoots.length > 0 && !parentComponent) {
1678
+ parentComponent = sbtSubprojectRoots[0];
1679
+ }
1680
+ }
1681
+
1682
+ // Cleanup
1683
+ safeUnlinkSync(tempSbtPlugins);
1684
+ } // else
1685
+
1686
+ if (DEBUG_MODE) {
1687
+ console.log(`Found ${pkgList.length} packages`);
1688
+ }
1689
+ // Should we attempt to resolve class names
1690
+ if (options.resolveClass || options.deep) {
1691
+ const tmpjarNSMapping = await collectJarNS(tempCacheDir);
1692
+ if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
1693
+ jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
1694
+ }
1695
+ // sbt can store jars in the target directory
1696
+ const jarNSData = await createJarBom(path, options);
1697
+ if (jarNSData?.bomJson?.components) {
1698
+ pkgList = pkgList.concat(jarNSData?.bomJson?.components);
1699
+ const targetJarNSMapping = {};
1700
+ for (const p of jarNSData.bomJson.components) {
1701
+ if (!p?.purl || !p?.properties?.length) {
1702
+ continue;
1703
+ }
1704
+ const nsProp = p.properties.filter(
1705
+ (prop) => prop.name === "internal:Namespaces",
1706
+ );
1707
+ if (nsProp.length) {
1708
+ targetJarNSMapping[p.purl] = nsProp[0].value;
1709
+ }
1710
+ }
1711
+ jarNSMapping = { ...jarNSMapping, ...targetJarNSMapping };
1712
+ }
1713
+ }
1714
+ }
1715
+ if (tempCacheDir?.startsWith(getTmpDir())) {
1716
+ safeRmSync(tempCacheDir, {
1717
+ recursive: true,
1718
+ force: true,
1719
+ });
1720
+ }
1721
+
1722
+ if (
1723
+ millFiles?.length &&
1724
+ isPackageManagerAllowed(
1725
+ "mill",
1726
+ ["bazel", "sbt", "gradle", "maven"],
1727
+ options,
1728
+ )
1729
+ ) {
1730
+ const millRootPath = dirname(millFiles[0]);
1731
+ parentComponent = createDefaultParentComponent(
1732
+ millRootPath,
1733
+ "maven",
1734
+ options,
1735
+ );
1736
+ const millCmd = getMillCommand(millRootPath);
1737
+ const millCommonArgs = [
1738
+ "--color",
1739
+ "false",
1740
+ "--disable-callgraph",
1741
+ "--disable-prompt",
1742
+ "--keep-going",
1743
+ "--silent",
1744
+ ];
1745
+ if (!["true", "1"].includes(readEnvironmentVariable("MILL_USE_SERVER"))) {
1746
+ millCommonArgs.unshift("--no-server");
1747
+ }
1748
+ const millArgs = [...millCommonArgs, "__.ivyDepsTree"];
1749
+ if (DEBUG_MODE) {
1750
+ console.log("Executing", millCmd, "in", millRootPath);
1751
+ }
1752
+ let sresult = safeSpawnSync(millCmd, millArgs, {
1753
+ cwd: millRootPath,
1754
+ shell: isWin,
1755
+ maxBuffer: MAX_BUFFER * 10,
1756
+ });
1757
+ if (sresult.status !== 0 || sresult.error) {
1758
+ if (options.failOnError || DEBUG_MODE) {
1759
+ console.error(sresult.stdout, sresult.stderr);
1760
+ }
1761
+ options.failOnError && process.exit(1);
1762
+ }
1763
+ const millResolveArgs = [...millCommonArgs, "resolve", "__.ivyDepsTree"];
1764
+ if (DEBUG_MODE) {
1765
+ console.log(
1766
+ "Executing",
1767
+ millCmd,
1768
+ millResolveArgs.join(" "),
1769
+ "in",
1770
+ millRootPath,
1771
+ );
1772
+ }
1773
+ sresult = safeSpawnSync(millCmd, millResolveArgs, {
1774
+ cwd: millRootPath,
1775
+ shell: isWin,
1776
+ });
1777
+ if (sresult.status !== 0 || sresult.error) {
1778
+ if (options.failOnError || DEBUG_MODE) {
1779
+ console.error(sresult.stdout, sresult.stderr);
1780
+ }
1781
+ options.failOnError && process.exit(1);
1782
+ }
1783
+ const sstdout = sresult.stdout;
1784
+ if (sstdout) {
1785
+ parentComponent.components = [];
1786
+ const modules = sstdout
1787
+ .trim()
1788
+ .split("\n")
1789
+ .map((a) => a.substring(0, a.lastIndexOf(".")))
1790
+ .filter((a) =>
1791
+ ["true", "1"].includes(readEnvironmentVariable("MILL_EXCLUDE_TEST"))
1792
+ ? !a.endsWith(".test")
1793
+ : true,
1794
+ );
1795
+ const moduleBomRefs = [];
1796
+ const packages = new Map();
1797
+ const relations = new Map();
1798
+ relations.set(parentComponent["bom-ref"], []);
1799
+ for (const module of modules) {
1800
+ moduleBomRefs.push(
1801
+ parseMillDependency(module, packages, relations, millRootPath),
1802
+ );
1803
+ }
1804
+ for (const module of moduleBomRefs) {
1805
+ parentComponent.components.push(packages.get(module));
1806
+ relations.get(parentComponent["bom-ref"]).push(module);
1807
+ packages.delete(module);
1808
+ }
1809
+ const newDependencies = [];
1810
+ for (const [ref, dependsOn] of relations.entries()) {
1811
+ newDependencies.push({
1812
+ ref,
1813
+ dependsOn,
1814
+ });
1815
+ }
1816
+ if (DEBUG_MODE) {
1817
+ console.log(
1818
+ `Obtained ${packages.size} components and ${relations.size} dependencies from mill.`,
1819
+ );
1820
+ }
1821
+ pkgList = pkgList.concat(...packages.values());
1822
+ dependencies = mergeDependencies(
1823
+ dependencies,
1824
+ newDependencies,
1825
+ parentComponent,
1826
+ );
1827
+ }
1828
+ if (
1829
+ (!readEnvironmentVariable("MILL_SHUTDOWN_SERVER") &&
1830
+ ["true", "1"].includes(readEnvironmentVariable("MILL_USE_SERVER"))) ||
1831
+ ["true", "1"].includes(readEnvironmentVariable("MILL_SHUTDOWN_SERVER"))
1832
+ ) {
1833
+ if (DEBUG_MODE) {
1834
+ console.log("Shutting down mill server...");
1835
+ }
1836
+ const sresult = safeSpawnSync(millCmd, ["shutdown"], {
1837
+ cwd: millRootPath,
1838
+ shell: isWin,
1839
+ });
1840
+ if (sresult.status !== 0 || sresult.error) {
1841
+ if (options.failOnError || DEBUG_MODE) {
1842
+ console.error(sresult.stdout, sresult.stderr);
1843
+ }
1844
+ options.failOnError && process.exit(1);
1845
+ }
1846
+ }
1847
+ }
1848
+
1849
+ pkgList = trimComponents(pkgList);
1850
+ pkgList = await getMvnMetadata(pkgList, jarNSMapping, options.deep);
1851
+ return buildBomNSData(options, pkgList, "maven", {
1852
+ src: path,
1853
+ nsMapping: jarNSMapping,
1854
+ dependencies,
1855
+ parentComponent,
1856
+ tools,
1857
+ });
1858
+ }