1
- import * as chalk from 'chalk' ;
2
- import * as fs from 'fs' ;
3
- import * as os from 'os' ;
4
- import * as path from 'path' ;
1
+ import { cyan , yellow } from 'chalk' ;
2
+ const stringUtils = require ( 'ember-cli-string-utils' ) ;
5
3
import { oneLine } from 'common-tags' ;
6
4
import { CliConfig } from '../models/config' ;
7
5
6
+ import 'rxjs/add/observable/of' ;
7
+ import 'rxjs/add/operator/ignoreElements' ;
8
+ import {
9
+ getCollection ,
10
+ getEngineHost
11
+ } from '../utilities/schematics' ;
12
+ import { DynamicPathOptions , dynamicPathParser } from '../utilities/dynamic-path-parser' ;
13
+ import { getAppFromConfig } from '../utilities/app-utils' ;
14
+ import * as path from 'path' ;
15
+ import { SchematicAvailableOptions } from '../tasks/schematic-get-options' ;
16
+
8
17
const Command = require ( '../ember-cli/lib/models/command' ) ;
9
- const Blueprint = require ( '../ember-cli/lib/models/blueprint' ) ;
10
- const parseOptions = require ( '../ember-cli/lib/utilities/parse-options' ) ;
11
18
const SilentError = require ( 'silent-error' ) ;
12
19
13
- function loadBlueprints ( ) : Array < any > {
14
- const blueprintList = fs . readdirSync ( path . join ( __dirname , '..' , 'blueprints' ) ) ;
15
- const blueprints = blueprintList
16
- . filter ( bp => bp . indexOf ( '-test' ) === - 1 )
17
- . filter ( bp => bp !== 'ng' )
18
- . map ( bp => Blueprint . load ( path . join ( __dirname , '..' , 'blueprints' , bp ) ) ) ;
19
-
20
- return blueprints ;
21
- }
22
20
23
21
export default Command . extend ( {
24
22
name : 'generate' ,
25
- description : 'Generates and/or modifies files based on a blueprint .' ,
23
+ description : 'Generates and/or modifies files based on a schematic .' ,
26
24
aliases : [ 'g' ] ,
27
25
28
26
availableOptions : [
@@ -34,117 +32,131 @@ export default Command.extend({
34
32
description : 'Run through without making any changes.'
35
33
} ,
36
34
{
37
- name : 'lint-fix ' ,
35
+ name : 'force ' ,
38
36
type : Boolean ,
39
- aliases : [ 'lf' ] ,
40
- description : 'Use lint to fix files after generation.'
37
+ default : false ,
38
+ aliases : [ 'f' ] ,
39
+ description : 'Forces overwriting of files.'
40
+ } ,
41
+ {
42
+ name : 'app' ,
43
+ type : String ,
44
+ aliases : [ 'a' ] ,
45
+ description : 'Specifies app name to use.'
46
+ } ,
47
+ {
48
+ name : 'collection' ,
49
+ type : String ,
50
+ aliases : [ 'c' ] ,
51
+ description : 'Schematics collection to use.'
41
52
} ,
42
53
{
43
- name : 'verbose ' ,
54
+ name : 'lint-fix ' ,
44
55
type : Boolean ,
45
- default : false ,
46
- aliases : [ 'v' ] ,
47
- description : 'Adds more details to output logging.'
56
+ aliases : [ 'lf' ] ,
57
+ description : 'Use lint to fix files after generation.'
48
58
}
49
59
] ,
50
60
51
61
anonymousOptions : [
52
- '<blueprint >'
62
+ '<schematic >'
53
63
] ,
54
64
55
- beforeRun : function ( rawArgs : string [ ] ) {
56
- if ( ! rawArgs . length ) {
57
- return ;
65
+ getCollectionName ( rawArgs : string [ ] ) {
66
+ let collectionName = CliConfig . getValue ( 'defaults.schematics.collection' )
67
+ if ( rawArgs ) {
68
+ const parsedArgs = this . parseArgs ( rawArgs , false ) ;
69
+ if ( parsedArgs . options . collection ) {
70
+ collectionName = parsedArgs . options . collection ;
71
+ }
58
72
}
73
+ return collectionName ;
74
+ } ,
75
+
76
+ beforeRun : function ( rawArgs : string [ ] ) {
59
77
60
78
const isHelp = [ '--help' , '-h' ] . includes ( rawArgs [ 0 ] ) ;
61
79
if ( isHelp ) {
62
80
return ;
63
81
}
64
82
65
- this . blueprints = loadBlueprints ( ) ;
66
-
67
- const name = rawArgs [ 0 ] ;
68
- const blueprint = this . blueprints . find ( ( bp : any ) => bp . name === name
69
- || ( bp . aliases && bp . aliases . includes ( name ) ) ) ;
70
-
71
- if ( ! blueprint ) {
72
- SilentError . debugOrThrow ( '@angular/cli/commands/generate' ,
73
- `Invalid blueprint: ${ name } ` ) ;
74
- }
75
-
76
- if ( ! rawArgs [ 1 ] ) {
77
- SilentError . debugOrThrow ( '@angular/cli/commands/generate' ,
78
- `The \`ng generate ${ name } \` command requires a name to be specified.` ) ;
83
+ const schematicName = rawArgs [ 0 ] ;
84
+ if ( ! schematicName ) {
85
+ return Promise . reject ( new SilentError ( oneLine `
86
+ The "ng generate" command requires a
87
+ schematic name to be specified.
88
+ For more details, use "ng help".
89
+ ` ) ) ;
79
90
}
80
91
81
92
if ( / ^ \d / . test ( rawArgs [ 1 ] ) ) {
82
93
SilentError . debugOrThrow ( '@angular/cli/commands/generate' ,
83
- `The \`ng generate ${ name } ${ rawArgs [ 1 ] } \` file name cannot begin with a digit.` ) ;
94
+ `The \`ng generate ${ schematicName } ${ rawArgs [ 1 ] } \` file name cannot begin with a digit.` ) ;
84
95
}
85
96
86
- rawArgs [ 0 ] = blueprint . name ;
87
- this . registerOptions ( blueprint ) ;
88
- } ,
97
+ const SchematicGetOptionsTask = require ( '../tasks/schematic-get-options' ) . default ;
89
98
90
- printDetailedHelp : function ( ) {
91
- if ( ! this . blueprints ) {
92
- this . blueprints = loadBlueprints ( ) ;
93
- }
94
- this . ui . writeLine ( chalk . cyan ( ' Available blueprints' ) ) ;
95
- this . ui . writeLine ( this . blueprints . map ( ( bp : any ) => bp . printBasicHelp ( false ) ) . join ( os . EOL ) ) ;
99
+ const getOptionsTask = new SchematicGetOptionsTask ( {
100
+ ui : this . ui ,
101
+ project : this . project
102
+ } ) ;
103
+
104
+ return getOptionsTask . run ( {
105
+ schematicName,
106
+ collectionName : this . getCollectionName ( rawArgs )
107
+ } )
108
+ . then ( ( availableOptions : SchematicAvailableOptions ) => {
109
+ this . registerOptions ( {
110
+ availableOptions : availableOptions
111
+ } ) ;
112
+ } ) ;
96
113
} ,
97
114
98
115
run : function ( commandOptions : any , rawArgs : string [ ] ) {
99
- const name = rawArgs [ 0 ] ;
100
- if ( ! name ) {
101
- return Promise . reject ( new SilentError ( oneLine `
102
- The "ng generate" command requires a
103
- blueprint name to be specified.
104
- For more details, use "ng help".
105
- ` ) ) ;
116
+ if ( rawArgs [ 0 ] === 'module' && ! rawArgs [ 1 ] ) {
117
+ throw 'The `ng generate module` command requires a name to be specified.' ;
106
118
}
107
119
108
- const blueprint = this . blueprints . find ( ( bp : any ) => bp . name === name
109
- || ( bp . aliases && bp . aliases . includes ( name ) ) ) ;
110
-
111
- const projectName = CliConfig . getValue ( 'project.name' ) ;
112
- const blueprintOptions = {
113
- target : this . project . root ,
114
- entity : {
115
- name : rawArgs [ 1 ] ,
116
- options : parseOptions ( rawArgs . slice ( 2 ) )
117
- } ,
118
- projectName,
119
- ui : this . ui ,
120
+ const entityName = rawArgs [ 1 ] ;
121
+ commandOptions . name = stringUtils . dasherize ( entityName . split ( path . sep ) . pop ( ) ) ;
122
+
123
+ const appConfig = getAppFromConfig ( commandOptions . app ) ;
124
+ const dynamicPathOptions : DynamicPathOptions = {
120
125
project : this . project ,
121
- settings : this . settings ,
122
- testing : this . testing ,
123
- args : rawArgs ,
124
- ...commandOptions
126
+ entityName : entityName ,
127
+ appConfig : appConfig ,
128
+ dryRun : commandOptions . dryRun
125
129
} ;
130
+ const parsedPath = dynamicPathParser ( dynamicPathOptions ) ;
131
+ commandOptions . sourceDir = appConfig . root ;
132
+ commandOptions . path = parsedPath . dir . replace ( appConfig . root + path . sep , '' ) ;
126
133
127
- return blueprint . install ( blueprintOptions )
128
- . then ( ( ) => {
129
- const lintFix = commandOptions . lintFix !== undefined ?
130
- commandOptions . lintFix : CliConfig . getValue ( 'defaults.lintFix' ) ;
131
-
132
- if ( lintFix && blueprint . modifiedFiles ) {
133
- const LintTask = require ( '../tasks/lint' ) . default ;
134
- const lintTask = new LintTask ( {
135
- ui : this . ui ,
136
- project : this . project
137
- } ) ;
138
-
139
- return lintTask . run ( {
140
- fix : true ,
141
- force : true ,
142
- silent : true ,
143
- configs : [ {
144
- files : blueprint . modifiedFiles . filter ( ( file : string ) => / .t s $ / . test ( file ) )
145
- } ]
146
- } ) ;
147
- }
148
- } ) ;
134
+ const cwd = this . project . root ;
135
+ const schematicName = rawArgs [ 0 ] ;
136
+
137
+ const SchematicRunTask = require ( '../tasks/schematic-run' ) . default ;
138
+ const schematicRunTask = new SchematicRunTask ( {
139
+ ui : this . ui ,
140
+ project : this . project
141
+ } ) ;
142
+
143
+ return schematicRunTask . run ( {
144
+ taskOptions : commandOptions ,
145
+ workingDir : cwd ,
146
+ collectionName : this . getCollectionName ( rawArgs ) ,
147
+ schematicName
148
+ } )
149
+ } ,
150
+
151
+ printDetailedHelp : function ( ) {
152
+ const engineHost = getEngineHost ( ) ;
153
+ const collectionName = this . getCollectionName ( ) ;
154
+ const collection = getCollection ( collectionName ) ;
155
+ const schematicNames : string [ ] = engineHost . listSchematics ( collection ) ;
156
+ this . ui . writeLine ( cyan ( 'Available schematics:' ) ) ;
157
+ schematicNames . forEach ( schematicName => {
158
+ this . ui . writeLine ( yellow ( ` ${ schematicName } ` ) ) ;
159
+ } ) ;
160
+ this . ui . writeLine ( '' ) ;
149
161
}
150
162
} ) ;
0 commit comments