2013-12-06 18:13:15 +04:00
// This file manages the root level config.js.
// It will create config.js from config.exampe.js
// if it doesn't exist and then always attempt to load
// config.js into memory, error and quitting if config.js
// has an improper format.
2013-09-24 07:37:36 +04:00
var fs = require ( 'fs' ) ,
url = require ( 'url' ) ,
when = require ( 'when' ) ,
2014-05-09 14:11:29 +04:00
errors = require ( './server/errors' ) ,
2014-01-05 10:40:53 +04:00
config = require ( './server/config' ) ,
2013-10-10 14:44:31 +04:00
2014-01-05 10:40:53 +04:00
appRoot = config ( ) . paths . appRoot ,
configExample = config ( ) . paths . configExample ,
2014-02-08 19:41:15 +04:00
rejectMessage = 'Unable to load config' ,
configFile ;
2013-12-28 21:53:05 +04:00
function readConfigFile ( envVal ) {
return require ( configFile ) [ envVal ] ;
}
2013-09-06 19:54:50 +04:00
function writeConfigFile ( ) {
var written = when . defer ( ) ;
/ * C h e c k f o r c o n f i g f i l e a n d c o p y f r o m c o n f i g . e x a m p l e . j s
if one doesn ' t exist . After that , start the server . * /
2013-12-28 21:53:05 +04:00
fs . exists ( configExample , function checkTemplate ( templateExists ) {
2013-09-06 19:54:50 +04:00
var read ,
write ;
if ( ! templateExists ) {
2013-10-10 14:44:31 +04:00
return errors . logError ( new Error ( 'Could not locate a configuration file.' ) , appRoot , 'Please check your deployment for config.js or config.example.js.' ) ;
2013-09-06 19:54:50 +04:00
}
// Copy config.example.js => config.js
2013-12-28 21:53:05 +04:00
read = fs . createReadStream ( configExample ) ;
2013-09-06 19:54:50 +04:00
read . on ( 'error' , function ( err ) {
2014-02-27 06:44:09 +04:00
/*jshint unused:false*/
2013-10-10 14:44:31 +04:00
return errors . logError ( new Error ( 'Could not open config.example.js for read.' ) , appRoot , 'Please check your deployment for config.js or config.example.js.' ) ;
2013-09-06 19:54:50 +04:00
} ) ;
read . on ( 'end' , written . resolve ) ;
2013-10-16 10:38:30 +04:00
write = fs . createWriteStream ( configFile ) ;
2013-09-06 19:54:50 +04:00
write . on ( 'error' , function ( err ) {
2014-02-27 06:44:09 +04:00
/*jshint unused:false*/
2013-10-10 14:44:31 +04:00
return errors . logError ( new Error ( 'Could not open config.js for write.' ) , appRoot , 'Please check your deployment for config.js or config.example.js.' ) ;
2013-09-06 19:54:50 +04:00
} ) ;
read . pipe ( write ) ;
} ) ;
return written . promise ;
}
2013-09-24 07:37:36 +04:00
function validateConfigEnvironment ( ) {
2013-12-28 20:01:08 +04:00
var envVal = process . env . NODE _ENV || undefined ,
2013-10-10 19:11:35 +04:00
hasHostAndPort ,
hasSocket ,
2013-09-24 07:37:36 +04:00
config ,
parsedUrl ;
try {
2013-12-28 21:53:05 +04:00
config = readConfigFile ( envVal ) ;
2013-09-24 07:37:36 +04:00
} catch ( ignore ) {
}
// Check if we don't even have a config
if ( ! config ) {
2013-10-22 10:38:41 +04:00
errors . logError ( new Error ( 'Cannot find the configuration for the current NODE_ENV' ) , "NODE_ENV=" + envVal ,
'Ensure your config.js has a section for the current NODE_ENV value and is formatted properly.' ) ;
2013-12-28 20:01:08 +04:00
return when . reject ( rejectMessage ) ;
2013-09-24 07:37:36 +04:00
}
// Check that our url is valid
2013-10-14 18:42:08 +04:00
parsedUrl = url . parse ( config . url || 'invalid' , false , true ) ;
if ( ! parsedUrl . host ) {
2013-09-24 07:37:36 +04:00
errors . logError ( new Error ( 'Your site url in config.js is invalid.' ) , config . url , 'Please make sure this is a valid url before restarting' ) ;
2013-12-28 20:01:08 +04:00
return when . reject ( rejectMessage ) ;
2013-09-24 07:37:36 +04:00
}
2013-12-28 21:53:05 +04:00
if ( /\/ghost(\/|$)/ . test ( parsedUrl . pathname ) ) {
errors . logError ( new Error ( 'Your site url in config.js cannot contain a subdirectory called ghost.' ) , config . url , 'Please rename the subdirectory before restarting' ) ;
return when . reject ( rejectMessage ) ;
}
2013-09-24 07:37:36 +04:00
// Check that we have database values
2013-12-28 21:53:05 +04:00
if ( ! config . database || ! config . database . client ) {
2013-09-24 07:37:36 +04:00
errors . logError ( new Error ( 'Your database configuration in config.js is invalid.' ) , JSON . stringify ( config . database ) , 'Please make sure this is a valid Bookshelf database configuration' ) ;
2013-12-28 20:01:08 +04:00
return when . reject ( rejectMessage ) ;
2013-09-24 07:37:36 +04:00
}
2013-10-10 19:11:35 +04:00
hasHostAndPort = config . server && ! ! config . server . host && ! ! config . server . port ;
hasSocket = config . server && ! ! config . server . socket ;
2013-09-24 07:37:36 +04:00
// Check for valid server host and port values
2013-10-10 19:11:35 +04:00
if ( ! config . server || ! ( hasHostAndPort || hasSocket ) ) {
errors . logError ( new Error ( 'Your server values (socket, or host and port) in config.js are invalid.' ) , JSON . stringify ( config . server ) , 'Please provide them before restarting.' ) ;
2013-12-28 20:01:08 +04:00
return when . reject ( rejectMessage ) ;
2013-09-24 07:37:36 +04:00
}
2013-11-26 07:22:59 +04:00
return when . resolve ( config ) ;
2013-09-24 07:37:36 +04:00
}
2014-02-08 19:41:15 +04:00
function loadConfig ( configFilePath ) {
2013-11-26 07:22:59 +04:00
var loaded = when . defer ( ) ,
pendingConfig ;
2014-02-08 19:41:15 +04:00
// Allow config file path to be taken from, in order of importance:
// environment process, passed in value, default location
configFile = process . env . GHOST _CONFIG || configFilePath || config ( ) . paths . config ;
2013-09-06 19:54:50 +04:00
/ * C h e c k f o r c o n f i g f i l e a n d c o p y f r o m c o n f i g . e x a m p l e . j s
if one doesn ' t exist . After that , start the server . * /
2013-10-16 10:38:30 +04:00
fs . exists ( configFile , function checkConfig ( configExists ) {
2013-11-26 07:22:59 +04:00
if ( ! configExists ) {
pendingConfig = writeConfigFile ( ) ;
2013-09-06 19:54:50 +04:00
}
2014-01-05 10:40:53 +04:00
when ( pendingConfig ) . then ( validateConfigEnvironment ) . then ( function ( rawConfig ) {
return config . init ( rawConfig ) . then ( loaded . resolve ) ;
} ) . otherwise ( loaded . reject ) ;
2013-09-06 19:54:50 +04:00
} ) ;
2014-01-05 10:40:53 +04:00
2013-09-06 19:54:50 +04:00
return loaded . promise ;
2013-11-20 17:58:52 +04:00
}
module . exports = loadConfig ;