@cdxgen/cdxgen 13.3.0 → 13.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/README.md +12 -9
  2. package/bin/cdxgen-secure.js +15 -0
  3. package/bin/cdxgen.js +115 -31
  4. package/bin/evinse.js +23 -1
  5. package/bin/hbom.js +15 -7
  6. package/bin/repl.js +115 -0
  7. package/bin/sign.js +45 -15
  8. package/bin/tracebom.js +5 -1
  9. package/bin/validate.js +84 -18
  10. package/bin/verify.js +155 -86
  11. package/data/cbomosdb-queries.json +13 -1
  12. package/data/component-tags.json +8 -0
  13. package/data/helpers/init.gradle +46 -21
  14. package/data/queries-darwin.json +25 -1
  15. package/data/queries-win.json +19 -1
  16. package/data/queries.json +41 -0
  17. package/data/remediations.json +344 -1
  18. package/data/rules/cbom-security.yaml +235 -4
  19. package/data/rules/dependency-sources.yaml +67 -0
  20. package/data/rules/go-binaries.yaml +46 -0
  21. package/data/rules/golem-go.yaml +80 -0
  22. package/data/rules/hbom-compliance.yaml +40 -22
  23. package/data/rules/hbom-performance.yaml +7 -1
  24. package/data/rules/host-topology.yaml +1 -1
  25. package/data/rules/obom-runtime.yaml +31 -2
  26. package/data/rules/php-runtime.yaml +143 -0
  27. package/data/rules/scala-evidence.yaml +115 -0
  28. package/lib/audit/index.js +52 -6
  29. package/lib/cli/bomAssembly.js +28 -3
  30. package/lib/cli/cliOptions.js +110 -3
  31. package/lib/cli/index.js +186 -58
  32. package/lib/cli/jsBom.js +50 -29
  33. package/lib/cli/jvmBom.js +779 -146
  34. package/lib/cli/managedBom.js +1021 -261
  35. package/lib/cli/nativeBom.js +364 -58
  36. package/lib/core/activity.js +12 -0
  37. package/lib/core/env.js +47 -17
  38. package/lib/core/fs.js +31 -21
  39. package/lib/core/httpClient.js +233 -69
  40. package/lib/core/pluginRun.js +184 -0
  41. package/lib/core/processTree.js +100 -0
  42. package/lib/core/projectConfig.js +1 -0
  43. package/lib/core/projectTooling.js +97 -0
  44. package/lib/core/propertySanitizer.js +72 -0
  45. package/lib/core/runState.js +39 -0
  46. package/lib/core/toml.js +72 -0
  47. package/lib/ecosystems/asarutils.js +4 -2
  48. package/lib/ecosystems/bunutils.js +5 -7
  49. package/lib/ecosystems/cargoCache.js +231 -8
  50. package/lib/ecosystems/cmakeResolver.js +10 -21
  51. package/lib/ecosystems/cppBuildContext.js +631 -0
  52. package/lib/ecosystems/cppEvidence.js +337 -22
  53. package/lib/ecosystems/cppIncludeResolver.js +294 -0
  54. package/lib/ecosystems/denoutils.js +93 -66
  55. package/lib/ecosystems/ecosystems.js +1967 -788
  56. package/lib/ecosystems/golem.js +578 -18
  57. package/lib/ecosystems/gradleutils.js +340 -46
  58. package/lib/ecosystems/jsEvidence.js +85 -24
  59. package/lib/ecosystems/kosi.js +21 -4
  60. package/lib/ecosystems/npmutils.js +64 -0
  61. package/lib/ecosystems/parsers-dotnet.js +668 -153
  62. package/lib/ecosystems/parsers-elm.js +46 -28
  63. package/lib/ecosystems/parsers-gleam.js +3 -4
  64. package/lib/ecosystems/parsers-go.js +1283 -297
  65. package/lib/ecosystems/parsers-js.js +92 -26
  66. package/lib/ecosystems/parsers-julia.js +2 -3
  67. package/lib/ecosystems/parsers-jvm.js +463 -29
  68. package/lib/ecosystems/parsers-misc.js +405 -93
  69. package/lib/ecosystems/parsers-python.js +152 -20
  70. package/lib/ecosystems/parsers-rust.js +4 -4
  71. package/lib/ecosystems/parsers-terraform.js +1573 -19
  72. package/lib/ecosystems/pythonutils.js +102 -6
  73. package/lib/ecosystems/remote/huggingface.js +3 -0
  74. package/lib/ecosystems/rubyutils.js +73 -20
  75. package/lib/ecosystems/rusi.js +32 -9
  76. package/lib/ecosystems/sbtutils.js +243 -187
  77. package/lib/ecosystems/scalacliutils.js +343 -0
  78. package/lib/ecosystems/scalasem.js +2620 -0
  79. package/lib/ecosystems/terraformRegistry.js +288 -0
  80. package/lib/ecosystems/utils.js +2 -0
  81. package/lib/ecosystems/vendoredCode.js +156 -0
  82. package/lib/evinser/evinser.js +695 -78
  83. package/lib/evinser/swiftsem.js +68 -5
  84. package/lib/helpers/agenticToolutils.js +2 -2
  85. package/lib/helpers/bomSigner.js +576 -128
  86. package/lib/inventory/agentSkillSpec.js +17 -0
  87. package/lib/inventory/aiCollector.js +4 -1
  88. package/lib/inventory/analyzer.js +110 -127
  89. package/lib/inventory/apkInstalledDb.js +243 -0
  90. package/lib/inventory/atomUtils.js +204 -48
  91. package/lib/inventory/auditCategories.js +10 -3
  92. package/lib/inventory/buildToolRateLimit.js +144 -0
  93. package/lib/inventory/cacheCommands.js +2 -1
  94. package/lib/inventory/cacheDir.js +52 -9
  95. package/lib/inventory/certificates.js +2371 -0
  96. package/lib/inventory/cmakeBuildDirs.js +254 -0
  97. package/lib/inventory/communityAiConfigParser.js +4 -9
  98. package/lib/inventory/deps.js +507 -128
  99. package/lib/inventory/display.js +200 -3
  100. package/lib/inventory/dosai.js +747 -101
  101. package/lib/inventory/dosaiParsers.js +310 -15
  102. package/lib/inventory/dynamic.js +96 -8
  103. package/lib/inventory/envcontext.js +168 -5
  104. package/lib/inventory/evidenceUtils.js +590 -132
  105. package/lib/inventory/fetchBatch.js +574 -38
  106. package/lib/inventory/fetchDiskCache.js +597 -0
  107. package/lib/inventory/forgeEnricher.js +14 -5
  108. package/lib/inventory/formulationParsers.js +3 -2
  109. package/lib/inventory/goBuildInfo.js +140 -0
  110. package/lib/inventory/hbom.js +67 -7
  111. package/lib/inventory/hbomAnalysis.js +16 -0
  112. package/lib/inventory/hostTopology.js +21 -0
  113. package/lib/inventory/jvmLocalRepos.js +917 -0
  114. package/lib/inventory/mcpConfigParser.js +2 -3
  115. package/lib/inventory/osPackagePurl.js +244 -0
  116. package/lib/inventory/osPackageResolver.js +89 -87
  117. package/lib/inventory/osinfo.js +79 -31
  118. package/lib/inventory/osqueryTransform.js +114 -5
  119. package/lib/inventory/parentSelection.js +146 -0
  120. package/lib/inventory/phpBuildInfo.js +487 -0
  121. package/lib/inventory/phpHostProbe.js +641 -0
  122. package/lib/inventory/rootfsCerts.js +426 -0
  123. package/lib/inventory/rustFormulationParser.js +3 -4
  124. package/lib/inventory/scalaCoords.js +153 -0
  125. package/lib/inventory/source.js +215 -11
  126. package/lib/inventory/spdx.js +245 -0
  127. package/lib/inventory/traceRunner.js +93 -8
  128. package/lib/inventory/tracedCrypto.js +423 -0
  129. package/lib/managers/binary.js +529 -183
  130. package/lib/managers/docker.js +199 -44
  131. package/lib/managers/oci.js +24 -2
  132. package/lib/parsers/cmakeCache.js +69 -0
  133. package/lib/parsers/cmakeLists.js +16 -2
  134. package/lib/parsers/cmakePresets.js +400 -0
  135. package/lib/parsers/compileCommands.js +557 -0
  136. package/lib/parsers/email.js +277 -0
  137. package/lib/parsers/largeJson.js +34 -2
  138. package/lib/parsers/strictJson.js +322 -0
  139. package/lib/parsers/terraformConfig.js +1073 -0
  140. package/lib/parsers/terraformSource.js +652 -0
  141. package/lib/server/server.js +209 -1
  142. package/lib/stages/postgen/annotator.js +17 -1
  143. package/lib/stages/postgen/introspection/markers.js +1 -1
  144. package/lib/stages/postgen/introspection/reflect.js +4 -1
  145. package/lib/stages/postgen/postgen.js +20 -6
  146. package/lib/stages/postgen/ruleEngine.js +58 -1
  147. package/lib/stages/postgen/specVersionCompat.js +62 -0
  148. package/lib/stages/pregen/pregen.js +117 -5
  149. package/lib/validator/bomValidator.js +26 -5
  150. package/lib/validator/generated/runtime.mjs +13 -0
  151. package/lib/validator/generated/validate-1.6.mjs +26 -7
  152. package/lib/validator/generated/validate-1.7.mjs +31 -12
  153. package/lib/validator/generated/validate-2.0.mjs +30 -11
  154. package/lib/validator/index.js +25 -10
  155. package/lib/validator/reporters/json.js +1 -0
  156. package/package.json +23 -23
  157. package/types/bin/cdxgen-secure.d.ts +3 -0
  158. package/types/bin/cdxgen-secure.d.ts.map +1 -0
  159. package/types/bin/repl.d.ts.map +1 -1
  160. package/types/lib/audit/index.d.ts.map +1 -1
  161. package/types/lib/cli/bomAssembly.d.ts +9 -2
  162. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  163. package/types/lib/cli/cliOptions.d.ts +43 -0
  164. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  165. package/types/lib/cli/index.d.ts.map +1 -1
  166. package/types/lib/cli/jsBom.d.ts.map +1 -1
  167. package/types/lib/cli/jvmBom.d.ts +44 -1
  168. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  169. package/types/lib/cli/managedBom.d.ts +7 -4
  170. package/types/lib/cli/managedBom.d.ts.map +1 -1
  171. package/types/lib/cli/nativeBom.d.ts +3 -1
  172. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  173. package/types/lib/core/activity.d.ts.map +1 -1
  174. package/types/lib/core/env.d.ts +27 -2
  175. package/types/lib/core/env.d.ts.map +1 -1
  176. package/types/lib/core/fs.d.ts.map +1 -1
  177. package/types/lib/core/httpClient.d.ts +13 -8
  178. package/types/lib/core/httpClient.d.ts.map +1 -1
  179. package/types/lib/core/pluginRun.d.ts +97 -0
  180. package/types/lib/core/pluginRun.d.ts.map +1 -0
  181. package/types/lib/core/processTree.d.ts +36 -0
  182. package/types/lib/core/processTree.d.ts.map +1 -0
  183. package/types/lib/core/projectConfig.d.ts.map +1 -1
  184. package/types/lib/core/projectTooling.d.ts +41 -0
  185. package/types/lib/core/projectTooling.d.ts.map +1 -0
  186. package/types/lib/core/propertySanitizer.d.ts +26 -0
  187. package/types/lib/core/propertySanitizer.d.ts.map +1 -1
  188. package/types/lib/core/runState.d.ts +29 -0
  189. package/types/lib/core/runState.d.ts.map +1 -0
  190. package/types/lib/core/toml.d.ts +20 -0
  191. package/types/lib/core/toml.d.ts.map +1 -0
  192. package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
  193. package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
  194. package/types/lib/ecosystems/cargoCache.d.ts +12 -0
  195. package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
  196. package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
  197. package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
  198. package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
  199. package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
  200. package/types/lib/ecosystems/cppEvidence.d.ts +19 -3
  201. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  202. package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
  203. package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
  204. package/types/lib/ecosystems/denoutils.d.ts +9 -3
  205. package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
  206. package/types/lib/ecosystems/ecosystems.d.ts +62 -13
  207. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  208. package/types/lib/ecosystems/golem.d.ts +81 -1
  209. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  210. package/types/lib/ecosystems/gradleutils.d.ts +59 -7
  211. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  212. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  213. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  214. package/types/lib/ecosystems/npmutils.d.ts +15 -0
  215. package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
  216. package/types/lib/ecosystems/parsers-dotnet.d.ts +155 -5
  217. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
  218. package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
  219. package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
  220. package/types/lib/ecosystems/parsers-go.d.ts +119 -5
  221. package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
  222. package/types/lib/ecosystems/parsers-js.d.ts +6 -1
  223. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  224. package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
  225. package/types/lib/ecosystems/parsers-jvm.d.ts +74 -3
  226. package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
  227. package/types/lib/ecosystems/parsers-misc.d.ts +21 -59
  228. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  229. package/types/lib/ecosystems/parsers-python.d.ts +57 -6
  230. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  231. package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
  232. package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
  233. package/types/lib/ecosystems/pythonutils.d.ts +26 -1
  234. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
  235. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  236. package/types/lib/ecosystems/rubyutils.d.ts +21 -1
  237. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  238. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  239. package/types/lib/ecosystems/sbtutils.d.ts +88 -2
  240. package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
  241. package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
  242. package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
  243. package/types/lib/ecosystems/scalasem.d.ts +311 -0
  244. package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
  245. package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
  246. package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
  247. package/types/lib/ecosystems/utils.d.ts +2 -2
  248. package/types/lib/ecosystems/utils.d.ts.map +1 -1
  249. package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
  250. package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
  251. package/types/lib/evinser/evinser.d.ts +100 -8
  252. package/types/lib/evinser/evinser.d.ts.map +1 -1
  253. package/types/lib/evinser/swiftsem.d.ts +10 -0
  254. package/types/lib/evinser/swiftsem.d.ts.map +1 -1
  255. package/types/lib/helpers/bomSigner.d.ts +80 -4
  256. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  257. package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
  258. package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
  259. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  260. package/types/lib/inventory/analyzer.d.ts.map +1 -1
  261. package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
  262. package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
  263. package/types/lib/inventory/atomUtils.d.ts +96 -10
  264. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  265. package/types/lib/inventory/auditCategories.d.ts +3 -0
  266. package/types/lib/inventory/auditCategories.d.ts.map +1 -1
  267. package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
  268. package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
  269. package/types/lib/inventory/cacheCommands.d.ts +2 -1
  270. package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
  271. package/types/lib/inventory/cacheDir.d.ts +12 -4
  272. package/types/lib/inventory/cacheDir.d.ts.map +1 -1
  273. package/types/lib/inventory/certificates.d.ts +205 -0
  274. package/types/lib/inventory/certificates.d.ts.map +1 -0
  275. package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
  276. package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
  277. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  278. package/types/lib/inventory/deps.d.ts +61 -2
  279. package/types/lib/inventory/deps.d.ts.map +1 -1
  280. package/types/lib/inventory/display.d.ts +18 -0
  281. package/types/lib/inventory/display.d.ts.map +1 -1
  282. package/types/lib/inventory/dosai.d.ts +202 -14
  283. package/types/lib/inventory/dosai.d.ts.map +1 -1
  284. package/types/lib/inventory/dosaiParsers.d.ts +53 -7
  285. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  286. package/types/lib/inventory/dynamic.d.ts +16 -1
  287. package/types/lib/inventory/dynamic.d.ts.map +1 -1
  288. package/types/lib/inventory/envcontext.d.ts +40 -2
  289. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  290. package/types/lib/inventory/evidenceUtils.d.ts +48 -14
  291. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  292. package/types/lib/inventory/fetchBatch.d.ts +83 -14
  293. package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
  294. package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
  295. package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
  296. package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
  297. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  298. package/types/lib/inventory/goBuildInfo.d.ts +10 -0
  299. package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
  300. package/types/lib/inventory/hbom.d.ts.map +1 -1
  301. package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
  302. package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
  303. package/types/lib/inventory/hostTopology.d.ts.map +1 -1
  304. package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
  305. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
  306. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  307. package/types/lib/inventory/osPackagePurl.d.ts +99 -0
  308. package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
  309. package/types/lib/inventory/osPackageResolver.d.ts +6 -2
  310. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
  311. package/types/lib/inventory/osinfo.d.ts +31 -6
  312. package/types/lib/inventory/osinfo.d.ts.map +1 -1
  313. package/types/lib/inventory/osqueryTransform.d.ts +51 -0
  314. package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
  315. package/types/lib/inventory/parentSelection.d.ts +34 -0
  316. package/types/lib/inventory/parentSelection.d.ts.map +1 -0
  317. package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
  318. package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
  319. package/types/lib/inventory/phpHostProbe.d.ts +35 -0
  320. package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
  321. package/types/lib/inventory/rootfsCerts.d.ts +27 -0
  322. package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
  323. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  324. package/types/lib/inventory/scalaCoords.d.ts +80 -0
  325. package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
  326. package/types/lib/inventory/source.d.ts +28 -0
  327. package/types/lib/inventory/source.d.ts.map +1 -1
  328. package/types/lib/inventory/spdx.d.ts +24 -0
  329. package/types/lib/inventory/spdx.d.ts.map +1 -1
  330. package/types/lib/inventory/traceRunner.d.ts +16 -1
  331. package/types/lib/inventory/traceRunner.d.ts.map +1 -1
  332. package/types/lib/inventory/tracedCrypto.d.ts +64 -0
  333. package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
  334. package/types/lib/managers/binary.d.ts +10 -0
  335. package/types/lib/managers/binary.d.ts.map +1 -1
  336. package/types/lib/managers/docker.d.ts +12 -0
  337. package/types/lib/managers/docker.d.ts.map +1 -1
  338. package/types/lib/managers/oci.d.ts +3 -1
  339. package/types/lib/managers/oci.d.ts.map +1 -1
  340. package/types/lib/parsers/cmakeCache.d.ts +16 -0
  341. package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
  342. package/types/lib/parsers/cmakeLists.d.ts +2 -1
  343. package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
  344. package/types/lib/parsers/cmakePresets.d.ts +78 -0
  345. package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
  346. package/types/lib/parsers/compileCommands.d.ts +115 -0
  347. package/types/lib/parsers/compileCommands.d.ts.map +1 -0
  348. package/types/lib/parsers/email.d.ts +19 -0
  349. package/types/lib/parsers/email.d.ts.map +1 -0
  350. package/types/lib/parsers/largeJson.d.ts +13 -0
  351. package/types/lib/parsers/largeJson.d.ts.map +1 -1
  352. package/types/lib/parsers/strictJson.d.ts +46 -0
  353. package/types/lib/parsers/strictJson.d.ts.map +1 -0
  354. package/types/lib/parsers/terraformConfig.d.ts +70 -0
  355. package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
  356. package/types/lib/parsers/terraformSource.d.ts +66 -0
  357. package/types/lib/parsers/terraformSource.d.ts.map +1 -0
  358. package/types/lib/server/server.d.ts +8 -0
  359. package/types/lib/server/server.d.ts.map +1 -1
  360. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  361. package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
  362. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  363. package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
  364. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  365. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  366. package/types/lib/stages/pregen/pregen.d.ts +14 -1
  367. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  368. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  369. package/types/lib/validator/index.d.ts +8 -0
  370. package/types/lib/validator/index.d.ts.map +1 -1
  371. package/types/lib/validator/reporters/json.d.ts.map +1 -1
  372. package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
@@ -1,7 +1,7 @@
1
1
  import { Buffer } from "node:buffer";
2
2
  import { readFileSync, statSync } from "node:fs";
3
3
  import { homedir } from "node:os";
4
- import { basename, dirname, join, relative, resolve } from "node:path";
4
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
5
  import process from "node:process";
6
6
 
7
7
  import { build } from "@cdxgen/cdx-purl";
@@ -23,11 +23,17 @@ import {
23
23
  import {
24
24
  checksumFile,
25
25
  getAllFiles,
26
+ getTmpDir,
26
27
  safeExistsSync,
27
28
  safeSpawnSync,
28
29
  } from "../core/fs.js";
29
30
  import { thoughtLog } from "../core/logger.js";
30
31
  import { dirNameStr, isMac } from "../core/paths.js";
32
+ import {
33
+ isProjectToolingAllowed,
34
+ reportProjectToolingSkipped,
35
+ } from "../core/projectTooling.js";
36
+ import { readCrateArchiveValues } from "../ecosystems/cargoCache.js";
31
37
  import {
32
38
  buildDependentPurl,
33
39
  collapseCmakeVersions,
@@ -35,7 +41,11 @@ import {
35
41
  resolveCmakeContext,
36
42
  withoutScrapedFetchDependency,
37
43
  } from "../ecosystems/cmakeResolver.js";
38
- import { getCppModules } from "../ecosystems/cppEvidence.js";
44
+ import {
45
+ emptyCppBuildContext,
46
+ resolveCppBuildContext,
47
+ } from "../ecosystems/cppBuildContext.js";
48
+ import { getCppModules, hasCppSources } from "../ecosystems/cppEvidence.js";
39
49
  import {
40
50
  getCratesMetadata,
41
51
  getSwiftPackageMetadata,
@@ -50,6 +60,7 @@ import {
50
60
  } from "../ecosystems/parsers-elm.js";
51
61
  import { parseGleamProject } from "../ecosystems/parsers-gleam.js";
52
62
  import {
63
+ compareGoVersions,
53
64
  isGoModWhyNotNeeded,
54
65
  parseGoListDep,
55
66
  parseGoModData,
@@ -58,6 +69,7 @@ import {
58
69
  parseGoModWhy,
59
70
  parseGopkgData,
60
71
  parseGosumData,
72
+ parseGosumHashes,
61
73
  } from "../ecosystems/parsers-go.js";
62
74
  import { parseJuliaProject } from "../ecosystems/parsers-julia.js";
63
75
  import {
@@ -115,7 +127,9 @@ import {
115
127
  } from "../ecosystems/parsers-rust.js";
116
128
  import { parseSpackLock } from "../ecosystems/parsers-spack.js";
117
129
  import { parseStackProject } from "../ecosystems/parsers-stack.js";
130
+ import { findVendoredCode } from "../ecosystems/vendoredCode.js";
118
131
  import { resolveZigGraph } from "../ecosystems/zigResolver.js";
132
+ import { cmakeBuildDirCandidates } from "../inventory/cmakeBuildDirs.js";
119
133
  import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
120
134
  import { convertOSQueryResults } from "../inventory/evidenceUtils.js";
121
135
  import { applyPurl, nixBomRef, tryBuildPurl } from "../inventory/purl.js";
@@ -190,6 +204,30 @@ export function getCargoCacheDir() {
190
204
  );
191
205
  }
192
206
 
207
+ /**
208
+ * Add a Go module of the project, a nested go.mod or a go.work member, under
209
+ * the parent component. A module that is already the parent, one of its
210
+ * subcomponents, or a component (a directory replacement inside the project)
211
+ * is not added again, so no bom-ref appears twice.
212
+ *
213
+ * @param {Object} parentComponent The project's parent component
214
+ * @param {Object} moduleComponent The module to add
215
+ * @param {Object[]} pkgList Components found so far
216
+ */
217
+ function addGoSubComponent(parentComponent, moduleComponent, pkgList) {
218
+ const ref = moduleComponent?.["bom-ref"];
219
+ if (
220
+ !ref ||
221
+ ref === parentComponent["bom-ref"] ||
222
+ parentComponent.components?.some((c) => c["bom-ref"] === ref) ||
223
+ pkgList.some((c) => c["bom-ref"] === ref)
224
+ ) {
225
+ return;
226
+ }
227
+ parentComponent.components = parentComponent.components || [];
228
+ parentComponent.components.push(moduleComponent);
229
+ }
230
+
193
231
  /**
194
232
  * Function to create bom string for Go projects
195
233
  *
@@ -305,6 +343,20 @@ export async function createGoBom(path, options) {
305
343
  }
306
344
  }
307
345
  }
346
+ // go mod why answers for a module path, but go.sum also names versions
347
+ // that only took part in version selection. Only a version whose content
348
+ // go.sum holds a checksum for was ever downloaded, and of those, MVS
349
+ // builds the highest.
350
+ const builtVersions = {};
351
+ for (const apkg of pkgList) {
352
+ const built = builtVersions[apkg.name];
353
+ if (
354
+ apkg._integrity &&
355
+ (!built || compareGoVersions(apkg.version, built) > 0)
356
+ ) {
357
+ builtVersions[apkg.name] = apkg.version;
358
+ }
359
+ }
308
360
  // A module go reports as unneeded is optional, but only when every module
309
361
  // was checked: once go mod why fails, the answers are incomplete, and a
310
362
  // tool failure is not evidence that a module is unused.
@@ -313,7 +365,9 @@ export async function createGoBom(path, options) {
313
365
  continue;
314
366
  }
315
367
  if (requiredModules.has(apkg.name)) {
316
- apkg.scope = "required";
368
+ if (builtVersions[apkg.name] === apkg.version) {
369
+ apkg.scope = "required";
370
+ }
317
371
  } else if (!circuitBreak && unneededModules.has(apkg.name)) {
318
372
  apkg.scope = "optional";
319
373
  }
@@ -339,12 +393,9 @@ export async function createGoBom(path, options) {
339
393
  console.log(`Parsing ${f}`);
340
394
  }
341
395
  const gosumData = readFileSync(f, { encoding: "utf-8" });
342
- const dlist = await parseGosumData(gosumData);
343
- if (dlist?.length) {
344
- dlist.forEach((pkg) => {
345
- gosumMap[`${pkg.name}@${pkg.version}`] = pkg._integrity;
346
- });
347
- }
396
+ // Only the hashes are needed here; reading them costs no registry
397
+ // round trip. The components come from go.mod and the go list output.
398
+ Object.assign(gosumMap, parseGosumHashes(gosumData));
348
399
  }
349
400
  }
350
401
 
@@ -379,6 +430,9 @@ export async function createGoBom(path, options) {
379
430
  });
380
431
 
381
432
  let rootParentComponent = null;
433
+ // Whether the go toolchain resolved a module graph. A module without
434
+ // dependencies resolves to no components, and that is a complete answer.
435
+ let resolvedByToolchain = false;
382
436
  // Use the go list -deps and go mod why commands to generate a good quality BOM for non-docker invocations
383
437
  if (
384
438
  !hasAnyProjectType(["docker", "oci", "container", "os"], options, false)
@@ -398,13 +452,15 @@ export async function createGoBom(path, options) {
398
452
  console.log("Executing go list -deps in", basePath);
399
453
  }
400
454
  // TODO: Replacing this with -json gives us more interesting data points such as GoFiles, Imports, and Deps
455
+ // The fields after Dir name the module content checksum and, for a
456
+ // module a replace directive swapped out, the replacement Go builds.
401
457
  let result = safeSpawnSync(
402
458
  "go",
403
459
  [
404
460
  "list",
405
461
  "-deps",
406
462
  "-f",
407
- "'{{with .Module}}{{.Path}}|{{.Version}}|{{.Indirect}}|{{.GoMod}}|{{.GoVersion}}|{{.Main}}|{{.Time}}|{{.Deprecated}}|{{.GoModSum}}|{{.Dir}}{{end}}'",
463
+ "'{{with .Module}}{{.Path}}|{{.Version}}|{{.Indirect}}|{{.GoMod}}|{{.GoVersion}}|{{.Main}}|{{.Time}}|{{.Deprecated}}|{{.GoModSum}}|{{.Dir}}|{{.Sum}}|{{with .Replace}}{{.Path}}{{end}}|{{with .Replace}}{{.Version}}{{end}}|{{with .Replace}}{{.Sum}}{{end}}{{end}}'",
408
464
  "./...",
409
465
  ],
410
466
  {
@@ -448,7 +504,9 @@ export async function createGoBom(path, options) {
448
504
  const stdout = result.stdout;
449
505
  if (stdout) {
450
506
  let cmdOutput = Buffer.from(stdout).toString();
451
- const retMap = await parseGoListDep(cmdOutput, gosumMap);
507
+ const retMap = await parseGoListDep(cmdOutput, gosumMap, {
508
+ mainModuleDir: basePath,
509
+ });
452
510
  if (retMap.pkgList?.length) {
453
511
  pkgList = pkgList.concat(retMap.pkgList);
454
512
  }
@@ -457,6 +515,7 @@ export async function createGoBom(path, options) {
457
515
  retMap.parentComponent &&
458
516
  Object.keys(retMap.parentComponent).length
459
517
  ) {
518
+ resolvedByToolchain = true;
460
519
  if (!rootParentComponent) {
461
520
  // First (shallowest) module becomes the root
462
521
  rootParentComponent = retMap.parentComponent;
@@ -464,12 +523,18 @@ export async function createGoBom(path, options) {
464
523
  parentComponent = rootParentComponent;
465
524
  } else {
466
525
  // Subsequent modules become subcomponents
467
- if (!parentComponent.components) {
468
- parentComponent.components = [];
469
- }
470
- parentComponent.components.push(retMap.parentComponent);
526
+ addGoSubComponent(
527
+ parentComponent,
528
+ retMap.parentComponent,
529
+ pkgList,
530
+ );
471
531
  }
472
532
  }
533
+ // The other members of a go.work workspace are modules of the same
534
+ // project, which no registry holds.
535
+ for (const workspaceModule of retMap.workspaceModules || []) {
536
+ addGoSubComponent(parentComponent, workspaceModule, pkgList);
537
+ }
473
538
  if (DEBUG_MODE) {
474
539
  console.log("Executing go mod graph in", basePath);
475
540
  }
@@ -519,8 +584,11 @@ export async function createGoBom(path, options) {
519
584
  }
520
585
  // Retain the parent component hierarchy
521
586
  if (Object.keys(retMap.parentComponent).length) {
522
- parentComponent.components = parentComponent.components || [];
523
- parentComponent.components.push(retMap.parentComponent);
587
+ addGoSubComponent(
588
+ parentComponent,
589
+ retMap.parentComponent,
590
+ pkgList,
591
+ );
524
592
  }
525
593
  }
526
594
  } else {
@@ -533,6 +601,7 @@ export async function createGoBom(path, options) {
533
601
  shell: isWin,
534
602
  });
535
603
  if (result.stdout) {
604
+ resolvedByToolchain = true;
536
605
  const cmdOutput = Buffer.from(result.stdout).toString();
537
606
  // The arguments to parseGoModGraph are slightly different to force inclusion of all packages
538
607
  const retMap = await parseGoModGraph(
@@ -561,8 +630,11 @@ export async function createGoBom(path, options) {
561
630
  parentComponent = rootParentComponent;
562
631
  } else {
563
632
  // Subsequent modules become subcomponents
564
- parentComponent.components = parentComponent.components || [];
565
- parentComponent.components.push(retMap.parentComponent);
633
+ addGoSubComponent(
634
+ parentComponent,
635
+ retMap.parentComponent,
636
+ pkgList,
637
+ );
566
638
  }
567
639
  }
568
640
  } else {
@@ -584,7 +656,7 @@ export async function createGoBom(path, options) {
584
656
  }
585
657
  }
586
658
  }
587
- if (pkgList.length && !shouldManuallyParse) {
659
+ if ((pkgList.length || resolvedByToolchain) && !shouldManuallyParse) {
588
660
  return buildBomNSData(options, pkgList, "golang", {
589
661
  dependencies,
590
662
  parentComponent,
@@ -727,11 +799,19 @@ function cargoAnswersVersion(cwd) {
727
799
  * @param {string} [filterPlatform] Target triple to resolve the graph for
728
800
  * @returns {object|undefined} Parsed `cargo metadata` output
729
801
  */
730
- function runCargoMetadata(cargoTomlFile, filterPlatform) {
731
- const basePath = dirname(cargoTomlFile);
802
+ function runCargoMetadata(cargoTomlFile, filterPlatform, options = {}) {
803
+ // cargo reads `.cargo/config.toml` (rustc, rustc-wrapper, [env]) and rustup
804
+ // reads `rust-toolchain.toml` from the working directory, and `cargo
805
+ // metadata` runs rustc to learn the target. Without permission to run the
806
+ // project's tooling, cargo starts outside the project and stays offline.
807
+ const toolingAllowed = isProjectToolingAllowed(options);
808
+ const basePath = toolingAllowed ? dirname(cargoTomlFile) : getTmpDir();
732
809
  const platformArgs = filterPlatform
733
810
  ? ["--filter-platform", filterPlatform]
734
811
  : [];
812
+ if (!toolingAllowed) {
813
+ platformArgs.push("--offline");
814
+ }
735
815
  // `--locked` keeps the user's lock file untouched; a workspace that is out of
736
816
  // date with its lock file needs the retry without it.
737
817
  for (const lockArgs of [["--locked"], []]) {
@@ -805,7 +885,7 @@ function annotateCargoDependencyKinds(
805
885
  let anyMetadata = false;
806
886
  let everyMetadata = true;
807
887
  for (const cargoTomlFile of cargoFiles) {
808
- const metadata = runCargoMetadata(cargoTomlFile);
888
+ const metadata = runCargoMetadata(cargoTomlFile, undefined, options);
809
889
  if (!metadata) {
810
890
  everyMetadata = false;
811
891
  continue;
@@ -819,7 +899,11 @@ function annotateCargoDependencyKinds(
819
899
  visitedWorkspaceRoots.add(workspaceRoot);
820
900
  anyMetadata = true;
821
901
  if (CARGO_TARGET) {
822
- const targetMetadata = runCargoMetadata(cargoTomlFile, CARGO_TARGET);
902
+ const targetMetadata = runCargoMetadata(
903
+ cargoTomlFile,
904
+ CARGO_TARGET,
905
+ options,
906
+ );
823
907
  if (targetMetadata) {
824
908
  for (const key of parseCargoMetadataResolve(targetMetadata)
825
909
  .resolvedKeys) {
@@ -957,13 +1041,31 @@ export async function createRustBom(path, options) {
957
1041
  `${options.multiProject ? "**/" : ""}Cargo.toml`,
958
1042
  options,
959
1043
  );
1044
+ // `cargo check` compiles the project, running its build scripts and
1045
+ // procedural macros, so --deep runs it only when the project's own tooling
1046
+ // may run.
1047
+ const cargoToolingAllowed = isProjectToolingAllowed(options);
1048
+ if (
1049
+ options.deep &&
1050
+ cargoFiles.length &&
1051
+ !cargoToolingAllowed &&
1052
+ !hasAnyProjectType(["oci"], options, false)
1053
+ ) {
1054
+ reportProjectToolingSkipped(
1055
+ options,
1056
+ null,
1057
+ "Skipping 'cargo check' since dependency installation is disabled. Build scripts and procedural macros are not run, so the files each crate uses are not recorded.",
1058
+ );
1059
+ }
960
1060
  // Attempt to build or generate lock files automatically
961
1061
  for (const f of cargoFiles) {
962
1062
  // If there are no cargo.lock files, we can attempt a cargo install when
963
1063
  // options.deep is true or options.lifecycle == build or post-build with installDeps
964
1064
  // Why the need for installDeps? It currently defaults to true, so let's obey if someone wants no installs
965
1065
  if (
966
- (options.deep && !hasAnyProjectType(["oci"], options, false)) ||
1066
+ (options.deep &&
1067
+ cargoToolingAllowed &&
1068
+ !hasAnyProjectType(["oci"], options, false)) ||
967
1069
  (options.installDeps &&
968
1070
  !safeExistsSync(f.replace(".toml", ".lock")) &&
969
1071
  ["build", "post-build"].includes(options.lifecycle))
@@ -1163,7 +1265,9 @@ export function buildCargoCacheComponent(crateFile) {
1163
1265
 
1164
1266
  /**
1165
1267
  * Enriches a cargo cache component with a SHA-256 hash and filename-based
1166
- * identity evidence (confidence 0.5). Hash computation failures are ignored.
1268
+ * identity evidence (confidence 0.5), and with what the archive's own manifest
1269
+ * says: its licence, description and repository, read from the archive without
1270
+ * extracting it anywhere. Hash computation failures are ignored.
1167
1271
  *
1168
1272
  * @param {string} crateFile Absolute path to the `.crate` archive
1169
1273
  * @param {object} [component] Component produced by `buildCargoCacheComponent`
@@ -1183,6 +1287,33 @@ export async function enrichCargoCacheComponent(crateFile, component) {
1183
1287
  } catch {
1184
1288
  // continue without hashes
1185
1289
  }
1290
+ const archive = await readCrateArchiveValues(
1291
+ crateFile,
1292
+ component.name,
1293
+ component.version,
1294
+ );
1295
+ if (archive) {
1296
+ if (archive.values.license && !component.license) {
1297
+ component.license = archive.values.license;
1298
+ }
1299
+ if (archive.values.licenses && !component.licenses) {
1300
+ component.licenses = archive.values.licenses;
1301
+ }
1302
+ if (archive.values.description && !component.description) {
1303
+ component.description = archive.values.description;
1304
+ }
1305
+ if (archive.values.repository && !component.repository) {
1306
+ component.repository = { url: archive.values.repository };
1307
+ }
1308
+ if (archive.values.homepage && !component.homepage) {
1309
+ component.homepage = { url: archive.values.homepage };
1310
+ }
1311
+ component.properties = component.properties || [];
1312
+ component.properties.push({
1313
+ name: "cdx:cargo:metadataSource",
1314
+ value: "local-registry",
1315
+ });
1316
+ }
1186
1317
  component.evidence = {
1187
1318
  identity: {
1188
1319
  field: "purl",
@@ -1365,6 +1496,7 @@ export function createCppBom(path, options) {
1365
1496
  }
1366
1497
  let pkgList = [];
1367
1498
  let parentComponentDependencies = [];
1499
+ const subProjects = [];
1368
1500
  if (conanLockFiles.length) {
1369
1501
  for (const f of conanLockFiles) {
1370
1502
  if (DEBUG_MODE) {
@@ -1477,8 +1609,17 @@ export function createCppBom(path, options) {
1477
1609
  Object.keys(retMap.parentComponent).length &&
1478
1610
  !addedParentComponentsMap[retMap.parentComponent.name]
1479
1611
  ) {
1612
+ // a project() below the scan root is a part of this project, not a
1613
+ // dependency of it
1480
1614
  retMap.parentComponent.type = "library";
1481
- pkgList.push(retMap.parentComponent);
1615
+ const subprojectDir = relative(scanRoot, resolve(dirname(f)))
1616
+ .split(sep)
1617
+ .join("/");
1618
+ retMap.parentComponent.properties = [
1619
+ ...(retMap.parentComponent.properties || []),
1620
+ { name: "cdx:cmake:subprojectDir", value: subprojectDir || "." },
1621
+ ];
1622
+ subProjects.push(retMap.parentComponent);
1482
1623
  addedParentComponentsMap[retMap.parentComponent.name] = true;
1483
1624
  }
1484
1625
  // Retain the dependency tree from cmake
@@ -1522,6 +1663,29 @@ export function createCppBom(path, options) {
1522
1663
  boundaries: new Map(),
1523
1664
  }
1524
1665
  : resolveCmakeContext(path, options);
1666
+ // How the project is built: its presets and compilers (formulation), its
1667
+ // hardening options (project properties) and its own include directories.
1668
+ const isImageScan = hasAnyProjectType(
1669
+ ["docker", "oci", "container", "os"],
1670
+ options,
1671
+ false,
1672
+ );
1673
+ // Code carried in the tree under a license of its own, outside the sources
1674
+ // of the dependencies CMake already knows and the build trees
1675
+ const vendored = isImageScan
1676
+ ? { components: [], dirs: [] }
1677
+ : findVendoredCode(path, options, [
1678
+ ...[...(cmakeContext.boundaries || new Map())]
1679
+ .filter(([, e]) => e?.kind === "fetch" || e?.kind === "submodule")
1680
+ .map(([dir]) => resolve(path, dir)),
1681
+ ...cmakeBuildDirCandidates(path, options),
1682
+ ]);
1683
+ if (vendored.components.length) {
1684
+ pkgList = pkgList.concat(vendored.components);
1685
+ }
1686
+ const buildContext = isImageScan
1687
+ ? emptyCppBuildContext()
1688
+ : resolveCppBuildContext(path, options, cmakeContext, vendored.dirs);
1525
1689
  if (cmakeContext.rootProject?.version && parentComponent) {
1526
1690
  const resolvedVersion = cmakeContext.rootProject.version;
1527
1691
  const scrapedVersion = parentComponent.version;
@@ -1651,30 +1815,44 @@ export function createCppBom(path, options) {
1651
1815
  // We collect OS packages with the word dev in the name using osquery here
1652
1816
  // rpm, deb and ebuild are supported
1653
1817
  // TODO: For archlinux and alpine users we need a different mechanism to collect this information
1654
- for (const queryCategory of Object.keys(cosDbQueries)) {
1655
- const queryObj = cosDbQueries[queryCategory];
1656
- const results = executeOsQuery(queryObj.query);
1657
- const dlist = convertOSQueryResults(
1658
- queryCategory,
1659
- queryObj,
1660
- results,
1661
- true,
1662
- {
1663
- deb: executeDpkgList,
1664
- rpm: executeRpmList,
1665
- apk: executeApkList,
1666
- ebuild: executeEqueryList,
1667
- alpm: executeAlpmList,
1668
- },
1669
- );
1670
- if (dlist?.length) {
1671
- osPkgsList = osPkgsList.concat(dlist);
1818
+ // The packages only resolve the headers named by the usages slice, so
1819
+ // they are not queried when there is neither a slice to reuse nor a C or
1820
+ // C++ source for atom to read.
1821
+ if (
1822
+ (options.usagesSlicesFile && safeExistsSync(options.usagesSlicesFile)) ||
1823
+ hasCppSources(path, options)
1824
+ ) {
1825
+ for (const queryCategory of Object.keys(cosDbQueries)) {
1826
+ const queryObj = cosDbQueries[queryCategory];
1827
+ const results = executeOsQuery(queryObj.query);
1828
+ const dlist = convertOSQueryResults(
1829
+ queryCategory,
1830
+ queryObj,
1831
+ results,
1832
+ true,
1833
+ {
1834
+ deb: executeDpkgList,
1835
+ rpm: executeRpmList,
1836
+ apk: executeApkList,
1837
+ ebuild: executeEqueryList,
1838
+ alpm: executeAlpmList,
1839
+ },
1840
+ );
1841
+ if (dlist?.length) {
1842
+ osPkgsList = osPkgsList.concat(dlist);
1843
+ }
1672
1844
  }
1673
1845
  }
1674
1846
  // Now we check with atom and attempt to detect all external modules via usages
1675
1847
  // We pass the current list of packages so that we enhance the current list and replace
1676
1848
  // components inadvertently. For example, we might resolved a name, version and url information already via cmake
1677
- const retMap = getCppModules(path, options, osPkgsList, pkgList);
1849
+ const retMap = getCppModules(
1850
+ path,
1851
+ options,
1852
+ osPkgsList,
1853
+ pkgList,
1854
+ buildContext.isFirstPartyHeader,
1855
+ );
1678
1856
  if (retMap.pkgList?.length) {
1679
1857
  pkgList = pkgList.concat(retMap.pkgList);
1680
1858
  }
@@ -1718,6 +1896,33 @@ export function createCppBom(path, options) {
1718
1896
  ]);
1719
1897
  }
1720
1898
 
1899
+ if (subProjects.length) {
1900
+ if (parentComponent) {
1901
+ parentComponent.components = parentComponent.components || [];
1902
+ for (const sub of subProjects) {
1903
+ if (
1904
+ !parentComponent.components.some(
1905
+ (c) => c["bom-ref"] === sub["bom-ref"],
1906
+ ) &&
1907
+ sub["bom-ref"] !== parentComponent["bom-ref"]
1908
+ ) {
1909
+ parentComponent.components.push(sub);
1910
+ }
1911
+ }
1912
+ } else {
1913
+ // with no project at the scan root there is nothing to nest them under
1914
+ pkgList = pkgList.concat(subProjects);
1915
+ }
1916
+ }
1917
+ if (parentComponent && buildContext.parentProperties.length) {
1918
+ parentComponent.properties = (parentComponent.properties || []).filter(
1919
+ (p) =>
1920
+ !buildContext.parentProperties.some(
1921
+ (bp) => bp.name === p.name && bp.value === p.value,
1922
+ ),
1923
+ );
1924
+ parentComponent.properties.push(...buildContext.parentProperties);
1925
+ }
1721
1926
  if (parentComponent) {
1722
1927
  sanitizeUnresolvedPurl(parentComponent);
1723
1928
  if (parentComponent.components) {
@@ -1734,6 +1939,7 @@ export function createCppBom(path, options) {
1734
1939
  src: path,
1735
1940
  parentComponent,
1736
1941
  dependencies,
1942
+ formulationList: buildContext.formulationComponents,
1737
1943
  });
1738
1944
  }
1739
1945
 
@@ -1761,11 +1967,35 @@ export function createClojureBom(path, options) {
1761
1967
  if (readEnvironmentVariable("LEIN_ARGS")) {
1762
1968
  LEIN_ARGS = readEnvironmentVariable("LEIN_ARGS").split(" ");
1763
1969
  }
1970
+ // `lein deps :tree-data` evaluates project.clj, which is a Clojure
1971
+ // program, so it belongs to the dependency-tooling surface disabled by
1972
+ // --no-install-deps and the pre-build lifecycle.
1973
+ const leinToolingAllowed = isProjectToolingAllowed(options);
1764
1974
  for (const f of leinFiles) {
1765
1975
  if (DEBUG_MODE) {
1766
1976
  console.log(`Parsing ${f}`);
1767
1977
  }
1768
1978
  const basePath = dirname(f);
1979
+ if (!leinToolingAllowed) {
1980
+ reportProjectToolingSkipped(
1981
+ options,
1982
+ "clojure.lein.tooling-disabled",
1983
+ "Skipping 'lein deps :tree-data' since dependency installation is disabled. Only the dependencies declared in project.clj will be used.",
1984
+ {
1985
+ ecosystem: "clojure",
1986
+ tool: "lein",
1987
+ impact: "transitive-deps",
1988
+ detail:
1989
+ "Dependency installation is disabled, so project.clj was not evaluated and only its directly declared dependencies are available.",
1990
+ },
1991
+ );
1992
+ const leinData = readFileSync(f, { encoding: "utf-8" });
1993
+ const dlist = parseLeiningenData(leinData);
1994
+ if (dlist?.length) {
1995
+ pkgList = pkgList.concat(dlist);
1996
+ }
1997
+ continue;
1998
+ }
1769
1999
  console.log("Executing", LEIN_CMD, "in", basePath);
1770
2000
  const result = safeSpawnSync(LEIN_CMD, LEIN_ARGS, {
1771
2001
  cwd: basePath,
@@ -2126,7 +2356,39 @@ export async function createSwiftBom(path, options) {
2126
2356
  );
2127
2357
  }
2128
2358
  if (swiftFiles.length) {
2359
+ // A SwiftPM manifest is a Swift program, so `swift package dump-package`
2360
+ // and `show-dependencies` execute the scanned project's code (and fetch
2361
+ // missing dependencies). They belong to the dependency-tooling surface
2362
+ // disabled by --no-install-deps and the pre-build lifecycle; the BOM then
2363
+ // comes from Package.resolved alone.
2364
+ const swiftToolingAllowed = isProjectToolingAllowed(options);
2365
+ if (!swiftToolingAllowed) {
2366
+ reportProjectToolingSkipped(
2367
+ options,
2368
+ "swift.tooling-disabled",
2369
+ "Skipping 'swift package show-dependencies' since dependency installation is disabled. Only the packages in Package.resolved will be used.",
2370
+ {
2371
+ ecosystem: "swift",
2372
+ tool: "swift",
2373
+ impact: "transitive-deps",
2374
+ detail:
2375
+ "Dependency installation is disabled, so the Package.swift manifest was not evaluated and only the packages from Package.resolved are available.",
2376
+ },
2377
+ );
2378
+ // The manifest is not run, so a project without Package.resolved still
2379
+ // gets a parent component named after its directory.
2380
+ if (!Object.keys(parentComponent).length) {
2381
+ parentComponent = createDefaultParentComponent(
2382
+ swiftFiles[0],
2383
+ "swift",
2384
+ options,
2385
+ );
2386
+ }
2387
+ }
2129
2388
  for (const f of swiftFiles) {
2389
+ if (!swiftToolingAllowed) {
2390
+ break;
2391
+ }
2130
2392
  const basePath = dirname(f);
2131
2393
  if (completedPath.includes(basePath)) {
2132
2394
  continue;
@@ -2328,7 +2590,7 @@ export async function createCocoaBom(path, options) {
2328
2590
  "application",
2329
2591
  );
2330
2592
  const podfileLock = loadYaml(readFileSync(lockFile, "utf-8"));
2331
- const pods = await parsePodfileLock(podfileLock, projectPath);
2593
+ const pods = await parsePodfileLock(podfileLock, projectPath, path);
2332
2594
  const allObjects = new Map();
2333
2595
  if (options) {
2334
2596
  // Every remote podspec the scan below reads is known from the lockfile,
@@ -2352,10 +2614,33 @@ export async function createCocoaBom(path, options) {
2352
2614
  allDependencies.set(name, podDependencies);
2353
2615
  }
2354
2616
  const targetDependencies = new Map();
2355
- if (
2356
- !readEnvironmentVariable("COCOA_INCLUDED_TARGETS") &&
2357
- !readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
2358
- ) {
2617
+ // `pod ipc podfile-json` evaluates the Podfile, which is a Ruby program,
2618
+ // so per-target filtering through it belongs to the dependency-tooling
2619
+ // surface disabled by --no-install-deps and the pre-build lifecycle. A
2620
+ // gated scan then keeps every pod the lockfile resolved (the union across
2621
+ // targets) instead of the configured target subset.
2622
+ const cocoaTargetsConfigured =
2623
+ readEnvironmentVariable("COCOA_INCLUDED_TARGETS") ||
2624
+ readEnvironmentVariable("COCOA_EXCLUDED_TARGETS");
2625
+ const cocoaToolingAllowed = isProjectToolingAllowed(options);
2626
+ // True only when target names the Podfile actually resolved are known, so
2627
+ // the include/exclude filters below can be applied to real targets.
2628
+ let targetFilteringActive = false;
2629
+ if (!cocoaTargetsConfigured || !cocoaToolingAllowed) {
2630
+ if (cocoaTargetsConfigured) {
2631
+ reportProjectToolingSkipped(
2632
+ options,
2633
+ "cocoa.podfile-json.tooling-disabled",
2634
+ "Skipping 'pod ipc podfile-json' since dependency installation is disabled. Every pod from Podfile.lock is included without per-target filtering.",
2635
+ {
2636
+ ecosystem: "cocoa",
2637
+ tool: "pod",
2638
+ impact: "components",
2639
+ detail:
2640
+ "Dependency installation is disabled, so the Podfile was not evaluated and target filtering fell back to all pods resolved in Podfile.lock.",
2641
+ },
2642
+ );
2643
+ }
2359
2644
  targetDependencies.set("Pods", podfileLock["DEPENDENCIES"]);
2360
2645
  } else {
2361
2646
  const result = executePodCommand(
@@ -2363,18 +2648,39 @@ export async function createCocoaBom(path, options) {
2363
2648
  projectPath,
2364
2649
  options,
2365
2650
  );
2366
- const resolvedPodFile = JSON.parse(result.stdout);
2367
- parsePodfileTargets(
2368
- resolvedPodFile["target_definitions"][0],
2369
- targetDependencies,
2370
- );
2651
+ let resolvedPodFile;
2652
+ try {
2653
+ resolvedPodFile = JSON.parse(result.stdout);
2654
+ } catch (_e) {
2655
+ resolvedPodFile = undefined;
2656
+ }
2657
+ if (resolvedPodFile?.target_definitions?.length) {
2658
+ parsePodfileTargets(
2659
+ resolvedPodFile["target_definitions"][0],
2660
+ targetDependencies,
2661
+ );
2662
+ targetFilteringActive = true;
2663
+ } else {
2664
+ // pod failed or printed nothing usable (it refuses to run as root,
2665
+ // for one), and an unparseable Podfile used to abort the whole scan.
2666
+ // Keep every locked pod rather than none.
2667
+ console.log(
2668
+ "The Podfile could not be resolved with CocoaPods, so all pods from Podfile.lock are included without per-target filtering.",
2669
+ );
2670
+ targetDependencies.set("Pods", podfileLock["DEPENDENCIES"]);
2671
+ }
2371
2672
  }
2372
2673
  const usedTargets = new Set(
2373
- readEnvironmentVariable("COCOA_INCLUDED_TARGETS")
2674
+ targetFilteringActive && readEnvironmentVariable("COCOA_INCLUDED_TARGETS")
2374
2675
  ? readEnvironmentVariable("COCOA_INCLUDED_TARGETS").split(",")
2375
2676
  : targetDependencies.keys(),
2376
2677
  );
2377
- if (readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")) {
2678
+ // Without the resolved Podfile there are no target names to exclude, and
2679
+ // excluding the lockfile's stand-in "Pods" target would drop every pod.
2680
+ if (
2681
+ targetFilteringActive &&
2682
+ readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
2683
+ ) {
2378
2684
  readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
2379
2685
  .split(",")
2380
2686
  .forEach((excludedTarget) => {