Skip to content

Commit

Permalink
feat(config): support TOML configuration files (#4877)
Browse files Browse the repository at this point in the history
* Add initial support for TOML in configuration files

* Missed brace

* Fix snapshots

* refactor: move loadToml to utils

* Use @iarna/toml

* Add tests for loadToml

* Fix test for CI

* Remove jest-extended

* Create snapshot for load-toml

* Add feat to docs

* lint docs

* Use @iarna/toml/parse-string

* Change path string
  • Loading branch information
jorgegonzalez authored and j-f1 committed Aug 3, 2018
1 parent 42ba638 commit 7d78ce6
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/configuration.md
Expand Up @@ -6,6 +6,7 @@ title: Configuration File
Prettier uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for configuration file support. This means you can configure prettier via:

- A `.prettierrc` file, written in YAML or JSON, with optional extensions: `.yaml/.yml/.json/.js`.
- A `.prettierrc.toml` file, written in TOML (the `.toml` extension is _required_).
- A `prettier.config.js` file that exports an object.
- A `"prettier"` key in your `package.json` file.

Expand Down Expand Up @@ -42,6 +43,14 @@ printWidth: 100
parser: flow
```

TOML:

```toml
# .prettierrc.toml
printWidth = 100
parser = "flow"
```

## Configuration Overrides

Prettier borrows eslint's [override format](http://eslint.org/docs/user-guide/configuring#example-configuration). This allows you to apply configuration to specific files.
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -17,6 +17,7 @@
"@babel/code-frame": "7.0.0-beta.46",
"@babel/parser": "7.0.0-beta.55",
"@glimmer/syntax": "0.30.3",
"@iarna/toml": "2.0.0",
"camelcase": "4.1.0",
"chalk": "2.1.0",
"cjk-regex": "1.0.2",
Expand Down
14 changes: 14 additions & 0 deletions src/config/resolve-config.js
Expand Up @@ -6,6 +6,7 @@ const path = require("path");
const mem = require("mem");

const resolveEditorConfig = require("./resolve-config-editorconfig");
const loadToml = require("../utils/load-toml");

const getExplorerMemoized = mem(opts => {
const explorer = thirdParty.cosmiconfig("prettier", {
Expand All @@ -22,6 +23,19 @@ const getExplorerMemoized = mem(opts => {
delete result.config.$schema;
}
return result;
},
searchPlaces: [
"package.json",
".prettierrc",
".prettierrc.json",
".prettierrc.yaml",
".prettierrc.yml",
".prettierrc.js",
"prettier.config.js",
".prettierrc.toml"
],
loaders: {
".toml": loadToml
}
});

Expand Down
12 changes: 12 additions & 0 deletions src/utils/load-toml.js
@@ -0,0 +1,12 @@
"use strict";

const parse = require("@iarna/toml/parse-string");

module.exports = function(filePath, content) {
try {
return parse(content);
} catch (error) {
error.message = `TOML Error in ${filePath}:\n${error.message}`;
throw error;
}
};
Expand Up @@ -62,6 +62,16 @@ function rcJson() {
],
);
}
function rcToml() {
console.log.apply(
null,
[
'rc-toml/file.js',
'should have trailing comma',
'and single quotes',
],
);
}
function rcYaml() {
console.log.apply(
null,
Expand Down Expand Up @@ -142,6 +152,13 @@ function rcJson() {
'and single quotes',
]);
}
function rcToml() {
console.log.apply(null, [
'rc-toml/file.js',
'should have trailing comma',
'and single quotes',
]);
}
function rcYaml() {
console.log.apply(null, [
'rc-yaml/file.js',
Expand Down Expand Up @@ -181,6 +198,15 @@ exports[`resolves json configuration file with --find-config-path file (stdout)

exports[`resolves json configuration file with --find-config-path file (write) 1`] = `Array []`;

exports[`resolves toml configuration file with --find-config-path file (stderr) 1`] = `""`;

exports[`resolves toml configuration file with --find-config-path file (stdout) 1`] = `
"rc-toml/.prettierrc.toml
"
`;

exports[`resolves toml configuration file with --find-config-path file (write) 1`] = `Array []`;

exports[`resolves yaml configuration file with --find-config-path file (stderr) 1`] = `""`;

exports[`resolves yaml configuration file with --find-config-path file (stdout) 1`] = `
Expand Down
36 changes: 36 additions & 0 deletions tests_integration/__tests__/__snapshots__/load-toml.js.snap
@@ -0,0 +1,36 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TOML loads toml successfully 1`] = `
Object {
"database": Object {
"connection_max": 5000,
"enabled": true,
"ports": Array [
8001,
8001,
8002,
],
"server": "192.168.1.1",
Symbol(type): Symbol(table),
Symbol(declared): true,
},
"owner": Object {
"dob": 1979-05-27T15:32:00.000Z,
"name": "Tom Preston-Werner",
Symbol(type): Symbol(table),
Symbol(declared): true,
},
"title": "TOML Example",
Symbol(type): Symbol(table),
Symbol(declared): false,
}
`;

exports[`TOML throws error on incorrect toml 1`] = `
"TOML Error in example.toml:
Unknown character \\"47\\" at row 1, col 2, pos 1:
1> ///ERROR///
^
"
`;
Expand Up @@ -139,6 +139,16 @@ function rcJson() {
],
);
}
function rcToml() {
console.log.apply(
null,
[
'rc-toml/file.js',
'should have trailing comma',
'and single quotes',
],
);
}
function rcYaml() {
console.log.apply(
null,
Expand Down Expand Up @@ -216,6 +226,16 @@ function rcJson() {
],
);
}
function rcToml() {
console.log.apply(
null,
[
'rc-toml/file.js',
'should have trailing comma',
'and single quotes',
],
);
}
function rcYaml() {
console.log.apply(
null,
Expand Down
6 changes: 6 additions & 0 deletions tests_integration/__tests__/config-resolution.js
Expand Up @@ -43,6 +43,12 @@ describe("resolves yaml configuration file with --find-config-path file", () =>
});
});

describe("resolves toml configuration file with --find-config-path file", () => {
runPrettier("cli/config/", ["--find-config-path", "rc-toml/file.js"]).test({
status: 0
});
});

describe("prints nothing when no file found with --find-config-path", () => {
runPrettier("cli/config/", ["--find-config-path", ".."]).test({
stdout: "",
Expand Down
37 changes: 37 additions & 0 deletions tests_integration/__tests__/load-toml.js
@@ -0,0 +1,37 @@
"use strict";

const loadToml = require("../../src/utils/load-toml");

describe("TOML", () => {
const exampleFilePath = "example.toml";

const exampleToml = `
# This is a TOML document.
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
`;

const wrongToml = "///ERROR///";

test("loads toml successfully", () => {
const parsedToml = loadToml(exampleFilePath, exampleToml);
expect(parsedToml).toMatchSnapshot();
});

test("throws error on incorrect toml", () => {
expect(() => {
loadToml(exampleFilePath, wrongToml);
}).toThrow();

expect(() => {
loadToml(exampleFilePath, wrongToml);
}).toThrowErrorMatchingSnapshot();
});
});
2 changes: 2 additions & 0 deletions tests_integration/cli/config/rc-toml/.prettierrc.toml
@@ -0,0 +1,2 @@
trailingComma = "all"
singleQuote = true
7 changes: 7 additions & 0 deletions tests_integration/cli/config/rc-toml/file.js
@@ -0,0 +1,7 @@
function rcToml() {
console.log.apply(null, [
"rc-toml/file.js",
"should have trailing comma",
"and single quotes"
]);
}
4 changes: 4 additions & 0 deletions yarn.lock
Expand Up @@ -563,6 +563,10 @@
dependencies:
"@glimmer/util" "^0.30.3"

"@iarna/toml@2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.0.0.tgz#7802115684397785b3b6dc8a3ba50e30d7a7422b"

"@types/commander@^2.11.0":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae"
Expand Down

0 comments on commit 7d78ce6

Please sign in to comment.