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

Feat: Include components from pnpm-lock.yaml importers #1377

Merged
merged 11 commits into from
Sep 22, 2024
228 changes: 153 additions & 75 deletions lib/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,18 @@ function _markTreeOptional(
}
}

function getVersionNumPnpm(depPkg) {
let version = depPkg;
if (typeof version === "object" && depPkg.version) {
version = depPkg.version;
}
// version: 3.0.1(ajv@8.14.0)
if (version?.includes("(")) {
version = version.split("(")[0];
}
return version;
}

/**
* Parse nodejs pnpm lock file
*
Expand Down Expand Up @@ -1770,86 +1782,152 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
}
// This logic matches the pnpm list command to include only direct dependencies
if (ppurl !== "") {
// In lock file version 9, direct dependencies is under importers
const rootDirectDeps =
lockfileVersion >= 9
? yamlObj.importers["."]?.dependencies || {}
: yamlObj.dependencies || {};
const rootDevDeps =
lockfileVersion >= 9
? yamlObj.importers["."]?.devDependencies || {}
: {};
const rootOptionalDeps =
lockfileVersion >= 9
? yamlObj.importers["."]?.optionalDependencies || {}
: {};
const ddeplist = [];
// Find the root optional dependencies
for (const rdk of Object.keys(rootDevDeps)) {
let version = rootDevDeps[rdk];
if (typeof version === "object" && version.version) {
version = version.version;
}
// version: 3.0.1(ajv@8.14.0)
if (version?.includes("(")) {
version = version.split("(")[0];
}
const dpurl = new PackageURL(
"npm",
"",
rdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}
for (const rdk of Object.keys(rootOptionalDeps)) {
let version = rootOptionalDeps[rdk];
if (typeof version === "object" && version.version) {
version = version.version;
}
// version: 3.0.1(ajv@8.14.0)
if (version?.includes("(")) {
version = version.split("(")[0];
if (yamlObj["importers"]) {
aryan-rajoria marked this conversation as resolved.
Show resolved Hide resolved
// In lock file version 9, direct dependencies is under importers
const rootDirectDeps =
lockfileVersion >= 9
aryan-rajoria marked this conversation as resolved.
Show resolved Hide resolved
? yamlObj.importers["."]?.dependencies || {}
: yamlObj.dependencies || {};
const rootDevDeps =
lockfileVersion >= 9
? yamlObj.importers["."]?.devDependencies || {}
: {};
const rootOptionalDeps =
lockfileVersion >= 9
? yamlObj.importers["."]?.optionalDependencies || {}
: {};
const ddeplist = [];
// Find the root optional dependencies
for (const rdk of Object.keys(rootDevDeps)) {
const version = getVersionNumPnpm(rootDevDeps[rdk]);
const dpurl = new PackageURL(
"npm",
"",
rdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}
const dpurl = new PackageURL(
"npm",
"",
rdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}
for (const dk of Object.keys(rootDirectDeps)) {
let version = rootDirectDeps[dk];
if (typeof version === "object" && version.version) {
version = version.version;
for (const rdk of Object.keys(rootOptionalDeps)) {
const version = getVersionNumPnpm(rootOptionalDeps[rdk]);
const dpurl = new PackageURL(
"npm",
"",
rdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}
// version: 3.0.1(ajv@8.14.0)
if (version?.includes("(")) {
version = version.split("(")[0];
for (const dk of Object.keys(rootDirectDeps)) {
const version = getVersionNumPnpm(rootDirectDeps[dk]);
const dpurl = new PackageURL(
"npm",
"",
dk,
version,
null,
null,
).toString();
ddeplist.push(decodeURIComponent(dpurl));
if (lockfileVersion >= 9) {
// These are direct dependencies so cannot be optional
possibleOptionalDeps[decodeURIComponent(dpurl)] = false;
}
}
const dpurl = new PackageURL(
"npm",
"",
dk,
version,
null,
null,
).toString();
ddeplist.push(decodeURIComponent(dpurl));
if (lockfileVersion >= 9) {
// These are direct dependencies so cannot be optional
possibleOptionalDeps[decodeURIComponent(dpurl)] = false;

dependenciesList.push({
ref: decodeURIComponent(ppurl),
dependsOn: ddeplist,
});

// pnpm-lock.yaml contains more than root dependencies in importers
// we do what we did above but for all the other components
for (const importedComponentName of Object.keys(yamlObj["importers"])) {
const componentDeps =
yamlObj["importers"][importedComponentName]["dependencies"] || {};
const componentDevDeps =
yamlObj["importers"][importedComponentName]["devDependencies"] ||
{};
const componentOptionalDeps =
yamlObj["importers"][importedComponentName][
"optionalDependencies"
] || {};

const name = importedComponentName.split("/");
const lastname = name[name.length - 1];

// let subpath = name.filter(part => part !== '.' && part !== '..').join('/');
const subpath = name
.join("/")
.replaceAll("../", "")
.replaceAll("./", "");

// if component name is '.' continue loop
if (lastname === ".") {
continue;
}

const compPurl = new PackageURL(
"npm",
parentComponent.group,
`${parentComponent.name}/${lastname}`,
parentComponent.version,
null,
subpath,
).toString();
// Find the component optional dependencies
const comDepList = [];
for (const cdk of Object.keys(componentDeps)) {
const version = getVersionNumPnpm(componentDeps[cdk]);
const dpurl = new PackageURL(
"npm",
"",
cdk,
version,
null,
null,
).toString();
comDepList.push(decodeURIComponent(dpurl));

possibleOptionalDeps[decodeURIComponent(dpurl)] = false;
}

dependenciesList.push({
ref: decodeURIComponent(compPurl),
dependsOn: comDepList,
});

for (const cdk of Object.keys(componentDevDeps)) {
const version = getVersionNumPnpm(componentDevDeps[cdk]);
const dpurl = new PackageURL(
"npm",
"",
cdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}

for (const cdk of Object.keys(componentOptionalDeps)) {
const version = getVersionNumPnpm(componentOptionalDeps[cdk]);
const dpurl = new PackageURL(
"npm",
"",
cdk,
version,
null,
null,
).toString();
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
}
}
}
dependenciesList.push({
ref: decodeURIComponent(ppurl),
dependsOn: ddeplist,
});
}
const packages = yamlObj.packages || {};
// snapshots is a new key under lockfile version 9
Expand Down
Loading