Skip to content

Commit 2fb79b7

Browse files
committed
feat: throw error on duplicate module names in workspace
Similar to how pnpm/yarn workspaces error when multiple packages share the same name, pgpm now throws a DUPLICATE_MODULE error when getModules() or listModules() encounters multiple modules with the same .control file name. Previously getModules() returned all matches (causing duplicate entries in pgpm deploy's interactive prompt) and listModules() silently picked the shortest path. Both now throw a descriptive error listing the conflicting paths.
1 parent 50a5043 commit 2fb79b7

2 files changed

Lines changed: 26 additions & 9 deletions

File tree

pgpm/core/src/core/class/pgpm.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,16 +284,29 @@ export class PgpmPackage {
284284
if (!this.workspacePath || !this.config) return [];
285285

286286
const dirs = this.loadAllowedDirs();
287-
const results: PgpmPackage[] = [];
287+
const seen = new Map<string, PgpmPackage[]>();
288288

289289
for (const dir of dirs) {
290290
const proj = new PgpmPackage(dir);
291291
if (proj.isInModule()) {
292-
results.push(proj);
292+
const name = proj.getModuleName();
293+
if (!seen.has(name)) {
294+
seen.set(name, []);
295+
}
296+
seen.get(name)!.push(proj);
297+
}
298+
}
299+
300+
// Error on duplicate module names, similar to pnpm/yarn workspace duplicate package errors
301+
const duplicates = Array.from(seen.entries()).filter(([, projs]) => projs.length > 1);
302+
if (duplicates.length > 0) {
303+
for (const [name, projs] of duplicates) {
304+
const paths = projs.map(p => ` - ${p.cwd}`).join('\n');
305+
throw errors.DUPLICATE_MODULE({ name, paths });
293306
}
294307
}
295308

296-
return results;
309+
return Array.from(seen.values()).map(projs => projs[0]);
297310
}
298311

299312
/**
@@ -318,17 +331,14 @@ export class PgpmPackage {
318331
filesByName.get(moduleName)!.push(file);
319332
});
320333

321-
// For each module name, pick the shortest path in case of collisions
334+
// Error on duplicate module names, similar to pnpm/yarn workspace duplicate package errors
322335
const selectedFiles = new Map<string, string>();
323336
filesByName.forEach((files, moduleName) => {
324337
if (files.length === 1) {
325338
selectedFiles.set(moduleName, files[0]);
326339
} else {
327-
// Multiple files with same name - pick shortest path
328-
const shortestFile = files.reduce((shortest, current) =>
329-
current.length < shortest.length ? current : shortest
330-
);
331-
selectedFiles.set(moduleName, shortestFile);
340+
const paths = files.map(f => ` - ${path.dirname(f)}`).join('\n');
341+
throw errors.DUPLICATE_MODULE({ name: moduleName, paths });
332342
}
333343
});
334344

pgpm/types/src/error-factory.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ export const errors = {
145145
`${type ? `${type} file` : 'File'} not found: ${filePath}`,
146146
404
147147
),
148+
149+
DUPLICATE_MODULE: makeError(
150+
'DUPLICATE_MODULE',
151+
({ name, paths }: { name: string, paths: string }) =>
152+
`Multiple modules share the name "${name}". Each module in a workspace must have a unique name.\n Found in:\n${paths}`,
153+
400
154+
),
148155
};
149156

150157
// throw errors.MODULE_NOT_FOUND({ name: 'auth' });

0 commit comments

Comments
 (0)