@@ -14,12 +14,15 @@ var request = require('request'),
1414 api = require ( './api' ) ,
1515 util = require ( 'util' ) ,
1616 chalk = require ( 'chalk' ) ,
17+ temp = require ( 'temp' ) ,
1718 _when = require ( 'when' ) ;
1819
1920var defaultSettings = {
2021 'public' : '.'
2122} ;
2223
24+ temp . track ( ) ;
25+
2326function getPrompt ( schema , onComplete , idx , results ) {
2427 if ( ! Array . isArray ( schema ) ) {
2528 console . log ( chalk . red ( 'An error occurred' ) ) ;
@@ -159,7 +162,7 @@ module.exports = {
159162 }
160163
161164 // Firebase names always a subset of ^[0-9a-z-]*$ so safe to regex
162- var templateList = Object . keys ( supportedTemplates ) ;
165+ var templateList = Object . keys ( supportedTemplates ) . sort ( ) ;
163166 var firebasePattern = new RegExp ( '^(' + res . firebases . join ( '|' ) + ')$' ) ;
164167 var templatePattern = new RegExp ( '^(' + templateList . join ( '|' ) + ')$' ) ;
165168 if ( ! argv . firebase || ( typeof ( argv . firebase ) !== 'string' ) || ! argv . firebase . match ( firebasePattern ) ) {
@@ -199,13 +202,15 @@ module.exports = {
199202 var firebase = results . firebase ;
200203 var dir = firebase ;
201204 var projectDir = path . resolve ( dir ) ;
205+ var tempDir = temp . mkdirSync ( ) ;
202206 if ( fs . existsSync ( projectDir ) ) {
203207 var i = 1 ;
204208 do {
205209 dir = firebase + '_' + i ++ ;
206210 projectDir = path . resolve ( dir ) ;
207211 } while ( fs . existsSync ( projectDir ) ) ;
208212 }
213+
209214 results . directory = dir ;
210215 console . log ( 'Bootstrapping into directory \'' + dir + '\'...' ) ;
211216 try {
@@ -216,47 +221,81 @@ module.exports = {
216221 process . exit ( 1 ) ;
217222 }
218223
224+ // Load the project root if defined, and gracefully handle missing '/'
225+ var templateRoot = supportedTemplates [ results . template ] . templateRoot || '/' ;
226+ if ( templateRoot && templateRoot [ 0 ] !== '/' ) {
227+ templateRoot = '/' + templateRoot ;
228+ }
229+
219230 console . log ( 'Downloading and unpacking template...' ) ;
220231 var gunzip = zlib . createGunzip ( ) ;
221232 var untar = tar . Extract ( {
222- path : projectDir ,
223- strip : 1
233+ path : tempDir ,
234+ strip : 1 ,
235+ filter : function ( entry ) {
236+ if ( ! templateRoot ) {
237+ return true ;
238+ } else {
239+ return ( entry . path === tempDir ) || ( entry . path . indexOf ( tempDir + templateRoot ) === 0 ) ;
240+ }
241+ }
224242 } ) ;
243+
225244 try {
226- request ( supportedTemplates [ results . template ] . url ) . pipe ( gunzip ) . pipe ( untar ) ;
245+ request ( supportedTemplates [ results . template ] . tarball ) . pipe ( gunzip ) . pipe ( untar ) ;
227246 } catch ( err ) {
228247 console . log ( chalk . red ( 'Download Error' ) + ' - Could not download ' +
229248 'template' ) ;
230249 process . exit ( 1 ) ;
231250 }
251+
252+ var caughtFinishedEvent = false ;
232253 untar . on ( 'end' , function ( ) {
233- var config = path . join (
234- projectDir ,
235- supportedTemplates [ results . template ] . config
236- ) ;
254+ if ( caughtFinishedEvent ) return ;
255+ caughtFinishedEvent = true ;
256+
237257 try {
238- var data = fs . readFileSync ( config , 'utf8' ) ,
239- realtimeHost = api . realtimeUrl . replace ( / \/ \/ / , '//' + firebase + '.' ) ;
240- var replaced = data . replace (
241- new RegExp ( supportedTemplates [ results . template ] . configRegex ) ,
242- realtimeHost
243- ) ;
244- fs . writeFileSync ( config , replaced ) ;
258+ fs . renameSync ( tempDir + templateRoot , projectDir ) ;
245259 } catch ( err ) {
246- console . log ( chalk . red ( 'Initialization Error' ) + ' - Couldn\'t update template with project settings ' ) ;
260+ console . log ( chalk . red ( 'Installation Error' ) + ' - Couldn\'t relocate project assets ' ) ;
247261 process . exit ( 1 ) ;
248262 }
249263
264+ var configFiles = supportedTemplates [ results . template ] . configFiles || [ ] ;
265+ for ( var i = 0 ; i < configFiles . length ; i ++ ) {
266+ var config = path . join (
267+ projectDir ,
268+ configFiles [ i ]
269+ ) ;
270+ try {
271+ var data = fs . readFileSync ( config , 'utf8' ) ,
272+ realtimeHost = api . realtimeUrl . replace ( / \/ \/ / , '//' + firebase + '.' ) ;
273+ var replaced = data . replace (
274+ new RegExp ( supportedTemplates [ results . template ] . configRegex , 'g' ) ,
275+ realtimeHost
276+ ) ;
277+ fs . writeFileSync ( config , replaced ) ;
278+ } catch ( err ) {
279+ console . log ( chalk . red ( 'Initialization Error' ) + ' - Couldn\'t update template with project settings' ) ;
280+ process . exit ( 1 ) ;
281+ }
282+ }
283+
250284 console . log ( 'Writing firebase.json settings file...' ) ;
251- var publicPath = supportedTemplates [ results . template ]
252- . settings [ 'public' ] . replace ( / \/ / g, path . sep ) ,
253- rulesPath = supportedTemplates [ results . template ]
254- . settings [ 'rules' ] . replace ( / \/ / g, path . sep ) ;
255285 var settings = {
256286 'firebase' : firebase ,
257- 'public' : publicPath ,
258- 'rules' : rulesPath
287+ 'public' : '.'
259288 } ;
289+
290+ if ( supportedTemplates [ results . template ] . settings ) {
291+ if ( supportedTemplates [ results . template ] . settings [ 'public' ] ) {
292+ settings . public = supportedTemplates [ results . template ] . settings [ 'public' ] . replace ( / \/ / g, path . sep )
293+ }
294+ if ( supportedTemplates [ results . template ] . settings [ 'rules' ] ) {
295+ settings . rules = supportedTemplates [ results . template ] . settings [ 'rules' ] . replace ( / \/ / g, path . sep ) ;
296+ }
297+ }
298+
260299 var settingsJSON = JSON . stringify ( settings , null , 2 ) + "\n" ;
261300 var settingsFile = path . join ( projectDir , 'firebase.json' ) ;
262301 try {
@@ -444,7 +483,13 @@ module.exports = {
444483 }
445484
446485 try {
447- resolve ( JSON . parse ( body ) ) ;
486+ var templates = JSON . parse ( body ) ;
487+ for ( var key in templates ) {
488+ if ( ! templates [ key ] . enabled ) {
489+ delete templates [ key ] ;
490+ }
491+ }
492+ resolve ( templates ) ;
448493 } catch ( e ) {
449494 error . type = 'PARSE-TEMPLATES' ;
450495 return reject ( error ) ;
0 commit comments