Skip to content

Commit

Permalink
Merge pull request #876 from Automattic/try/config-overrides
Browse files Browse the repository at this point in the history
Framework: Cascading Configs
  • Loading branch information
mjangda committed Feb 16, 2016
2 parents 247e012 + b68047c commit f5e708f
Show file tree
Hide file tree
Showing 17 changed files with 324 additions and 106 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ env-config.sh
# added during build
/config/secrets.json

# config overrides
/config/*.local.json

/build

/public/*.js
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ mixedindentlint: node_modules/mixedindentlint
@$(RECORD_ENV) $@

# generate the client-side `config` js file
$(CLIENT_CONFIG_FILE): .env config/$(CALYPSO_ENV).json config/client.json client/config/regenerate.js
@$(NODE) client/config/regenerate.js > $@
$(CLIENT_CONFIG_FILE): .env config/$(CALYPSO_ENV).json config/client.json server/config/regenerate-client.js
@$(NODE) server/config/regenerate-client.js > $@

public/style.css: node_modules $(SASS_FILES)
@$(SASS) assets/stylesheets/style.scss $@
Expand Down
60 changes: 0 additions & 60 deletions client/config/regenerate.js

This file was deleted.

3 changes: 3 additions & 0 deletions config/_shared.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"discover_blog_id": 53424024
}
1 change: 0 additions & 1 deletion config/desktop-mac-app-store.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"login_url": "/login",
"logout_url": "/logout",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "/",
"features": {
"ad-tracking": true,
Expand Down
1 change: 0 additions & 1 deletion config/desktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"login_url": "/login",
"logout_url": "/logout",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "/",
"features": {
"ad-tracking": true,
Expand Down
1 change: 0 additions & 1 deletion config/development.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"login_url": "https://wordpress.com/wp-login.php",
"logout_url": "https://wordpress.com/wp-login.php?action=logout&redirect_to=https%3A%2F%2F|subdomain|wordpress.com",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "https://discover.wordpress.com",
"features": {
"accept-invite": true,
Expand Down
1 change: 0 additions & 1 deletion config/horizon.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"login_url": "https://wordpress.com/wp-login.php",
"logout_url": "https://wordpress.com/wp-login.php?action=logout&redirect_to=https%3A%2F%2F|subdomain|wordpress.com",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "https://discover.wordpress.com",
"features": {
"accept-invite": true,
Expand Down
1 change: 0 additions & 1 deletion config/production.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"login_url": "https://wordpress.com/wp-login.php",
"logout_url": "https://wordpress.com/wp-login.php?action=logout&redirect_to=https%3A%2F%2F|subdomain|wordpress.com",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "https://discover.wordpress.com",
"features": {
"accept-invite": true,
Expand Down
1 change: 0 additions & 1 deletion config/stage.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"login_url": "https://wordpress.com/wp-login.php",
"logout_url": "https://wordpress.com/wp-login.php?action=logout&redirect_to=https%3A%2F%2F|subdomain|wordpress.com",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "https://discover.wordpress.com",
"features": {
"accept-invite": true,
Expand Down
1 change: 0 additions & 1 deletion config/wpcalypso.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"login_url": "https://wordpress.com/wp-login.php",
"logout_url": "https://wordpress.com/wp-login.php?action=logout&redirect_to=https%3A%2F%2F|subdomain|wordpress.com",
"facebook_api_key": "249643311490",
"discover_blog_id": 53424024,
"discover_logged_out_redirect_url": "https://discover.wordpress.com",
"features": {
"accept-invite": true,
Expand Down
12 changes: 12 additions & 0 deletions server/config/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NODE_BIN := $(shell npm bin)
MOCHA ?= $(NODE_BIN)/mocha
BASE_DIR := $(NODE_BIN)/../..
NODE_PATH := ../:$(BASE_DIR)/client
COMPILERS ?= js:babel/register
REPORTER ?= spec
UI ?= bdd

test:
@NODE_PATH=$(NODE_PATH) $(MOCHA) --compilers $(COMPILERS) --reporter $(REPORTER) --ui $(UI)

.PHONY: test
48 changes: 11 additions & 37 deletions server/config/index.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,24 @@
/**
* Module dependencies
*/
var fs = require( 'fs' ),
path = require( 'path' ),
assign = require( 'lodash/object/assign' ),
debug = require( 'debug' )( 'config' );

var env = process.env.CALYPSO_ENV || process.env.NODE_ENV || 'development',
filename = env + '.json',
configPath = path.resolve( __dirname, '..', '..', 'config', filename ),
actualSecretsPath = path.resolve( __dirname, '..', '..', 'config', 'secrets.json' ),
emptySecretsPath = path.resolve( __dirname, '..', '..', 'config', 'empty-secrets.json' ),
secretsPath = fs.existsSync( actualSecretsPath ) ? actualSecretsPath : emptySecretsPath,
secretsData = JSON.parse( fs.readFileSync( secretsPath, 'utf8' ) ),
data = JSON.parse( fs.readFileSync( configPath, 'utf8' ) ),
enabledFeatures = process.env.ENABLE_FEATURES ? process.env.ENABLE_FEATURES.split(',') : [],
disabledFeatures = process.env.DISABLE_FEATURES ? process.env.DISABLE_FEATURES.split(',') : [];

assign( data, secretsData );

debug( 'using configuration file: %o', filename );

if ( data.hasOwnProperty( 'features' ) ) {
enabledFeatures.forEach( function( feature ) {
data.features[ feature ] = true;
debug( 'overriding feature %s to true', feature );
} );
disabledFeatures.forEach( function( feature ) {
data.features[ feature ] = false;
debug( 'overriding feature %s to false', feature );
} );
}
const configPath = require( 'path' ).resolve( __dirname, '..', '..', 'config' );
const data = require( './parser' )( configPath, {
env: process.env.CALYPSO_ENV || process.env.NODE_ENV || 'development',
includeSecrets: true,
enabledFeatures: process.env.ENABLE_FEATURES,
disabledFeatures: process.env.DISABLE_FEATURES
} );

/**
* Return config `key`.
* Throws an error if the requested `key` is not set in the config file.
*
* @param {String} key
* @return {Mixed}
* @param {String} key The key of the config entry.
* @return {Mixed} Value of config or error if not found.
* @api public
*/
function config( key ) {
if ( key in data ) {
return data[ key ];
}
throw new Error( 'config key `' + key + '` does not exist in "' + filename + '"' );
throw new Error( 'config key `' + key + '` does not exist' );
}

function isEnabled( feature ) {
Expand All @@ -54,7 +28,7 @@ function isEnabled( feature ) {
function anyEnabled() {
var args = Array.prototype.slice.call( arguments );
return args.some( function( feature ) {
return !! data.features[ feature ];
return isEnabled( feature );
} );
}

Expand Down
65 changes: 65 additions & 0 deletions server/config/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/***** WARNING: ES5 code only here. Used by un-transpiled script! *****/

/**
* Module dependencies
*/
const fs = require( 'fs' ),
path = require( 'path' ),
assign = require( 'lodash/object/assign' ),
debug = require( 'debug' )( 'config' );

function getDataFromFile( file ) {
var fileData = {};

if ( fs.existsSync( file ) ) {
debug( 'getting data from config file: %o', file );
fileData = JSON.parse( fs.readFileSync( file, 'utf8' ) );
} else {
debug( 'skipping config file; not found: %o', file );
}

return fileData;
}

module.exports = function( configPath, defaultOpts ) {
var opts = assign( {
env: 'development',
includeSecrets: false,
}, defaultOpts ),
data = {},
configFiles = [
path.resolve( configPath, '_shared.json' ),
path.resolve( configPath, opts.env + '.json' ),
path.resolve( configPath, opts.env + '.local.json' )
],
realSecretsPath,
emptySecretsPath,
secretsPath,
enabledFeatures = opts.enabledFeatures ? opts.enabledFeatures.split( ',' ) : [],
disabledFeatures = opts.disabledFeatures ? opts.disabledFeatures.split( ',' ) : [];

if ( opts.includeSecrets ) {
realSecretsPath = path.resolve( configPath, 'secrets.json' );
emptySecretsPath = path.resolve( configPath, 'empty-secrets.json' );
secretsPath = fs.existsSync( realSecretsPath ) ? realSecretsPath : emptySecretsPath;

configFiles.push( secretsPath );
}

configFiles.forEach( function( file ) {
assign( data, getDataFromFile( file ) );
} );

if ( data.hasOwnProperty( 'features' ) ) {
enabledFeatures.forEach( function( feature ) {
data.features[ feature ] = true;
debug( 'overriding feature %s to true', feature );
} );
disabledFeatures.forEach( function( feature ) {
data.features[ feature ] = false;
debug( 'overriding feature %s to false', feature );
} );
}

return data;
}
35 changes: 35 additions & 0 deletions server/config/regenerate-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env node
/***** WARNING: ES5 code only here. Not transpiled! *****/

/**
* Module dependencies/
*/
var fs = require( 'fs' ),
path = require( 'path' ),
configPath = path.resolve( __dirname, '..', '..', 'config' ),
keysPath = path.resolve( configPath, 'client.json' ),
keys = JSON.parse( fs.readFileSync( keysPath, 'utf8' ) ),
config = require( './' ),
data = require( './parser' )( configPath, {
env: process.env.CALYPSO_ENV || 'development',
includeSecrets: false,
enabledFeatures: process.env.ENABLE_FEATURES,
disabledFeatures: process.env.DISABLE_FEATURES
} ),
obj = {};

keys.forEach( function( key ) {
if ( key in data ) {
obj[ key ] = data[ key ];
}
} );

console.log( '/* This file is automatically generated. Do not edit manually. */' );
console.log();
console.log( 'var data = %s;', JSON.stringify( obj, null, 2 ) );
console.log( config.toString() );
console.log( config.isEnabled.toString() );
console.log( config.anyEnabled.toString() );
console.log( 'module.exports = config;' );
console.log( 'module.exports.isEnabled = isEnabled;' );
console.log( 'module.exports.anyEnabled = anyEnabled;' );
Loading

0 comments on commit f5e708f

Please sign in to comment.