diff --git a/pgpm/core/src/core/class/pgpm.ts b/pgpm/core/src/core/class/pgpm.ts index 74937c70a..9b6565ceb 100644 --- a/pgpm/core/src/core/class/pgpm.ts +++ b/pgpm/core/src/core/class/pgpm.ts @@ -284,16 +284,29 @@ export class PgpmPackage { if (!this.workspacePath || !this.config) return []; const dirs = this.loadAllowedDirs(); - const results: PgpmPackage[] = []; + const seen = new Map(); for (const dir of dirs) { const proj = new PgpmPackage(dir); if (proj.isInModule()) { - results.push(proj); + const name = proj.getModuleName(); + if (!seen.has(name)) { + seen.set(name, []); + } + seen.get(name)!.push(proj); + } + } + + // Error on duplicate module names, similar to pnpm/yarn workspace duplicate package errors + const duplicates = Array.from(seen.entries()).filter(([, projs]) => projs.length > 1); + if (duplicates.length > 0) { + for (const [name, projs] of duplicates) { + const paths = projs.map(p => ` - ${p.cwd}`).join('\n'); + throw errors.DUPLICATE_MODULE({ name, paths }); } } - return results; + return Array.from(seen.values()).map(projs => projs[0]); } /** @@ -318,17 +331,14 @@ export class PgpmPackage { filesByName.get(moduleName)!.push(file); }); - // For each module name, pick the shortest path in case of collisions + // Error on duplicate module names, similar to pnpm/yarn workspace duplicate package errors const selectedFiles = new Map(); filesByName.forEach((files, moduleName) => { if (files.length === 1) { selectedFiles.set(moduleName, files[0]); } else { - // Multiple files with same name - pick shortest path - const shortestFile = files.reduce((shortest, current) => - current.length < shortest.length ? current : shortest - ); - selectedFiles.set(moduleName, shortestFile); + const paths = files.map(f => ` - ${path.dirname(f)}`).join('\n'); + throw errors.DUPLICATE_MODULE({ name: moduleName, paths }); } }); diff --git a/pgpm/types/src/error-factory.ts b/pgpm/types/src/error-factory.ts index 117505c52..a2e22cec4 100644 --- a/pgpm/types/src/error-factory.ts +++ b/pgpm/types/src/error-factory.ts @@ -145,6 +145,13 @@ export const errors = { `${type ? `${type} file` : 'File'} not found: ${filePath}`, 404 ), + + DUPLICATE_MODULE: makeError( + 'DUPLICATE_MODULE', + ({ name, paths }: { name: string, paths: string }) => + `Multiple modules share the name "${name}". Each module in a workspace must have a unique name.\n Found in:\n${paths}`, + 400 + ), }; // throw errors.MODULE_NOT_FOUND({ name: 'auth' });