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

fix: plugin no longer crashes in rollup only scenarios #68

Merged
merged 3 commits into from
May 3, 2024
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@commitlint/cli": "19.2.2",
"@commitlint/config-conventional": "19.2.2",
"@types/node": "20.12.7",
"@types/normalize-package-data": "^2.4.4",
"@typescript-eslint/eslint-plugin": "7.7.0",
"@typescript-eslint/parser": "7.7.0",
"@vitest/coverage-v8": "1.5.0",
Expand Down
5 changes: 4 additions & 1 deletion pnpm-lock.yaml

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

35 changes: 16 additions & 19 deletions src/builder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { dirname } from "node:path";
import { createRequire } from "node:module";

import { type Builders, type Models, type Factories } from "@cyclonedx/cyclonedx-library";
import { getPackageJson } from "./helpers";
import { getCorrespondingPackageFromModuleId } from "./helpers";

const require = createRequire(import.meta.url);

const knownTools = ["rollup-plugin-sbom", "vite", "rollup"];

export function registerPackageUrlOnComponent(
component: Models.Component | undefined,
factory: Factories.FromNodePackageJson.PackageUrlFactory,
Expand All @@ -17,24 +18,20 @@ export function registerPackageUrlOnComponent(
}

export async function registerTools(bom: Models.Bom, builder: Builders.FromNodePackageJson.ToolBuilder) {
// register rollup-plugin-sbom (for vite and rollup)
const pkg = await getPackageJson(dirname(require.resolve("rollup-plugin-sbom")));
if (pkg) {
const tool = builder.makeTool(pkg);
tool && bom.metadata.tools.add(tool);
}

// register vite if available
const vitePkg = await getPackageJson(dirname(require.resolve("vite")));
if (vitePkg) {
const tool = builder.makeTool(vitePkg);
tool && bom.metadata.tools.add(tool);
async function registerTool(packageName: string) {
try {
const modulePath = require.resolve(packageName);
const pkgJson = await getCorrespondingPackageFromModuleId(modulePath);
if (pkgJson) {
const tool = builder.makeTool(pkgJson);
tool && bom.metadata.tools.add(tool);
}
} catch {
// do nothing
}
}

// register rollup if available
const rollupPkg = await getPackageJson(dirname(require.resolve("rollup")));
if (rollupPkg) {
const tool = builder.makeTool(rollupPkg);
tool && bom.metadata.tools.add(tool);
for (const pkgName of knownTools) {
await registerTool(pkgName);
}
}
25 changes: 17 additions & 8 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,31 @@ export async function getPackageJson(dir: string): Promise<Package> {
* getPackageRootFromModuleId(moduleId); // "/User/home/.pnpm/[email protected][email protected]/node_modules/react-dom"
* ```
*/
export function getCorrespondingPackageFromModuleId(moduleId: string, traversalLimit = 10) {
if (!moduleId.includes("node_modules")) {
return Promise.resolve(null);
}

export async function getCorrespondingPackageFromModuleId(
modulePath: string,
traversalLimit = 10,
): Promise<Package | null> {
if (traversalLimit === 0) {
return Promise.resolve(null);
}

const folder = dirname(moduleId);
// dirname() will do the equivalent of traversing up the
// directory tree one level when called on a path without
// a file.
const folder = dirname(modulePath);
const potentialPackagePath = join(folder, "./package.json");

let pkgJson: Package | null = null;

if (existsSync(potentialPackagePath)) {
return getPackageJson(folder);
pkgJson = await getPackageJson(folder);
}

if (pkgJson !== null) {
return pkgJson;
}

return getCorrespondingPackageFromModuleId(join(folder, ".."), traversalLimit - 1);
return await getCorrespondingPackageFromModuleId(folder, traversalLimit - 1);
janbiasi marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
14 changes: 12 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,19 @@ export default function rollupPluginSbom(userOptions?: RollupPluginSbomOptions):
* Register only the effectively imported third party modules from `node_modules`
*/
async moduleParsed(moduleInfo) {
const nodeModuleImportedIds = moduleInfo.importedIds.filter((entry) => entry.includes("node_modules"));
// filter out modules that exists in node_modules and
// also are not Rollup virtual modules (starting with \0)
const nodeModuleImportedIds = moduleInfo.importedIds.filter(
(entry) => entry.includes("node_modules") && !entry.startsWith("\0"),
);

const potentialComponents = await Promise.all(
nodeModuleImportedIds.map(getCorrespondingPackageFromModuleId),
nodeModuleImportedIds.map((moduleId) => {
if (!moduleId.includes("node_modules")) {
return Promise.resolve(null);
}
return getCorrespondingPackageFromModuleId(moduleId);
}),
);

// iterate over all imported unique modules and add them to the BOM
Expand Down
Loading