Skip to content

Commit f7234b6

Browse files
committed
fix(core): consider config outside of current git repo
1 parent 64981d2 commit f7234b6

File tree

11 files changed

+148
-15
lines changed

11 files changed

+148
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
rules: {
3+
'type-enum': [2, 'always', ['outer']]
4+
}
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
rules: {
3+
'type-enum': [2, 'always', ['inner']]
4+
}
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
rules: {
3+
'type-enum': [2, 'always', ['outer']]
4+
}
5+
};

@commitlint/cli/src/cli.test.js

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import path from 'path';
2-
import {git} from '@commitlint/test';
2+
import {fix, git} from '@commitlint/test';
33
import test from 'ava';
44
import execa from 'execa';
55
import {merge} from 'lodash';
@@ -118,6 +118,38 @@ test('should pick up parser preset and succeed accordingly', async t => {
118118
t.is(actual.code, 0);
119119
});
120120

121+
test('should pick up config from outside git repo and fail accordingly', async t => {
122+
const outer = await fix.bootstrap('fixtures/outer-scope');
123+
const cwd = await git.init(path.join(outer, 'inner-scope'));
124+
125+
const actual = await cli([], {cwd})('inner: bar');
126+
t.is(actual.code, 1);
127+
});
128+
129+
test('should pick up config from outside git repo and succeed accordingly', async t => {
130+
const outer = await fix.bootstrap('fixtures/outer-scope');
131+
const cwd = await git.init(path.join(outer, 'inner-scope'));
132+
133+
const actual = await cli([], {cwd})('outer: bar');
134+
t.is(actual.code, 0);
135+
});
136+
137+
test('should pick up config from inside git repo with precedence and succeed accordingly', async t => {
138+
const outer = await fix.bootstrap('fixtures/inner-scope');
139+
const cwd = await git.init(path.join(outer, 'inner-scope'));
140+
141+
const actual = await cli([], {cwd})('inner: bar');
142+
t.is(actual.code, 0);
143+
});
144+
145+
test('should pick up config from inside git repo with precedence and fail accordingly', async t => {
146+
const outer = await fix.bootstrap('fixtures/inner-scope');
147+
const cwd = await git.init(path.join(outer, 'inner-scope'));
148+
149+
const actual = await cli([], {cwd})('outer: bar');
150+
t.is(actual.code, 1);
151+
});
152+
121153
async function writePkg(payload, options) {
122154
const pkgPath = path.join(options.cwd, 'package.json');
123155
const pkg = JSON.parse(await sander.readFile(pkgPath));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
rules: {
3+
outer: true,
4+
inner: false,
5+
child: false
6+
}
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
rules: {
3+
outer: false,
4+
inner: false,
5+
child: true
6+
}
7+
};

@commitlint/core/src/load.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,16 @@ import resolveFrom from 'resolve-from';
55

66
import executeRule from './library/execute-rule';
77
import resolveExtends from './library/resolve-extends';
8-
import toplevel from './library/toplevel';
98

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

1312
export default async (seed = {}, options = {cwd: ''}) => {
14-
const explorer = cosmiconfig('commitlint', {
15-
rcExtensions: true,
16-
stopDir: await toplevel(options.cwd)
17-
});
18-
19-
const raw = (await explorer.load(options.cwd)) || {};
20-
const base = raw.filepath ? path.dirname(raw.filepath) : options.cwd;
13+
const loaded = await loadConfig(options.cwd);
14+
const base = loaded.filepath ? path.dirname(loaded.filepath) : options.cwd;
2115

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

2620
// Resolve parserPreset key
@@ -80,3 +74,17 @@ export default async (seed = {}, options = {cwd: ''}) => {
8074
return registry;
8175
}, preset);
8276
};
77+
78+
async function loadConfig(cwd) {
79+
const explorer = cosmiconfig('commitlint', {
80+
rcExtensions: true
81+
});
82+
83+
const local = await explorer.load(cwd);
84+
85+
if (local) {
86+
return local;
87+
}
88+
89+
return {};
90+
}

@commitlint/core/src/load.test.js

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {git} from '@commitlint/test';
1+
import path from 'path';
2+
import {fix, git} from '@commitlint/test';
23
import test from 'ava';
34

45
import load from './load';
@@ -181,3 +182,35 @@ test('ignores unknow keys recursively', async t => {
181182
}
182183
});
183184
});
185+
186+
test('find up from given cwd', async t => {
187+
const outer = await fix.bootstrap('fixtures/outer-scope');
188+
await git.init(path.join(outer, 'inner-scope'));
189+
const cwd = path.join(outer, 'inner-scope', 'child-scope');
190+
191+
const actual = await load({}, {cwd});
192+
193+
t.deepEqual(actual, {
194+
extends: [],
195+
rules: {
196+
child: true,
197+
inner: false,
198+
outer: false
199+
}
200+
});
201+
});
202+
203+
test('find up config from outside current git repo', async t => {
204+
const outer = await fix.bootstrap('fixtures/outer-scope');
205+
const cwd = await git.init(path.join(outer, 'inner-scope'));
206+
const actual = await load({}, {cwd});
207+
208+
t.deepEqual(actual, {
209+
extends: [],
210+
rules: {
211+
child: false,
212+
inner: false,
213+
outer: true
214+
}
215+
});
216+
});

@packages/test/src/fix.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import crypto from 'crypto';
2+
import os from 'os';
3+
import path from 'path';
4+
5+
import * as sander from '@marionebl/sander';
6+
import pkgDir from 'pkg-dir';
7+
8+
export {bootstrap};
9+
10+
async function bootstrap(fixture) {
11+
const cwd = path.join(os.tmpdir(), rand());
12+
13+
if (typeof fixture !== 'undefined') {
14+
await sander.copydir(await pkgDir(), fixture).to(cwd);
15+
}
16+
17+
return cwd;
18+
}
19+
20+
function rand() {
21+
return crypto
22+
.randomBytes(Math.ceil(6))
23+
.toString('hex')
24+
.slice(0, 12);
25+
}

@packages/test/src/git.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as sander from '@marionebl/sander';
66
import execa from 'execa';
77
import pkgDir from 'pkg-dir';
88

9-
export {bootstrap, clone};
9+
export {bootstrap, clone, init};
1010

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

18-
await execa('git', ['init', cwd]);
19-
await setup(cwd);
18+
await init(cwd);
2019
return cwd;
2120
}
2221

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

29+
async function init(cwd) {
30+
await execa('git', ['init', cwd]);
31+
await setup(cwd);
32+
return cwd;
33+
}
34+
3035
async function setup(cwd) {
3136
try {
3237
await execa('git', ['config', 'user.name', 'ava'], {cwd});

@packages/test/src/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1+
import * as fix from './fix';
12
import * as git from './git';
23
import * as npm from './npm';
34

4-
export {git, npm};
5+
export {fix, git, npm};

0 commit comments

Comments
 (0)