Skip to content

Commit

Permalink
fix(core): consider config outside of current git repo
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Oct 18, 2017
1 parent 64981d2 commit f7234b6
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 15 deletions.
5 changes: 5 additions & 0 deletions @commitlint/cli/fixtures/inner-scope/commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
'type-enum': [2, 'always', ['outer']]
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
'type-enum': [2, 'always', ['inner']]
}
};
5 changes: 5 additions & 0 deletions @commitlint/cli/fixtures/outer-scope/commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
'type-enum': [2, 'always', ['outer']]
}
};
34 changes: 33 additions & 1 deletion @commitlint/cli/src/cli.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path';
import {git} from '@commitlint/test';
import {fix, git} from '@commitlint/test';
import test from 'ava';
import execa from 'execa';
import {merge} from 'lodash';
Expand Down Expand Up @@ -118,6 +118,38 @@ test('should pick up parser preset and succeed accordingly', async t => {
t.is(actual.code, 0);
});

test('should pick up config from outside git repo and fail accordingly', async t => {
const outer = await fix.bootstrap('fixtures/outer-scope');
const cwd = await git.init(path.join(outer, 'inner-scope'));

const actual = await cli([], {cwd})('inner: bar');
t.is(actual.code, 1);
});

test('should pick up config from outside git repo and succeed accordingly', async t => {
const outer = await fix.bootstrap('fixtures/outer-scope');
const cwd = await git.init(path.join(outer, 'inner-scope'));

const actual = await cli([], {cwd})('outer: bar');
t.is(actual.code, 0);
});

test('should pick up config from inside git repo with precedence and succeed accordingly', async t => {
const outer = await fix.bootstrap('fixtures/inner-scope');
const cwd = await git.init(path.join(outer, 'inner-scope'));

const actual = await cli([], {cwd})('inner: bar');
t.is(actual.code, 0);
});

test('should pick up config from inside git repo with precedence and fail accordingly', async t => {
const outer = await fix.bootstrap('fixtures/inner-scope');
const cwd = await git.init(path.join(outer, 'inner-scope'));

const actual = await cli([], {cwd})('outer: bar');
t.is(actual.code, 1);
});

async function writePkg(payload, options) {
const pkgPath = path.join(options.cwd, 'package.json');
const pkg = JSON.parse(await sander.readFile(pkgPath));
Expand Down
7 changes: 7 additions & 0 deletions @commitlint/core/fixtures/outer-scope/commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
rules: {
outer: true,
inner: false,
child: false
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
rules: {
outer: false,
inner: false,
child: true
}
};
26 changes: 17 additions & 9 deletions @commitlint/core/src/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@ import resolveFrom from 'resolve-from';

import executeRule from './library/execute-rule';
import resolveExtends from './library/resolve-extends';
import toplevel from './library/toplevel';

const w = (a, b) => (Array.isArray(b) ? b : undefined);
const valid = input => pick(input, 'extends', 'rules', 'parserPreset');

export default async (seed = {}, options = {cwd: ''}) => {
const explorer = cosmiconfig('commitlint', {
rcExtensions: true,
stopDir: await toplevel(options.cwd)
});

const raw = (await explorer.load(options.cwd)) || {};
const base = raw.filepath ? path.dirname(raw.filepath) : options.cwd;
const loaded = await loadConfig(options.cwd);
const base = loaded.filepath ? path.dirname(loaded.filepath) : options.cwd;

// Merge passed config with file based options
const config = valid(merge(raw.config, seed));
const config = valid(merge(loaded.config, seed));
const opts = merge({extends: [], rules: {}}, pick(config, 'extends'));

// Resolve parserPreset key
Expand Down Expand Up @@ -80,3 +74,17 @@ export default async (seed = {}, options = {cwd: ''}) => {
return registry;
}, preset);
};

async function loadConfig(cwd) {
const explorer = cosmiconfig('commitlint', {
rcExtensions: true
});

const local = await explorer.load(cwd);

if (local) {
return local;
}

return {};
}
35 changes: 34 additions & 1 deletion @commitlint/core/src/load.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {git} from '@commitlint/test';
import path from 'path';
import {fix, git} from '@commitlint/test';
import test from 'ava';

import load from './load';
Expand Down Expand Up @@ -181,3 +182,35 @@ test('ignores unknow keys recursively', async t => {
}
});
});

test('find up from given cwd', async t => {
const outer = await fix.bootstrap('fixtures/outer-scope');
await git.init(path.join(outer, 'inner-scope'));
const cwd = path.join(outer, 'inner-scope', 'child-scope');

const actual = await load({}, {cwd});

t.deepEqual(actual, {
extends: [],
rules: {
child: true,
inner: false,
outer: false
}
});
});

test('find up config from outside current git repo', async t => {
const outer = await fix.bootstrap('fixtures/outer-scope');
const cwd = await git.init(path.join(outer, 'inner-scope'));
const actual = await load({}, {cwd});

t.deepEqual(actual, {
extends: [],
rules: {
child: false,
inner: false,
outer: true
}
});
});
25 changes: 25 additions & 0 deletions @packages/test/src/fix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import crypto from 'crypto';
import os from 'os';
import path from 'path';

import * as sander from '@marionebl/sander';
import pkgDir from 'pkg-dir';

export {bootstrap};

async function bootstrap(fixture) {
const cwd = path.join(os.tmpdir(), rand());

if (typeof fixture !== 'undefined') {
await sander.copydir(await pkgDir(), fixture).to(cwd);
}

return cwd;
}

function rand() {
return crypto
.randomBytes(Math.ceil(6))
.toString('hex')
.slice(0, 12);
}
11 changes: 8 additions & 3 deletions @packages/test/src/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as sander from '@marionebl/sander';
import execa from 'execa';
import pkgDir from 'pkg-dir';

export {bootstrap, clone};
export {bootstrap, clone, init};

async function bootstrap(fixture) {
const cwd = path.join(os.tmpdir(), rand());
Expand All @@ -15,8 +15,7 @@ async function bootstrap(fixture) {
await sander.copydir(await pkgDir(), fixture).to(cwd);
}

await execa('git', ['init', cwd]);
await setup(cwd);
await init(cwd);
return cwd;
}

Expand All @@ -27,6 +26,12 @@ async function clone(source, ...args) {
return cwd;
}

async function init(cwd) {
await execa('git', ['init', cwd]);
await setup(cwd);
return cwd;
}

async function setup(cwd) {
try {
await execa('git', ['config', 'user.name', 'ava'], {cwd});
Expand Down
3 changes: 2 additions & 1 deletion @packages/test/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as fix from './fix';
import * as git from './git';
import * as npm from './npm';

export {git, npm};
export {fix, git, npm};

0 comments on commit f7234b6

Please sign in to comment.