Skip to content

Commit

Permalink
Feat: Configuration via cosmiconfig
Browse files Browse the repository at this point in the history
Closes sapegin#25
  • Loading branch information
apoleshchuk committed Oct 9, 2018
1 parent 8b62d83 commit 6540fbb
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 17 deletions.
10 changes: 9 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,17 @@ Create `~/.mrm/config.json` or `~/dotfiles/mrm/config.json`:
}
```

Via [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) `.mrmrc.json`:

```json5
{
"preset": "@company/mrm-preset-default"
}
```

See [tasks docs](https://github.com/sapegin/mrm-tasks) for available config options.

*Config file isn’t required, you can also pass config options via command line. Default tasks will try to [read data](https://github.com/sapegin/user-meta) fom your npm and Git configuration.*
*Config file isn’t required, you can also pass config options via command line or cosmiconfig. Default tasks will try to [read data](https://github.com/sapegin/user-meta) fom your npm and Git configuration.*

## Tasks

Expand Down
14 changes: 9 additions & 5 deletions bin/mrm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const listify = require('listify');
const updateNotifier = require('update-notifier');
const { padEnd, sortBy } = require('lodash');
const { random } = require('middleearth-names');
const { run, getConfig, getAllTasks, tryResolve } = require('../src/index');
const { run, getConfig, getConfigFromCosmiconfig, getAllTasks, tryResolve } = require('../src/index');
const { MrmUnknownTask, MrmUnknownAlias, MrmUndefinedOption } = require('../src/errors');

let directories = [path.resolve(userHome, 'dotfiles/mrm'), path.resolve(userHome, '.mrm')];
Expand Down Expand Up @@ -43,9 +43,13 @@ const tasks = argv._;
const binaryPath = process.env._;
const binaryName = binaryPath && binaryPath.endsWith('/npx') ? 'npx mrm' : 'mrm';

const configFromCosmiconfig = getConfigFromCosmiconfig();

// Custom config / tasks directory
if (argv.dir) {
const dir = path.resolve(argv.dir);
const customDirs = [configFromCosmiconfig, argv]
.filter(conf => conf.dir)
.map(conf => path.resolve(conf.dir));
for (const dir of customDirs) {
if (!isDirectory.sync(dir)) {
printError(`Directory “${dir}” not found.`);
process.exit(1);
Expand All @@ -55,7 +59,7 @@ if (argv.dir) {
}

// Preset
const preset = argv.preset || 'default';
const preset = argv.preset || configFromCosmiconfig.preset || 'default';
const isDefaultPreset = preset === 'default';
if (isDefaultPreset) {
directories.push(path.dirname(require.resolve('mrm-preset-default')));
Expand All @@ -70,7 +74,7 @@ We’ve tried to load “mrm-preset-${preset}” and “${preset}” globally in
directories = [path.dirname(presetPath)];
}

const options = getConfig(directories, 'config.json', argv);
const options = getConfig(directories, 'config.json', argv, configFromCosmiconfig);
if (tasks.length === 0 || tasks[0] === 'help') {
commandHelp();
} else {
Expand Down
15 changes: 5 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"src"
],
"dependencies": {
"cosmiconfig": "^5.0.6",
"git-username": "^1.0.0",
"glob": "^7.1.2",
"is-directory": "^0.3.1",
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
tryResolve,
getConfigFromFile,
getConfigFromCommandLine,
getConfigFromCosmiconfig,
getConfig,
getConfigGetter,
runTask,
Expand Down Expand Up @@ -42,6 +43,8 @@ const argv = {
'config:foo': 42,
'config:bar': 'coffee',
};
const cosmiconfigOptions = {stopDir: path.resolve(__dirname, '../..')};
const cosmiconfigDirectory = path.resolve(__dirname, '../../test/cosmiconfig');

const file = name => path.join(__dirname, '../../test', name);

Expand Down Expand Up @@ -121,6 +124,21 @@ describe('getConfigFromCommandLine', () => {
});
});

describe('getConfigFromCosmiconfig', () => {
it('should return a config object', () => {
const result = getConfigFromCosmiconfig(cosmiconfigDirectory, cosmiconfigOptions);
expect(result).toEqual({
foo: 42,
bar: 'coffee',
});
});

it('should return an empty object when no config options found', () => {
const result = getConfigFromCosmiconfig(__dirname, cosmiconfigOptions);
expect(result).toEqual({});
});
});

describe('getConfig', () => {
it('should return a config object', () => {
const result = getConfig(directories, configFile, argv);
Expand Down
24 changes: 23 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const glob = require('glob');
const kleur = require('kleur');
const requireg = require('requireg');
const { get, forEach } = require('lodash');
const cosmiconfig = require('cosmiconfig');
const { MrmUnknownTask, MrmUnknownAlias, MrmUndefinedOption } = require('./errors');

/* eslint-disable no-console */
Expand Down Expand Up @@ -209,12 +210,14 @@ function getConfigGetter(options) {
* @param {string[]} directories
* @param {string} filename
* @param {Object} argv
* @param {Object} [configFromCosmiconfig]
* @return {Object}
*/
function getConfig(directories, filename, argv) {
function getConfig(directories, filename, argv, configFromCosmiconfig) {
return Object.assign(
{},
getConfigFromFile(directories, filename),
configFromCosmiconfig || {},
getConfigFromCommandLine(argv)
);
}
Expand Down Expand Up @@ -251,6 +254,24 @@ function getConfigFromCommandLine(argv) {
return options;
}

/**
* Get config options from cosmiconfig.
*
* @param {string} [searchFrom]
* @param {Object} [cosmiconfigOptions]
* @return {Object}
*/
function getConfigFromCosmiconfig(searchFrom, cosmiconfigOptions) {
const explorer = cosmiconfig('mrm', cosmiconfigOptions);
const result = explorer.searchSync(searchFrom);

if (result) {
return result.config;
}

return {};
}

/**
* Try to load a file from a list of folders.
*
Expand Down Expand Up @@ -306,6 +327,7 @@ module.exports = {
getConfig,
getConfigFromFile,
getConfigFromCommandLine,
getConfigFromCosmiconfig,
tryFile,
tryResolve,
firstResult,
Expand Down
1 change: 1 addition & 0 deletions test/cosmiconfig/.mrmrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"bar": "coffee", "foo": 42}

0 comments on commit 6540fbb

Please sign in to comment.