Skip to content

Commit 8b220a4

Browse files
delastevefilipesilva
authored andcommitted
feat(@angular/cli): add import flag to modules
closes #5377
1 parent 3d9a7ff commit 8b220a4

File tree

4 files changed

+112
-6
lines changed

4 files changed

+112
-6
lines changed

docs/documentation/generate/module.md

+12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
</p>
2727
</details>
2828

29+
<details>
30+
<summary>module</summary>
31+
<p>
32+
<code>--module</code> (aliases: <code>-m</code>)
33+
</p>
34+
<p>
35+
Specifies where the module should be imported.
36+
</p>
37+
</details>
38+
2939
<details>
3040
<summary>spec</summary>
3141
<p>
@@ -45,3 +55,5 @@
4555
Specifies if a routing module file should be generated.
4656
</p>
4757
</details>
58+
59+

packages/@angular/cli/blueprints/module/index.ts

+56-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import {CliConfig} from '../../models/config';
2-
import {getAppFromConfig} from '../../utilities/app-utils';
3-
import {dynamicPathParser} from '../../utilities/dynamic-path-parser';
1+
import * as chalk from 'chalk';
2+
import * as path from 'path';
3+
import { oneLine } from 'common-tags';
4+
import { NodeHost } from '../../lib/ast-tools';
5+
import { CliConfig } from '../../models/config';
6+
import { getAppFromConfig } from '../../utilities/app-utils';
7+
import { resolveModulePath } from '../../utilities/resolve-module-file';
8+
import { dynamicPathParser } from '../../utilities/dynamic-path-parser';
49

5-
const path = require('path');
6-
const Blueprint = require('../../ember-cli/lib/models/blueprint');
10+
const stringUtils = require('ember-cli-string-utils');
11+
const Blueprint = require('../../ember-cli/lib/models/blueprint');
12+
const astUtils = require('../../utilities/ast-utils');
713
const getFiles = Blueprint.prototype.files;
814

915
export default Blueprint.extend({
@@ -32,9 +38,22 @@ export default Blueprint.extend({
3238
type: String,
3339
aliases: ['a'],
3440
description: 'Specifies app name to use.'
41+
},
42+
{
43+
name: 'module',
44+
type: String, aliases: ['m'],
45+
description: 'Specifies where the module should be imported.'
3546
}
3647
],
3748

49+
beforeInstall: function(options: any) {
50+
if (options.module) {
51+
const appConfig = getAppFromConfig(this.options.app);
52+
this.pathToModule =
53+
resolveModulePath(options.module, this.project, this.project.root, appConfig);
54+
}
55+
},
56+
3857
normalizeEntityName: function (entityName: string) {
3958
this.entityName = entityName;
4059
const appConfig = getAppFromConfig(this.options.app);
@@ -59,7 +78,7 @@ export default Blueprint.extend({
5978
};
6079
},
6180

62-
files: function() {
81+
files: function () {
6382
let fileList = getFiles.call(this) as Array<string>;
6483

6584
if (!this.options || !this.options.spec) {
@@ -84,5 +103,36 @@ export default Blueprint.extend({
84103
return this.generatePath;
85104
}
86105
};
106+
},
107+
108+
afterInstall(options: any) {
109+
const returns: Array<any> = [];
110+
111+
if (!this.pathToModule) {
112+
const warningMessage = oneLine`
113+
Module is generated but not provided,
114+
it must be provided to be used
115+
`;
116+
this._writeStatusToUI(chalk.yellow, 'WARNING', warningMessage);
117+
} else {
118+
let className = stringUtils.classify(`${options.entity.name}Module`);
119+
let fileName = stringUtils.dasherize(`${options.entity.name}.module`);
120+
if (options.routing) {
121+
className = stringUtils.classify(`${options.entity.name}RoutingModule`);
122+
fileName = stringUtils.dasherize(`${options.entity.name}-routing.module`);
123+
}
124+
const fullGeneratePath = path.join(this.project.root, this.generatePath);
125+
const moduleDir = path.parse(this.pathToModule).dir;
126+
const relativeDir = path.relative(moduleDir, fullGeneratePath);
127+
const importPath = relativeDir ? `./${relativeDir}/${fileName}` : `./${fileName}`;
128+
returns.push(
129+
astUtils.addImportToModule(this.pathToModule, className, importPath)
130+
.then((change: any) => change.apply(NodeHost)));
131+
this._writeStatusToUI(chalk.yellow,
132+
'update',
133+
path.relative(this.project.root, this.pathToModule));
134+
}
135+
136+
return Promise.all(returns);
87137
}
88138
});

packages/@angular/cli/utilities/ast-utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ export {
99
getDecoratorMetadata,
1010
addDeclarationToModule,
1111
addProviderToModule,
12+
addImportToModule,
1213
addExportToModule
1314
} from '../lib/ast-tools';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { join } from 'path';
2+
import { ng } from '../../../utils/process';
3+
import { expectFileToMatch } from '../../../utils/fs';
4+
5+
export default function () {
6+
const modulePath = join('src', 'app', 'app.module.ts');
7+
const subModulePath = join('src', 'app', 'sub', 'sub.module.ts');
8+
const deepSubModulePath = join('src', 'app', 'sub', 'deep', 'deep.module.ts');
9+
10+
return Promise.resolve()
11+
.then(() => ng('generate', 'module', 'sub'))
12+
.then(() => ng('generate', 'module', 'sub/deep'))
13+
14+
.then(() => ng('generate', 'module', 'test1', '--module', 'app.module.ts'))
15+
.then(() => expectFileToMatch(modulePath,
16+
/import { Test1Module } from '.\/test1\/test1.module'/))
17+
.then(() => expectFileToMatch(modulePath, /imports: \[(.|\s)*Test1Module(.|\s)*\]/m))
18+
19+
.then(() => ng('generate', 'module', 'test2', '--module', 'app.module'))
20+
.then(() => expectFileToMatch(modulePath,
21+
/import { Test2Module } from '.\/test2\/test2.module'/))
22+
.then(() => expectFileToMatch(modulePath, /imports: \[(.|\s)*Test2Module(.|\s)*\]/m))
23+
24+
.then(() => ng('generate', 'module', 'test3', '--module', 'app'))
25+
.then(() => expectFileToMatch(modulePath,
26+
/import { Test3Module } from '.\/test3\/test3.module'/))
27+
.then(() => expectFileToMatch(modulePath, /imports: \[(.|\s)*Test3Module(.|\s)*\]/m))
28+
29+
.then(() => ng('generate', 'module', 'test4', '--routing', '--module', 'app'))
30+
.then(() => expectFileToMatch(modulePath,
31+
/import { Test4RoutingModule } from '.\/test4\/test4-routing.module'/))
32+
.then(() => expectFileToMatch(modulePath, /imports: \[(.|\s)*Test4RoutingModule(.|\s)*\]/m))
33+
34+
.then(() => ng('generate', 'module', 'test5', '--module', 'sub'))
35+
.then(() => expectFileToMatch(subModulePath,
36+
/import { Test5Module } from '.\/..\/test5\/test5.module'/))
37+
.then(() => expectFileToMatch(subModulePath, /imports: \[(.|\s)*Test5Module(.|\s)*\]/m))
38+
39+
.then(() => ng('generate', 'module', 'test6', '--module', join('sub', 'deep'))
40+
.then(() => expectFileToMatch(deepSubModulePath,
41+
/import { Test6Module } from '.\/..\/..\/test6\/test6.module'/))
42+
.then(() => expectFileToMatch(deepSubModulePath, /imports: \[(.|\s)*Test6Module(.|\s)*\]/m)));
43+
}

0 commit comments

Comments
 (0)