Skip to content

Commit 2b14ac6

Browse files
clydinalan-agius4
authored andcommitted
refactor(@schematics/angular): use a helper function for basic generation schematics
An internal schematics helper rule has been introduced for Angular schematics that only generate a set of project files from a set of templated files. Multiple current generation schematics contained essentially the same code which increased the sustainment burden and made refactoring and improvements more complicated.
1 parent 4b86f67 commit 2b14ac6

File tree

8 files changed

+117
-287
lines changed

8 files changed

+117
-287
lines changed

packages/schematics/angular/class/index.ts

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
Tree,
13-
apply,
14-
applyTemplates,
15-
chain,
16-
filter,
17-
mergeWith,
18-
move,
19-
noop,
20-
url,
21-
} from '@angular-devkit/schematics';
22-
import { applyLintFix } from '../utility/lint-fix';
23-
import { parseName } from '../utility/parse-name';
24-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2511
import { Schema as ClassOptions } from './schema';
2612

2713
export default function (options: ClassOptions): Rule {
28-
return async (host: Tree) => {
29-
if (options.path === undefined) {
30-
options.path = await createDefaultPath(host, options.project as string);
31-
}
14+
options.type = options.type ? `.${options.type}` : '';
3215

33-
options.type = options.type ? `.${options.type}` : '';
34-
35-
const parsedPath = parseName(options.path, options.name);
36-
options.name = parsedPath.name;
37-
options.path = parsedPath.path;
38-
39-
const templateSource = apply(url('./files'), [
40-
options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
41-
applyTemplates({
42-
...strings,
43-
...options,
44-
}),
45-
move(parsedPath.path),
46-
]);
47-
48-
return chain([
49-
mergeWith(templateSource),
50-
options.lintFix ? applyLintFix(options.path) : noop(),
51-
]);
52-
};
16+
return generateFromFiles(options);
5317
}

packages/schematics/angular/enum/index.ts

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
Tree,
13-
apply,
14-
applyTemplates,
15-
chain,
16-
mergeWith,
17-
move,
18-
noop,
19-
url,
20-
} from '@angular-devkit/schematics';
21-
import { applyLintFix } from '../utility/lint-fix';
22-
import { parseName } from '../utility/parse-name';
23-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2411
import { Schema as EnumOptions } from './schema';
2512

2613
export default function (options: EnumOptions): Rule {
27-
return async (host: Tree) => {
28-
if (options.path === undefined) {
29-
options.path = await createDefaultPath(host, options.project as string);
30-
}
14+
options.type = options.type ? `.${options.type}` : '';
3115

32-
const parsedPath = parseName(options.path, options.name);
33-
options.name = parsedPath.name;
34-
options.path = parsedPath.path;
35-
36-
options.type = options.type ? `.${options.type}` : '';
37-
38-
const templateSource = apply(url('./files'), [
39-
applyTemplates({
40-
...strings,
41-
...options,
42-
}),
43-
move(parsedPath.path),
44-
]);
45-
46-
return chain([
47-
mergeWith(templateSource),
48-
options.lintFix ? applyLintFix(options.path) : noop(),
49-
]);
50-
};
16+
return generateFromFiles(options);
5117
}

packages/schematics/angular/guard/index.ts

Lines changed: 22 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,72 +6,37 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
SchematicsException,
13-
Tree,
14-
apply,
15-
applyTemplates,
16-
chain,
17-
filter,
18-
mergeWith,
19-
move,
20-
noop,
21-
url,
22-
} from '@angular-devkit/schematics';
23-
import { applyLintFix } from '../utility/lint-fix';
24-
import { parseName } from '../utility/parse-name';
25-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule, SchematicsException } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2611
import { Implement as GuardInterface, Schema as GuardOptions } from './schema';
2712

2813
export default function (options: GuardOptions): Rule {
29-
return async (host: Tree) => {
30-
if (options.path === undefined) {
31-
options.path = await createDefaultPath(host, options.project as string);
32-
}
33-
34-
if (!options.implements) {
35-
throw new SchematicsException('Option "implements" is required.');
36-
}
14+
if (!options.implements) {
15+
throw new SchematicsException('Option "implements" is required.');
16+
}
3717

38-
const implementations = options.implements
39-
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
40-
.join(', ');
41-
const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
42-
const routerNamedImports: string[] = [...options.implements, 'UrlTree'];
18+
const implementations = options.implements
19+
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
20+
.join(', ');
21+
const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
22+
const routerNamedImports: string[] = [...options.implements, 'UrlTree'];
4323

44-
if (options.implements.includes(GuardInterface.CanLoad)) {
45-
routerNamedImports.push('Route', 'UrlSegment');
24+
if (options.implements.includes(GuardInterface.CanLoad)) {
25+
routerNamedImports.push('Route', 'UrlSegment');
4626

47-
if (options.implements.length > 1) {
48-
routerNamedImports.push(...commonRouterNameImports);
49-
}
50-
} else {
27+
if (options.implements.length > 1) {
5128
routerNamedImports.push(...commonRouterNameImports);
5229
}
30+
} else {
31+
routerNamedImports.push(...commonRouterNameImports);
32+
}
5333

54-
routerNamedImports.sort();
55-
56-
const implementationImports = routerNamedImports.join(', ');
57-
const parsedPath = parseName(options.path, options.name);
58-
options.name = parsedPath.name;
59-
options.path = parsedPath.path;
34+
routerNamedImports.sort();
6035

61-
const templateSource = apply(url('./files'), [
62-
options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
63-
applyTemplates({
64-
implementations,
65-
implementationImports,
66-
...strings,
67-
...options,
68-
}),
69-
move(parsedPath.path + (options.flat ? '' : '/' + strings.dasherize(options.name))),
70-
]);
36+
const implementationImports = routerNamedImports.join(', ');
7137

72-
return chain([
73-
mergeWith(templateSource),
74-
options.lintFix ? applyLintFix(options.path) : noop(),
75-
]);
76-
};
38+
return generateFromFiles(options, {
39+
implementations,
40+
implementationImports,
41+
});
7742
}

packages/schematics/angular/interceptor/index.ts

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,16 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
Tree,
13-
apply,
14-
applyTemplates,
15-
chain,
16-
filter,
17-
mergeWith,
18-
move,
19-
noop,
20-
url,
21-
} from '@angular-devkit/schematics';
22-
import { applyLintFix } from '../utility/lint-fix';
23-
import { parseName } from '../utility/parse-name';
24-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2511
import { Schema as InterceptorOptions } from './schema';
2612

2713
export default function (options: InterceptorOptions): Rule {
28-
return async (host: Tree) => {
29-
if (options.path === undefined) {
30-
options.path = await createDefaultPath(host, options.project as string);
31-
}
14+
// This schematic uses an older method to implement the flat option
15+
const flat = options.flat;
16+
options.flat = true;
3217

33-
const parsedPath = parseName(options.path, options.name);
34-
options.name = parsedPath.name;
35-
options.path = parsedPath.path;
36-
37-
const templateSource = apply(url('./files'), [
38-
options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
39-
applyTemplates({
40-
...strings,
41-
'if-flat': (s: string) => (options.flat ? '' : s),
42-
...options,
43-
}),
44-
move(parsedPath.path),
45-
]);
46-
47-
return chain([
48-
mergeWith(templateSource),
49-
options.lintFix ? applyLintFix(options.path) : noop(),
50-
]);
51-
};
18+
return generateFromFiles(options, {
19+
'if-flat': (s: string) => (flat ? '' : s),
20+
});
5221
}

packages/schematics/angular/interface/index.ts

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
Tree,
13-
apply,
14-
applyTemplates,
15-
chain,
16-
mergeWith,
17-
move,
18-
noop,
19-
url,
20-
} from '@angular-devkit/schematics';
21-
import { applyLintFix } from '../utility/lint-fix';
22-
import { parseName } from '../utility/parse-name';
23-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2411
import { Schema as InterfaceOptions } from './schema';
2512

2613
export default function (options: InterfaceOptions): Rule {
27-
return async (host: Tree) => {
28-
if (options.path === undefined) {
29-
options.path = await createDefaultPath(host, options.project as string);
30-
}
14+
options.type = options.type ? `.${options.type}` : '';
3115

32-
const parsedPath = parseName(options.path, options.name);
33-
options.name = parsedPath.name;
34-
options.path = parsedPath.path;
35-
36-
options.prefix = options.prefix ? options.prefix : '';
37-
options.type = options.type ? `.${options.type}` : '';
38-
39-
const templateSource = apply(url('./files'), [
40-
applyTemplates({
41-
...strings,
42-
...options,
43-
}),
44-
move(parsedPath.path),
45-
]);
46-
47-
return chain([
48-
mergeWith(templateSource),
49-
options.lintFix ? applyLintFix(options.path) : noop(),
50-
]);
51-
};
16+
return generateFromFiles(options);
5217
}

packages/schematics/angular/resolver/index.ts

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { strings } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
Tree,
13-
apply,
14-
applyTemplates,
15-
chain,
16-
filter,
17-
mergeWith,
18-
move,
19-
noop,
20-
url,
21-
} from '@angular-devkit/schematics';
22-
import { parseName } from '../utility/parse-name';
23-
import { createDefaultPath } from '../utility/workspace';
9+
import { Rule } from '@angular-devkit/schematics';
10+
import { generateFromFiles } from '../utility/generate-from-files';
2411
import { Schema } from './schema';
2512

2613
export default function (options: Schema): Rule {
27-
return async (host: Tree) => {
28-
if (options.path === undefined) {
29-
options.path = await createDefaultPath(host, options.project as string);
30-
}
31-
32-
const parsedPath = parseName(options.path, options.name);
33-
options.name = parsedPath.name;
34-
options.path = parsedPath.path;
35-
36-
const templateSource = apply(url('./files'), [
37-
options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
38-
applyTemplates({
39-
...strings,
40-
...options,
41-
}),
42-
move(parsedPath.path + (options.flat ? '' : '/' + strings.dasherize(options.name))),
43-
]);
44-
45-
return chain([mergeWith(templateSource)]);
46-
};
14+
return generateFromFiles(options);
4715
}

0 commit comments

Comments
 (0)