Skip to content

Commit

Permalink
feat(config): enable configurability with a config file
Browse files Browse the repository at this point in the history
Introduce a new `ace-config` package:
- exposes a `paths` object storing the system paths (log, config, data, etc)
- exposes the config stored in the config file in the `config` object
- exposes constants in the `constants` object

The config file will be stored in the user's OS-specific configuration directory

Fixes #63, Fixes #77
  • Loading branch information
rdeltour committed Dec 13, 2017
1 parent 93402d8 commit 8987dd8
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 1 deletion.
27 changes: 27 additions & 0 deletions packages/ace-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@daisy/ace-config",
"version": "0.0.1",
"description": "Config utilities for Ace",
"author": {
"name": "DAISY developers",
"organization": "DAISY Consortium",
"url": "http://www.daisy.org/"
},
"repository": {
"type": "git",
"url": "https://github.com/daisy/ace"
},
"bugs": {
"url": "https://github.com/daisy/ace/issues"
},
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"conf": "^1.3.1",
"env-paths": "^1.0.0",
"lodash.mergewith": "^4.6.0"
},
"publishConfig": {
"access": "public"
}
}
60 changes: 60 additions & 0 deletions packages/ace-config/src/__tests__/config-store.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

const ConfigStore = require('../config-store');
const tmp = require('tmp');

tmp.setGracefulCleanup();

let conf;
const fixture = {
a: 1,
b: [2, 2],
c: { x: 3, y: 3 },
};

beforeEach(() => {
conf = new ConfigStore({ cwd: tmp.dirSync({ unsafeCleanup: true }).name });
});

test('config store is defined', () => {
expect(ConfigStore).toBeDefined();
});

test('.get 2-args to work as in parent', () => {
expect(conf.get('foo')).not.toBeDefined();
expect(conf.get('foo', 'bar')).toBe('bar');
conf.set('foo', fixture);
expect(conf.get('foo')).toEqual(fixture);
});

test('.get to ignore null or false merge mode', () => {
conf.set('foo', fixture);
expect(conf.get('foo', { d: 4 }, null)).toEqual(fixture);
expect(conf.get('foo', { d: 4 }, false)).toEqual(fixture);
});

test('.get merge mode to merge the defaults', () => {
conf.set('foo', fixture);
expect(conf.get('foo', { c: { z: 3 } }, true)).toEqual({
a: 1,
b: [2, 2],
c: { x: 3, y: 3, z: 3 },
});
});

test('.get merge mode override the defaults', () => {
conf.set('foo', fixture);
expect(conf.get('foo', { a: 'foo' }, true)).toEqual(fixture);
expect(conf.get('foo', { c: { x: 'foo' } }, true)).toEqual(fixture);
});

test('.get merge mode ignores non-object defaults', () => {
conf.set('foo', fixture);
expect(conf.get('foo', 'foo', true)).toEqual(fixture);
expect(conf.get('foo', null, true)).toEqual(fixture);
});

test('.get merge mode concatenates arrays', () => {
conf.set('foo', fixture);
expect(conf.get('foo', { b: ['x'] }, true)).toMatchObject({ b: ['x', 2, 2] });
});
29 changes: 29 additions & 0 deletions packages/ace-config/src/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

const path = require('path');
const { config, paths, constants } = require('..');

test('config store is defined', () => {
expect(config).toBeDefined();
});

test('config file default name', () => {
expect(path.basename(config.path)).toEqual('config.json');
expect(path.basename(path.dirname(config.path))).toEqual('DAISY Ace');
});

test('paths are defined', () => {
expect(paths).toBeDefined();
expect(paths.config).toBeDefined();
expect(paths.data).toBeDefined();
expect(paths.log).toBeDefined();
expect(paths.temp).toBeDefined();
});

test('constants are defined', () => {
expect(constants).toBeDefined();
});

test('constants are as in constants.json', () => {
expect(constants.dirname).toBe('DAISY Ace');
});
20 changes: 20 additions & 0 deletions packages/ace-config/src/config-store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

const Conf = require('conf');
const merge = require('lodash.mergewith');

class ConfigStore extends Conf {

get(key, defaultValue, mergeMode) {
if (mergeMode && typeof defaultValue === 'object') {
return merge({}, defaultValue, super.get(key), (obj, val) => {
if (Array.isArray(obj)) {
return obj.concat(val);
}
});
}
return super.get(key, defaultValue);
}
}

module.exports = ConfigStore;
3 changes: 3 additions & 0 deletions packages/ace-config/src/constants.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"dirname": "DAISY Ace"
}
17 changes: 17 additions & 0 deletions packages/ace-config/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const envPaths = require('env-paths');
const constants = require('./constants');
const ConfigStore = require('./config-store');

const paths = envPaths(constants.dirname, { suffix: null });

const config = new ConfigStore({
cwd: paths.config,
});

module.exports = {
config,
constants: Object.freeze(constants),
paths,
};
24 changes: 23 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,16 @@ [email protected], concat-stream@^1.4.10, concat-stream@^1.5.0, concat-stream@
readable-stream "^2.2.2"
typedarray "^0.0.6"

conf@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/conf/-/conf-1.3.1.tgz#829a82b081bb355129992333be1598f797a56f58"
dependencies:
dot-prop "^4.1.0"
env-paths "^1.0.0"
make-dir "^1.0.0"
pkg-up "^2.0.0"
write-file-atomic "^2.3.0"

configstore@^1.0.0, configstore@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021"
Expand Down Expand Up @@ -1649,6 +1659,12 @@ dot-prop@^3.0.0:
dependencies:
is-obj "^1.0.0"

dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
dependencies:
is-obj "^1.0.0"

duplexer2@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
Expand Down Expand Up @@ -3685,7 +3701,7 @@ lodash.defaultsdeep@^4.3.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81"

lodash.mergewith@^4.3.1:
lodash.mergewith@^4.3.1, lodash.mergewith@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55"

Expand Down Expand Up @@ -4382,6 +4398,12 @@ pkg-dir@^1.0.0:
dependencies:
find-up "^1.0.0"

pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
dependencies:
find-up "^2.1.0"

pluralize@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
Expand Down

0 comments on commit 8987dd8

Please sign in to comment.