Skip to content

Commit

Permalink
Add support for TOML configuration files via --config (refs #113, refs
Browse files Browse the repository at this point in the history
  • Loading branch information
BenniWi committed Feb 21, 2024
1 parent 5fa53b1 commit ca05bed
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 9 deletions.
9 changes: 5 additions & 4 deletions README.md
Expand Up @@ -27,7 +27,7 @@ markdownlint --help

Options:
-V, --version output the version number
-c, --config [configFile] configuration file (JSON, JSONC, JS, or YAML)
-c, --config [configFile] configuration file (JSON, JSONC, JS, YAML, or TOML)
-d, --dot include files/folders with a dot (for example `.github`)
-f, --fix fix basic errors (does not work with STDIN)
-i, --ignore [file|directory|glob] file(s) to ignore/exclude (default: [])
Expand Down Expand Up @@ -88,7 +88,7 @@ Because this option makes changes to the input files, it is good to make a backu

`markdownlint-cli` reuses [the rules][rules] from `markdownlint` package.

Configuration is stored in JSON, JSONC, YAML, or INI files in the same [config format][config].
Configuration is stored in JSON, JSONC, YAML, INI, or TOML files in the same [config format][config].

A sample configuration file:

Expand All @@ -102,7 +102,7 @@ A sample configuration file:
}
```

For more examples, see [.markdownlint.jsonc][markdownlint-jsonc], [.markdownlint.yaml][markdownlint-yaml], or the [style folder][style-folder].
For more examples, see [.markdownlint.jsonc][markdownlint-jsonc], [.markdownlint.yaml][markdownlint-yaml], [test-config.toml](test/test-config.toml) or the [style folder][style-folder].

The CLI argument `--config` is not required.
If it is not provided, `markdownlint-cli` looks for the file `.markdownlint.jsonc`/`.markdownlint.json`/`.markdownlint.yaml`/`.markdownlint.yml` in current folder, or for the file `.markdownlintrc` in the current or all parent folders.
Expand All @@ -116,7 +116,8 @@ A JS configuration file may internally `require` one or more npm packages as a w
`--enable` and `--disable` override configuration files; if a configuration file disables `MD123` and you pass `--enable MD123`, it will be enabled.
If a rule is passed to both `--enable` and `--disable`, it will be disabled.

> JS configuration files must be provided via the `--config` argument; they are not automatically loaded because running untrusted code is a security concern.
> - JS configuration files must be provided via the `--config` argument; they are not automatically loaded because running untrusted code is a security concern.
> - TOML configuration files must be provided via the `--config` argument; they are not automatically loaded.
## Exit codes

Expand Down
8 changes: 7 additions & 1 deletion markdownlint.js
Expand Up @@ -36,6 +36,11 @@ function yamlParse(text) {
return require('js-yaml').load(text);
}

function tomlParse(text) {
// It is necessary to add the prototype manually because of https://github.com/BinaryMuse/toml-node/issues/55
return require('deep-extend')({}, require('toml').parse(text));
}

const exitCodes = {
lintFindings: 1,
failedToWriteOutputFile: 2,
Expand All @@ -44,7 +49,8 @@ const exitCodes = {
};

const projectConfigFiles = ['.markdownlint.jsonc', '.markdownlint.json', '.markdownlint.yaml', '.markdownlint.yml'];
const configParsers = [jsoncParse, yamlParse];
// TOML files can be (incorrectly) read by yamlParse (but not vice versa), so tomlParse needs to go before yamlParse
const configParsers = [jsoncParse, tomlParse, yamlParse];
const fsOptions = {encoding: 'utf8'};
const processCwd = process.cwd();

Expand Down
13 changes: 12 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -45,7 +45,8 @@
"jsonc-parser": "~3.2.1",
"markdownlint": "~0.33.0",
"minimatch": "~9.0.3",
"run-con": "~1.3.2"
"run-con": "~1.3.2",
"toml": "~3.0.0"
},
"devDependencies": {
"ava": "^6.1.1",
Expand Down
2 changes: 1 addition & 1 deletion test/md043-config.js
Expand Up @@ -6,6 +6,6 @@
module.exports = {
MD012: false,
MD043: {
headers: ['# First', '## Second', '### Third']
headings: ['# First', '## Second', '### Third']
}
};
2 changes: 1 addition & 1 deletion test/md043-config.json
@@ -1,7 +1,7 @@
{
"MD012": false,
"MD043": {
"headers": [
"headings": [
"# First",
"## Second",
"### Third"
Expand Down
2 changes: 2 additions & 0 deletions test/md043-config.toml
@@ -0,0 +1,2 @@
MD012 = false
MD043 = { headings = ["# First", "## Second", "### Third"] }
14 changes: 14 additions & 0 deletions test/test-config.toml
@@ -0,0 +1,14 @@
default = true
no-hard-tabs = false
whitespace = false
MD033 = false
MD034 = false

[MD003]
style = "atx"

[MD007]
indent = 4

[MD013]
line_length = 200
12 changes: 12 additions & 0 deletions test/test-config.yaml
@@ -0,0 +1,12 @@
default: true
no-hard-tabs: false
whitespace: false
MD033: false
MD034: false
MD003:
style: atx
MD007:
indent: 2
MD013:
line_length: 200

29 changes: 29 additions & 0 deletions test/test.js
Expand Up @@ -400,6 +400,35 @@ test('configuration file can be JavaScript', async t => {
t.is(result.exitCode, 0);
});

test('configuration file can be TOML', async t => {
const result = await execa('../markdownlint.js', ['--config', 'md043-config.toml', 'md043-config.md'], {stripFinalNewline: false});
t.is(result.stdout, '');
t.is(result.stderr, '');
t.is(result.exitCode, 0);
});

test('linting using a toml configuration file works', async t => {
try {
await execa('../markdownlint.js', ['--config', 'test-config.toml', '**/*.md'], {stripFinalNewline: false});
t.fail();
} catch (error) {
t.is(error.stdout, '');
t.is(error.stderr.match(errorPattern).length, 15);
t.is(error.exitCode, 1);
}
});

test('linting using a yaml configuration file works', async t => {
try {
await execa('../markdownlint.js', ['--config', 'test-config.yaml', '**/*.md'], {stripFinalNewline: false});
t.fail();
} catch (error) {
t.is(error.stdout, '');
t.is(error.stderr.match(errorPattern).length, 15);
t.is(error.exitCode, 1);
}
});

test('error on configuration file not found', async t => {
try {
await execa('../markdownlint.js', ['--config', 'non-existent-file-path.yaml', 'correct.md'], {stripFinalNewline: false});
Expand Down

0 comments on commit ca05bed

Please sign in to comment.