Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change configuration loading to cosmiconfig #420

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/options-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const os = require('os');
const path = require('path');
const arrify = require('arrify');
const {cosmiconfigSync, defaultLoaders} = require('cosmiconfig');
const mergeWith = require('lodash/mergeWith');
const multimatch = require('multimatch');
const pathExists = require('path-exists');
Expand Down Expand Up @@ -155,14 +156,27 @@ const normalizeOptions = options => {
return options;
};

const loadPackageConfig = options => {
const moduleName = 'xo';
// Yaml is disabled
const searchPlaces = ['package.json',
`.${moduleName}rc`,
`.${moduleName}rc.json`,
`.${moduleName}rc.js`,
`${moduleName}.config.js`];
const loaders = {noExt: defaultLoaders['.json']};
const searchResult = cosmiconfigSync(moduleName, {searchPlaces, loaders}).search(options.cwd);
return searchResult ? searchResult.config : {};
};

const mergeWithPackageConfig = options => {
options = {
cwd: process.cwd(),
...options
};

options.cwd = path.resolve(options.cwd);
const config = pkgConf.sync('xo', {cwd: options.cwd, skipOnFalse: true});
const config = loadPackageConfig(options);
const engines = pkgConf.sync('engines', {cwd: options.cwd});

return {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
],
"dependencies": {
"arrify": "^2.0.1",
"cosmiconfig": "^6.0.0",
"debug": "^4.1.0",
"eslint": "^6.4.0",
"eslint-config-prettier": "^6.3.0",
Expand Down
19 changes: 18 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ Then just run `$ npm test` and XO will be run before your tests.

## Config

You can configure some options in XO by putting it in package.json:
You can configure some options in XO by putting it

1. either in package.json:
```json
{
"name": "awesome-package",
Expand All @@ -145,6 +146,22 @@ You can configure some options in XO by putting it in package.json:
}
```

2. putting valid json data in one of the files `.xorc` or `.xorc.json`:
```json
{
"space": true
}
```
3. or creating a loadable js-module in one of the files `.xorc.js` or `xo.config.js`:
```js
use strict;

module.exports = {
space: true
};
```
All configuration files should be created in the same folder as the package.json file and should contain pure json data or a loadable js-module. YAML configuration files are not supported.

[Globals](https://eslint.org/docs/user-guide/configuring#specifying-globals) and [rules](https://eslint.org/docs/user-guide/configuring#configuring-rules) can be configured inline in files.

### envs
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/config_file/js_config_extension/xo.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
eslint: true,
space: true
};
6 changes: 6 additions & 0 deletions test/fixtures/config_file/js_extension/.xorc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
eslint: true,
space: false
};
4 changes: 4 additions & 0 deletions test/fixtures/config_file/json_extension/.xorc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"esnext": false,
"space": true
}
4 changes: 4 additions & 0 deletions test/fixtures/config_file/no_extension/.xorc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"esnext": true,
"space": true
}
3 changes: 3 additions & 0 deletions test/fixtures/config_file/yaml/.xorc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# yaml config
---
eslint: true
35 changes: 35 additions & 0 deletions test/options-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,38 @@ test('mergeWithPackageConfig: XO engine options false supersede package.json\'s'
const expected = {nodeVersion: false, cwd};
t.deepEqual(result, expected);
});

test('mergeWithPackageConfig: read config from json-file `.xorc`', t => {
const cwd = path.resolve('fixtures', 'config_file', 'no_extension');
const result = manager.mergeWithPackageConfig({cwd, nodeVersion: false});
const expected = {esnext: true, space: true, nodeVersion: false, cwd};
t.deepEqual(result, expected);
});

test('mergeWithPackageConfig: read config from json-file `.xorc.json`', t => {
const cwd = path.resolve('fixtures', 'config_file', 'json_extension');
const result = manager.mergeWithPackageConfig({cwd, nodeVersion: false});
const expected = {esnext: false, space: true, nodeVersion: false, cwd};
t.deepEqual(result, expected);
});

test('mergeWithPackageConfig: read config from js-module `.xorc.js`', t => {
const cwd = path.resolve('fixtures', 'config_file', 'js_extension');
const result = manager.mergeWithPackageConfig({cwd, nodeVersion: false});
const expected = {eslint: true, space: false, nodeVersion: false, cwd};
t.deepEqual(result, expected);
});

test('mergeWithPackageConfig: read config from js-module `xo.config.js`', t => {
const cwd = path.resolve('fixtures', 'config_file', 'js_config_extension');
const result = manager.mergeWithPackageConfig({cwd, nodeVersion: false});
const expected = {eslint: true, space: true, nodeVersion: false, cwd};
t.deepEqual(result, expected);
});

test('mergeWithPackageConfig: should fail when `.xorc` is yaml-file', t => {
const cwd = path.resolve('fixtures', 'config_file', 'yaml');
t.throws(() => {
manager.mergeWithPackageConfig({cwd, nodeVersion: false});
}, {name: 'JSONError'});
});