Skip to content

Commit

Permalink
feat(misc): add linter flag to create-nx-workspace (#3826)
Browse files Browse the repository at this point in the history
* feat(misc): add linter flag to create-nx-workspace

* fix(core): prompt linter when preset is angular or angular-nest

Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
  • Loading branch information
vsavkin and FrozenPandaz committed Sep 30, 2020
1 parent 3f436fc commit c25628a
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 104 deletions.
4 changes: 3 additions & 1 deletion e2e/utils/index.ts
Expand Up @@ -91,7 +91,9 @@ export function runCreateWorkspace(
base?: string;
}
) {
let command = `npx create-nx-workspace@${process.env.PUBLISHED_VERSION} ${name} --cli=${cli} --preset=${preset} --no-nxCloud --no-interactive`;
const linterArg =
preset === 'angular' || preset === 'angular-nest' ? ' --linter=tslint' : '';
let command = `npx create-nx-workspace@${process.env.PUBLISHED_VERSION} ${name} --cli=${cli} --preset=${preset} ${linterArg} --no-nxCloud --no-interactive`;
if (appName) {
command += ` --appName=${appName}`;
}
Expand Down
42 changes: 9 additions & 33 deletions e2e/workspace/src/workspace-aux-commands.test.ts
Expand Up @@ -810,17 +810,9 @@ forEachCli((cli) => {
expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`);
if (workspace === 'angular') {
expect(project.architect.lint.options.tsConfig).toEqual([
`libs/shared/${lib1}/data-access/tsconfig.lib.json`,
`libs/shared/${lib1}/data-access/tsconfig.spec.json`,
]);
}
if (workspace === 'workspace') {
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);
}
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);

/**
* Check that the import in lib2 has been updated
Expand Down Expand Up @@ -955,17 +947,9 @@ forEachCli((cli) => {
expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`);
if (workspace === 'angular') {
expect(project.architect.lint.options.tsConfig).toEqual([
`libs/shared/${lib1}/data-access/tsconfig.lib.json`,
`libs/shared/${lib1}/data-access/tsconfig.spec.json`,
]);
}
if (workspace === 'workspace') {
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);
}
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);

/**
* Check that the import in lib2 has been updated
Expand Down Expand Up @@ -1102,17 +1086,9 @@ forEachCli((cli) => {
expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`);
if (workspace === 'angular') {
expect(project.architect.lint.options.tsConfig).toEqual([
`packages/shared/${lib1}/data-access/tsconfig.lib.json`,
`packages/shared/${lib1}/data-access/tsconfig.spec.json`,
]);
}
if (workspace === 'workspace') {
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`packages/shared/${lib1}/data-access/**/*.ts`,
]);
}
expect(project.architect.lint.options.lintFilePatterns).toEqual([
`packages/shared/${lib1}/data-access/**/*.ts`,
]);

/**
* Check that the import in lib2 has been updated
Expand Down
1 change: 1 addition & 0 deletions packages/angular/package.json
Expand Up @@ -38,6 +38,7 @@
"dependencies": {
"@nrwl/cypress": "*",
"@nrwl/jest": "*",
"@nrwl/linter": "*",
"@angular-devkit/schematics": "~10.1.3",
"@schematics/angular": "~10.1.3",
"jasmine-marbles": "~0.6.0"
Expand Down
21 changes: 12 additions & 9 deletions packages/angular/src/schematics/library/lib/update-project.ts
Expand Up @@ -5,6 +5,7 @@ import {
MergeStrategy,
mergeWith,
move,
noop,
Rule,
SchematicContext,
template,
Expand Down Expand Up @@ -191,15 +192,17 @@ export function updateProject(options: NormalizedSchema): Rule {
},
};
}),
updateJsonInTree(`${options.projectRoot}/tslint.json`, (json) => {
return {
...json,
extends: `${offsetFromRoot(options.projectRoot)}tslint.json`,
linterOptions: {
exclude: ['!**/*'],
},
};
}),
options.linter === Linter.TsLint
? updateJsonInTree(`${options.projectRoot}/tslint.json`, (json) => {
return {
...json,
extends: `${offsetFromRoot(options.projectRoot)}tslint.json`,
linterOptions: {
exclude: ['!**/*'],
},
};
})
: noop(),
updateJsonInTree(`/nx.json`, (json) => {
return {
...json,
Expand Down
1 change: 0 additions & 1 deletion packages/angular/src/schematics/library/library.ts
Expand Up @@ -59,7 +59,6 @@ export default function (schema: Schema): Rule {
(host) => {
host.delete('tsconfig.json');
},

move(options.name, options.projectRoot),
updateProject(options),
updateTsConfig(options),
Expand Down
3 changes: 0 additions & 3 deletions packages/angular/src/schematics/stories/stories-app.spec.ts
Expand Up @@ -21,9 +21,6 @@ describe('angular:stories for applications', () => {
appTree
);

console.log(appTree);
console.log(tree);

expect(tree.exists('apps/test-app/src/app/app.component.ts')).toBeTruthy();
expect(
tree.exists('apps/test-app/src/app/app.component.stories.ts')
Expand Down
115 changes: 81 additions & 34 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Expand Up @@ -30,40 +30,40 @@ const presetOptions = [
'empty [an empty workspace with a layout that works best for building apps]',
},
{
value: 'oss',
name:
'oss [an empty workspace with a layout that works best for open-source projects]',
},
{
value: 'web-components',
name:
'web components [a workspace with a single app built using web components]',
value: Preset.React,
name: 'react [a workspace with a single React application]',
},
{
value: Preset.Angular,
name: 'angular [a workspace with a single Angular application]',
},
{
value: Preset.AngularWithNest,
name:
'angular-nest [a workspace with a full stack application (Angular + Nest)]',
value: Preset.NextJs,
name: 'next.js [a workspace with a single Next.js application]',
},
{
value: Preset.Nest,
name: 'nest [a workspace with a single Nest application]',
},
{
value: Preset.React,
name: 'react [a workspace with a single React application]',
value: 'web-components',
name:
'web components [a workspace with a single app built using web components]',
},
{
value: Preset.ReactWithExpress,
name:
'react-express [a workspace with a full stack application (React + Express)]',
},
{
value: Preset.NextJs,
name: 'next.js [a workspace with a single Next.js application]',
value: Preset.AngularWithNest,
name:
'angular-nest [a workspace with a full stack application (Angular + Nest)]',
},
{
value: 'oss',
name:
'oss [an empty workspace with a layout that works best for open-source projects]',
},
];

Expand All @@ -74,7 +74,7 @@ const angularCliVersion = 'ANGULAR_CLI_VERSION';
const prettierVersion = 'PRETTIER_VERSION';

const parsedArgs = yargsParser(process.argv, {
string: ['cli', 'preset', 'appName', 'style', 'defaultBase'],
string: ['cli', 'preset', 'appName', 'style', 'linter', 'defaultBase'],
alias: {
appName: 'app-name',
nxCloud: 'nx-cloud',
Expand All @@ -93,22 +93,25 @@ determineWorkspaceName(parsedArgs).then((name) => {
return determineAppName(preset, parsedArgs).then((appName) => {
return determineStyle(preset, parsedArgs).then((style) => {
return determineCli(preset, parsedArgs).then((cli) => {
return askAboutNxCloud(parsedArgs).then((cloud) => {
const tmpDir = createSandbox(packageManager);
createApp(
tmpDir,
cli,
parsedArgs,
name,
preset,
appName,
style,
cloud,
parsedArgs.interactive,
parsedArgs.defaultBase
);
showNxWarning(name);
pointToTutorialAndCourse(preset);
return determineLinter(cli, parsedArgs).then((linter) => {
return askAboutNxCloud(parsedArgs).then((cloud) => {
const tmpDir = createSandbox(packageManager);
createApp(
tmpDir,
cli,
parsedArgs,
name,
preset,
appName,
style,
linter,
cloud,
parsedArgs.interactive,
parsedArgs.defaultBase
);
showNxWarning(name);
pointToTutorialAndCourse(preset);
});
});
});
});
Expand Down Expand Up @@ -137,7 +140,9 @@ function showHelp() {
cli CLI to power the Nx workspace (options: "nx", "angular")
style Default style option to be used when a non-empty preset is selected
options: ("css", "scss", "styl", "less") for React/Next.js also ("styled-components", "@emotion/styled")
options: ("css", "scss", "styl", "less") for React/Next.js also ("styled-components", "@emotion/styled")
linter Default linter. Options: "eslint", "tslint".
interactive Enable interactive mode when using presets (boolean)
Expand Down Expand Up @@ -376,6 +381,45 @@ function determineStyle(preset: Preset, parsedArgs: any) {
return Promise.resolve(parsedArgs.style);
}

function determineLinter(preset: Preset, parsedArgs: any) {
if (!parsedArgs.linter) {
if (preset === Preset.Angular || preset === Preset.AngularWithNest) {
return inquirer
.prompt([
{
name: 'linter',
message: `Default linter `,
default: 'tslint',
type: 'list',
choices: [
{
value: 'tslint',
name: 'TSLint [ Used by Angular CLI ]',
},
{
value: 'eslint',
name: 'ESLint [ Modern linting tool ]',
},
],
},
])
.then((a) => a.linter);
} else {
return Promise.resolve('eslint');
}
} else {
if (parsedArgs.linter !== 'eslint' && parsedArgs.linter !== 'tslint') {
output.error({
title: 'Invalid linter',
bodyLines: [`It must be one of the following:`, '', 'eslint', 'tslint'],
});
process.exit(1);
} else {
return Promise.resolve(parsedArgs.linter);
}
}
}

function createSandbox(packageManager: string) {
console.log(`Creating a sandbox with Nx...`);
const tmpDir = dirSync().name;
Expand Down Expand Up @@ -408,6 +452,7 @@ function createApp(
preset: Preset,
appName: string,
style: string | null,
linter: string,
nxCloud: boolean,
interactive: boolean,
defaultBase: string
Expand All @@ -424,6 +469,7 @@ function createApp(
'nxCloud',
'preset',
'style',
'linter',
];

// These are the arguments that are passed to the schematic
Expand All @@ -434,14 +480,15 @@ function createApp(

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}"` : ``;

const packageExec = getPackageManagerExecuteCommand(packageManager);
const command = `new ${name} ${args} --preset="${preset}"${appNameArg}${styleArg}${nxCloudArg}${interactiveArg}${defaultBaseArg} --collection=@nrwl/workspace`;
const command = `new ${name} ${args} --preset="${preset}"${appNameArg}${styleArg}${linterArg}${nxCloudArg}${interactiveArg}${defaultBaseArg} --collection=@nrwl/workspace`;
console.log(command);

const collectionJsonPath = require.resolve(
Expand Down
6 changes: 6 additions & 0 deletions packages/workspace/src/schematics/ng-new/schema.json
Expand Up @@ -86,6 +86,12 @@
"type": "string",
"description": "Root directory.",
"hidden": true
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["tslint", "eslint"],
"default": "eslint"
}
}
}

0 comments on commit c25628a

Please sign in to comment.