fix(core): handle commit object argument when creating workspace

This commit is contained in:
Tasos Bekos 2020-12-05 12:40:42 +02:00 committed by Victor Savkin
parent a529df017f
commit 056f4eb20e
8 changed files with 91 additions and 99 deletions

View File

@ -43,6 +43,7 @@ export function runCreateWorkspace(
base,
packageManager,
cli,
extraArgs,
}: {
preset: string;
appName?: string;
@ -50,6 +51,7 @@ export function runCreateWorkspace(
base?: string;
packageManager?: string;
cli?: string;
extraArgs?: string;
}
) {
setCurrentProjName(name);
@ -76,6 +78,10 @@ export function runCreateWorkspace(
command += ` --package-manager=${packageManager}`;
}
if (extraArgs) {
command += ` ${extraArgs}`;
}
const create = execSync(command, {
cwd: `./tmp/${currentCli()}`,
stdio: [0, 1, 2],

View File

@ -100,6 +100,15 @@ describe('create-nx-workspace', () => {
});
});
it('should be able to create a workspace with custom commit information', () => {
const wsName = uniq('branch');
runCreateWorkspace(wsName, {
preset: 'empty',
extraArgs:
'--commit.name="John Doe" --commit.email="myemail@test.com" --commit.message="Custom commit message!"',
});
});
it('should be able to create a nest workspace', () => {
const wsName = uniq('nest');
const appName = uniq('app');

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
// we can import from '@nrwl/workspace' because it will require typescript
import { output } from '@nrwl/workspace/src/utils/output';
import { output, unparse } from '@nrwl/workspace';
import { Schema, Preset } from '@nrwl/workspace/src/schematics/new/new';
import { getPackageManagerCommand } from '@nrwl/tao/src/shared/package-manager';
import { execSync } from 'child_process';
import { writeFileSync } from 'fs';
@ -11,19 +11,7 @@ import { dirSync } from 'tmp';
import * as yargsParser from 'yargs-parser';
import { showNxWarning } from './shared';
enum Preset {
Empty = 'empty',
OSS = 'oss',
WebComponents = 'web-components',
Angular = 'angular',
AngularWithNest = 'angular-nest',
React = 'react',
ReactWithExpress = 'react-express',
NextJs = 'next',
Nest = 'nest',
}
const presetOptions = [
const presetOptions: { value: Preset; name: string }[] = [
{
value: Preset.Empty,
name:
@ -46,7 +34,7 @@ const presetOptions = [
name: 'nest [a workspace with a single Nest application]',
},
{
value: 'web-components',
value: Preset.WebComponents,
name:
'web components [a workspace with a single app built using web components]',
},
@ -61,7 +49,7 @@ const presetOptions = [
'angular-nest [a workspace with a full stack application (Angular + Nest)]',
},
{
value: 'oss',
value: Preset.OSS,
name:
'oss [an empty workspace with a layout that works best for open-source projects]',
},
@ -70,10 +58,14 @@ const presetOptions = [
const tsVersion = 'TYPESCRIPT_VERSION';
const cliVersion = 'NX_VERSION';
const nxVersion = 'NX_VERSION';
const angularCliVersion = 'ANGULAR_CLI_VERSION';
const prettierVersion = 'PRETTIER_VERSION';
const parsedArgs = yargsParser(process.argv, {
interface WorkspaceArgs extends Schema {
_?: string[];
help?: boolean;
}
const parsedArgs: WorkspaceArgs = yargsParser(process.argv.slice(2), {
string: [
'cli',
'preset',
@ -84,12 +76,17 @@ const parsedArgs = yargsParser(process.argv, {
'packageManager',
],
alias: {
appName: 'app-name',
nxCloud: 'nx-cloud',
defaultBase: 'default-base',
packageManager: 'pm',
},
boolean: ['help', 'interactive', 'nxCloud'],
});
default: {
interactive: false,
},
configuration: {
'strip-dashed': true,
'strip-aliased': true,
},
}) as any;
if (parsedArgs.help) {
showHelp();
@ -102,21 +99,17 @@ determineWorkspaceName(parsedArgs).then((name) => {
return determineStyle(preset, parsedArgs).then((style) => {
return determineCli(preset, parsedArgs).then((cli) => {
return determineLinter(preset, parsedArgs).then((linter) => {
return askAboutNxCloud(parsedArgs).then((cloud) => {
return askAboutNxCloud(parsedArgs).then((nxCloud) => {
const tmpDir = createSandbox(packageManager);
createApp(
tmpDir,
createApp(tmpDir, name, {
...parsedArgs,
cli,
parsedArgs,
name,
preset,
appName,
style,
linter,
cloud,
parsedArgs.interactive,
parsedArgs.defaultBase
);
nxCloud,
});
showNxWarning(name);
pointToTutorialAndCourse(preset);
});
@ -160,8 +153,8 @@ function showHelp() {
`);
}
function determineWorkspaceName(parsedArgs: any): Promise<string> {
const workspaceName: string = parsedArgs._[2];
function determineWorkspaceName(parsedArgs: WorkspaceArgs): Promise<string> {
const workspaceName: string = parsedArgs._[0];
if (workspaceName) {
return Promise.resolve(workspaceName);
@ -187,7 +180,7 @@ function determineWorkspaceName(parsedArgs: any): Promise<string> {
});
}
function determinePreset(parsedArgs: any): Promise<Preset> {
function determinePreset(parsedArgs: WorkspaceArgs): Promise<Preset> {
if (parsedArgs.preset) {
if (Object.values(Preset).indexOf(parsedArgs.preset) === -1) {
output.error({
@ -217,7 +210,10 @@ function determinePreset(parsedArgs: any): Promise<Preset> {
.then((a: { Preset: Preset }) => a.Preset);
}
function determineAppName(preset: Preset, parsedArgs: any): Promise<string> {
function determineAppName(
preset: Preset,
parsedArgs: WorkspaceArgs
): Promise<string> {
if (preset === Preset.Empty || preset === Preset.OSS) {
return Promise.resolve('');
}
@ -248,7 +244,7 @@ function determineAppName(preset: Preset, parsedArgs: any): Promise<string> {
function determineCli(
preset: Preset,
parsedArgs: any
parsedArgs: WorkspaceArgs
): Promise<'nx' | 'angular'> {
if (parsedArgs.cli) {
if (['nx', 'angular'].indexOf(parsedArgs.cli) === -1) {
@ -272,7 +268,7 @@ function determineCli(
}
}
function determineStyle(preset: Preset, parsedArgs: any) {
function determineStyle(preset: Preset, parsedArgs: WorkspaceArgs) {
if (
preset === Preset.Empty ||
preset === Preset.OSS ||
@ -351,7 +347,7 @@ function determineStyle(preset: Preset, parsedArgs: any) {
return Promise.resolve(parsedArgs.style);
}
function determineLinter(preset: Preset, parsedArgs: any) {
function determineLinter(preset: Preset, parsedArgs: WorkspaceArgs) {
if (!parsedArgs.linter) {
if (preset === Preset.Angular || preset === Preset.AngularWithNest) {
return inquirer
@ -414,51 +410,12 @@ function createSandbox(packageManager: string) {
return tmpDir;
}
function createApp(
tmpDir: string,
cli: 'nx' | 'angular',
parsedArgs: any,
name: string,
preset: Preset,
appName: string,
style: string | null,
linter: string,
nxCloud: boolean,
interactive: boolean,
defaultBase: string
) {
const filterArgs = [
'_',
'app-name',
'appName',
'cli',
'default-base',
'defaultBase',
'interactive',
'nx-cloud',
'nxCloud',
'preset',
'style',
'linter',
];
// These are the arguments that are passed to the schematic
const args = Object.keys(parsedArgs)
.filter((key) => !filterArgs.includes(key))
.map((key) => `--${key}=${parsedArgs[key]}`)
.join(' ');
const appNameArg = appName ? ` --appName="${appName}"` : ``;
const styleArg = style ? ` --style="${style}"` : ``;
const linterArg = ` --linter="${linter}"`;
const nxCloudArg = nxCloud ? ` --nxCloud` : ``;
const interactiveArg = interactive
? ` --interactive=true`
: ` --interactive=false`;
const defaultBaseArg = defaultBase ? ` --defaultBase="${defaultBase}"` : ``;
function createApp(tmpDir: string, name: string, parsedArgs: WorkspaceArgs) {
const { _, cli, ...restArgs } = parsedArgs;
const args = unparse(restArgs).join(' ');
const pmc = getPackageManagerCommand(packageManager);
const command = `new ${name} ${args} --preset="${preset}"${appNameArg}${styleArg}${linterArg}${nxCloudArg}${interactiveArg}${defaultBaseArg} --collection=@nrwl/workspace`;
const command = `new ${name} ${args} --collection=@nrwl/workspace`;
console.log(command);
execSync(
@ -471,7 +428,7 @@ function createApp(
}
);
if (nxCloud) {
if (parsedArgs.nxCloud) {
output.addVerticalSeparator();
execSync(`${pmc.exec} nx g @nrwl/nx-cloud:init --no-analytics`, {
stdio: [0, 1, 2],
@ -480,7 +437,7 @@ function createApp(
}
}
async function askAboutNxCloud(parsedArgs: any) {
async function askAboutNxCloud(parsedArgs: WorkspaceArgs) {
if (parsedArgs.nxCloud === undefined) {
return inquirer
.prompt([

View File

@ -29,9 +29,9 @@
"dependencies": {
"@nrwl/workspace": "*",
"tmp": "0.0.33",
"yargs": "15.4.1",
"yargs-parser": "20.0.0",
"tslib": "^2.0.0",
"inquirer": "^6.3.1"
"inquirer": "^6.3.1",
"typescript": "~4.0.3"
}
}

View File

@ -59,6 +59,8 @@ export {
serializeTarget,
} from './src/utils/cli-config-utils';
export { unparse } from './src/tasks-runner/utils';
export {
getWorkspace,
updateWorkspace,

View File

@ -24,10 +24,21 @@ import * as path from 'path';
import { Observable } from 'rxjs';
import { spawn } from 'child_process';
import { getPackageManagerCommand } from '@nrwl/tao/src/shared/package-manager';
// @ts-ignore
import yargsParser = require('yargs-parser');
import * as yargsParser from 'yargs-parser';
import { names } from '@nrwl/devkit';
export enum Preset {
Empty = 'empty',
OSS = 'oss',
WebComponents = 'web-components',
Angular = 'angular',
AngularWithNest = 'angular-nest',
React = 'react',
ReactWithExpress = 'react-express',
NextJs = 'next',
Nest = 'nest',
}
export interface Schema {
cli: 'nx' | 'angular';
directory: string;
@ -38,16 +49,7 @@ export interface Schema {
skipGit?: boolean;
style?: string;
nxCloud?: boolean;
preset:
| 'empty'
| 'oss'
| 'angular'
| 'react'
| 'web-components'
| 'angular-nest'
| 'react-express'
| 'next'
| 'nest';
preset: Preset;
commit?: { name: string; email: string; message?: string };
defaultBase?: string;
nxWorkspaceRoot?: string;

View File

@ -236,5 +236,19 @@ describe('utils', () => {
'--foo.z=4',
]);
});
it('should quote string values with space(s)', () => {
const options = {
string1: 'one',
string2: 'one two',
string3: 'one two three',
};
expect(unparse(options)).toEqual([
'--string1=one',
'--string2="one two"',
'--string3="one two three"',
]);
});
});
});

View File

@ -108,7 +108,9 @@ function unparseOption(key: string, value: any, unparsed: string[]) {
unparsed
);
}
} else if (typeof value === 'string' || value != null) {
} else if (typeof value === 'string' && value.includes(' ')) {
unparsed.push(`--${key}="${value}"`);
} else if (value != null) {
unparsed.push(`--${key}=${value}`);
}
}