diff --git a/options-manager.js b/options-manager.js index 54563286..2c70ad1d 100644 --- a/options-manager.js +++ b/options-manager.js @@ -74,8 +74,8 @@ function normalizeOpts(opts) { function mergeWithPkgConf(opts) { opts = Object.assign({cwd: process.cwd()}, opts); - - return Object.assign({}, pkgConf.sync('xo', opts.cwd), opts); + const pkgConfOpts = {cwd: opts.cwd, skipOnFalse: true}; + return Object.assign({}, pkgConf.sync('xo', pkgConfOpts), opts); } // define the shape of deep properties for deepAssign diff --git a/package.json b/package.json index a0f510bf..ceea5f6b 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "meow": "^3.4.2", "multimatch": "^2.1.0", "path-exists": "^3.0.0", - "pkg-conf": "^1.0.1", + "pkg-conf": "^2.0.0", "resolve-cwd": "^1.0.0", "resolve-from": "^2.0.0", "update-notifier": "^1.0.0", diff --git a/readme.md b/readme.md index 8ccd6635..874d7b31 100644 --- a/readme.md +++ b/readme.md @@ -252,6 +252,10 @@ XO makes it easy to override configs for specific files. The `overrides` propert } ``` +## Using a parent's config +If you have a directory structured with nested `package.json` files +and you want one of the child manifests to be skipped you can do so +by setting `"xo": false`. ## FAQ diff --git a/test/fixtures/nested/child-empty/package.json b/test/fixtures/nested/child-empty/package.json new file mode 100644 index 00000000..91bf1fcd --- /dev/null +++ b/test/fixtures/nested/child-empty/package.json @@ -0,0 +1,3 @@ +{ + "xo": {} +} diff --git a/test/fixtures/nested/child-ignore/package.json b/test/fixtures/nested/child-ignore/package.json new file mode 100644 index 00000000..f2639cdb --- /dev/null +++ b/test/fixtures/nested/child-ignore/package.json @@ -0,0 +1,3 @@ +{ + "xo": false +} diff --git a/test/fixtures/nested/child/package.json b/test/fixtures/nested/child/package.json new file mode 100644 index 00000000..403fa360 --- /dev/null +++ b/test/fixtures/nested/child/package.json @@ -0,0 +1,5 @@ +{ + "xo": { + "esnext": false + } +} diff --git a/test/fixtures/nested/file.js b/test/fixtures/nested/file.js new file mode 100644 index 00000000..ad7d1b96 --- /dev/null +++ b/test/fixtures/nested/file.js @@ -0,0 +1,2 @@ +var obj = { a: 1 }; +console.log(obj.a); diff --git a/test/fixtures/nested/package.json b/test/fixtures/nested/package.json new file mode 100644 index 00000000..730c497c --- /dev/null +++ b/test/fixtures/nested/package.json @@ -0,0 +1,5 @@ +{ + "xo": { + "esnext": true + } +} diff --git a/test/options-manager.js b/test/options-manager.js index 57ce02ce..3fff1a72 100644 --- a/test/options-manager.js +++ b/test/options-manager.js @@ -1,5 +1,8 @@ +import path from 'path'; import test from 'ava'; import proxyquire from 'proxyquire'; +import parentConfig from './fixtures/nested/package.json'; +import childConfig from './fixtures/nested/child/package.json'; const manager = proxyquire('../options-manager', { 'resolve-from': (cwd, path) => `cwd/${path}` @@ -138,3 +141,30 @@ test('groupConfigs', t => { return obj; })); }); + +test('mergeWithPkgConf: use child if closest', t => { + const cwd = path.resolve('fixtures', 'nested', 'child'); + const result = manager.mergeWithPkgConf({cwd}); + const expected = Object.assign({}, childConfig.xo, {cwd}); + t.deepEqual(result, expected); +}); + +test('mergeWithPkgConf: use parent if closest', t => { + const cwd = path.resolve('fixtures', 'nested'); + const result = manager.mergeWithPkgConf({cwd}); + const expected = Object.assign({}, parentConfig.xo, {cwd}); + t.deepEqual(result, expected); +}); + +test('mergeWithPkgConf: use parent if child is ignored', t => { + const cwd = path.resolve('fixtures', 'nested', 'child-ignore'); + const result = manager.mergeWithPkgConf({cwd}); + const expected = Object.assign({}, parentConfig.xo, {cwd}); + t.deepEqual(result, expected); +}); + +test('mergeWithPkgConf: use child if child is empty', t => { + const cwd = path.resolve('fixtures', 'nested', 'child-empty'); + const result = manager.mergeWithPkgConf({cwd}); + t.deepEqual(result, {cwd}); +});