1
1
import * as fs from 'fs' ;
2
2
import * as path from 'path' ;
3
- import { logging , tags } from '@angular-devkit/core' ;
3
+ import { logging , schema , strings , tags } from '@angular-devkit/core' ;
4
+ import { formats } from '@angular-devkit/schematics' ;
5
+ import {
6
+ NodeModulesEngineHost ,
7
+ validateOptionsWithSchema
8
+ } from '@angular-devkit/schematics/tools' ;
4
9
5
10
export default async function ( ) {
6
11
const commandsPath = __dirname + '/../../../packages/@angular/cli/commands' ;
7
12
const commandFiles = fs . readdirSync ( commandsPath ) ;
8
13
14
+ const engineHost = new NodeModulesEngineHost ( ) ;
15
+ const registry = new schema . CoreSchemaRegistry ( formats . standardFormats ) ;
16
+ engineHost . registerOptionsTransform ( validateOptionsWithSchema ( registry ) ) ;
17
+
9
18
for ( const commandFile of commandFiles ) {
10
19
const commandConstructor = require ( path . join ( commandsPath , commandFile ) ) . default ;
11
20
const command = new commandConstructor (
@@ -17,70 +26,121 @@ export default async function () {
17
26
continue ;
18
27
}
19
28
20
- try {
21
- await command . initialize ( { } ) ;
22
- } catch ( e ) {
23
- console . log ( `initialize failed [${ commandFile } ]: ` + e . toString ( ) ) ;
24
- }
29
+ generateDoc ( command , commandFile ) ;
25
30
26
- let optionText ;
27
- if ( ! command . options ) {
28
- optionText = '' ;
29
- } else {
30
- optionText = ( command . options as any [ ] )
31
- . filter ( option => ! option . hidden )
32
- . map ( option => {
33
- let defaultText = '' ;
34
- if ( option . default ) {
35
- defaultText = `<em>default value: ${ option . default } </em>` ;
36
- }
37
- let aliasText = '' ;
38
- if ( option . aliases && option . aliases . length > 0 ) {
39
- aliasText = ( option . aliases as string [ ] )
40
- . map ( alias => '<code>' + ( alias . length === 1 ? '-' : '--' ) + alias + '</code>' )
41
- . join ( ',' ) ;
42
- aliasText = ` (alias: ${ aliasText } )` ;
43
- }
44
-
45
- return tags . stripIndent `
46
- <details>
47
- <summary>${ option . name } </summary>
48
- <p>
49
- <code>--${ option . name } </code>${ aliasText } ${ defaultText }
50
- </p>
51
- <p>
52
- ${ option . description }
53
- </p>
54
- </details>
55
- ` ;
56
- } ) . join ( '\n' ) ;
31
+ if ( command . name === 'generate' ) {
32
+ const collection = engineHost . createCollectionDescription ( '@schematics/angular' ) ;
33
+
34
+ for ( const schematicName in collection . schematics ) {
35
+ const schematic = collection . schematics [ schematicName ] ;
36
+ if ( schematic . hidden || schematic . private ) {
37
+ continue ;
38
+ }
39
+ const generateCommand = new commandConstructor (
40
+ { project : { root : path . join ( __dirname , '../fake_root/' ) } } ,
41
+ new logging . NullLogger ( ) ,
42
+ ) ;
43
+ generateDoc (
44
+ generateCommand ,
45
+ commandFile ,
46
+ { _ : [ `${ collection . name } :${ schematicName } ` ] } ,
47
+ {
48
+ name : strings . dasherize ( schematicName ) ,
49
+ namePrefix : 'generate ' ,
50
+ description : schematic . description ,
51
+ path : 'generate'
52
+ } ,
53
+ ) ;
54
+ }
57
55
}
56
+ }
57
+ }
58
58
59
- const docFile = path . join (
60
- __dirname ,
61
- '../../../docs/documentation/' ,
62
- path . basename ( commandFile , '.ts' ) + '.md' ) ;
59
+ interface DocInfo {
60
+ name : string ;
61
+ namePrefix : string ;
62
+ description : string ;
63
+ path : string ;
64
+ }
65
+ async function generateDoc (
66
+ command : any ,
67
+ commandFile : string ,
68
+ options : any = { } ,
69
+ info ?: Partial < DocInfo > ,
70
+ ) {
71
+ const docInfo = {
72
+ name : command . name ,
73
+ namePrefix : '' ,
74
+ description : command . description ,
75
+ path : '' ,
76
+ ...info ,
77
+ } ;
63
78
64
- let docText ;
65
- if ( fs . existsSync ( docFile ) ) {
66
- docText = fs . readFileSync ( docFile , 'utf8' ) ;
67
- docText = docText . slice ( 0 , docText . indexOf ( '## Options' ) + 10 ) ;
68
- } else {
69
- // tslint:disable:max-line-length
70
- docText = tags . stripIndent `
71
- <!-- Links in /docs/documentation should NOT have \`.md\` at the end, because they end up in our wiki at release. -->
79
+ try {
80
+ await command . initialize ( options ) ;
81
+ } catch ( e ) {
82
+ console . log ( `initialize failed [${ commandFile } ]: ` + e ) ;
83
+ }
72
84
73
- # ng ${ command . name }
85
+ let optionText ;
86
+ if ( ! command . options ) {
87
+ optionText = '' ;
88
+ } else {
89
+ optionText = ( command . options as any [ ] )
90
+ . filter ( option => ! option . hidden )
91
+ . map ( option => {
92
+ let defaultText = '' ;
93
+ if ( option . default ) {
94
+ defaultText = ` <em>default value: ${ option . default } </em>` ;
95
+ }
96
+ let aliasText = '' ;
97
+ if ( option . aliases && option . aliases . length > 0 ) {
98
+ aliasText = ( option . aliases as string [ ] )
99
+ . map ( alias => '<code>' + ( alias . length === 1 ? '-' : '--' ) + alias + '</code>' )
100
+ . join ( ',' ) ;
101
+ aliasText = ` (alias: ${ aliasText } )` ;
102
+ }
74
103
75
- ## Overview
76
- ${ command . description }
104
+ return tags . stripIndent `
105
+ <details>
106
+ <summary>${ option . name } </summary>
107
+ <p>
108
+ <code>--${ option . name } </code>${ aliasText } ${ defaultText }
109
+ </p>
110
+ <p>
111
+ ${ option . description }
112
+ </p>
113
+ </details>
114
+ ` ;
115
+ } ) . join ( '\n' ) ;
116
+ }
77
117
78
- ## Options
79
- ` ;
80
- // tslint:enable:max-line-length
81
- }
118
+ const docFile = path . join (
119
+ __dirname ,
120
+ '../../../docs/documentation/' ,
121
+ docInfo . path ,
122
+ strings . dasherize ( docInfo . name ) + '.md' ,
123
+ ) ;
124
+
125
+ let docText ;
126
+ if ( fs . existsSync ( docFile ) ) {
127
+ docText = fs . readFileSync ( docFile , 'utf8' ) ;
128
+ docText = docText . slice ( 0 , docText . indexOf ( '## Options' ) + 10 ) ;
129
+ } else {
130
+ // tslint:disable:max-line-length
131
+ docText = tags . stripIndent `
132
+ <!-- Links in /docs/documentation should NOT have \`.md\` at the end, because they end up in our wiki at release. -->
82
133
83
- const finalText = docText + '\n' + ( optionText ? optionText : 'None.' ) + '\n' ;
84
- fs . writeFileSync ( docFile , finalText ) ;
134
+ # ng ${ docInfo . namePrefix } ${ docInfo . name }
135
+
136
+ ## Overview
137
+ ${ docInfo . description }
138
+
139
+ ## Options
140
+ ` ;
141
+ // tslint:enable:max-line-length
85
142
}
143
+
144
+ const finalText = docText + '\n' + ( optionText ? optionText : 'None.' ) + '\n' ;
145
+ fs . writeFileSync ( docFile , finalText ) ;
86
146
}
0 commit comments