Skip to content

Commit

Permalink
fix(misc): create-nx-workspace errors should display properly (#15988)
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder authored Mar 30, 2023
1 parent d24d850 commit 5d51ed9
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 109 deletions.
50 changes: 25 additions & 25 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
'strip-dashed': true,
'dot-notation': true,
})
.command(
.command<Arguments>(
// this is the default and only command
'$0 [name] [options]',
'Create a new Nx workspace',
Expand Down Expand Up @@ -152,7 +152,7 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
throw error;
});
},
[normalizeArgsMiddleware]
[normalizeArgsMiddleware as yargs.MiddlewareFunction<{}>]
)
.help('help', chalk.dim`Show help`)
.updateLocale(yargsDecorator)
Expand Down Expand Up @@ -195,7 +195,7 @@ async function normalizeArgsMiddleware(
"Let's create a new workspace [https://nx.dev/getting-started/intro]",
});

let thirdPartyPreset: string;
let thirdPartyPreset: string | null;
try {
thirdPartyPreset = await getThirdPartyPreset(argv.preset);
} catch (e) {
Expand Down Expand Up @@ -262,7 +262,7 @@ async function normalizeArgsMiddleware(
}
} else {
name = await determineRepoName(argv);
appName = await determineAppName(preset, argv);
appName = await determineAppName(preset as Preset, argv);
if (preset === Preset.ReactMonorepo) {
bundler = await determineBundler(argv);
}
Expand All @@ -276,7 +276,7 @@ async function normalizeArgsMiddleware(
(argv.interactive ? await determineRouting(argv) : true);
}
}
style = await determineStyle(preset, argv);
style = await determineStyle(preset as Preset, argv);
}

const packageManager = await determinePackageManager(argv);
Expand Down Expand Up @@ -439,7 +439,7 @@ async function determinePackageManager(
],
},
])
.then((a: { packageManager }) => a.packageManager);
.then((a) => a.packageManager);
}

return Promise.resolve(detectInvokedPackageManager());
Expand All @@ -453,15 +453,15 @@ async function determineDefaultBase(
}
if (parsedArgs.allPrompts) {
return enquirer
.prompt([
.prompt<{ DefaultBase: string }>([
{
name: 'DefaultBase',
message: `Main branch name `,
initial: `main`,
type: 'input',
},
])
.then((a: { DefaultBase: string }) => {
.then((a) => {
if (!a.DefaultBase) {
output.error({
title: 'Invalid branch name',
Expand Down Expand Up @@ -524,14 +524,14 @@ async function determineAppName(
}

return enquirer
.prompt([
.prompt<{ AppName: string }>([
{
name: 'AppName',
message: `Application name `,
type: 'input',
},
])
.then((a: { AppName: string }) => {
.then((a) => {
if (!a.AppName) {
output.error({
title: 'Invalid name',
Expand Down Expand Up @@ -571,15 +571,15 @@ async function determineFramework(

if (!parsedArgs.framework) {
return enquirer
.prompt([
.prompt<{ framework: Framework }>([
{
message: 'What framework should be used?',
type: 'autocomplete',
name: 'framework',
choices: frameworkChoices,
},
])
.then((a: { framework: string }) => a.framework);
.then((a) => a.framework);
}

const foundFramework = frameworkChoices
Expand Down Expand Up @@ -607,7 +607,7 @@ async function determineStandaloneApi(
): Promise<boolean> {
if (parsedArgs.standaloneApi === undefined) {
return enquirer
.prompt([
.prompt<{ standaloneApi: 'Yes' | 'No' }>([
{
name: 'standaloneApi',
message:
Expand All @@ -625,7 +625,7 @@ async function determineStandaloneApi(
initial: 'No' as any,
},
])
.then((a: { standaloneApi: 'Yes' | 'No' }) => a.standaloneApi === 'Yes');
.then((a) => a.standaloneApi === 'Yes');
}

return parsedArgs.standaloneApi;
Expand All @@ -636,7 +636,7 @@ async function determineDockerfile(
): Promise<boolean> {
if (parsedArgs.docker === undefined) {
return enquirer
.prompt([
.prompt<{ docker: 'Yes' | 'No' }>([
{
name: 'docker',
message:
Expand All @@ -654,7 +654,7 @@ async function determineDockerfile(
initial: 'No' as any,
},
])
.then((a: { docker: 'Yes' | 'No' }) => a.docker === 'Yes');
.then((a) => a.docker === 'Yes');
} else {
return Promise.resolve(parsedArgs.docker);
}
Expand All @@ -663,7 +663,7 @@ async function determineDockerfile(
async function determineStyle(
preset: Preset,
parsedArgs: yargs.Arguments<Arguments>
): Promise<string> {
): Promise<string | null> {
if (
preset === Preset.Apps ||
preset === Preset.Core ||
Expand Down Expand Up @@ -727,7 +727,7 @@ async function determineStyle(

if (!parsedArgs.style) {
return enquirer
.prompt([
.prompt<{ style: string }>([
{
name: 'style',
message: `Default stylesheet format `,
Expand Down Expand Up @@ -762,7 +762,7 @@ async function determineRouting(
): Promise<boolean> {
if (!parsedArgs.routing) {
return enquirer
.prompt([
.prompt<{ routing: 'Yes' | 'No' }>([
{
name: 'routing',
message: 'Would you like to add routing?',
Expand All @@ -779,7 +779,7 @@ async function determineRouting(
initial: 'Yes' as any,
},
])
.then((a: { routing: 'Yes' | 'No' }) => a.routing === 'Yes');
.then((a) => a.routing === 'Yes');
}

return parsedArgs.routing;
Expand All @@ -801,7 +801,7 @@ async function determineBundler(

if (!parsedArgs.bundler) {
return enquirer
.prompt([
.prompt<{ bundler: Bundler }>([
{
name: 'bundler',
message: `Bundler to be used to build the application`,
Expand All @@ -810,7 +810,7 @@ async function determineBundler(
choices: choices,
},
])
.then((a: { bundler: 'vite' | 'webpack' }) => a.bundler);
.then((a) => a.bundler);
}

const foundBundler = choices.find(
Expand Down Expand Up @@ -838,7 +838,7 @@ async function determineNxCloud(
): Promise<boolean> {
if (parsedArgs.nxCloud === undefined) {
return enquirer
.prompt([
.prompt<{ NxCloud: 'Yes' | 'No' }>([
{
name: 'NxCloud',
message: messages.getPromptMessage('nxCloudCreation'),
Expand All @@ -856,7 +856,7 @@ async function determineNxCloud(
initial: 'Yes' as any,
},
])
.then((a: { NxCloud: 'Yes' | 'No' }) => a.NxCloud === 'Yes');
.then((a) => a.NxCloud === 'Yes');
} else {
return parsedArgs.nxCloud;
}
Expand Down Expand Up @@ -886,7 +886,7 @@ async function determineCI(
if (parsedArgs.allPrompts) {
return (
enquirer
.prompt([
.prompt<{ CI: string }>([
{
name: 'CI',
message: `CI workflow file to generate? `,
Expand Down
15 changes: 10 additions & 5 deletions packages/create-nx-workspace/src/create-empty-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import * as ora from 'ora';
import { join } from 'path';
import { CreateWorkspaceOptions } from './create-workspace-options';
import { execAndWait } from './utils/child-process-utils';
import { mapErrorToBodyLines } from './utils/error-utils';
import { output } from './utils/output';
import {
getPackageManagerCommand,
getPackageManagerVersion,
PackageManager,
} from './utils/package-manager';
import { getFileName, mapErrorToBodyLines } from './utils/string-utils';
import { getFileName } from './utils/string-utils';
import { unparse } from './utils/unparse';

/**
Expand Down Expand Up @@ -67,10 +68,14 @@ export async function createEmptyWorkspace<T extends CreateWorkspaceOptions>(
);
} catch (e) {
workspaceSetupSpinner.fail();
output.error({
title: `Nx failed to create a workspace.`,
bodyLines: mapErrorToBodyLines(e),
});
if (e instanceof Error) {
output.error({
title: `Nx failed to create a workspace.`,
bodyLines: mapErrorToBodyLines(e),
});
} else {
console.error(e);
}
process.exit(1);
} finally {
workspaceSetupSpinner.stop();
Expand Down
14 changes: 9 additions & 5 deletions packages/create-nx-workspace/src/create-sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
} from './utils/package-manager';
import { execAndWait } from './utils/child-process-utils';
import { output } from './utils/output';
import { mapErrorToBodyLines } from './utils/string-utils';
import { nxVersion } from './utils/nx/nx-version';
import { mapErrorToBodyLines } from './utils/error-utils';

/**
* Creates a temporary directory and installs Nx in it.
Expand Down Expand Up @@ -44,10 +44,14 @@ export async function createSandbox(packageManager: PackageManager) {
installSpinner.succeed();
} catch (e) {
installSpinner.fail();
output.error({
title: `Nx failed to install dependencies`,
bodyLines: mapErrorToBodyLines(e),
});
if (e instanceof Error) {
output.error({
title: `Nx failed to install dependencies`,
bodyLines: mapErrorToBodyLines(e),
});
} else {
console.error(e);
}
process.exit(1);
} finally {
installSpinner.stop();
Expand Down
17 changes: 11 additions & 6 deletions packages/create-nx-workspace/src/create-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { messages, recordStat } from './utils/nx/ab-testing';
import { initializeGitRepo } from './utils/git/git';
import { nxVersion } from './utils/nx/nx-version';
import { getThirdPartyPreset } from './utils/preset/get-third-party-preset';
import { mapErrorToBodyLines } from './utils/error-utils';

export async function createWorkspace<T extends CreateWorkspaceOptions>(
preset: string,
Expand Down Expand Up @@ -59,23 +60,27 @@ export async function createWorkspace<T extends CreateWorkspaceOptions>(
name,
ci,
packageManager,
nxCloud && nxCloudInstallRes.code === 0
nxCloud && nxCloudInstallRes?.code === 0
);
}
if (!skipGit) {
try {
await initializeGitRepo(directory, { defaultBase, commit });
} catch (e) {
output.error({
title: 'Could not initialize git repository',
bodyLines: [e.message],
});
if (e instanceof Error) {
output.error({
title: 'Could not initialize git repository',
bodyLines: mapErrorToBodyLines(e),
});
} else {
console.error(e);
}
}
}

showNxWarning(name);

if (nxCloud && nxCloudInstallRes.code === 0) {
if (nxCloud && nxCloudInstallRes?.code === 0) {
printNxCloudSuccessMessage(nxCloudInstallRes.stdout);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/create-nx-workspace/src/utils/child-process-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { spawn, exec } from 'child_process';
import { writeFileSync } from 'fs';
import { join } from 'path';
import { CreateNxWorkspaceError } from './error-utils';

/**
* Use spawn only for interactive shells
Expand All @@ -24,15 +25,15 @@ export function spawnAndWait(command: string, args: string[], cwd: string) {
}

export function execAndWait(command: string, cwd: string) {
return new Promise((res, rej) => {
return new Promise<{ code: number; stdout: string }>((res, rej) => {
exec(
command,
{ cwd, env: { ...process.env, NX_DAEMON: 'false' } },
(error, stdout, stderr) => {
if (error) {
const logFile = join(cwd, 'error.log');
writeFileSync(logFile, `${stdout}\n${stderr}`);
rej({ code: error.code, logFile, logMessage: stderr });
rej(new CreateNxWorkspaceError(stderr, error.code, logFile));
} else {
res({ code: 0, stdout });
}
Expand Down
16 changes: 10 additions & 6 deletions packages/create-nx-workspace/src/utils/ci/setup-ci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import * as ora from 'ora';
import { join } from 'path';

import { execAndWait } from '../child-process-utils';
import { mapErrorToBodyLines } from '../error-utils';
import { output } from '../output';
import { getPackageManagerCommand, PackageManager } from '../package-manager';
import { getFileName, mapErrorToBodyLines } from '../string-utils';
import { getFileName } from '../string-utils';

export async function setupCI(
name: string,
Expand Down Expand Up @@ -32,11 +33,14 @@ export async function setupCI(
return res;
} catch (e) {
ciSpinner.fail();

output.error({
title: `Nx failed to generate CI workflow`,
bodyLines: mapErrorToBodyLines(e),
});
if (e instanceof Error) {
output.error({
title: `Nx failed to generate CI workflow`,
bodyLines: mapErrorToBodyLines(e),
});
} else {
console.error(e);
}

process.exit(1);
} finally {
Expand Down
Loading

0 comments on commit 5d51ed9

Please sign in to comment.