From ef6a0e448a083d70b60995302a729537d4296e3c Mon Sep 17 00:00:00 2001 From: Colum Ferry Date: Fri, 29 Nov 2024 16:51:43 +0000 Subject: [PATCH] fix(core): use fork to execute nx generate workspace:preset --- .../src/generators/new/generate-preset.ts | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/workspace/src/generators/new/generate-preset.ts b/packages/workspace/src/generators/new/generate-preset.ts index 6824da637cc09..cb18fc145f96e 100644 --- a/packages/workspace/src/generators/new/generate-preset.ts +++ b/packages/workspace/src/generators/new/generate-preset.ts @@ -13,7 +13,7 @@ import { getNpmPackageVersion } from '../utils/get-npm-package-version'; import { NormalizedSchema } from './new'; import { join } from 'path'; import * as yargsParser from 'yargs-parser'; -import { spawn, SpawnOptions } from 'child_process'; +import { fork, ForkOptions } from 'child_process'; export function addPresetDependencies(host: Tree, options: NormalizedSchema) { const { dependencies, dev } = getPresetDependencies(options); @@ -32,25 +32,33 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) { interactive: true, }, }); - const spawnOptions: SpawnOptions = { + + const newWorkspaceRoot = join(host.root, opts.directory); + const spawnOptions: ForkOptions = { stdio: 'inherit', - shell: true, - cwd: join(host.root, opts.directory), - windowsHide: false, + cwd: newWorkspaceRoot, }; const pmc = getPackageManagerCommand(); - const executable = `${pmc.exec} nx`; + const nxBinForNewWorkspaceRoot = require.resolve('nx/bin/nx', { + paths: [join(newWorkspaceRoot, 'node_modules')], + }); const args = getPresetArgs(opts); return new Promise((resolve, reject) => { - spawn(executable, args, spawnOptions).on('close', (code: number) => { - if (code === 0) { - resolve(); - } else { - const message = 'Workspace creation failed, see above.'; - reject(new Error(message)); + // This needs to be `fork` instead of `spawn` because `spawn` is failing on Windows with pnpm + yarn + // The root cause is unclear. Spawn causes the `@nx/workspace:preset` generator to be called twice + // and the second time it fails with `Project {projectName} already exists.` + fork(nxBinForNewWorkspaceRoot, args, spawnOptions).on( + 'close', + (code: number) => { + if (code === 0) { + resolve(); + } else { + const message = 'Workspace creation failed, see above.'; + reject(new Error(message)); + } } - }); + ); }); function getPresetArgs(options: NormalizedSchema) {