@@ -6,61 +6,83 @@ const { gitInit } = require('../git')
66const packageJson = require ( '../../package.json' )
77
88async function create ( opts = { } ) {
9- const answers = await inquirer . prompt ( [
10- {
11- type : 'input' ,
12- name : 'path' ,
13- message : 'Where would you like to create your project?' ,
14- default : 'statusboard' ,
15- when : ( ) => ! opts . directory ,
16- validate : value => value . trim ( ) . length > 0 || 'Enter a project directory.'
17- } ,
18- {
19- type : 'confirm' ,
20- name : 'defaultLabels' ,
21- message : 'Do you want to use the default labels?' ,
22- default : true
23- } ,
24- {
25- type : 'input' ,
26- name : 'labels' ,
27- message : 'What labels do you want to use (use commas to separate)?' ,
28- when : answers => ! answers . defaultLabels
29- } ,
30- {
31- type : 'input' ,
32- name : 'orgs' ,
33- message : 'What organizations do you want to include (use commas to separate)?'
34- } ,
35- {
36- type : 'input' ,
37- name : 'repositories' ,
38- message : 'What repositories do you want to include (owner/repo, separated by commas)?' ,
39- validate : value => transformUserInput ( value ) . every ( repo => / ^ [ \w . - ] + \/ [ \w . - ] + $ / . test ( repo ) ) || 'Use owner/repo for each repository.'
40- } ,
41- {
42- type : 'confirm' ,
43- name : 'githubActions' ,
44- message : 'Do you want to deploy with GitHub Actions?' ,
45- default : false
46- }
47- ] )
9+ let directory = opts . directory
10+ if ( directory === undefined ) {
11+ directory = opts . yes
12+ ? 'statusboard'
13+ : ( await inquirer . prompt ( [ {
14+ type : 'input' ,
15+ name : 'path' ,
16+ message : 'Where would you like to create your project?' ,
17+ default : 'statusboard' ,
18+ validate : async value => {
19+ try {
20+ await validateDirectory ( value )
21+ return true
22+ } catch ( error ) {
23+ return error . message
24+ }
25+ }
26+ } ] ) ) . path
27+ }
28+ const appPath = await validateDirectory ( directory )
29+ if ( opts . repositories !== undefined && ! validRepositories ( opts . repositories ) ) {
30+ throw new Error ( 'Use owner/repo for each repository.' )
31+ }
4832
49- const directory = ( opts . directory || answers . path || '' ) . trim ( )
50- if ( ! directory ) throw new Error ( 'Enter a project directory.' )
51- const appPath = path . resolve ( directory )
33+ const answers = opts . yes
34+ ? { }
35+ : await inquirer . prompt ( [
36+ {
37+ type : 'confirm' ,
38+ name : 'defaultLabels' ,
39+ message : 'Do you want to use the default labels?' ,
40+ default : true ,
41+ when : ( ) => opts . labels === undefined
42+ } ,
43+ {
44+ type : 'input' ,
45+ name : 'labels' ,
46+ message : 'What labels do you want to use (use commas to separate)?' ,
47+ when : answers => opts . labels === undefined && ! answers . defaultLabels
48+ } ,
49+ {
50+ type : 'input' ,
51+ name : 'orgs' ,
52+ message : 'What organizations do you want to include (use commas to separate)?' ,
53+ when : ( ) => opts . orgs === undefined
54+ } ,
55+ {
56+ type : 'input' ,
57+ name : 'repositories' ,
58+ message : 'What repositories do you want to include (owner/repo, separated by commas)?' ,
59+ when : ( ) => opts . repositories === undefined ,
60+ validate : value => validRepositories ( value ) || 'Use owner/repo for each repository.'
61+ } ,
62+ {
63+ type : 'confirm' ,
64+ name : 'githubActions' ,
65+ message : 'Do you want to deploy with GitHub Actions?' ,
66+ default : false ,
67+ when : ( ) => opts . githubActions === undefined
68+ }
69+ ] )
70+
71+ const repositories = opts . repositories ?? answers . repositories
72+ if ( ! validRepositories ( repositories ) ) throw new Error ( 'Use owner/repo for each repository.' )
73+ // Recheck after prompting in case the destination changed while waiting.
74+ await validateDirectory ( appPath )
5275 await fs . mkdir ( appPath , { recursive : true } )
53- if ( ( await fs . readdir ( appPath ) ) . length ) {
54- throw new Error ( `Directory is not empty: ${ appPath } ` )
55- }
5676
5777 const config = {
5878 path : appPath ,
5979 name : path . basename ( appPath ) ,
60- labels : answers . defaultLabels ? undefined : transformUserInput ( answers . labels ) ,
61- orgs : transformUserInput ( answers . orgs ) ,
62- projects : transformUserInput ( answers . repositories ) ,
63- githubActions : answers . githubActions
80+ labels : opts . labels !== undefined
81+ ? transformUserInput ( opts . labels )
82+ : answers . defaultLabels === false ? transformUserInput ( answers . labels ) : undefined ,
83+ orgs : transformUserInput ( opts . orgs ?? answers . orgs ) ,
84+ projects : transformUserInput ( repositories ) ,
85+ githubActions : opts . githubActions ?? answers . githubActions ?? false
6486 }
6587
6688 if ( config . githubActions ) await createBuildAction ( config )
@@ -86,7 +108,7 @@ async function create (opts = {}) {
86108 }
87109 await fs . writeFile ( path . join ( appPath , 'package.json' ) , `${ JSON . stringify ( manifest , null , 2 ) } \n` , { flag : 'wx' } )
88110
89- if ( ! gitInit ( appPath ) ) {
111+ if ( opts . git !== false && ! gitInit ( appPath ) ) {
90112 console . warn ( 'Could not create the initial Git commit. Project files are ready; check Git installation and user configuration.' )
91113 }
92114 console . log ( `Created Statusboard in ${ appPath } . Run npm install there, set GITHUB_TOKEN, then run npm run build.` )
@@ -95,6 +117,21 @@ async function create (opts = {}) {
95117 }
96118}
97119
120+ async function validateDirectory ( directory ) {
121+ if ( typeof directory !== 'string' || ! directory . trim ( ) ) throw new Error ( 'Enter a project directory.' )
122+ const appPath = path . resolve ( directory . trim ( ) )
123+ try {
124+ if ( ( await fs . readdir ( appPath ) ) . length ) throw new Error ( `Directory is not empty: ${ appPath } ` )
125+ } catch ( error ) {
126+ if ( error . code !== 'ENOENT' ) throw error
127+ }
128+ return appPath
129+ }
130+
131+ function validRepositories ( input ) {
132+ return transformUserInput ( input ) . every ( repo => / ^ [ \w . - ] + \/ [ \w . - ] + $ / . test ( repo ) )
133+ }
134+
98135async function createConfigFile ( config ) {
99136 const fields = {
100137 ...( config . labels === undefined ? { } : { issueLabels : config . labels } ) ,
@@ -114,7 +151,7 @@ async function createConfigFile (config) {
114151}
115152
116153function transformUserInput ( input = '' ) {
117- return input . split ( ',' ) . map ( value => value . trim ( ) ) . filter ( Boolean )
154+ return [ input ] . flat ( ) . flatMap ( value => value . split ( ',' ) ) . map ( value => value . trim ( ) ) . filter ( Boolean )
118155}
119156
120157async function createBuildAction ( config ) {
0 commit comments