@cdxgen/cdxgen 13.6.0 → 13.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/bin/audit.js +7 -4
- package/bin/cdxgen.js +256 -37
- package/bin/convert.js +146 -22
- package/bin/evinse.js +25 -3
- package/bin/repl.js +47 -3
- package/bin/sign.js +211 -34
- package/bin/tracebom.js +18 -6
- package/bin/validate.js +18 -3
- package/bin/verify.js +113 -5
- package/data/behavior-taxonomy.schema.json +1491 -0
- package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
- package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
- package/data/pqc-migration.json +239 -0
- package/data/remediations.json +52 -0
- package/data/rules/cbom-security.yaml +4 -3
- package/data/rules/package-integrity.yaml +28 -0
- package/lib/audit/index.js +25 -3
- package/lib/cli/bomAssembly.js +80 -1
- package/lib/cli/cliOptions.js +121 -17
- package/lib/cli/index.js +609 -898
- package/lib/cli/jsBom.js +3 -0
- package/lib/cli/jvmBom.js +365 -40
- package/lib/cli/managedBom.js +19 -3
- package/lib/cli/nativeBom.js +10 -0
- package/lib/core/env.js +26 -0
- package/lib/core/fs.js +126 -3
- package/lib/core/globPatterns.js +218 -0
- package/lib/core/processTree.js +99 -12
- package/lib/core/projectConfig.js +332 -25
- package/lib/core/toolRegistry.js +15 -1
- package/lib/ecosystems/denoutils.js +2 -2
- package/lib/ecosystems/golem.js +3 -8
- package/lib/ecosystems/gradleutils.js +1082 -6
- package/lib/ecosystems/jsEvidence.js +90 -38
- package/lib/ecosystems/kosi.js +3 -5
- package/lib/ecosystems/npmVersionResolution.js +376 -0
- package/lib/ecosystems/parsers-python.js +89 -28
- package/lib/ecosystems/parsers-rust.js +117 -15
- package/lib/ecosystems/remote/huggingface.js +22 -0
- package/lib/ecosystems/rusi.js +2 -4
- package/lib/ecosystems/scalasem.js +2 -1
- package/lib/evinser/evinser.js +196 -34
- package/lib/evinser/scalasem.js +5 -1
- package/lib/helpers/agenticToolutils.js +112 -1
- package/lib/helpers/bomSigner.js +43 -9
- package/lib/helpers/jssSigner.js +1276 -0
- package/lib/inventory/agentBlueprint.js +193 -0
- package/lib/inventory/agentToolNames.js +145 -0
- package/lib/inventory/aiCollector.js +153 -7
- package/lib/inventory/aiInventory.js +44 -8
- package/lib/inventory/aiProviders.js +324 -0
- package/lib/inventory/bomUtils.js +8 -1
- package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
- package/lib/inventory/citations.js +31 -2
- package/lib/inventory/communityAiConfigParser.js +978 -80
- package/lib/inventory/cyclonedx20.js +152 -0
- package/lib/inventory/cyclonedx20Common.js +286 -0
- package/lib/inventory/cyclonedx20Derived.js +159 -0
- package/lib/inventory/cyclonedx20Parties.js +552 -0
- package/lib/inventory/cyclonedx20Read.js +768 -0
- package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
- package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
- package/lib/inventory/cyclonedx20ReadContext.js +380 -0
- package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
- package/lib/inventory/cyclonedx20ReadSections.js +599 -0
- package/lib/inventory/cyclonedx20Render.js +766 -0
- package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
- package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
- package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
- package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
- package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
- package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
- package/lib/inventory/cyclonedx20RenderSections.js +499 -0
- package/lib/inventory/cyclonedx20Tables.js +594 -0
- package/lib/inventory/deps.js +106 -13
- package/lib/inventory/dosai.js +236 -1
- package/lib/inventory/dosaiParsers.js +3 -6
- package/lib/inventory/dotnetRuntime.js +164 -14
- package/lib/inventory/ecosystemFormulationParsers.js +979 -0
- package/lib/inventory/envcontext.js +132 -38
- package/lib/inventory/evidenceUtils.js +2 -1
- package/lib/inventory/formulationParsers.js +95 -13
- package/lib/inventory/hbom.js +45 -6
- package/lib/inventory/hbomLoader.js +166 -0
- package/lib/inventory/mcpConfigParser.js +5 -0
- package/lib/inventory/occurrenceKey.js +90 -0
- package/lib/inventory/pqcMigration.js +426 -0
- package/lib/inventory/rustFormulationParser.js +21 -10
- package/lib/inventory/source.js +65 -6
- package/lib/parsers/huggingfaceManifest.js +9 -1
- package/lib/parsers/huggingfaceUtils.js +18 -0
- package/lib/parsers/kiroPermissions.js +166 -0
- package/lib/server/server.js +36 -34
- package/lib/stages/postgen/postgen.js +41 -1
- package/lib/stages/postgen/specVersionCompat.js +76 -0
- package/lib/validator/bomValidator.js +8 -1
- package/lib/validator/complianceEngine.js +30 -3
- package/lib/validator/complianceRules.js +1416 -4
- package/lib/validator/generated/validate-2.0.mjs +57554 -13851
- package/lib/validator/index.js +48 -7
- package/lib/validator/reporters/json.js +6 -0
- package/package.json +9 -9
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +6 -2
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +16 -0
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +6 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +2 -1
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +15 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +30 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +10 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +4 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/globPatterns.d.ts +70 -0
- package/types/lib/core/globPatterns.d.ts.map +1 -0
- package/types/lib/core/paths.d.ts +9 -0
- package/types/lib/core/paths.d.ts.map +1 -1
- package/types/lib/core/processTree.d.ts +16 -5
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts +47 -8
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +248 -8
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
- package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts +58 -16
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +61 -9
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/scalasem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +53 -19
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +20 -3
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/helpers/jssSigner.d.ts +288 -0
- package/types/lib/helpers/jssSigner.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +303 -19
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/inventory/agentBlueprint.d.ts +70 -0
- package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
- package/types/lib/inventory/agentToolNames.d.ts +51 -0
- package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/aiProviders.d.ts +85 -0
- package/types/lib/inventory/aiProviders.d.ts.map +1 -0
- package/types/lib/inventory/bomUtils.d.ts.map +1 -1
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +5 -0
- package/types/lib/inventory/citations.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/cyclonedx20.d.ts +99 -0
- package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +35 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +19 -0
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +51 -4
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -1
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +22 -6
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts +11 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomLoader.d.ts +54 -0
- package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/occurrenceKey.d.ts +52 -0
- package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
- package/types/lib/inventory/pqcMigration.d.ts +84 -0
- package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
- package/types/lib/inventory/scalaDedupe.d.ts +43 -0
- package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +15 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/kiroPermissions.d.ts +62 -0
- package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +7 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts +5 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceEngine.d.ts +4 -4
- package/types/lib/validator/complianceEngine.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts +14 -2
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
|
@@ -8,6 +8,7 @@ import { parse as _load } from "yaml";
|
|
|
8
8
|
import { DEBUG_MODE } from "../core/activity.js";
|
|
9
9
|
import { recordDegradation } from "../core/buildLedger.js";
|
|
10
10
|
import { getAllFiles, safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
11
|
+
import { sanitizeBomUrl } from "../core/propertySanitizer.js";
|
|
11
12
|
import { PYTHON_STD_MODULES } from "../core/state.js";
|
|
12
13
|
import { parseToml } from "../core/toml.js";
|
|
13
14
|
import { tryBuildPurl } from "../inventory/purl.js";
|
|
@@ -1137,10 +1138,22 @@ export async function parsePyLockData(
|
|
|
1137
1138
|
hasWorkspaces = true;
|
|
1138
1139
|
}
|
|
1139
1140
|
for (const amember of workspaceMembers) {
|
|
1140
|
-
if (amember === parentComponent
|
|
1141
|
+
if (amember === parentComponent?.name) {
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
// a lock file read without its pyproject.toml has no parent to hold
|
|
1145
|
+
// the members, which is said once for the whole lock file
|
|
1146
|
+
if (!parentComponent) {
|
|
1147
|
+
if (!workspaceWarningShown) {
|
|
1148
|
+
console.log(
|
|
1149
|
+
`The workspace members in ${lockFile || "the lock file"} are read without a pyproject.toml, so there is no project to list them under.`,
|
|
1150
|
+
);
|
|
1151
|
+
workspaceWarningShown = true;
|
|
1152
|
+
}
|
|
1141
1153
|
continue;
|
|
1142
1154
|
}
|
|
1143
1155
|
if (workspaceComponentMap[amember]) {
|
|
1156
|
+
parentComponent.components = parentComponent.components || [];
|
|
1144
1157
|
parentComponent.components.push(workspaceComponentMap[amember]);
|
|
1145
1158
|
} else {
|
|
1146
1159
|
if (!workspaceWarningShown) {
|
|
@@ -1629,14 +1642,40 @@ export async function parsePyLockData(
|
|
|
1629
1642
|
}
|
|
1630
1643
|
|
|
1631
1644
|
/**
|
|
1632
|
-
*
|
|
1633
|
-
*
|
|
1645
|
+
* An exact PEP 440 version clause: `==` or `===` and a version with no
|
|
1646
|
+
* wildcard.
|
|
1634
1647
|
*
|
|
1635
|
-
*
|
|
1636
|
-
*
|
|
1637
|
-
* or a local version label (`2.1.0+cpu`).
|
|
1648
|
+
* Whitespace may separate the operator from the version, and a version may
|
|
1649
|
+
* carry a PEP 440 epoch (`1!2.0`) or a local version label (`2.1.0+cpu`).
|
|
1638
1650
|
*/
|
|
1639
|
-
const
|
|
1651
|
+
const PEP440_EXACT_CLAUSE = /^(===?)\s*([0-9A-Za-z._+!-]+)$/;
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* Version a PEP 508 requirement pins: the version of its only exact clause.
|
|
1655
|
+
*
|
|
1656
|
+
* A requirement with no exact clause, a wildcard (`==1.2.*`) or more than one
|
|
1657
|
+
* exact clause pins no version, so a range such as `>=1.0,<2` gives null
|
|
1658
|
+
* rather than one of its bounds. Per-requirement options such as
|
|
1659
|
+
* `--config-settings` are not clauses.
|
|
1660
|
+
*
|
|
1661
|
+
* @param {String} versionSpecifiers Version specifiers of the requirement
|
|
1662
|
+
* @returns {String|null} The pinned version, or null
|
|
1663
|
+
*/
|
|
1664
|
+
function pinnedRequirementVersion(versionSpecifiers) {
|
|
1665
|
+
const specifiers = versionSpecifiers || "";
|
|
1666
|
+
const optionsIndex = specifiers.indexOf(" --");
|
|
1667
|
+
const clausesSource =
|
|
1668
|
+
optionsIndex === -1 ? specifiers : specifiers.substring(0, optionsIndex);
|
|
1669
|
+
let trimmed = clausesSource.trim();
|
|
1670
|
+
if (trimmed.startsWith("(") && trimmed.endsWith(")")) {
|
|
1671
|
+
trimmed = trimmed.substring(1, trimmed.length - 1);
|
|
1672
|
+
}
|
|
1673
|
+
const exactClauses = trimmed
|
|
1674
|
+
.split(",")
|
|
1675
|
+
.map((clause) => clause.trim().match(PEP440_EXACT_CLAUSE))
|
|
1676
|
+
.filter(Boolean);
|
|
1677
|
+
return exactClauses.length === 1 ? exactClauses[0][2] : null;
|
|
1678
|
+
}
|
|
1640
1679
|
|
|
1641
1680
|
/**
|
|
1642
1681
|
* Method to parse requirements.txt file. This must be replaced with atom parsedeps.
|
|
@@ -1825,7 +1864,7 @@ async function parseReqData(
|
|
|
1825
1864
|
|
|
1826
1865
|
// Handle extras (e.g., package[extra1,extra2])
|
|
1827
1866
|
let extras = null;
|
|
1828
|
-
const extrasMatch = l.match(/^([a-zA-Z0-9_\-.]+)(\[([^\]]+)])?(.*)$/);
|
|
1867
|
+
const extrasMatch = l.match(/^([a-zA-Z0-9_\-.]+)(\s*\[([^\]]+)])?(.*)$/);
|
|
1829
1868
|
if (extrasMatch) {
|
|
1830
1869
|
const [, packageName, , extrasStr, versionSpecifiers] = extrasMatch;
|
|
1831
1870
|
const name = packageName;
|
|
@@ -1836,14 +1875,7 @@ async function parseReqData(
|
|
|
1836
1875
|
if (PYTHON_STD_MODULES.includes(name)) {
|
|
1837
1876
|
continue;
|
|
1838
1877
|
}
|
|
1839
|
-
const
|
|
1840
|
-
let version = null;
|
|
1841
|
-
if (versionMatch) {
|
|
1842
|
-
version = versionMatch[2].replaceAll("*", "0") || null;
|
|
1843
|
-
if (version === "0") {
|
|
1844
|
-
version = null;
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1878
|
+
const version = pinnedRequirementVersion(versionSpecifiers);
|
|
1847
1879
|
const apkg = {
|
|
1848
1880
|
name,
|
|
1849
1881
|
version,
|
|
@@ -1863,7 +1895,10 @@ async function parseReqData(
|
|
|
1863
1895
|
value: extras.join(","),
|
|
1864
1896
|
});
|
|
1865
1897
|
}
|
|
1866
|
-
if (
|
|
1898
|
+
if (
|
|
1899
|
+
versionSpecifiers?.trim() &&
|
|
1900
|
+
(!version || !versionSpecifiers.trim().startsWith("=="))
|
|
1901
|
+
) {
|
|
1867
1902
|
properties.push({
|
|
1868
1903
|
name: "cdx:pypi:versionSpecifiers",
|
|
1869
1904
|
value: versionSpecifiers.trim(),
|
|
@@ -1900,12 +1935,7 @@ async function parseReqData(
|
|
|
1900
1935
|
if (PYTHON_STD_MODULES.includes(name)) {
|
|
1901
1936
|
continue;
|
|
1902
1937
|
}
|
|
1903
|
-
const
|
|
1904
|
-
let version = null;
|
|
1905
|
-
if (versionMatch) {
|
|
1906
|
-
version = versionMatch[2].replaceAll("*", "0") || null;
|
|
1907
|
-
if (version === "0") version = null;
|
|
1908
|
-
}
|
|
1938
|
+
const version = pinnedRequirementVersion(versionSpecifiers);
|
|
1909
1939
|
const apkg = {
|
|
1910
1940
|
name,
|
|
1911
1941
|
version,
|
|
@@ -1916,7 +1946,10 @@ async function parseReqData(
|
|
|
1916
1946
|
if (licenses) {
|
|
1917
1947
|
apkg.licenses = licenses;
|
|
1918
1948
|
}
|
|
1919
|
-
if (
|
|
1949
|
+
if (
|
|
1950
|
+
versionSpecifiers?.trim() &&
|
|
1951
|
+
(!version || !versionSpecifiers.trim().startsWith("=="))
|
|
1952
|
+
) {
|
|
1920
1953
|
properties.push({
|
|
1921
1954
|
name: "cdx:pypi:versionSpecifiers",
|
|
1922
1955
|
value: versionSpecifiers.trim(),
|
|
@@ -2064,6 +2097,33 @@ function createPixiBomRef(packageData) {
|
|
|
2064
2097
|
return `library:${packageData["name"]}:${packageData["version"] || ""}`;
|
|
2065
2098
|
}
|
|
2066
2099
|
|
|
2100
|
+
/**
|
|
2101
|
+
* Return the download url of a pixi.lock package, without credentials, query
|
|
2102
|
+
* or fragment. A private conda channel can carry its access token in a
|
|
2103
|
+
* `/t/<token>/` path segment, so such a url is left out.
|
|
2104
|
+
*
|
|
2105
|
+
* @param {unknown} url Package url from pixi.lock
|
|
2106
|
+
* @returns {string|undefined} Distribution url
|
|
2107
|
+
*/
|
|
2108
|
+
function pixiDistributionUrl(url) {
|
|
2109
|
+
if (typeof url !== "string" || !url.trim()) {
|
|
2110
|
+
return undefined;
|
|
2111
|
+
}
|
|
2112
|
+
const sanitized = sanitizeBomUrl(url);
|
|
2113
|
+
try {
|
|
2114
|
+
const parsed = new URL(sanitized);
|
|
2115
|
+
if (
|
|
2116
|
+
!["http:", "https:"].includes(parsed.protocol) ||
|
|
2117
|
+
parsed.pathname.split("/").includes("t")
|
|
2118
|
+
) {
|
|
2119
|
+
return undefined;
|
|
2120
|
+
}
|
|
2121
|
+
} catch {
|
|
2122
|
+
return undefined;
|
|
2123
|
+
}
|
|
2124
|
+
return sanitized;
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2067
2127
|
/**
|
|
2068
2128
|
* Method to parse pixi.lock data
|
|
2069
2129
|
*
|
|
@@ -2153,10 +2213,13 @@ export function parsePixiLockFile(pixiLockFileName, path) {
|
|
|
2153
2213
|
*
|
|
2154
2214
|
*/
|
|
2155
2215
|
const purlTemplate = createPurlTemplate(packageData);
|
|
2216
|
+
const distributionUrl = pixiDistributionUrl(packageData["url"]);
|
|
2156
2217
|
return {
|
|
2157
2218
|
name: packageData["name"],
|
|
2158
2219
|
version: packageData["version"],
|
|
2159
2220
|
...(purlTemplate ? { purl: purlTemplate } : {}),
|
|
2221
|
+
// The package download url becomes a distribution external reference.
|
|
2222
|
+
...(distributionUrl ? { distribution: { url: distributionUrl } } : {}),
|
|
2160
2223
|
type: "library",
|
|
2161
2224
|
"bom-ref": createPixiBomRef(packageData),
|
|
2162
2225
|
// "licenses": [
|
|
@@ -2164,10 +2227,8 @@ export function parsePixiLockFile(pixiLockFileName, path) {
|
|
|
2164
2227
|
// "id": packageData["license"]
|
|
2165
2228
|
// }]
|
|
2166
2229
|
// ],
|
|
2167
|
-
supplier
|
|
2168
|
-
|
|
2169
|
-
url: packageData["url"],
|
|
2170
|
-
},
|
|
2230
|
+
// The conda build string is not a supplier, so it stays in
|
|
2231
|
+
// cdx:pixi:build below.
|
|
2171
2232
|
// "hashes": [
|
|
2172
2233
|
// {"md5": packageData["md5"]},
|
|
2173
2234
|
// {"sha256": packageData["sha256"]}
|
|
@@ -506,27 +506,55 @@ function resolveCargoWorkspaceDependencyTarget(
|
|
|
506
506
|
) {
|
|
507
507
|
return workspaceMemberMap.get(resolvedDependencyName);
|
|
508
508
|
}
|
|
509
|
-
|
|
510
|
-
dependencyNode
|
|
511
|
-
typeof dependencyNode
|
|
512
|
-
typeof dependencyNode.path
|
|
513
|
-
dependencyNode.path
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
509
|
+
if (
|
|
510
|
+
!dependencyNode ||
|
|
511
|
+
typeof dependencyNode !== "object" ||
|
|
512
|
+
typeof dependencyNode.path !== "string" ||
|
|
513
|
+
!dependencyNode.path
|
|
514
|
+
) {
|
|
515
|
+
return undefined;
|
|
516
|
+
}
|
|
517
|
+
// A member cannot combine `workspace = true` with its own `path`, so a path
|
|
518
|
+
// on such an entry came from [workspace.dependencies], and Cargo reads it
|
|
519
|
+
// relative to the workspace root rather than to the member.
|
|
520
|
+
const pathBaseFile =
|
|
521
|
+
dependencyNode.workspace === true && workspaceContext?.workspaceRootFile
|
|
522
|
+
? workspaceContext.workspaceRootFile
|
|
523
|
+
: cargoTomlFile;
|
|
524
|
+
const dependencyPath = resolve(
|
|
525
|
+
dirname(pathBaseFile),
|
|
526
|
+
dependencyNode.path,
|
|
527
|
+
"Cargo.toml",
|
|
528
|
+
);
|
|
529
|
+
if (!safeExistsSync(dependencyPath)) {
|
|
517
530
|
return undefined;
|
|
518
531
|
}
|
|
519
532
|
const dependencyCargoData = readCargoTomlData(dependencyPath);
|
|
520
|
-
|
|
533
|
+
// A path dependency names a package; a virtual workspace root has none.
|
|
534
|
+
if (!dependencyCargoData?.package) {
|
|
521
535
|
return undefined;
|
|
522
536
|
}
|
|
537
|
+
// A path crate outside the current workspace inherits `*.workspace = true`
|
|
538
|
+
// fields from its own workspace, which resolveCargoWorkspaceContext finds by
|
|
539
|
+
// walking up from the crate. Handing it the current workspace would give
|
|
540
|
+
// the crate this workspace's version.
|
|
541
|
+
const workspaceRootDir = workspaceContext?.workspaceRootFile
|
|
542
|
+
? resolve(dirname(workspaceContext.workspaceRootFile))
|
|
543
|
+
: undefined;
|
|
544
|
+
const dependencyDir = dirname(dependencyPath);
|
|
545
|
+
const isInsideWorkspace =
|
|
546
|
+
workspaceRootDir &&
|
|
547
|
+
(dependencyDir === workspaceRootDir ||
|
|
548
|
+
dependencyDir.startsWith(`${workspaceRootDir}${_sep}`));
|
|
523
549
|
const dependencyIdentity = resolveCargoManifestPackageIdentity(
|
|
524
550
|
dependencyPath,
|
|
525
551
|
dependencyCargoData,
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
552
|
+
isInsideWorkspace
|
|
553
|
+
? {
|
|
554
|
+
workspaceRootData: workspaceContext.workspaceRootData,
|
|
555
|
+
workspaceRootFile: workspaceContext.workspaceRootFile,
|
|
556
|
+
}
|
|
557
|
+
: {},
|
|
530
558
|
);
|
|
531
559
|
if (!dependencyIdentity?.name || !dependencyIdentity?.version) {
|
|
532
560
|
return undefined;
|
|
@@ -656,6 +684,68 @@ function applyCargoDependencySpecMetadata(
|
|
|
656
684
|
);
|
|
657
685
|
}
|
|
658
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Version to record for a Cargo.toml dependency whose requirement is the only
|
|
689
|
+
* thing known about it.
|
|
690
|
+
*
|
|
691
|
+
* A Cargo requirement is not a version: `serde = "1.0"` means `^1.0`, and even
|
|
692
|
+
* `"1.0.94"` means `^1.0.94`. The component version is therefore left out
|
|
693
|
+
* unless the whole requirement is an exact `=X.Y.Z` pin (with an optional
|
|
694
|
+
* prerelease and build label), which is the one requirement Cargo resolves to
|
|
695
|
+
* a single version. `=1.0` is not exact, because Cargo reads it as
|
|
696
|
+
* `>=1.0.0,<1.1.0`.
|
|
697
|
+
*
|
|
698
|
+
* When the requirement is not the node's `version` key, it is a `git+`, `path+`
|
|
699
|
+
* or `workspace` fallback from normalizeCargoDependencyVersion, and it is kept
|
|
700
|
+
* as it stands so the dependency stays traceable to its source.
|
|
701
|
+
*
|
|
702
|
+
* @param {Object|String} dependencyNode Dependency entry from the manifest
|
|
703
|
+
* @param {String} requirement Requirement string from normalizeCargoDependencyVersion
|
|
704
|
+
* @returns {String|undefined} The pinned version, or undefined
|
|
705
|
+
*/
|
|
706
|
+
function cargoManifestComponentVersion(dependencyNode, requirement) {
|
|
707
|
+
if (
|
|
708
|
+
typeof dependencyNode === "object" &&
|
|
709
|
+
dependencyNode?.version !== requirement
|
|
710
|
+
) {
|
|
711
|
+
return requirement;
|
|
712
|
+
}
|
|
713
|
+
const pin = requirement
|
|
714
|
+
.trim()
|
|
715
|
+
.match(/^=\s*(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)$/);
|
|
716
|
+
return pin ? pin[1] : undefined;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Version to record for a Cargo.toml dependency component once the dependency
|
|
721
|
+
* has been resolved to a crate on disk.
|
|
722
|
+
*
|
|
723
|
+
* A path dependency or a workspace dependency always builds against the
|
|
724
|
+
* version in the target crate's own `[package]` section; the requirement next
|
|
725
|
+
* to it (`local = { path = "local", version = "0.2" }`) matters only when the
|
|
726
|
+
* crate is published to a registry. Recording the resolved version keeps one
|
|
727
|
+
* component per crate: the manifest entry and the target's own manifest, which
|
|
728
|
+
* a recursive scan parses as well, then describe the same cargo purl and
|
|
729
|
+
* merge, instead of listing the crate once version-less and once resolved
|
|
730
|
+
* (issue #4719). The `cdx:cargo:path` property keeps the dependency
|
|
731
|
+
* traceable to its source.
|
|
732
|
+
*
|
|
733
|
+
* @param {Object|String} dependencyNode Dependency entry from the manifest
|
|
734
|
+
* @param {String} requirement Requirement string from normalizeCargoDependencyVersion
|
|
735
|
+
* @param {Object|undefined} resolvedTarget Identity of the resolved local crate
|
|
736
|
+
* @returns {String|undefined} The resolved version, or cargoManifestComponentVersion's answer
|
|
737
|
+
*/
|
|
738
|
+
function cargoManifestDependencyComponentVersion(
|
|
739
|
+
dependencyNode,
|
|
740
|
+
requirement,
|
|
741
|
+
resolvedTarget,
|
|
742
|
+
) {
|
|
743
|
+
if (resolvedTarget?.version) {
|
|
744
|
+
return resolvedTarget.version;
|
|
745
|
+
}
|
|
746
|
+
return cargoManifestComponentVersion(dependencyNode, requirement);
|
|
747
|
+
}
|
|
748
|
+
|
|
659
749
|
function collectCargoManifestDependencyComponents(
|
|
660
750
|
dependencyEntries,
|
|
661
751
|
addPackageToList,
|
|
@@ -689,9 +779,21 @@ function collectCargoManifestDependencyComponents(
|
|
|
689
779
|
continue;
|
|
690
780
|
}
|
|
691
781
|
const pkg = {
|
|
692
|
-
|
|
693
|
-
|
|
782
|
+
// A renamed local dependency (`alias = { path = "…", package = "real" }`)
|
|
783
|
+
// is the crate `real`; the alias only names it inside this manifest and
|
|
784
|
+
// stays on cdx:cargo:package. Keeping the alias with the resolved version
|
|
785
|
+
// would describe a crate that does not exist, or a different one on
|
|
786
|
+
// crates.io.
|
|
787
|
+
name: resolvedWorkspaceTarget?.name || dependencyName,
|
|
788
|
+
version: cargoManifestDependencyComponentVersion(
|
|
789
|
+
dependencyNode,
|
|
790
|
+
version,
|
|
791
|
+
resolvedWorkspaceTarget,
|
|
792
|
+
),
|
|
694
793
|
};
|
|
794
|
+
if (resolvedWorkspaceTarget?.group) {
|
|
795
|
+
pkg.group = resolvedWorkspaceTarget.group;
|
|
796
|
+
}
|
|
695
797
|
applyCargoDependencySpecMetadata(
|
|
696
798
|
pkg,
|
|
697
799
|
dependencyNode,
|
|
@@ -10,6 +10,10 @@ import {
|
|
|
10
10
|
detectAiModelVariants,
|
|
11
11
|
normalizeDetectedVariants,
|
|
12
12
|
} from "../../inventory/aiModelVariants.js";
|
|
13
|
+
import {
|
|
14
|
+
modelCreatorEntity,
|
|
15
|
+
modelCreatorFromOrganization,
|
|
16
|
+
} from "../../inventory/aiProviders.js";
|
|
13
17
|
import { getLicenses } from "../../inventory/spdx.js";
|
|
14
18
|
import {
|
|
15
19
|
createHuggingFaceComponentReference,
|
|
@@ -26,6 +30,7 @@ import {
|
|
|
26
30
|
toHuggingFaceAssetPath,
|
|
27
31
|
toHuggingFaceAssetUrl,
|
|
28
32
|
toHuggingFacePurl,
|
|
33
|
+
toHuggingFaceSupplier,
|
|
29
34
|
} from "../../parsers/huggingfaceUtils.js";
|
|
30
35
|
|
|
31
36
|
const CACHE_MISS = Symbol("huggingface-cache-miss");
|
|
@@ -1191,6 +1196,23 @@ export async function fetchHuggingFaceAssetInventory(
|
|
|
1191
1196
|
payload?.sha ||
|
|
1192
1197
|
(revision !== "HEAD" ? revision : payload?.lastModified),
|
|
1193
1198
|
purl,
|
|
1199
|
+
// The repository namespace published the asset, so it is the
|
|
1200
|
+
// supplier. Its url is the organisation or user page, not the
|
|
1201
|
+
// repository. A model is credited to a creator as manufacturer only
|
|
1202
|
+
// when the namespace is that creator's own organisation, since
|
|
1203
|
+
// re-packagers publish models other organisations made.
|
|
1204
|
+
supplier:
|
|
1205
|
+
slashIndex > 0
|
|
1206
|
+
? toHuggingFaceSupplier(normalizedRepoId.slice(0, slashIndex))
|
|
1207
|
+
: undefined,
|
|
1208
|
+
manufacturer:
|
|
1209
|
+
normalizedAssetType === "model" && slashIndex > 0
|
|
1210
|
+
? modelCreatorEntity(
|
|
1211
|
+
modelCreatorFromOrganization(
|
|
1212
|
+
normalizedRepoId.slice(0, slashIndex),
|
|
1213
|
+
),
|
|
1214
|
+
)
|
|
1215
|
+
: undefined,
|
|
1194
1216
|
description:
|
|
1195
1217
|
normalizedAssetType === "dataset"
|
|
1196
1218
|
? datasetDescriptionFromStats(payload)
|
package/lib/ecosystems/rusi.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../core/pluginRun.js";
|
|
17
17
|
import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
18
18
|
import { applyAlgorithmProperties } from "../inventory/cryptoAlgorithmFamily.js";
|
|
19
|
+
import { occurrenceLocationKey } from "../inventory/occurrenceKey.js";
|
|
19
20
|
import { resolvePluginBinary } from "../inventory/plugins.js";
|
|
20
21
|
|
|
21
22
|
const RUST_LANGUAGES = new Set(["rust", "rs", "rust-lang"]);
|
|
@@ -67,10 +68,7 @@ function positionLocation(position) {
|
|
|
67
68
|
if (!position?.filename) {
|
|
68
69
|
return undefined;
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
return `${position.filename}#${position.line}`;
|
|
72
|
-
}
|
|
73
|
-
return position.filename;
|
|
71
|
+
return occurrenceLocationKey(position.filename, position.line);
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
function purlWithoutVersion(purl) {
|
|
@@ -30,6 +30,7 @@ import { isProjectToolingAllowed } from "../core/projectTooling.js";
|
|
|
30
30
|
import { parsetoolsFile } from "../inventory/atomUtils.js";
|
|
31
31
|
import { applyAlgorithmProperties } from "../inventory/cryptoAlgorithmFamily.js";
|
|
32
32
|
import { getJarClasses } from "../inventory/deps.js";
|
|
33
|
+
import { occurrenceLocationKey } from "../inventory/occurrenceKey.js";
|
|
33
34
|
import {
|
|
34
35
|
parseScalaArtifact,
|
|
35
36
|
scalaCoordinateKey,
|
|
@@ -1984,7 +1985,7 @@ function addUsageEvidence(
|
|
|
1984
1985
|
let added = false;
|
|
1985
1986
|
for (const [file, lines] of files) {
|
|
1986
1987
|
if (depth < lines.length && locations.size < cap) {
|
|
1987
|
-
locations.add(
|
|
1988
|
+
locations.add(occurrenceLocationKey(file, lines[depth]));
|
|
1988
1989
|
added = true;
|
|
1989
1990
|
}
|
|
1990
1991
|
}
|