Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 327e71a

Browse filesBrowse files
committed
feat(@schematics/angular): tslint migration for 8
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
1 parent 4a093e5 commit 327e71a
Copy full SHA for 327e71a

4 files changed

+216Lines changed: 216 additions & 0 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎packages/schematics/angular/migrations/migration-collection.json‎

Copy file name to clipboardExpand all lines: packages/schematics/angular/migrations/migration-collection.json
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"version": "7.0.3",
3030
"factory": "./update-7/index#updateDevkitBuildNgPackagr",
3131
"description": "Update an Angular CLI project to version 7."
32+
},
33+
"migration-07": {
34+
"version": "8.0.0",
35+
"factory": "./update-8",
36+
"description": "Update an Angular CLI project to version 8."
3237
}
3338
}
3439
}
Collapse file
+124Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { JsonParseMode, Path, normalize, parseJson, parseJsonAst } from '@angular-devkit/core';
9+
import {
10+
Rule,
11+
SchematicContext,
12+
SchematicsException,
13+
Tree,
14+
chain,
15+
} from '@angular-devkit/schematics';
16+
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
17+
import { CliConfig } from '../../utility/config';
18+
import {
19+
NodeDependency,
20+
NodeDependencyType,
21+
addPackageJsonDependency,
22+
} from '../../utility/dependencies';
23+
import { findPropertyInAstObject } from '../../utility/json-utils';
24+
25+
const ruleMapping: {[key: string]: string} = {
26+
'contextual-life-cycle': 'contextual-lifecycle',
27+
'no-conflicting-life-cycle-hooks': 'no-conflicting-lifecycle',
28+
'no-life-cycle-call': 'no-lifecycle-call',
29+
'use-life-cycle-interface': 'use-lifecycle-interface',
30+
'decorator-not-allowed': 'contextual-decorator',
31+
'enforce-component-selector': 'use-component-selector',
32+
'no-output-named-after-standard-event': 'no-output-native',
33+
'use-host-property-decorator': 'no-host-metadata-property',
34+
'use-input-property-decorator': 'no-inputs-metadata-property',
35+
'use-output-property-decorator': 'no-outputs-metadata-property',
36+
'no-queries-parameter': 'no-queries-metadata-property',
37+
'pipe-impure': 'no-pipe-impure',
38+
'use-view-encapsulation': 'use-component-view-encapsulation',
39+
i18n: 'template-i18n',
40+
'banana-in-box': 'template-banana-in-box',
41+
'no-template-call-expression': 'template-no-call-expression',
42+
'templates-no-negated-async': 'template-no-negated-async',
43+
'trackBy-function': 'template-use-track-by-function',
44+
'no-attribute-parameter-decorator': 'no-attribute-decorator',
45+
'max-inline-declarations': 'component-max-inline-declarations',
46+
};
47+
48+
function updateTsLintConfig(): Rule {
49+
return (host: Tree) => {
50+
const tsLintPath = '/tslint.json';
51+
const buffer = host.read(tsLintPath);
52+
if (!buffer) {
53+
return host;
54+
}
55+
const tsCfgAst = parseJsonAst(buffer.toString(), JsonParseMode.Loose);
56+
57+
if (tsCfgAst.kind != 'object') {
58+
return host;
59+
}
60+
61+
const rulesNode = findPropertyInAstObject(tsCfgAst, 'rules');
62+
if (!rulesNode || rulesNode.kind != 'object') {
63+
return host;
64+
}
65+
66+
const recorder = host.beginUpdate(tsLintPath);
67+
68+
rulesNode.properties.forEach(prop => {
69+
const mapping = ruleMapping[prop.key.value];
70+
if (mapping) {
71+
recorder.remove(prop.key.start.offset + 1, prop.key.value.length);
72+
recorder.insertLeft(prop.key.start.offset + 1, mapping);
73+
}
74+
});
75+
76+
host.commitUpdate(recorder);
77+
78+
return host;
79+
};
80+
}
81+
82+
function updatePackageJson(config: CliConfig) {
83+
return (host: Tree, context: SchematicContext) => {
84+
const dependency: NodeDependency = {
85+
type: NodeDependencyType.Dev,
86+
name: 'codelyzer',
87+
version: '^5.0.0',
88+
overwrite: true,
89+
};
90+
91+
addPackageJsonDependency(host, dependency);
92+
93+
return host;
94+
};
95+
}
96+
97+
function getConfigPath(tree: Tree): Path {
98+
const possiblePath = normalize('angular.json');
99+
if (tree.exists(possiblePath)) {
100+
return possiblePath;
101+
}
102+
103+
throw new SchematicsException('Could not find configuration file');
104+
}
105+
106+
export default function(): Rule {
107+
return (host: Tree) => {
108+
const configPath = getConfigPath(host);
109+
const configBuffer = host.read(normalize(configPath));
110+
if (configBuffer == null) {
111+
throw new SchematicsException(`Could not find configuration file (${configPath})`);
112+
}
113+
114+
const config = parseJson(configBuffer.toString(), JsonParseMode.Loose);
115+
if (typeof config != 'object' || Array.isArray(config) || config === null) {
116+
throw new SchematicsException('Invalid angular.json configuration; expected an object.');
117+
}
118+
119+
return chain([
120+
updateTsLintConfig(),
121+
updatePackageJson(config),
122+
]);
123+
};
124+
}
Collapse file
+85Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
// tslint:disable:no-big-function
9+
import { EmptyTree } from '@angular-devkit/schematics';
10+
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
11+
12+
const renames = [
13+
'use-lifecycle-interface',
14+
'no-host-metadata-property',
15+
'no-outputs-metadata-property',
16+
'no-inputs-metadata-property',
17+
];
18+
19+
describe('Migration to version 8', () => {
20+
const schematicRunner = new SchematicTestRunner(
21+
'migrations',
22+
require.resolve('../migration-collection.json'),
23+
);
24+
25+
let tree: UnitTestTree;
26+
const tslintPath = '/tslint.json';
27+
const packageJsonPath = '/package.json';
28+
const baseConfig = {};
29+
const defaultOptions = {};
30+
const configPath = `/angular-cli.json`;
31+
const tslintConfig = {
32+
rules: {
33+
'directive-selector': [
34+
true,
35+
'attribute',
36+
'app',
37+
'camelCase',
38+
],
39+
'component-selector': [
40+
true,
41+
'element',
42+
'app',
43+
'kebab-case',
44+
],
45+
'no-output-on-prefix': true,
46+
'use-input-property-decorator': true,
47+
'use-output-property-decorator': true,
48+
'use-host-property-decorator': true,
49+
'no-input-rename': true,
50+
'no-output-rename': true,
51+
'use-life-cycle-interface': true,
52+
'use-pipe-transform-interface': true,
53+
'component-class-suffix': true,
54+
'directive-class-suffix': true,
55+
},
56+
};
57+
const packageJson = {
58+
devDependencies: {
59+
codelyzer: '^4.5.0',
60+
},
61+
};
62+
63+
describe('tslint.json', () => {
64+
beforeEach(() => {
65+
tree = new UnitTestTree(new EmptyTree());
66+
tree.create(configPath, JSON.stringify(baseConfig, null, 2));
67+
tree.create(packageJsonPath, JSON.stringify(packageJson, null, 2));
68+
tree.create(tslintPath, JSON.stringify(tslintConfig, null, 2));
69+
});
70+
71+
it('should rename all previous rules', () => {
72+
tree = schematicRunner.runSchematic('migration-07', defaultOptions, tree);
73+
const tslint = JSON.parse(tree.readContent(tslintPath));
74+
for (const rule of renames) {
75+
expect(rule in tslint.rules).toBeTruthy(`Rule ${rule} not renamed`);
76+
}
77+
});
78+
79+
it('should update codelyzer\'s version', () => {
80+
tree = schematicRunner.runSchematic('migration-07', defaultOptions, tree);
81+
const packageJson = JSON.parse(tree.readContent(packageJsonPath));
82+
expect(packageJson.devDependencies.codelyzer).toBe('^5.0.0');
83+
});
84+
});
85+
});
Collapse file

‎scripts/test.ts‎

Copy file name to clipboardExpand all lines: scripts/test.ts
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ export default function (args: ParsedArgs, logger: logging.Logger) {
213213
logger.info(`Found ${tests.length} spec files, out of ${allTests.length}.`);
214214
}
215215

216+
tests = tests.filter(e => e.endsWith('update-8/index_spec.ts'));
217+
216218
if (args.shard !== undefined) {
217219
// Remove tests that are not part of this shard.
218220
const shardId = args['shard'];

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.