11#!/usr/bin/env node
22
3- import chalk from " chalk" ;
4- import { exec } from " child_process" ;
5- import fs from "fs" ;
6- import path from " path" ;
7- import readline from " readline" ;
8- import util from " util" ;
9- import yargs from " yargs" ;
10- import { hideBin } from " yargs/helpers" ;
3+ import chalk from ' chalk'
4+ import { exec } from ' child_process'
5+ import fs from 'fs-extra'
6+ import path from ' path'
7+ import readline from ' readline'
8+ import util from ' util'
9+ import yargs from ' yargs'
10+ import { hideBin } from ' yargs/helpers'
1111
12- import config from " ./config.js" ;
12+ import config from ' ./config.js'
1313
1414/* --- Helpers --- */
1515
16- const run = util . promisify ( exec ) ;
16+ const run = util . promisify ( exec )
1717
1818const rl = readline . createInterface ( {
1919 input : process . stdin ,
2020 output : process . stdout ,
21- } ) ;
21+ } )
2222
2323function prompt ( question , defaultAnswer ) {
2424 return new Promise ( ( resolve ) => {
25- rl . question ( question , ( input ) => resolve ( input || defaultAnswer ) ) ;
26- } ) ;
25+ rl . question ( question , ( input ) => resolve ( input || defaultAnswer ) )
26+ } )
2727}
2828
2929function getDirName ( defaultDirName ) {
30- let dirName = args . _ [ 0 ] ?? defaultDirName ;
31- if ( fs . existsSync ( dirName ) ) dirName += `-${ timestamp } ` ;
32- return dirName ;
30+ let dirName = args . _ [ 0 ] ?? defaultDirName
31+ if ( fs . existsSync ( dirName ) ) dirName += `-${ timestamp } `
32+ return dirName
3333}
3434
3535async function installDependencies ( dirName ) {
36- console . log ( `Installing dependencies ...` ) ;
37- await run ( `cd ${ dirName } && npm install` ) ;
36+ console . log ( `Installing dependencies ...` )
37+ await run ( `cd ${ dirName } && npm install` )
3838}
3939
4040async function initGit ( dirName ) {
41- console . log ( `Setting up Git ...` ) ;
42- await run ( `rm -rf ${ dirName } /.git` ) ;
43- await run (
44- `cd ${ dirName } && git init && git add . && git commit -m "New Stackbit project"`
45- ) ;
41+ console . log ( `Setting up Git ...` )
42+ await fs . remove ( `${ dirName } / .git` , { recursive : true } , async ( ) => {
43+ await run (
44+ `cd ${ dirName } && git init && git add . && git commit -m "New Stackbit project"`
45+ )
46+ } )
4647}
47-
4848/**
4949 * Given a version string, compare it to a control version. Returns:
5050 *
@@ -57,131 +57,148 @@ async function initGit(dirName) {
5757 */
5858function compareVersion ( version , control ) {
5959 // References
60- let returnValue = 0 ;
60+ let returnValue = 0
6161 // Return 0 if the versions match.
62- if ( version === control ) return returnValue ;
62+ if ( version === control ) return returnValue
6363 // Break the versions into arrays of integers.
64- const getVersionParts = ( str ) => str . split ( "." ) . map ( ( v ) => parseInt ( v ) ) ;
65- const versionParts = getVersionParts ( version ) ;
66- const controlParts = getVersionParts ( control ) ;
64+ const getVersionParts = ( str ) => str . split ( '.' ) . map ( ( v ) => parseInt ( v ) )
65+ const versionParts = getVersionParts ( version )
66+ const controlParts = getVersionParts ( control )
6767 // Loop and compare each item.
6868 controlParts . every ( ( controlPart , idx ) => {
6969 // If the versions are equal at this part, we move on to the next part.
70- if ( versionParts [ idx ] === controlPart ) return true ;
70+ if ( versionParts [ idx ] === controlPart ) return true
7171 // Otherwise, set the return value, then break out of the loop.
72- returnValue = versionParts [ idx ] > controlPart ? 1 : - 1 ;
73- return false ;
74- } ) ;
75- return returnValue ;
72+ returnValue = versionParts [ idx ] > controlPart ? 1 : - 1
73+ return false
74+ } )
75+ return returnValue
7676}
7777
7878/* --- Parse CLI Arguments */
7979
8080const args = yargs ( hideBin ( process . argv ) )
81- . option ( " starter" , {
82- alias : "s" ,
83- describe : " Choose a starter" ,
81+ . option ( ' starter' , {
82+ alias : 's' ,
83+ describe : ' Choose a starter' ,
8484 choices : config . starters . map ( ( s ) => s . name ) ,
8585 } )
86- . option ( " example" , {
87- alias : "e" ,
88- describe : " Start from an example" ,
86+ . option ( ' example' , {
87+ alias : 'e' ,
88+ describe : ' Start from an example' ,
8989 choices : config . examples . directories ,
9090 } )
9191 . help ( )
92- . parse ( ) ;
92+ . parse ( )
9393
9494/* --- References --- */
9595
9696const starter = config . starters . find (
9797 ( s ) => s . name === ( args . starter ?? config . defaults . starter . name )
98- ) ;
98+ )
9999
100100// Current time in seconds.
101- const timestamp = Math . round ( new Date ( ) . getTime ( ) / 1000 ) ;
101+ const timestamp = Math . round ( new Date ( ) . getTime ( ) / 1000 )
102102
103103/* --- New Project from Starter --- */
104104
105105async function cloneStarter ( ) {
106106 // Set references
107- const dirName = getDirName ( config . defaults . dirName ) ;
107+ const dirName = getDirName ( config . defaults . dirName )
108108
109109 // Clone repo
110- const cloneCommand = `git clone --depth=1 ${ starter . repoUrl } ${ dirName } ` ;
111- console . log ( `\nCreating new project in ${ dirName } ...` ) ;
112- await run ( cloneCommand ) ;
110+ const cloneCommand = `git clone --depth=1 ${ starter . repoUrl } ${ dirName } `
111+ console . log ( `\nCreating new project in ${ dirName } ...` )
112+ await run ( cloneCommand )
113113
114114 // Project Setup
115- await installDependencies ( dirName ) ;
116- await initGit ( dirName ) ;
115+ await installDependencies ( dirName )
116+ await initGit ( dirName )
117117
118118 // Output next steps:
119119 console . log ( `
120- 🎉 ${ chalk . bold ( " Welcome to Stackbit!" ) } 🎉
120+ 🎉 ${ chalk . bold ( ' Welcome to Stackbit!' ) } 🎉
121121
122122Follow the instructions for getting Started here:
123123
124124 ${ starter . repoUrl } #readme
125- ` ) ;
125+ ` )
126126}
127127
128128/* --- New Project from Example --- */
129129
130130async function cloneExample ( ) {
131- const gitResult = await run ( " git --version" ) ;
132- const gitVersionMatch = gitResult . stdout . match ( / \d + \. \d + \. \d + / ) ;
131+ const gitResult = await run ( ' git --version' )
132+ const gitVersionMatch = gitResult . stdout . match ( / \d + \. \d + \. \d + / )
133133 if ( ! gitVersionMatch || ! gitVersionMatch [ 0 ] ) {
134134 console . error (
135135 `Cannot determine git version, which is required for starting from an example.` ,
136136 `\nPlease report this:` ,
137137 chalk . underline (
138- " https://github.com/stackbit/create-stackbit-app/issues/new"
138+ ' https://github.com/stackbit/create-stackbit-app/issues/new'
139139 )
140- ) ;
141- process . exit ( 1 ) ;
140+ )
141+ process . exit ( 1 )
142142 }
143143 if ( compareVersion ( gitVersionMatch [ 0 ] , config . minGitVersion ) < 0 ) {
144144 console . error (
145145 `Starting from an example requires git version ${ config . minGitVersion } or later.` ,
146- " Please upgrade"
147- ) ;
148- process . exit ( 1 ) ;
146+ ' Please upgrade'
147+ )
148+ process . exit ( 1 )
149149 }
150150
151- const dirName = getDirName ( args . example ) ;
152- const tmpDir = `__tmp${ timestamp } __` ;
153- console . log ( `\nCreating new project in ${ dirName } ...` ) ;
151+ const dirName = getDirName ( args . example )
152+ const tmpDir = `__tmp${ timestamp } __`
153+ console . log ( `\nCreating new project in ${ dirName } ...` )
154154
155155 try {
156156 // Sparse clone the monorepo.
157157 await run (
158158 `git clone --depth 1 --filter=blob:none --sparse ${ config . examples . repoUrl } ${ tmpDir } `
159- ) ;
159+ )
160160 // Checkout just the example dir.
161- await run ( `cd ${ tmpDir } && git sparse-checkout set ${ args . example } ` ) ;
161+ await run ( `cd ${ tmpDir } && git sparse-checkout set ${ args . example } ` )
162+
162163 // Copy out into a new directory within current working directory.
163- await run ( `cp -R ${ tmpDir } /${ args . example } ${ dirName } ` ) ;
164- // Delete the clone.
165- await run ( `rm -rf ${ tmpDir } ` ) ;
164+ await fs . copy ( `${ tmpDir } /${ args . example } ` , dirName , async ( err ) => {
165+ if ( err ) {
166+ console . log ( err )
167+ }
168+ } )
166169
170+ // Delete the clone.
171+ await fs . remove ( tmpDir , { recursive : true } , ( err ) => {
172+ if ( err ) {
173+ console . log ( err )
174+ }
175+ } )
176+
177+ if ( fs . existsSync ( path . join ( process . cwd ( ) , dirName ) ) )
178+ await installDependencies ( path . join ( process . cwd ( ) , dirName ) )
167179 // Project Setup
168- await installDependencies ( dirName ) ;
169- await initGit ( dirName ) ;
180+ // await
181+ // await initGit(prestineFolder)
170182 } catch ( err ) {
171- console . error ( err ) ;
172- if ( fs . existsSync ( dirName ) ) await run ( `rm -rf ${ dirName } ` ) ;
173- if ( fs . existsSync ( tmpDir ) ) await run ( `rm -rf ${ tmpDir } ` ) ;
174- process . exit ( 1 ) ;
183+
184+ if ( fs . existsSync ( dirName ) ) await fs . remove ( dirName )
185+ if ( fs . existsSync ( tmpDir ) )
186+ await fs . remove ( tmpDir , ( err ) => {
187+ if ( err ) {
188+ console . log ( err )
189+ }
190+ } )
191+ process . exit ( 1 )
175192 }
176193
177194 // Output next steps:
178195 console . log ( `
179- 🎉 ${ chalk . bold ( " Your example project is ready!" ) } 🎉
196+ 🎉 ${ chalk . bold ( ' Your example project is ready!' ) } 🎉
180197
181198Follow the instructions and learn more about the example here:
182199
183200 ${ config . examples . repoUrl } /tree/main/${ args . example } #readme
184- ` ) ;
201+ ` )
185202}
186203
187204/* --- Existing Project --- */
@@ -190,37 +207,37 @@ async function integrateStackbit() {
190207 return new Promise ( async ( resolve ) => {
191208 const integrate = await prompt ( `
192209 This looks like an existing project.
193- ${ chalk . bold ( " Would you like to install Stackbit in this project?" ) } [Y/n] ` ) ;
210+ ${ chalk . bold ( ' Would you like to install Stackbit in this project?' ) } [Y/n] ` )
194211
195- if ( ! [ " yes" , "y" ] . includes ( integrate ?. toLowerCase ( ) ) ) return resolve ( false ) ;
212+ if ( ! [ ' yes' , 'y' ] . includes ( integrate ?. toLowerCase ( ) ) ) return resolve ( false )
196213
197214 console . log ( `
198215Visit the following URL to learn more about the integration process:
199216
200217 https://docs.stackbit.com/how-to-guides/site-management/integrate-stackbit/
201- ` ) ;
202- return resolve ( true ) ;
203- } ) ;
218+ ` )
219+ return resolve ( true )
220+ } )
204221}
205222
206223/* --- Run --- */
207224
208225async function doCreate ( ) {
209226 // If the current directory has a package.json file, we assume we're in an
210227 // active project, and will not create a new project.
211- const packageJsonFilePath = path . join ( process . cwd ( ) , " package.json" ) ;
212- if ( fs . existsSync ( packageJsonFilePath ) ) return integrateStackbit ( ) ;
228+ const packageJsonFilePath = path . join ( process . cwd ( ) , ' package.json' )
229+ if ( fs . existsSync ( packageJsonFilePath ) ) return integrateStackbit ( )
213230 // If both starter and example were specified, throw an error message.
214231 if ( args . starter && args . example ) {
215- console . error ( " [ERROR] Cannot specify a starter and an example." ) ;
216- process . exit ( 1 ) ;
232+ console . error ( ' [ERROR] Cannot specify a starter and an example.' )
233+ process . exit ( 1 )
217234 }
218235 // Start from an example if specified.
219- if ( args . example ) return cloneExample ( ) ;
236+ if ( args . example ) return cloneExample ( )
220237 // Otherwise, use a starter, which falls back to the default if not set.
221- return cloneStarter ( ) ;
238+ return cloneStarter ( )
222239}
223240
224- await doCreate ( ) ;
241+ await doCreate ( )
225242
226- rl . close ( ) ;
243+ rl . close ( )
0 commit comments