Skip to content

Commit 226a8d2

Browse files
committed
feat(@schematics/angular): remove tslint and codelyzer from new projects
Both of these projects and the tslint builder are deprecated. Closes #20105 and closes #18465
1 parent b6d693f commit 226a8d2

File tree

12 files changed

+4
-210
lines changed

12 files changed

+4
-210
lines changed

packages/schematics/angular/application/files/tslint.json.template

-18
This file was deleted.

packages/schematics/angular/application/index.ts

+1-37
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
3131
import { Schema as ComponentOptions } from '../component/schema';
3232
import { Schema as E2eOptions } from '../e2e/schema';
3333
import { NodeDependencyType, addPackageJsonDependency } from '../utility/dependencies';
34-
import { JSONFile } from '../utility/json-file';
3534
import { latestVersions } from '../utility/latest-versions';
3635
import { applyLintFix } from '../utility/lint-fix';
3736
import { relativePathToWorkspaceRoot } from '../utility/paths';
@@ -68,28 +67,6 @@ function addDependenciesToPackageJson(options: ApplicationOptions) {
6867
};
6968
}
7069

71-
/**
72-
* Merges the application tslint.json with the workspace tslint.json
73-
* when the application being created is a root application
74-
*
75-
* @param {Tree} parentHost The root host of the schematic
76-
*/
77-
function mergeWithRootTsLint(parentHost: Tree) {
78-
return (host: Tree) => {
79-
const tsLintPath = '/tslint.json';
80-
const rulesPath = ['rules'];
81-
if (!host.exists(tsLintPath)) {
82-
return;
83-
}
84-
85-
const rootTsLintFile = new JSONFile(parentHost, tsLintPath);
86-
const rootRules = rootTsLintFile.get(rulesPath) as {};
87-
const appRules = new JSONFile(host, tsLintPath).get(rulesPath) as {};
88-
rootTsLintFile.modify(rulesPath, { ...rootRules, ...appRules });
89-
host.overwrite(tsLintPath, rootTsLintFile.content);
90-
};
91-
}
92-
9370
function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rule {
9471
let projectRoot = appDir;
9572
if (projectRoot) {
@@ -245,18 +222,6 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul
245222
scripts: [],
246223
},
247224
},
248-
lint: options.minimal ? undefined : {
249-
builder: Builders.TsLint,
250-
options: {
251-
tsConfig: [
252-
`${projectRoot}tsconfig.app.json`,
253-
`${projectRoot}tsconfig.spec.json`,
254-
],
255-
exclude: [
256-
'**/node_modules/**',
257-
],
258-
},
259-
},
260225
},
261226
};
262227

@@ -272,7 +237,7 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul
272237
});
273238
}
274239
function minimalPathFilter(path: string): boolean {
275-
const toRemoveList = /(test.ts|tsconfig.spec.json|karma.conf.js|tslint.json).template$/;
240+
const toRemoveList = /(test.ts|tsconfig.spec.json|karma.conf.js).template$/;
276241

277242
return !toRemoveList.test(path);
278243
}
@@ -327,7 +292,6 @@ export default function (options: ApplicationOptions): Rule {
327292
appName: options.name,
328293
isRootApp,
329294
}),
330-
isRootApp ? mergeWithRootTsLint(host) : noop(),
331295
move(appDir),
332296
]), MergeStrategy.Overwrite),
333297
schematic('module', {

packages/schematics/angular/application/index_spec.ts

+1-64
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ describe('Application Schematic', () => {
5151
'/projects/foo/karma.conf.js',
5252
'/projects/foo/tsconfig.app.json',
5353
'/projects/foo/tsconfig.spec.json',
54-
'/projects/foo/tslint.json',
5554
'/projects/foo/src/environments/environment.ts',
5655
'/projects/foo/src/environments/environment.prod.ts',
5756
'/projects/foo/src/favicon.ico',
@@ -153,42 +152,21 @@ describe('Application Schematic', () => {
153152
expect(_extends).toBe('../../tsconfig.json');
154153
});
155154

156-
it('should set the right path and prefix in the tslint file', async () => {
157-
const tree = await schematicRunner.runSchematicAsync('application', defaultOptions, workspaceTree)
158-
.toPromise();
159-
const path = '/projects/foo/tslint.json';
160-
const content = JSON.parse(tree.readContent(path));
161-
expect(content.extends).toMatch('../../tslint.json');
162-
expect(content.rules['directive-selector'][2]).toMatch('app');
163-
expect(content.rules['component-selector'][2]).toMatch('app');
164-
});
165-
166-
it('should set the right prefix in the tslint file when provided is kebabed', async () => {
167-
const options: ApplicationOptions = { ...defaultOptions, prefix: 'foo-bar' };
168-
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
169-
.toPromise();
170-
const path = '/projects/foo/tslint.json';
171-
const content = JSON.parse(tree.readContent(path));
172-
expect(content.rules['directive-selector'][2]).toMatch('fooBar');
173-
expect(content.rules['component-selector'][2]).toMatch('foo-bar');
174-
});
175-
176155
it('should set the right coverage folder in the karma.json file', async () => {
177156
const tree = await schematicRunner.runSchematicAsync('application', defaultOptions, workspaceTree)
178157
.toPromise();
179158
const karmaConf = getFileContent(tree, '/projects/foo/karma.conf.js');
180159
expect(karmaConf).toContain(`dir: require('path').join(__dirname, '../../coverage/foo')`);
181160
});
182161

183-
it('minimal=true should not create e2e, lint and test targets', async () => {
162+
it('minimal=true should not create e2e and test targets', async () => {
184163
const options = { ...defaultOptions, minimal: true };
185164
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
186165
.toPromise();
187166
const config = JSON.parse(tree.readContent('/angular.json'));
188167
const architect = config.projects.foo.architect;
189168
expect(architect.test).not.toBeDefined();
190169
expect(architect.e2e).not.toBeDefined();
191-
expect(architect.e2e).not.toBeDefined();
192170
});
193171

194172
it('minimal=true should configure the schematics options for components', async () => {
@@ -235,7 +213,6 @@ describe('Application Schematic', () => {
235213
const files = tree.files;
236214
[
237215
'/projects/foo/tsconfig.spec.json',
238-
'/projects/foo/tslint.json',
239216
'/projects/foo/karma.conf.js',
240217
'/projects/foo/src/test.ts',
241218
'/projects/foo/src/app/app.component.css',
@@ -264,7 +241,6 @@ describe('Application Schematic', () => {
264241
const files = tree.files;
265242
[
266243
'/projects/foo/tsconfig.spec.json',
267-
'/projects/foo/tslint.json',
268244
'/projects/foo/karma.conf.js',
269245
'/projects/foo/src/test.ts',
270246
'/projects/foo/src/app/app.component.html',
@@ -293,7 +269,6 @@ describe('Application Schematic', () => {
293269
const files = tree.files;
294270
[
295271
'/projects/foo/tsconfig.spec.json',
296-
'/projects/foo/tslint.json',
297272
'/projects/foo/karma.conf.js',
298273
'/projects/foo/src/test.ts',
299274
'/projects/foo/src/app/app.component.css',
@@ -355,18 +330,6 @@ describe('Application Schematic', () => {
355330
const packageJson = JSON.parse(tree.readContent('package.json'));
356331
expect(packageJson.devDependencies['@angular-devkit/build-angular']).toBeUndefined();
357332
});
358-
359-
it('should set the lint tsConfig option', async () => {
360-
const tree = await schematicRunner.runSchematicAsync('application', defaultOptions, workspaceTree)
361-
.toPromise();
362-
const workspace = JSON.parse(tree.readContent('/angular.json'));
363-
const lintOptions = workspace.projects.foo.architect.lint.options;
364-
expect(lintOptions.tsConfig).toEqual([
365-
'projects/foo/tsconfig.app.json',
366-
'projects/foo/tsconfig.spec.json',
367-
'projects/foo/e2e/tsconfig.json',
368-
]);
369-
});
370333
});
371334

372335
describe('custom projectRoot', () => {
@@ -380,7 +343,6 @@ describe('Application Schematic', () => {
380343
'/karma.conf.js',
381344
'/tsconfig.app.json',
382345
'/tsconfig.spec.json',
383-
'/tslint.json',
384346
'/src/environments/environment.ts',
385347
'/src/environments/environment.prod.ts',
386348
'/src/favicon.ico',
@@ -448,31 +410,6 @@ describe('Application Schematic', () => {
448410
expect(specTsConfig.files).toEqual(['src/test.ts', 'src/polyfills.ts']);
449411
});
450412

451-
it('should set the relative path and prefix in the tslint file', async () => {
452-
const options = { ...defaultOptions, projectRoot: '' };
453-
454-
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
455-
.toPromise();
456-
const content = JSON.parse(tree.readContent('/tslint.json'));
457-
expect(content.extends).toMatch('tslint:recommended');
458-
expect(content.rules['directive-selector'][2]).toMatch('app');
459-
expect(content.rules['component-selector'][2]).toMatch('app');
460-
});
461-
462-
it('should merge tslint file', async () => {
463-
const options = { ...defaultOptions, projectRoot: '' };
464-
465-
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
466-
.toPromise();
467-
const content = JSON.parse(tree.readContent('/tslint.json'));
468-
expect(content.extends).toMatch('tslint:recommended');
469-
expect(content.rules['component-selector'][2]).toMatch('app');
470-
expect(content.rules['no-console']).toBeDefined();
471-
// codelyzer rules should be after base tslint rules
472-
expect(Object.keys(content.rules).indexOf('component-selector'))
473-
.toBeGreaterThan(Object.keys(content.rules).indexOf('no-console'));
474-
});
475-
476413
it(`should create correct paths when 'newProjectRoot' is blank`, async () => {
477414
const workspaceTree = await schematicRunner.runSchematicAsync('workspace', { ...workspaceOptions, newProjectRoot: '' }).toPromise();
478415
const options = { ...defaultOptions, projectRoot: undefined };

packages/schematics/angular/e2e/index.ts

-7
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ export default function (options: E2eOptions): Rule {
6262
},
6363
});
6464

65-
const e2eTsConfig = `${root}/tsconfig.json`;
66-
const lintTarget = project.targets.get('lint');
67-
if (lintTarget && lintTarget.options && Array.isArray(lintTarget.options.tsConfig)) {
68-
lintTarget.options.tsConfig =
69-
lintTarget.options.tsConfig.concat(e2eTsConfig);
70-
}
71-
7265
return chain([
7366
updateWorkspace(workspace),
7467
mergeWith(

packages/schematics/angular/library/files/tslint.json.template

-17
This file was deleted.

packages/schematics/angular/library/index.ts

-12
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,6 @@ function addLibToWorkspaceFile(
116116
karmaConfig: `${projectRoot}/karma.conf.js`,
117117
},
118118
},
119-
lint: {
120-
builder: Builders.TsLint,
121-
options: {
122-
tsConfig: [
123-
`${projectRoot}/tsconfig.lib.json`,
124-
`${projectRoot}/tsconfig.spec.json`,
125-
],
126-
exclude: [
127-
'**/node_modules/**',
128-
],
129-
},
130-
},
131119
},
132120
});
133121
});

packages/schematics/angular/library/index_spec.ts

-19
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ describe('Library Schematic', () => {
5050
'/projects/foo/ng-package.json',
5151
'/projects/foo/package.json',
5252
'/projects/foo/README.md',
53-
'/projects/foo/tslint.json',
5453
'/projects/foo/tsconfig.lib.json',
5554
'/projects/foo/tsconfig.lib.prod.json',
5655
'/projects/foo/src/test.ts',
@@ -126,15 +125,6 @@ describe('Library Schematic', () => {
126125
expect(workspace.projects.foo.prefix).toEqual('pre');
127126
});
128127

129-
it('should set the right prefix in the tslint file when provided is kebabed', async () => {
130-
const options: GenerateLibrarySchema = { ...defaultOptions, prefix: 'foo-bar' };
131-
const tree = await schematicRunner.runSchematicAsync('library', options, workspaceTree).toPromise();
132-
const path = '/projects/foo/tslint.json';
133-
const content = JSON.parse(tree.readContent(path));
134-
expect(content.rules['directive-selector'][2]).toMatch('fooBar');
135-
expect(content.rules['component-selector'][2]).toMatch('foo-bar');
136-
});
137-
138128
it('should handle a pascalCasedName', async () => {
139129
const options = { ...defaultOptions, name: 'pascalCasedName' };
140130
const tree = await schematicRunner.runSchematicAsync('library', options, workspaceTree).toPromise();
@@ -152,15 +142,6 @@ describe('Library Schematic', () => {
152142
expect(fileContent).toContain('exports: [FooComponent]');
153143
});
154144

155-
it('should set the right path and prefix in the tslint file', async () => {
156-
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree).toPromise();
157-
const path = '/projects/foo/tslint.json';
158-
const content = JSON.parse(tree.readContent(path));
159-
expect(content.extends).toMatch('../../tslint.json');
160-
expect(content.rules['directive-selector'][2]).toMatch('lib');
161-
expect(content.rules['component-selector'][2]).toMatch('lib');
162-
});
163-
164145
describe(`update package.json`, () => {
165146
it(`should add ng-packagr to devDependencies`, async () => {
166147
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree).toPromise();

packages/schematics/angular/universal/index.ts

-5
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,6 @@ function updateConfigFile(options: UniversalOptions, tsConfigDirectory: Path): R
9191
},
9292
configurations,
9393
});
94-
95-
const lintTarget = clientProject.targets.get('lint');
96-
if (lintTarget && lintTarget.options && Array.isArray(lintTarget.options.tsConfig)) {
97-
lintTarget.options.tsConfig = lintTarget.options.tsConfig.concat(serverTsConfig);
98-
}
9994
}
10095
});
10196
}

packages/schematics/angular/utility/workspace-models.ts

-7
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,6 @@ export interface TestBuilderOptions extends Partial<BrowserBuilderBaseOptions> {
9898
karmaConfig: string;
9999
}
100100

101-
export interface LintBuilderOptions {
102-
tsConfig: string[] | string;
103-
exclude?: string[];
104-
}
105-
106101
export interface ExtractI18nOptions {
107102
browserTarget: string;
108103
}
@@ -125,7 +120,6 @@ export type LibraryBuilderTarget = BuilderTarget<Builders.NgPackagr, LibraryBuil
125120
export type BrowserBuilderTarget = BuilderTarget<Builders.Browser, BrowserBuilderOptions>;
126121
export type ServerBuilderTarget = BuilderTarget<Builders.Server, ServerBuilderOptions>;
127122
export type AppShellBuilderTarget = BuilderTarget<Builders.AppShell, AppShellBuilderOptions>;
128-
export type LintBuilderTarget = BuilderTarget<Builders.TsLint, LintBuilderOptions>;
129123
export type TestBuilderTarget = BuilderTarget<Builders.Karma, TestBuilderOptions>;
130124
export type ServeBuilderTarget = BuilderTarget<Builders.DevServer, ServeBuilderOptions>;
131125
export type ExtractI18nBuilderTarget = BuilderTarget<Builders.ExtractI18n, ExtractI18nOptions>;
@@ -165,7 +159,6 @@ export interface WorkspaceProject<TProjectType extends ProjectType = ProjectType
165159
export interface WorkspaceTargets<TProjectType extends ProjectType = ProjectType.Application> {
166160
build?: TProjectType extends ProjectType.Library ? LibraryBuilderTarget : BrowserBuilderTarget;
167161
server?: ServerBuilderTarget;
168-
lint?: LintBuilderTarget;
169162
test?: TestBuilderTarget;
170163
serve?: ServeBuilderTarget;
171164
e2e?: E2EBuilderTarget;

packages/schematics/angular/web-worker/index.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { JSONFile } from '../utility/json-file';
2020
import { parseName } from '../utility/parse-name';
2121
import { relativePathToWorkspaceRoot } from '../utility/paths';
2222
import { buildDefaultPath, getWorkspace, updateWorkspace } from '../utility/workspace';
23-
import { BrowserBuilderOptions, LintBuilderOptions } from '../utility/workspace-models';
23+
import { BrowserBuilderOptions } from '../utility/workspace-models';
2424
import { Schema as WebWorkerOptions } from './schema';
2525

2626

@@ -135,13 +135,6 @@ export default function (options: WebWorkerOptions): Rule {
135135
if (needWebWorkerConfig) {
136136
const workerConfigPath = join(normalize(root), 'tsconfig.worker.json');
137137
projectTargetOptions.webWorkerTsConfig = workerConfigPath;
138-
139-
// add worker tsconfig to lint architect target
140-
const lintTarget = project.targets.get('lint');
141-
if (lintTarget) {
142-
const lintOptions = (lintTarget.options || {}) as unknown as LintBuilderOptions;
143-
lintOptions.tsConfig = (lintOptions.tsConfig || []).concat(workerConfigPath);
144-
}
145138
}
146139

147140
const templateSource = apply(url('./files/worker'), [

0 commit comments

Comments
 (0)