Skip to content
This repository has been archived by the owner on Apr 20, 2018. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Einar Löve committed Aug 14, 2016
0 parents commit 710bc2d
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"presets": [
"es2015",
"stage-0"
],
"plugins": [
"lodash"
]
}
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TEST='this is a test'
10 changes: 10 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"parser": "babel-eslint",
"extends": [
"airbnb-base"
],
"rules": {
"semi": [2, "never"],
"no-param-reassign": [2, { "props": false }]
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
lib
node_modules
37 changes: 37 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "config-variables",
"version": "0.1.0",
"description": "Config for you project that cascades app.json, .env and process.env",
"main": "lib/index.js",
"scripts": {
"test": "ava",
"build": "babel src --out-dir lib"
},
"ava": {
"require": "babel-register",
"babel": "inherit"
},
"keywords": [
"config",
".env",
"enviroment"
],
"author": "Unfold",
"license": "ISC",
"devDependencies": {
"ava": "^0.16.0",
"babel-cli": "^6.11.4",
"babel-eslint": "^6.1.2",
"babel-plugin-lodash": "^3.2.6",
"babel-preset-es2015": "^6.13.2",
"babel-preset-stage-0": "^6.5.0",
"eslint": "^3.3.0",
"eslint-config-airbnb-base": "^5.0.2",
"eslint-plugin-import": "^1.13.0"
},
"dependencies": {
"chalk": "^1.1.3",
"dotenv": "^2.0.0",
"lodash": "^4.15.0"
}
}
60 changes: 60 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import chalk from 'chalk'
import {
isObject,
isUndefined,
reduce,
} from 'lodash'

const NODE_ENV = process.env.NODE_ENV || 'development'

export const getAppJsonVariables = appJson =>
reduce(appJson.env, (variables, variable, name) => {
const value = isObject(variable) ? variable.value : variable

if (!isUndefined(value)) {
variables[name] = value
}

return variables
}, {})

export const getMissingRequiredVariables = appJson =>
reduce(appJson.env, (missingVariables, variable, name) => {
if (!isObject(variable)) return missingVariables
const required = variable.required || variable[`required.${NODE_ENV}`]
const missing = !process.env[name]

if (required && missing) {
missingVariables.push({ name, ...variable })
}

return missingVariables
}, [])


/* eslint-disable no-console */

const print = (message, pad, background = 'bgRed') => {
const space = chalk[background](' ')
if (pad) {
console.log(`${space}\n${space} ${message}\n${space}`)
} else {
console.log(`${space} ${message}`)
}
}

export const reportMissingVariables = missingVariables => {
const count = missingVariables.length
print(`Missing ${count} required variable${count > 1 ? 's' : ''}:`, true)

missingVariables.map(({ name, description }) => {
if (description) {
return `${name}: ${chalk.dim(description)}`
}
return name
}).forEach(row => print(`${row}`))

print('Use .env file in root directory to set config variables for development', true)

process.exit(1)
}
33 changes: 33 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable global-require, no-console */
import dotenv from 'dotenv'
import path from 'path'
import { forEach, attempt, isError } from 'lodash'
import {
getAppJsonVariables,
getMissingRequiredVariables,
reportMissingVariables,
} from './helpers'

const pathToAppjson = path.join(process.cwd(), 'app.json')
const appjson = attempt(() => require(pathToAppjson))
const hasAppjson = !isError(appjson)

if (hasAppjson) {
forEach(getAppJsonVariables(appjson), (variable, name) => {
process.env[name] = process.env[name] || variable
})
}

// Load, parse and apply .env variables to process.env
dotenv.config({
path: path.join(process.cwd(), '.env'),
silent: true,
})

if (hasAppjson) {
const missingVariables = getMissingRequiredVariables(appjson)

if (missingVariables.length) {
reportMissingVariables(missingVariables)
}
}
44 changes: 44 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* eslint-disable import/no-extraneous-dependencies */

import test from 'ava'
import {
getAppJsonVariables,
getMissingRequiredVariables,
} from './src/helpers'

const appJsonFixture = {
env: {
first: 1,
second: {
value: 2,
},
third: {
required: true,
},
fourth: {
value: 4,
'required.development': true,
},
fifth: {
'required.production': true,
},
},
}

test('Extracts all app.json variables', t => {
const variables = getAppJsonVariables(appJsonFixture)
t.deepEqual(variables, { first: 1, second: 2, fourth: 4 })
})

test('Extracts all missing required app.json variables', t => {
const required = getMissingRequiredVariables(appJsonFixture)
t.deepEqual(required.map(v => v.name), ['third', 'fourth'])
})

test.todo('app.json variables are included')
test.todo('.env variables are included')

test.todo('process.env should have presedence over .env')
test.todo('.env should have presedence over app.json')

test.todo('It should warn if required variables are missing')

0 comments on commit 710bc2d

Please sign in to comment.