@cdxgen/cdxgen 13.1.0 → 13.3.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 (283) hide show
  1. package/README.md +32 -15
  2. package/bin/cdxgen.js +243 -122
  3. package/bin/evinse.js +7 -0
  4. package/bin/sign.js +88 -14
  5. package/bin/tracebom.js +64 -4
  6. package/bin/validate.js +29 -7
  7. package/bin/verify.js +79 -39
  8. package/data/crypto-oid.json +88 -12
  9. package/data/remediations.json +47 -0
  10. package/data/rules/ai-bom.yaml +78 -0
  11. package/data/rules/cargo-rust.yaml +132 -0
  12. package/data/rules/mcp-servers.yaml +122 -0
  13. package/lib/audit/targets.js +6 -1
  14. package/lib/cli/bomAssembly.js +117 -15
  15. package/lib/cli/cliOptions.js +93 -1
  16. package/lib/cli/index.js +235 -5
  17. package/lib/cli/jsBom.js +108 -26
  18. package/lib/cli/jvmBom.js +68 -12
  19. package/lib/cli/managedBom.js +264 -41
  20. package/lib/cli/nativeBom.js +923 -15
  21. package/lib/core/activity.js +120 -2
  22. package/lib/core/env.js +44 -7
  23. package/lib/core/fs.js +174 -6
  24. package/lib/core/metadataProperties.js +97 -0
  25. package/lib/core/projectConfig.js +31 -4
  26. package/lib/core/userAgent.js +151 -0
  27. package/lib/ecosystems/bunutils.js +269 -101
  28. package/lib/ecosystems/cargoCache.js +364 -0
  29. package/lib/ecosystems/caxa.js +447 -7
  30. package/lib/ecosystems/cmakeResolver.js +66 -0
  31. package/lib/ecosystems/cppEvidence.js +104 -33
  32. package/lib/ecosystems/ecosystems.js +260 -99
  33. package/lib/ecosystems/golem.js +11 -1
  34. package/lib/ecosystems/gradleutils.js +185 -9
  35. package/lib/ecosystems/jsEvidence.js +19 -20
  36. package/lib/ecosystems/kosi.js +1263 -0
  37. package/lib/ecosystems/npmutils.js +110 -9
  38. package/lib/ecosystems/parsers-crystal.js +179 -0
  39. package/lib/ecosystems/parsers-dotnet.js +120 -49
  40. package/lib/ecosystems/parsers-elm.js +816 -0
  41. package/lib/ecosystems/parsers-gleam.js +1 -1
  42. package/lib/ecosystems/parsers-go.js +47 -9
  43. package/lib/ecosystems/parsers-js.js +171 -50
  44. package/lib/ecosystems/parsers-julia.js +268 -0
  45. package/lib/ecosystems/parsers-lua.js +218 -0
  46. package/lib/ecosystems/parsers-misc.js +919 -161
  47. package/lib/ecosystems/parsers-nim.js +221 -0
  48. package/lib/ecosystems/parsers-opam.js +180 -0
  49. package/lib/ecosystems/parsers-perl.js +277 -0
  50. package/lib/ecosystems/parsers-python.js +27 -15
  51. package/lib/ecosystems/parsers-r.js +148 -0
  52. package/lib/ecosystems/parsers-rebar.js +411 -0
  53. package/lib/ecosystems/parsers-rust.js +954 -33
  54. package/lib/ecosystems/parsers-spack.js +204 -0
  55. package/lib/ecosystems/parsers-stack.js +264 -0
  56. package/lib/ecosystems/parsers-terraform.js +194 -0
  57. package/lib/ecosystems/rubyutils.js +1426 -166
  58. package/lib/ecosystems/rusi.js +158 -7
  59. package/lib/evinser/evinser.js +547 -129
  60. package/lib/evinser/swiftsem.js +1914 -302
  61. package/lib/helpers/agenticToolutils.js +925 -0
  62. package/lib/helpers/bomSigner.js +652 -221
  63. package/lib/inventory/agentFormulationParser.js +57 -4
  64. package/lib/inventory/aiCollector.js +504 -10
  65. package/lib/inventory/aiInventory.js +12 -0
  66. package/lib/inventory/analyzer.js +488 -30
  67. package/lib/inventory/astWorker.js +6 -0
  68. package/lib/inventory/atomUtils.js +568 -31
  69. package/lib/inventory/auditCategories.js +8 -0
  70. package/lib/inventory/cbomutils.js +30 -0
  71. package/lib/inventory/cdxrs.js +110 -14
  72. package/lib/inventory/communityAiConfigParser.js +215 -2
  73. package/lib/inventory/depsUtils.js +183 -11
  74. package/lib/inventory/display.js +4 -5
  75. package/lib/inventory/dosai.js +627 -13
  76. package/lib/inventory/dynamic.js +39 -1
  77. package/lib/inventory/envcontext.js +9 -6
  78. package/lib/inventory/evidenceUtils.js +26 -5
  79. package/lib/inventory/fetchBatch.js +190 -19
  80. package/lib/inventory/fetchRate.js +74 -11
  81. package/lib/inventory/forgeEnricher.js +3 -2
  82. package/lib/inventory/jvmToolEnv.js +6 -5
  83. package/lib/inventory/mcpConfigParser.js +166 -2
  84. package/lib/inventory/mcpDiscovery.js +11 -0
  85. package/lib/inventory/mcpServerManifest.js +389 -0
  86. package/lib/inventory/mcpbBundle.js +419 -0
  87. package/lib/inventory/plugins.js +3 -0
  88. package/lib/inventory/protobom.js +62 -89
  89. package/lib/inventory/protobomLoader.js +4 -0
  90. package/lib/inventory/purl.js +152 -3
  91. package/lib/inventory/rustFormulationParser.js +1 -1
  92. package/lib/inventory/sbomDocument.js +2 -70
  93. package/lib/inventory/source.js +47 -23
  94. package/lib/inventory/stylePackageRefs.js +41 -0
  95. package/lib/inventory/svelteUtils.js +524 -0
  96. package/lib/inventory/traceRunner.js +210 -21
  97. package/lib/managers/binary.js +115 -24
  98. package/lib/managers/docker.js +440 -20
  99. package/lib/managers/oci.js +39 -1
  100. package/lib/parsers/cmakeLists.js +452 -0
  101. package/lib/parsers/huggingfaceUtils.js +15 -7
  102. package/lib/parsers/largeJson.js +454 -0
  103. package/lib/parsers/npmrc.js +19 -1
  104. package/lib/parsers/onnx.js +294 -0
  105. package/lib/parsers/safetensors.js +114 -0
  106. package/lib/stages/postgen/introspection/markers.js +29 -6
  107. package/lib/stages/postgen/postgen.js +237 -16
  108. package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
  109. package/lib/validator/bomValidator.js +6 -16
  110. package/lib/validator/index.js +48 -10
  111. package/lib/validator/reporters/console.js +3 -0
  112. package/lib/validator/reporters/json.js +1 -0
  113. package/lib/validator/reporters/sarif.js +7 -0
  114. package/package.json +27 -27
  115. package/types/lib/audit/targets.d.ts.map +1 -1
  116. package/types/lib/cli/bomAssembly.d.ts +2 -1
  117. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  118. package/types/lib/cli/cliOptions.d.ts +33 -1
  119. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  120. package/types/lib/cli/index.d.ts +2 -2
  121. package/types/lib/cli/index.d.ts.map +1 -1
  122. package/types/lib/cli/jsBom.d.ts +23 -0
  123. package/types/lib/cli/jsBom.d.ts.map +1 -1
  124. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  125. package/types/lib/cli/managedBom.d.ts +33 -0
  126. package/types/lib/cli/managedBom.d.ts.map +1 -1
  127. package/types/lib/cli/nativeBom.d.ts +88 -8
  128. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  129. package/types/lib/core/activity.d.ts.map +1 -1
  130. package/types/lib/core/env.d.ts +21 -0
  131. package/types/lib/core/env.d.ts.map +1 -1
  132. package/types/lib/core/fs.d.ts +55 -0
  133. package/types/lib/core/fs.d.ts.map +1 -1
  134. package/types/lib/core/metadataProperties.d.ts +39 -0
  135. package/types/lib/core/metadataProperties.d.ts.map +1 -0
  136. package/types/lib/core/projectConfig.d.ts +6 -2
  137. package/types/lib/core/projectConfig.d.ts.map +1 -1
  138. package/types/lib/core/userAgent.d.ts +56 -0
  139. package/types/lib/core/userAgent.d.ts.map +1 -0
  140. package/types/lib/ecosystems/bunutils.d.ts +12 -5
  141. package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
  142. package/types/lib/ecosystems/cargoCache.d.ts +75 -0
  143. package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
  144. package/types/lib/ecosystems/caxa.d.ts +14 -0
  145. package/types/lib/ecosystems/caxa.d.ts.map +1 -1
  146. package/types/lib/ecosystems/cmakeResolver.d.ts +23 -0
  147. package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
  148. package/types/lib/ecosystems/cppEvidence.d.ts +2 -2
  149. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  150. package/types/lib/ecosystems/ecosystems.d.ts +15 -1
  151. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  152. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  153. package/types/lib/ecosystems/gradleutils.d.ts +40 -4
  154. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  155. package/types/lib/ecosystems/jsEvidence.d.ts +5 -2
  156. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  157. package/types/lib/ecosystems/kosi.d.ts +86 -0
  158. package/types/lib/ecosystems/kosi.d.ts.map +1 -0
  159. package/types/lib/ecosystems/npmutils.d.ts +42 -0
  160. package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
  161. package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
  162. package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
  163. package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
  164. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
  165. package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
  166. package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
  167. package/types/lib/ecosystems/parsers-go.d.ts +10 -0
  168. package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
  169. package/types/lib/ecosystems/parsers-js.d.ts +10 -4
  170. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  171. package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
  172. package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
  173. package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
  174. package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
  175. package/types/lib/ecosystems/parsers-misc.d.ts +90 -3
  176. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  177. package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
  178. package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
  179. package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
  180. package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
  181. package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
  182. package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
  183. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  184. package/types/lib/ecosystems/parsers-r.d.ts +35 -0
  185. package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
  186. package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
  187. package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
  188. package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
  189. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  190. package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
  191. package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
  192. package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
  193. package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
  194. package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
  195. package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
  196. package/types/lib/ecosystems/pythonutils.d.ts +1 -1
  197. package/types/lib/ecosystems/rubyutils.d.ts +143 -2
  198. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  199. package/types/lib/ecosystems/rusi.d.ts +13 -0
  200. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  201. package/types/lib/evinser/evinser.d.ts +81 -2
  202. package/types/lib/evinser/evinser.d.ts.map +1 -1
  203. package/types/lib/evinser/swiftsem.d.ts +280 -15
  204. package/types/lib/evinser/swiftsem.d.ts.map +1 -1
  205. package/types/lib/helpers/agenticToolutils.d.ts +87 -0
  206. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
  207. package/types/lib/helpers/bomSigner.d.ts +106 -13
  208. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  209. package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
  210. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  211. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  212. package/types/lib/inventory/analyzer.d.ts.map +1 -1
  213. package/types/lib/inventory/atomUtils.d.ts +145 -3
  214. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  215. package/types/lib/inventory/auditCategories.d.ts +4 -0
  216. package/types/lib/inventory/auditCategories.d.ts.map +1 -1
  217. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  218. package/types/lib/inventory/cdxrs.d.ts +8 -3
  219. package/types/lib/inventory/cdxrs.d.ts.map +1 -1
  220. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  221. package/types/lib/inventory/depsUtils.d.ts +15 -0
  222. package/types/lib/inventory/depsUtils.d.ts.map +1 -1
  223. package/types/lib/inventory/display.d.ts.map +1 -1
  224. package/types/lib/inventory/dosai.d.ts +87 -1
  225. package/types/lib/inventory/dosai.d.ts.map +1 -1
  226. package/types/lib/inventory/dynamic.d.ts.map +1 -1
  227. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  228. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  229. package/types/lib/inventory/fetchBatch.d.ts +34 -0
  230. package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
  231. package/types/lib/inventory/fetchRate.d.ts +9 -6
  232. package/types/lib/inventory/fetchRate.d.ts.map +1 -1
  233. package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
  234. package/types/lib/inventory/jvmToolEnv.d.ts +5 -4
  235. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  236. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  237. package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
  238. package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
  239. package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
  240. package/types/lib/inventory/mcpbBundle.d.ts +19 -0
  241. package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
  242. package/types/lib/inventory/plugins.d.ts.map +1 -1
  243. package/types/lib/inventory/protobom.d.ts +18 -13
  244. package/types/lib/inventory/protobom.d.ts.map +1 -1
  245. package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
  246. package/types/lib/inventory/purl.d.ts +71 -2
  247. package/types/lib/inventory/purl.d.ts.map +1 -1
  248. package/types/lib/inventory/sbomDocument.d.ts.map +1 -1
  249. package/types/lib/inventory/source.d.ts.map +1 -1
  250. package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
  251. package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
  252. package/types/lib/inventory/svelteUtils.d.ts +124 -0
  253. package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
  254. package/types/lib/inventory/traceRunner.d.ts +47 -1
  255. package/types/lib/inventory/traceRunner.d.ts.map +1 -1
  256. package/types/lib/managers/binary.d.ts +30 -1
  257. package/types/lib/managers/binary.d.ts.map +1 -1
  258. package/types/lib/managers/docker.d.ts +29 -0
  259. package/types/lib/managers/docker.d.ts.map +1 -1
  260. package/types/lib/managers/oci.d.ts +14 -0
  261. package/types/lib/managers/oci.d.ts.map +1 -1
  262. package/types/lib/parsers/cmakeLists.d.ts +76 -0
  263. package/types/lib/parsers/cmakeLists.d.ts.map +1 -0
  264. package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
  265. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  266. package/types/lib/parsers/largeJson.d.ts +52 -0
  267. package/types/lib/parsers/largeJson.d.ts.map +1 -0
  268. package/types/lib/parsers/npmrc.d.ts +5 -0
  269. package/types/lib/parsers/npmrc.d.ts.map +1 -1
  270. package/types/lib/parsers/onnx.d.ts +28 -0
  271. package/types/lib/parsers/onnx.d.ts.map +1 -0
  272. package/types/lib/parsers/safetensors.d.ts +22 -0
  273. package/types/lib/parsers/safetensors.d.ts.map +1 -0
  274. package/types/lib/stages/postgen/introspection/markers.d.ts +3 -2
  275. package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -1
  276. package/types/lib/stages/postgen/postgen.d.ts +33 -0
  277. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  278. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  279. package/types/lib/validator/index.d.ts +10 -1
  280. package/types/lib/validator/index.d.ts.map +1 -1
  281. package/types/lib/validator/reporters/console.d.ts.map +1 -1
  282. package/types/lib/validator/reporters/json.d.ts.map +1 -1
  283. package/types/lib/validator/reporters/sarif.d.ts.map +1 -1
@@ -24,7 +24,35 @@ import { CPP_STD_MODULES } from "../core/state.js";
24
24
  import { findAppModules } from "../inventory/atomUtils.js";
25
25
  import { getOSPackageForFile } from "../inventory/osPackageResolver.js";
26
26
  import { locateGenericPackage } from "../inventory/purl.js";
27
- import { parseCmakeLikeFile, parseCUsageSlice } from "./parsers-misc.js";
27
+ import {
28
+ parseCmakeLikeFile,
29
+ parseCUsageSlice,
30
+ parseXmakeRequiresLock,
31
+ } from "./parsers-misc.js";
32
+
33
+ /**
34
+ * Add the symbols a file uses to a component's `internal:ImportedSymbols`,
35
+ * keeping every other property and the symbols already recorded.
36
+ *
37
+ * @param {Object} apkg Component to enrich
38
+ * @param {string[]} symbols Symbol names
39
+ */
40
+ function mergeImportedSymbols(apkg, symbols) {
41
+ apkg.properties = apkg.properties || [];
42
+ const prop = apkg.properties.find(
43
+ (p) => p.name === "internal:ImportedSymbols",
44
+ );
45
+ if (prop) {
46
+ prop.value = Array.from(new Set([...prop.value.split("|"), ...symbols]))
47
+ .sort()
48
+ .join("|");
49
+ } else {
50
+ apkg.properties.push({
51
+ name: "internal:ImportedSymbols",
52
+ value: symbols.join("|"),
53
+ });
54
+ }
55
+ }
28
56
 
29
57
  /**
30
58
  * Method to find c/c++ modules by collecting usages with atom
@@ -44,8 +72,11 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
44
72
  let parentComponent;
45
73
  const dependsOn = new Set();
46
74
 
75
+ // Components from CMake and Conan carry no group: the key spells a missing
76
+ // group the same way on insert and on lookup.
77
+ const epkgKey = (group, name) => `${group || ""}/${name}`;
47
78
  (epkgList || []).forEach((p) => {
48
- epkgMap[`${p.group}/${p.name}`] = p;
79
+ epkgMap[epkgKey(p.group, p.name)] = p;
49
80
  });
50
81
  // Let's look for any vcpkg.json file to tell us about the directory we're scanning
51
82
  // users can use this file to give us a clue even if they do not use vcpkg library manager
@@ -72,11 +103,22 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
72
103
  if (vcPkgData.homepage) {
73
104
  parentComponent.homepage = { url: vcPkgData.homepage };
74
105
  }
106
+ // The builtin baseline is the vcpkg commit that pins every port version,
107
+ // so it identifies the version set the manifest resolves against.
108
+ if (typeof vcPkgData["builtin-baseline"] === "string") {
109
+ parentComponent.properties = [
110
+ {
111
+ name: "cdx:vcpkg:baseline",
112
+ value: vcPkgData["builtin-baseline"],
113
+ },
114
+ ];
115
+ }
75
116
  // Are there any dependencies declared in vcpkg.json
76
117
  if (vcPkgData.dependencies && Array.isArray(vcPkgData.dependencies)) {
77
118
  for (const avcdep of vcPkgData.dependencies) {
78
119
  let avcpkgName;
79
120
  let scope;
121
+ let vcpkgFeatures;
80
122
  if (typeof avcdep === "string" || avcdep instanceof String) {
81
123
  avcpkgName = avcdep;
82
124
  } else if (Object.keys(avcdep).length && avcdep.name) {
@@ -84,13 +126,16 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
84
126
  if (avcdep.host) {
85
127
  scope = "optional";
86
128
  }
129
+ vcpkgFeatures = Array.isArray(avcdep.features)
130
+ ? avcdep.features.join(",")
131
+ : undefined;
87
132
  }
88
133
  // Is this a dependency we haven't seen before including the all lower and upper case version?
89
134
  if (
90
135
  avcpkgName &&
91
- !epkgMap[`/${avcpkgName}`] &&
92
- !epkgMap[`/${avcpkgName.toLowerCase()}`] &&
93
- !epkgMap[`/${avcpkgName.toUpperCase()}`]
136
+ !epkgMap[epkgKey("", avcpkgName)] &&
137
+ !epkgMap[epkgKey("", avcpkgName.toLowerCase())] &&
138
+ !epkgMap[epkgKey("", avcpkgName.toUpperCase())]
94
139
  ) {
95
140
  const pkgPurl = build({
96
141
  type: pkgType,
@@ -106,6 +151,12 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
106
151
  purl: pkgPurl,
107
152
  scope,
108
153
  "bom-ref": decodeURIComponent(pkgPurl),
154
+ properties: [
155
+ { name: "cdx:vcpkg:declared", value: "true" },
156
+ ...(vcpkgFeatures
157
+ ? [{ name: "cdx:vcpkg:features", value: vcpkgFeatures }]
158
+ : []),
159
+ ],
109
160
  evidence: {
110
161
  identity: {
111
162
  field: "purl",
@@ -129,7 +180,21 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
129
180
  }
130
181
  }
131
182
  } // if
132
- } else if (safeExistsSync(join(src, "CMakeLists.txt"))) {
183
+ }
184
+ // xmake locks its resolved requirements in `xmake-requires.lock`; the
185
+ // entries are additions to whatever other evidence collectors found.
186
+ const xmakeLockFile = join(src, "xmake-requires.lock");
187
+ if (safeExistsSync(xmakeLockFile)) {
188
+ const xmakePkgs = parseXmakeRequiresLock(xmakeLockFile);
189
+ for (const apkg of xmakePkgs) {
190
+ if (!pkgAddedMap[apkg.name]) {
191
+ pkgList.push(apkg);
192
+ dependsOn.add(apkg["bom-ref"]);
193
+ pkgAddedMap[apkg.name] = true;
194
+ }
195
+ }
196
+ }
197
+ if (!parentComponent && safeExistsSync(join(src, "CMakeLists.txt"))) {
133
198
  const retMap = parseCmakeLikeFile(join(src, "CMakeLists.txt"), pkgType);
134
199
  if (retMap.parentComponent && Object.keys(retMap.parentComponent).length) {
135
200
  parentComponent = retMap.parentComponent;
@@ -167,6 +232,8 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
167
232
  );
168
233
  }
169
234
  const usageData = parseCUsageSlice(sliceData);
235
+ const osComponents = new Map();
236
+ const addedRefs = new Set();
170
237
  for (let afile of Object.keys(usageData)) {
171
238
  // Normalize windows separator
172
239
  afile = afile.replace("..\\", "").replace(/\\/g, "/");
@@ -197,13 +264,31 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
197
264
  if (CPP_STD_MODULES.includes(name)) {
198
265
  continue;
199
266
  }
200
- let apkg = getOSPackageForFile(afile, osPkgsList) ||
201
- epkgMap[`${group}/${name}`] || {
267
+ // The OS package list is shared by every header: a component taken from it
268
+ // is a copy, so the internal:PkgProvides the next header is matched against
269
+ // stays intact. A component the caller already listed is enriched in place
270
+ // and not listed again.
271
+ const osPkg = getOSPackageForFile(afile, osPkgsList);
272
+ const listedPkg = osPkg ? undefined : epkgMap[epkgKey(group, name)];
273
+ let apkg;
274
+ if (osPkg) {
275
+ const osRef = osPkg["bom-ref"] || osPkg.purl || osPkg.name;
276
+ apkg = osComponents.get(osRef);
277
+ if (!apkg) {
278
+ apkg = {
279
+ ...osPkg,
280
+ properties: (osPkg.properties || []).map((prop) => ({ ...prop })),
281
+ };
282
+ osComponents.set(osRef, apkg);
283
+ }
284
+ } else {
285
+ apkg = listedPkg || {
202
286
  name,
203
287
  group,
204
288
  version: "",
205
289
  type: pkgType,
206
290
  };
291
+ }
207
292
  // If this is a relative file, there is a good chance we can reuse the project group
208
293
  if (!afile.startsWith(_sep) && !group.length) {
209
294
  group = options.projectGroup || "";
@@ -253,36 +338,22 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
253
338
  )
254
339
  .map((v) => v.split(":")[0])
255
340
  .sort();
256
- if (!apkg["properties"] && usymbols.length) {
257
- apkg["properties"] = [
258
- { name: "internal:ImportedSymbols", value: usymbols.join("|") },
259
- ];
260
- } else {
261
- apkg["properties"] = [];
262
- }
263
- const newProps = [];
264
- let symbolsPropertyFound = false;
265
- for (const prop of apkg["properties"]) {
266
- if (prop.name === "internal:ImportedSymbols") {
267
- symbolsPropertyFound = true;
268
- let existingSymbols = prop.value.split("|");
269
- existingSymbols = existingSymbols.concat(usymbols);
270
- prop.value = Array.from(new Set(existingSymbols)).sort().join("|");
271
- }
272
- newProps.push(prop);
341
+ if (usymbols.length) {
342
+ mergeImportedSymbols(apkg, usymbols);
273
343
  }
274
- if (!symbolsPropertyFound && usymbols.length) {
275
- apkg["properties"].push({
276
- name: "internal:ImportedSymbols",
277
- value: usymbols.join("|"),
278
- });
279
- }
280
- apkg["properties"] = newProps;
281
344
  }
282
345
  // At this point, we have a package but we don't know what it's called
283
346
  // So let's try to locate this generic package using some heuristics
284
347
  apkg = locateGenericPackage(apkg);
285
- if (!pkgAddedMap[name]) {
348
+ if (listedPkg) {
349
+ dependsOn.add(apkg["bom-ref"]);
350
+ } else if (osPkg) {
351
+ if (!addedRefs.has(apkg["bom-ref"])) {
352
+ pkgList.push(apkg);
353
+ dependsOn.add(apkg["bom-ref"]);
354
+ addedRefs.add(apkg["bom-ref"]);
355
+ }
356
+ } else if (!pkgAddedMap[name]) {
286
357
  pkgList.push(apkg);
287
358
  dependsOn.add(apkg["bom-ref"]);
288
359
  pkgAddedMap[name] = true;