* feat(linter): convert-tslint-to-eslint generators * fix(core): remove generators in collection for ng and nest * fix(core): update tao to support mixed generators and schematics * fix(core): update tao to support mixed generators and schematics * fix(core): address some PR feedback * fix(core): fix snapshots after syncing up with master * feat(core): store user preference for removeTSLintIfNoMoreTSLintTargets * fix(linter): unit tests * feat(core): apply root tslint.json conversion to root .eslintrc.json
164 lines
4.7 KiB
TypeScript
164 lines
4.7 KiB
TypeScript
import {
|
|
addDependenciesToPackageJson,
|
|
addProjectConfiguration,
|
|
convertNxGenerator,
|
|
formatFiles,
|
|
generateFiles,
|
|
getWorkspaceLayout,
|
|
joinPathFragments,
|
|
names,
|
|
offsetFromRoot,
|
|
toJS,
|
|
Tree,
|
|
updateJson,
|
|
} from '@nrwl/devkit';
|
|
import { Linter, lintProjectGenerator } from '@nrwl/linter';
|
|
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
|
|
|
import { join } from 'path';
|
|
// app
|
|
import { Schema } from './schema';
|
|
import { eslintPluginCypressVersion } from '../../utils/versions';
|
|
|
|
export interface CypressProjectSchema extends Schema {
|
|
projectName: string;
|
|
projectRoot: string;
|
|
}
|
|
|
|
function createFiles(host: Tree, options: CypressProjectSchema) {
|
|
generateFiles(host, join(__dirname, './files'), options.projectRoot, {
|
|
tmpl: '',
|
|
...options,
|
|
project: options.project || 'Project',
|
|
ext: options.js ? 'js' : 'ts',
|
|
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
|
});
|
|
|
|
if (options.js) {
|
|
toJS(host);
|
|
}
|
|
}
|
|
|
|
function addProject(host: Tree, options: CypressProjectSchema) {
|
|
addProjectConfiguration(host, options.projectName, {
|
|
root: options.projectRoot,
|
|
sourceRoot: joinPathFragments(options.projectRoot, 'src'),
|
|
projectType: 'application',
|
|
targets: {
|
|
e2e: {
|
|
executor: '@nrwl/cypress:cypress',
|
|
options: {
|
|
cypressConfig: joinPathFragments(options.projectRoot, 'cypress.json'),
|
|
tsConfig: joinPathFragments(options.projectRoot, 'tsconfig.e2e.json'),
|
|
devServerTarget: `${options.project}:serve`,
|
|
},
|
|
configurations: {
|
|
production: {
|
|
devServerTarget: `${options.project}:serve:production`,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
tags: [],
|
|
implicitDependencies: options.project ? [options.project] : undefined,
|
|
});
|
|
}
|
|
|
|
export async function addLinter(host: Tree, options: CypressProjectSchema) {
|
|
const installTask = await lintProjectGenerator(host, {
|
|
project: options.projectName,
|
|
linter: options.linter,
|
|
skipFormat: true,
|
|
tsConfigPaths: [
|
|
joinPathFragments(options.projectRoot, 'tsconfig.e2e.json'),
|
|
],
|
|
eslintFilePatterns: [
|
|
`${options.projectRoot}/**/*.${options.js ? 'js' : '{js,ts}'}`,
|
|
],
|
|
});
|
|
|
|
if (!options.linter || options.linter !== Linter.EsLint) {
|
|
return installTask;
|
|
}
|
|
|
|
const installTask2 = addDependenciesToPackageJson(
|
|
host,
|
|
{},
|
|
{ 'eslint-plugin-cypress': eslintPluginCypressVersion }
|
|
);
|
|
|
|
updateJson(host, join(options.projectRoot, '.eslintrc.json'), (json) => {
|
|
json.extends = ['plugin:cypress/recommended', ...json.extends];
|
|
json.overrides = [
|
|
/**
|
|
* In order to ensure maximum efficiency when typescript-eslint generates TypeScript Programs
|
|
* behind the scenes during lint runs, we need to make sure the project is configured to use its
|
|
* own specific tsconfigs, and not fall back to the ones in the root of the workspace.
|
|
*/
|
|
{
|
|
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
|
|
parserOptions: {
|
|
project: `${options.projectRoot}/tsconfig.*?.json`,
|
|
},
|
|
/**
|
|
* Having an empty rules object present makes it more obvious to the user where they would
|
|
* extend things from if they needed to
|
|
*/
|
|
rules: {},
|
|
},
|
|
/**
|
|
* We need this override because we enabled allowJS in the tsconfig to allow for JS based Cypress tests.
|
|
* That however leads to issues with the CommonJS Cypress plugin file.
|
|
*/
|
|
{
|
|
files: ['src/plugins/index.js'],
|
|
rules: {
|
|
'@typescript-eslint/no-var-requires': 'off',
|
|
'no-undef': 'off',
|
|
},
|
|
},
|
|
];
|
|
|
|
return json;
|
|
});
|
|
|
|
return runTasksInSerial(installTask, installTask2);
|
|
}
|
|
|
|
export async function cypressProjectGenerator(host: Tree, schema: Schema) {
|
|
const options = normalizeOptions(host, schema);
|
|
createFiles(host, options);
|
|
addProject(host, options);
|
|
const installTask = await addLinter(host, options);
|
|
if (!options.skipFormat) {
|
|
await formatFiles(host);
|
|
}
|
|
return installTask;
|
|
}
|
|
|
|
function normalizeOptions(host: Tree, options: Schema): CypressProjectSchema {
|
|
const { appsDir } = getWorkspaceLayout(host);
|
|
const projectName = options.directory
|
|
? names(options.directory).fileName + '-' + options.name
|
|
: options.name;
|
|
const projectRoot = options.directory
|
|
? joinPathFragments(
|
|
appsDir,
|
|
names(options.directory).fileName,
|
|
options.name
|
|
)
|
|
: joinPathFragments(appsDir, options.name);
|
|
|
|
options.linter = options.linter || Linter.EsLint;
|
|
return {
|
|
...options,
|
|
projectName,
|
|
projectRoot,
|
|
};
|
|
}
|
|
|
|
export default cypressProjectGenerator;
|
|
export const cypressProjectSchematic = convertNxGenerator(
|
|
cypressProjectGenerator
|
|
);
|