11import * as fs from 'fs' ;
22import * 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' ;
49
510export default async function ( ) {
611 const commandsPath = __dirname + '/../../../packages/@angular/cli/commands' ;
712 const commandFiles = fs . readdirSync ( commandsPath ) ;
813
14+ const engineHost = new NodeModulesEngineHost ( ) ;
15+ const registry = new schema . CoreSchemaRegistry ( formats . standardFormats ) ;
16+ engineHost . registerOptionsTransform ( validateOptionsWithSchema ( registry ) ) ;
17+
918 for ( const commandFile of commandFiles ) {
1019 const commandConstructor = require ( path . join ( commandsPath , commandFile ) ) . default ;
1120 const command = new commandConstructor (
@@ -17,70 +26,121 @@ export default async function () {
1726 continue ;
1827 }
1928
20- try {
21- await command . initialize ( { } ) ;
22- } catch ( e ) {
23- console . log ( `initialize failed [${ commandFile } ]: ` + e . toString ( ) ) ;
24- }
29+ generateDoc ( command , commandFile ) ;
2530
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+ }
5755 }
56+ }
57+ }
5858
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+ } ;
6378
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+ }
7284
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+ }
74103
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+ }
77117
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. -->
82133
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
85142 }
143+
144+ const finalText = docText + '\n' + ( optionText ? optionText : 'None.' ) + '\n' ;
145+ fs . writeFileSync ( docFile , finalText ) ;
86146}
0 commit comments