Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track workspaces for transitive dependencies for uv monorepos #1582

Merged
merged 4 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

Loading