Skip to content

feat(core): Allow to configure with json, yaml and package.json #74

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

Closed
wants to merge 1 commit 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
30 changes: 24 additions & 6 deletions @commitlint/cli/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const exec = (command, args = [], opts = {}) => {
console.log(result.stderr);
}
return result;
}
};
};

const cli = exec.bind(null, CLI);
Expand All @@ -40,8 +40,12 @@ const mkdir = exec.bind(null, bin('mkdirp'));
const npm = exec.bind(null, 'npm');
const rm = exec.bind(null, bin('rimraf'));

test('should throw when called without [input]', t => {
t.throws(cli()(), /Expected a raw commit/);
test('should throw when called without [input]', async t => {
const dir = tmp.dirSync().name;

await init(dir);
await t.throws(cli([], {cwd: dir})(), /Expected a raw commit/);
await rm([dir])();
});

test('should reprint input from stdin', async t => {
Expand Down Expand Up @@ -73,11 +77,19 @@ test('should fail for input from stdin with rule from rc', async t => {
});

test('should fail for input from stdin with rule from js', async t => {
const dir = tmp.dirSync().name;

await init(dir);
await sander.copydir(EXTENDS_ROOT).to(dir);

const actual = await t.throws(
cli(['--extends', './extended'], {cwd: EXTENDS_ROOT})('foo: bar')
cli(['--extends', './extended'], {cwd: dir})('foo: bar')
);

t.true(includes(actual.stdout, 'type must not be one of [foo]'));
t.is(actual.code, 1);

await rm([dir])();
});

test('should produce no error output with --quiet flag', async t => {
Expand Down Expand Up @@ -129,7 +141,9 @@ test('should pick up parser preset', async t => {
const actual = await t.throws(cli([], {cwd})('type(scope)-ticket subject'));
t.true(includes(actual.stdout, 'message may not be empty [subject-empty]'));

await cli(['--parser-preset', './parser-preset'], {cwd})('type(scope)-ticket subject');
await cli(['--parser-preset', './parser-preset'], {cwd})(
'type(scope)-ticket subject'
);
});

async function init(cwd) {
Expand All @@ -142,5 +156,9 @@ async function init(cwd) {
}

function pkg(cwd) {
return sander.writeFile(cwd, 'package.json', JSON.stringify({scripts: {commitmsg: `${CLI} -e`}}));
return sander.writeFile(
cwd,
'package.json',
JSON.stringify({scripts: {commitmsg: `${CLI} -e`}})
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['./first-extended'],
rules: {
zero: 0
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['./second-extended'],
rules: {
one: 1
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
two: 2
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": ["./first-extended"],
"rules": {
"zero": 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['./second-extended'],
rules: {
one: 1
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
two: 2
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['./second-extended'],
rules: {
one: 1
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
two: 2
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"commitlint": {
"extends": ["./first-extended"],
"rules": {
"zero": 0
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extends:
- "./first-extended"
rules:
zero: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['./second-extended'],
rules: {
one: 1
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
two: 2
}
};
3 changes: 2 additions & 1 deletion @commitlint/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"nyc": "10.3.2",
"path-exists": "3.0.0",
"resolve-from": "3.0.0",
"sander": "^0.6.0",
"rimraf": "2.6.1",
"xo": "0.18.2"
},
Expand All @@ -86,10 +87,10 @@
"chalk": "^2.0.1",
"conventional-changelog-angular": "^1.3.3",
"conventional-commits-parser": "^1.3.0",
"cosmiconfig": "^3.0.1",
"find-up": "^2.1.0",
"franc": "^2.0.0",
"git-raw-commits": "^1.1.2",
"import-from": "^2.1.0",
"lodash": "^4.17.4",
"mz": "^2.6.0",
"path-exists": "^3.0.0",
Expand Down
53 changes: 33 additions & 20 deletions @commitlint/core/src/load.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import path from 'path';
import importFrom from 'import-from';
import {entries, merge, mergeWith, pick} from 'lodash';
import rc from 'rc';
import cosmiconfig from 'cosmiconfig';
import resolveFrom from 'resolve-from';
import up from 'find-up';

import resolveExtends from './library/resolve-extends';
import executeRule from './library/execute-rule';
Expand All @@ -12,19 +13,23 @@ const valid = input => pick(input, 'extends', 'rules', 'parserPreset');

export default async (seed = {}) => {
// Obtain config from .rc files
const raw = file();

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

// Resolve parserPreset key
if (typeof config.parserPreset === 'string') {
const resolvedParserPreset = resolveFrom(process.cwd(), config.parserPreset);
const resolvedParserPreset = resolveFrom(
process.cwd(),
config.parserPreset
);

config.parserPreset = {
name: config.parserPreset,
path: `./${path.posix.relative(process.cwd(), resolvedParserPreset)}`.split(path.sep).join('/'),
path: `./${path.posix.relative(process.cwd(), resolvedParserPreset)}`
.split(path.sep)
.join('/'),
opts: require(resolvedParserPreset)
};
}
Expand All @@ -39,7 +44,10 @@ export default async (seed = {}) => {
const preset = valid(mergeWith(extended, config, w));

// Await parser-preset if applicable
if (typeof preset.parserPreset === 'object' && typeof preset.parserPreset.opts === 'object') {
if (
typeof preset.parserPreset === 'object' &&
typeof preset.parserPreset.opts === 'object'
) {
preset.parserPreset.opts = await preset.parserPreset.opts;
}

Expand Down Expand Up @@ -73,14 +81,16 @@ export default async (seed = {}) => {
}, preset);
};

function file() {
async function file() {
const legacy = rc('conventional-changelog-lint');
const legacyFound = typeof legacy.config === 'string';
const explorer = cosmiconfig('commitlint', {
rcExtensions: true,
stopDir: await toplevel()
});
const config = await explorer.load('.');

const found = resolveable('./commitlint.config');
const raw = found ? importFrom(process.cwd(), './commitlint.config') : {};

if (legacyFound && !found) {
if (legacyFound && !config) {
console.warn(
`Using legacy ${path.relative(
process.cwd(),
Expand All @@ -89,7 +99,7 @@ function file() {
);
}

if (legacyFound && found) {
if (legacyFound && config) {
console.warn(
`Ignored legacy ${path.relative(
process.cwd(),
Expand All @@ -98,18 +108,21 @@ function file() {
);
}

if (found) {
return raw;
if (config) {
return config.config;
}

return legacy;
}

function resolveable(id) {
try {
resolveFrom(process.cwd(), id);
return true;
} catch (err) {
return false;
// Find the next git root
// (start: string) => Promise<string | null>
async function toplevel(cwd = process.cwd()) {
const found = await up('.git', {cwd});

if (typeof found !== 'string') {
return found;
}

return path.join(found, '..');
}
Loading