From bdf48b1b4b1ad49ced6b955b9ae0c20ef6a25d0c Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Sat, 28 Sep 2024 16:47:27 +0200 Subject: [PATCH] Reuse package manager for subprojects --- openrewrite/src/javascript/projectParser.ts | 26 +++++----- .../src/javascript/projectParserMain.ts | 49 ++++++++++--------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/openrewrite/src/javascript/projectParser.ts b/openrewrite/src/javascript/projectParser.ts index 42d9ec0..0f0bbdb 100644 --- a/openrewrite/src/javascript/projectParser.ts +++ b/openrewrite/src/javascript/projectParser.ts @@ -11,20 +11,22 @@ export enum PackageManager { export class Subproject { rootDir: string; - packageManager: PackageManager; + packageManager: PackageManager | undefined; packageManagerInstalled: boolean; dependenciesInstalled: boolean; tsConfigPath?: string; tsTestConfigPath?: string; - constructor(rootDir: string) { + constructor(rootDir: string, packageManager: PackageManager | undefined = undefined) { this.rootDir = rootDir; - this.packageManager = PackageManager.Npm; // Default to NPM this.packageManagerInstalled = false; this.dependenciesInstalled = false; + this.packageManager = packageManager; } - detectPackageManager(): void { + detectPackageManager(): PackageManager { + if (this.packageManager) return this.packageManager; + const hasYarnLock = fs.existsSync(path.join(this.rootDir, 'yarn.lock')); const hasPnpmLock = fs.existsSync(path.join(this.rootDir, 'pnpm-lock.yaml')); @@ -35,6 +37,7 @@ export class Subproject { } else { this.packageManager = PackageManager.Npm; } + return this.packageManager; } locateTsConfigs(): void { @@ -59,13 +62,13 @@ export class Subproject { return; } - if (!installedPackageManagers.has(this.packageManager)) { + if (!installedPackageManagers.has(this.packageManager!)) { console.log(`Installing package manager: ${this.packageManager} globally...`); - const result = spawnSync('corepack', ['enable', this.packageManager], {stdio: 'inherit'}); + const result = spawnSync('corepack', ['enable', this.packageManager!], {stdio: 'inherit'}); if (result.status !== 0) { throw new Error(`Failed to install ${this.packageManager} globally.`); } - installedPackageManagers.add(this.packageManager); + installedPackageManagers.add(this.packageManager!); } this.packageManagerInstalled = true; @@ -145,11 +148,10 @@ export function findSubprojects(rootDir: string): string[] { if (entries.some((entry) => entry.name === 'package.json')) { subprojects.push(directory); - } else { - for (const entry of entries) { - if (entry.isDirectory() && !entry.name.startsWith('.')) { - searchDirectory(path.join(directory, entry.name)); - } + } + for (const entry of entries) { + if (entry.isDirectory() && !entry.name.startsWith('.')) { + searchDirectory(path.join(directory, entry.name)); } } } diff --git a/openrewrite/src/javascript/projectParserMain.ts b/openrewrite/src/javascript/projectParserMain.ts index 3b5f4f8..9ef1f2b 100644 --- a/openrewrite/src/javascript/projectParserMain.ts +++ b/openrewrite/src/javascript/projectParserMain.ts @@ -25,32 +25,37 @@ function main(): void { const installedPackageManagers = new Set(); const tsParser = new TypeScriptParser(); + let detectedPackageManager: PackageManager | undefined = undefined; for (const subprojectPath of subprojectPaths) { - console.log(`\nProcessing subproject at ${subprojectPath}...`); - const subproject = new Subproject(subprojectPath); - subproject.detectPackageManager(); - subproject.locateTsConfigs(); - subproject.installPackageManager(installedPackageManagers); - subproject.installDependencies(); - - let productionProgram: ts.Program | undefined = undefined; - - const parser = JavaScriptParser.builder().build(); - const sourceFiles: SourceFile[] = []; - if (subproject.tsConfigPath) { - productionProgram = tsParser.parseProject(subproject.tsConfigPath); - sourceFiles.push(...parser.parseProgramSources(productionProgram, rootDir, new InMemoryExecutionContext())); - } + try { + console.log(`\nProcessing subproject at ${subprojectPath}...`); + const subproject: Subproject = new Subproject(subprojectPath, detectedPackageManager); + detectedPackageManager = subproject.detectPackageManager(); + subproject.locateTsConfigs(); + subproject.installPackageManager(installedPackageManagers); + subproject.installDependencies(); - if (subproject.tsTestConfigPath) { - let testProgram = tsParser.parseProject(subproject.tsTestConfigPath, productionProgram); - sourceFiles.push(...parser.parseProgramSources(testProgram, rootDir, new InMemoryExecutionContext())); - } + let productionProgram: ts.Program | undefined = undefined; + + const parser = JavaScriptParser.builder().build(); + const sourceFiles: SourceFile[] = []; + if (subproject.tsConfigPath) { + productionProgram = tsParser.parseProject(subproject.tsConfigPath); + sourceFiles.push(...parser.parseProgramSources(productionProgram, rootDir, new InMemoryExecutionContext())); + } + + if (subproject.tsTestConfigPath) { + let testProgram = tsParser.parseProject(subproject.tsTestConfigPath, productionProgram); + sourceFiles.push(...parser.parseProgramSources(testProgram, rootDir, new InMemoryExecutionContext())); + } - console.log(`\nParsed ${sourceFiles.length} source files:`); - for (let sourceFile of sourceFiles) { - console.log(`\t${sourceFile.sourcePath}`); + console.log(`\nParsed ${sourceFiles.length} source files:`); + for (let sourceFile of sourceFiles) { + console.log(`\t${sourceFile.sourcePath}`); + } + } catch (e) { + console.log('\nSkipping subproject.'); } }