Skip to content

Commit

Permalink
Track workspaces for transitive dependencies for uv monorepos (#1582)
Browse files Browse the repository at this point in the history
* Track workspaces for transitive dependencies for uv monorepos

Signed-off-by: Prabhu Subramanian <[email protected]>

---------

Signed-off-by: Prabhu Subramanian <[email protected]>
  • Loading branch information
prabhu authored Jan 20, 2025
1 parent e6b6d67 commit 3371526
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/repotests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,6 @@ jobs:
- name: repotests bionomia
run: |
bin/cdxgen.js -r -t ruby repotests/bionomia -o bomresults/bom-bionomia.json --fail-on-error
CDXGEN_DEBUG_MODE=debug bin/cdxgen.js -r -t ruby3.3.6 repotests/bionomia -o bomresults/bom-bionomia-deep.json --deep --fail-on-error
CDXGEN_DEBUG_MODE=debug bin/cdxgen.js -r -p -t ruby3.3.6 repotests/bionomia -o bomresults/bom-bionomia-research.json --profile research --fail-on-error
shell: bash
- name: repotests bazel-examples
run: |
Expand Down
67 changes: 61 additions & 6 deletions lib/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2613,7 +2613,19 @@ export async function parsePnpmLock(
if (!depsWorkspaceRefs[dref]) {
depsWorkspaceRefs[dref] = [];
}
depsWorkspaceRefs[dref].push(wref);
if (!depsWorkspaceRefs[dref].includes(wref)) {
depsWorkspaceRefs[dref].push(wref);
}
if (dependenciesMap[dref]) {
for (const l2ref of dependenciesMap[dref]) {
if (!depsWorkspaceRefs[l2ref]) {
depsWorkspaceRefs[l2ref] = [];
}
if (!depsWorkspaceRefs[l2ref].includes(wref)) {
depsWorkspaceRefs[l2ref].push(wref);
}
}
}
}
}
const thePkg = {
Expand Down Expand Up @@ -2693,7 +2705,7 @@ export async function parsePnpmLock(
}
if (depsWorkspaceRefs[apkg["bom-ref"]]?.length) {
const wsprops = apkg.properties.filter(
(p) => p.name === "interal:workspaceRef",
(p) => p.name === "internal:workspaceRef",
);
if (!wsprops.length) {
for (const wref of depsWorkspaceRefs[apkg["bom-ref"]]) {
Expand Down Expand Up @@ -4647,6 +4659,7 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
const dependenciesList = [];
const depsMap = {};
const existingPkgMap = {};
const pkgBomRefMap = {};
let directDepsKeys = {};
let groupDepsKeys = {};
let parentComponent;
Expand Down Expand Up @@ -4901,6 +4914,7 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
}
// This would help the lookup
existingPkgMap[pkg.name.toLowerCase()] = pkg["bom-ref"];
pkgBomRefMap[pkg["bom-ref"]] = pkg;
pkgList.push(pkg);
if (!depsMap[pkg["bom-ref"]]) {
depsMap[pkg["bom-ref"]] = new Set();
Expand All @@ -4922,6 +4936,24 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
const nameStr =
apkgDep.name || apkgDep.split(/(==|<=|~=|>=)/)[0].split(" ")[0];
depsMap[pkg["bom-ref"]].add(existingPkgMap[nameStr] || nameStr);
// Propagate the workspace properties to the child components
if (
existingPkgMap[nameStr] &&
pkgBomRefMap[existingPkgMap[nameStr]]
) {
const dependentPkg = pkgBomRefMap[existingPkgMap[nameStr]];
dependentPkg.properties = dependentPkg.properties || [];
const addedValue = {};
for (const pprop of pkg.properties) {
if (
pprop.name.startsWith("internal:workspace") &&
!addedValue[pprop.value]
) {
dependentPkg.properties.push(pprop);
addedValue[pprop.value] = true;
}
}
}
}
} else if (Object.keys(apkg.dependencies).length) {
for (const apkgDep of Object.keys(apkg.dependencies)) {
Expand All @@ -4933,15 +4965,38 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
pkgList = await getPyMetadata(pkgList, false);
for (const key of Object.keys(depsMap)) {
const dependsOnList = new Set();
const parentPkg = pkgBomRefMap[key];
for (const adep of Array.from(depsMap[key])) {
let depRef;
if (adep.startsWith("pkg:")) {
dependsOnList.add(adep);
depRef = adep;
} else if (existingPkgMap[adep]) {
dependsOnList.add(existingPkgMap[adep]);
depRef = existingPkgMap[adep];
} else if (existingPkgMap[`py${adep}`]) {
dependsOnList.add(existingPkgMap[`py${adep}`]);
depRef = existingPkgMap[`py${adep}`];
} else if (existingPkgMap[adep.replace(/-/g, "_")]) {
dependsOnList.add(existingPkgMap[adep.replace(/-/g, "_")]);
depRef = existingPkgMap[adep.replace(/-/g, "_")];
}
if (depRef) {
dependsOnList.add(depRef);
// We need to propagate the workspace properties from the parent
const dependentPkg = pkgBomRefMap[depRef];
dependentPkg.properties = dependentPkg.properties || [];
const addedValue = {};
for (const p of dependentPkg.properties) {
if (p.name.startsWith("internal:workspace")) {
addedValue[p.value] = true;
}
}
for (const pprop of parentPkg.properties) {
if (
pprop.name.startsWith("internal:workspace") &&
!addedValue[pprop.value]
) {
dependentPkg.properties.push(pprop);
addedValue[pprop.value] = true;
}
}
}
}
dependenciesList.push({
Expand Down
2 changes: 1 addition & 1 deletion types/lib/helpers/utils.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3371526

Please sign in to comment.