1
- import { build , fs , IParameters , http , install } from '../index'
1
+ import { build , fs , IParameters , http , install , logger , strings } from '../index'
2
2
import { parseParams } from '../toolbox/parameter-tools'
3
3
import * as path from 'path'
4
4
5
5
const debug = require ( 'debug' ) ( 'weex:core' )
6
6
7
- // export class Cli {
8
- // private cli: any;
9
- // constructor(options: {
10
- // brand?: string
11
- // help?: any
12
- // defaultCommand?: any
13
- // version?: any
14
- // plugin?: {
15
- // value?: string
16
- // options?: any
17
- // }
18
- // plugins?: {
19
- // value?: string
20
- // options?: any
21
- // }
22
- // exclude?: string[]
23
- // } = {}) {
24
- // // create a CLI runtime
25
- // this.cli = build(options.brand || 'weex')
26
- // .src(__dirname)
27
- // .help(options.help)
28
- // .version(options.version)
29
- // .exclude(options.exclude)
30
- // .defaultCommand(options.defaultCommand);
31
-
32
- // if (options.plugins && options.plugins.value) {
33
- // this.cli = this.cli.plugins(options.plugins.value, options.plugins.options)
34
- // }
35
-
36
- // if (options.plugin) {
37
- // if (Array.isArray(options.plugin)) {
38
- // options.plugin.forEach(p => {
39
- // this.cli = this.cli.plugin(p.value, p.options)
40
- // })
41
- // }
42
- // else {
43
- // this.cli = this.cli.plugin(options.plugin.value, options.plugin.options)
44
- // }
45
- // }
46
- // }
47
-
48
- // async start(argv?: string[] | string) {
49
- // const params = parseParams(argv);
50
- // // run the cli
51
- // const toolbox = await this.cli.run(argv)
52
- // // send it back (for testing, mostly)
53
- // return toolbox
54
- // }
55
- // }
56
7
enum ModType {
57
8
PLUGIN ,
58
9
EXTENSION ,
@@ -150,23 +101,40 @@ export class Cli {
150
101
}
151
102
152
103
async start ( ) {
153
- // run the cli
154
- // const toolbox = await this.cli.run(this.rawArgv)
155
- // // send it back (for testing, mostly)
156
- // return toolbox
157
104
const command = this . argv . array [ 0 ]
158
-
159
105
if ( this . cliOptions . modules ) {
160
106
this . plugins = this . pickPlugins ( this . cliOptions . modules )
161
107
} else {
162
- fs . file ( path . join ( this . cliOptions . moduleRoot , this . cliOptions . moduleName ) , {
163
- mode : '777' ,
164
- jsonIndent : 2 ,
165
- content : JSON . stringify ( { mods : { } , last_update_time : new Date ( ) . getTime ( ) } ) ,
166
- } )
108
+ fs . write ( path . join ( this . cliOptions . moduleRoot , this . cliOptions . moduleName ) , { mods : { } , last_update_time : new Date ( ) . getTime ( ) } )
167
109
}
110
+ if ( command === 'repair' ) {
111
+ debug ( `Do repair` ) ;
112
+ const repairModule = this . argv . array [ 1 ] ;
113
+ let repairName ;
114
+ let repairVersion ;
115
+ if ( repairModule ) {
116
+ const args = repairModule . split ( '@' )
117
+ if ( repairModule . slice ( 0 , 1 ) === '@' ) {
118
+
119
+ }
120
+ else {
168
121
169
- if ( command ) {
122
+ }
123
+ try {
124
+ await this . repairPackage ( repairModule ) ;
125
+ debug ( `repair ${ repairModule } successed!` ) ;
126
+ logger . success ( `\nRepair ${ repairModule } successed!` )
127
+ }
128
+ catch ( e ) {
129
+ this . analyzer ( 'repair' , e . stack , { module : repairModule } )
130
+ }
131
+ }
132
+ else {
133
+ logger . error ( 'Need to specify the repaired module' )
134
+ }
135
+ return ;
136
+ }
137
+ else if ( command ) {
170
138
const plugin = this . searchPlugin ( command , this . plugins )
171
139
let commands = [ ]
172
140
let type = ModType . EXTENSION
@@ -175,7 +143,6 @@ export class Cli {
175
143
if ( ! res . error ) {
176
144
const packages : any = await this . installPackage ( `@weex-cli/${ command } ` , 'latest' , {
177
145
root : this . cliOptions . moduleRoot ,
178
- trash : this . cliOptions . trash ,
179
146
registry : this . cliOptions . registry ,
180
147
} )
181
148
for ( let i = 0 ; i < packages . length ; i ++ ) {
@@ -216,11 +183,7 @@ export class Cli {
216
183
}
217
184
}
218
185
// update module file
219
- fs . file ( path . join ( this . cliOptions . moduleRoot , this . cliOptions . moduleName ) , {
220
- mode : '777' ,
221
- jsonIndent : 2 ,
222
- content : JSON . stringify ( { mods : this . cliOptions . modules . mods , last_update_time : new Date ( ) . getTime ( ) } ) ,
223
- } )
186
+ fs . write ( path . join ( this . cliOptions . moduleRoot , this . cliOptions . moduleName ) , { mods : this . cliOptions . modules . mods , last_update_time : new Date ( ) . getTime ( ) } )
224
187
}
225
188
}
226
189
if ( this . plugins . length > 0 ) {
@@ -229,13 +192,83 @@ export class Cli {
229
192
} )
230
193
}
231
194
}
195
+
232
196
// run the cli
233
197
const toolbox = await this . cli . create ( ) . run ( this . rawArgv )
234
198
// send it back (for testing, mostly)
235
199
return toolbox
236
200
}
237
201
238
- async installPackage ( name , version , options , result = [ ] ) {
202
+ async repairPackage ( mod : string ) {
203
+ let modVersion ;
204
+ let modName ;
205
+ let commands = [ ] ;
206
+ let type = ModType . EXTENSION ;
207
+ const first = mod . slice ( 0 , 1 ) ;
208
+ // check for origin npm package
209
+ if ( first === '@' ) {
210
+ const arg = mod . split ( '@' ) ;
211
+ if ( arg . length > 2 ) {
212
+ modVersion = arg . pop ( ) ;
213
+ modName = arg . join ( '@' ) ;
214
+ }
215
+ else {
216
+ modName = arg . join ( '@' ) ;
217
+ modVersion = 'latest' ;
218
+ }
219
+ }
220
+ else {
221
+ const arg = mod . split ( '@' ) ;
222
+ if ( arg . length > 1 ) {
223
+ modVersion = arg . pop ( ) ;
224
+ modName = arg . join ( '@' ) ;
225
+ }
226
+ else {
227
+ modName = arg [ 0 ] ;
228
+ modVersion = 'latest' ;
229
+ }
230
+ }
231
+ const packages : any = await this . installPackage ( modName , modVersion , {
232
+ root : this . cliOptions . moduleRoot ,
233
+ registry : this . cliOptions . registry ,
234
+ } )
235
+ for ( let i = 0 ; i < packages . length ; i ++ ) {
236
+ const commandBasePath = path . join ( packages [ i ] . root , 'commands' )
237
+ const commandFiles : string [ ] = fs . list ( commandBasePath ) || [ ]
238
+ commandFiles . forEach ( file => {
239
+ let content
240
+ try {
241
+ content = require ( path . join ( commandBasePath , file ) )
242
+ } catch ( e ) {
243
+ debug ( `Check module error with: ${ e . stack } ` )
244
+ // try prev version
245
+ }
246
+ commands . push ( {
247
+ name : content . name || '' ,
248
+ alias : content . alias || '' ,
249
+ showed : typeof content . dashed === 'boolean' ? ! content . dashed : true ,
250
+ description : content . description || '' ,
251
+ } )
252
+ type = ModType . PLUGIN
253
+ } )
254
+ if ( commands . length > 0 ) {
255
+ this . cliOptions . modules . mods [ packages [ i ] . package . name ] = {
256
+ type : type ,
257
+ version : packages [ i ] . package . version ,
258
+ next_version : '' ,
259
+ is_next : true ,
260
+ changelog : packages [ i ] . changelog || '' ,
261
+ local : packages [ i ] . root ,
262
+ commands : commands ,
263
+ }
264
+ }
265
+ }
266
+ debug ( `save modjson: ${ JSON . stringify ( this . cliOptions . modules . mods ) } ` )
267
+ // update module file
268
+ fs . write ( path . join ( this . cliOptions . moduleRoot , this . cliOptions . moduleName ) , { mods : this . cliOptions . modules . mods , last_update_time : new Date ( ) . getTime ( ) } )
269
+ }
270
+
271
+ async installPackage ( name : string , version : string , options : any , result :any = [ ] ) {
239
272
const info : any = await install ( name , version || 'latest' , options )
240
273
if ( Array . isArray ( info . package . extensionDependencies ) ) {
241
274
let len = info . package . extensionDependencies . length
@@ -247,14 +280,48 @@ export class Cli {
247
280
return [ info ]
248
281
}
249
282
250
- async suggestPackage ( command , registry ) {
283
+ async suggestPackage ( command : string , registry : string ) {
251
284
const npmApi = http . create ( {
252
285
baseURL : `${ registry } /@weex-cli/` ,
253
286
} )
254
287
const res = await npmApi . get ( `${ command } ` )
255
288
return res . data
256
289
}
257
290
291
+ async analyzer ( type : string , stack : string , options ?: any ) {
292
+ if ( type === 'repair' ) {
293
+ if ( / 4 0 4 s t a t u s / . test ( stack ) ) {
294
+ const innerMods = [
295
+ '@weex-cli/debug' ,
296
+ '@weex-cli/generator' ,
297
+ '@weex-cli/build' ,
298
+ '@weex-cli/preview'
299
+ ]
300
+ let score ;
301
+ let tempScore ;
302
+ let suggestName ;
303
+ innerMods . forEach ( mod => {
304
+ tempScore = strings . strSimilarity2Number ( mod , options . module ) ;
305
+ if ( ! score ) {
306
+ score = tempScore ;
307
+ suggestName = mod ;
308
+ }
309
+ else if ( tempScore < score ) {
310
+ score = tempScore ;
311
+ suggestName = mod ;
312
+ }
313
+ } )
314
+ logger . warn ( `Module "${ options . module } " not found, do you mean "${ suggestName } "?` )
315
+ }
316
+ }
317
+ else {
318
+ const logPath = path . join ( process . cwd ( ) , '.weex-error.log' )
319
+ fs . write ( logPath , stack ) ;
320
+ logger . warn ( `Unkown issue, see error stack on logPath.` )
321
+ logger . warn ( `To fix this, you can create a issue on https://github.com/weexteam/weex-toolkit/issues.` )
322
+ }
323
+ }
324
+
258
325
pickPlugins ( modules : ModData ) : PluginItem [ ] {
259
326
if ( ! modules ) return [ ]
260
327
let plugins = [ ]
@@ -271,14 +338,20 @@ export class Cli {
271
338
}
272
339
273
340
searchPlugin ( command : string , mods : PluginItem [ ] ) : PluginItem | boolean {
274
- mods . forEach ( ( mod : PluginItem ) => {
275
- mod . commands . forEach ( cmd => {
276
- if ( cmd . name === command || cmd . alias === command ) {
277
- return mod
278
- }
341
+ if ( mods . length > 0 ) {
342
+ let result
343
+ mods . forEach ( ( mod : PluginItem ) => {
344
+ mod . commands . forEach ( cmd => {
345
+ if ( cmd . name === command || cmd . alias === command ) {
346
+ result = mod
347
+ }
348
+ } )
279
349
} )
280
- } )
281
- return false
350
+ return result ;
351
+ } else {
352
+ return false
353
+ }
354
+
282
355
}
283
356
}
284
357
0 commit comments