Skip to content

Commit

Permalink
Update: Support prettierignore and custom processors (#111)
Browse files Browse the repository at this point in the history
* Ignore files in .prettierignore

Fixes #88

* Force the babylon parser when parsing not-js files

Forcing the parser stops errors that are caused by trying to run a JS
fragment through the graphql / markdown parsers.

The 'html' parser has not yet been released yet, but will be in Prettier
1.15.

This uses a block list over an allow list because I expect the list of
"file types with a prettier parser that could contain javascript fragments"
will grow at a slower pace than "file types with a prettier parser that
are variations of the javascript language".

Fixes #98, Fixes #81
  • Loading branch information
BPScott authored and not-an-aardvark committed Sep 26, 2018
1 parent 047dc8f commit 38537ba
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .prettierignore
@@ -0,0 +1,5 @@
package.json

# this file doesn't exist, but we use it as a filename that should be ignored
# by prettier in the tests
ignore-me.js
50 changes: 48 additions & 2 deletions eslint-plugin-prettier.js
Expand Up @@ -356,6 +356,7 @@ module.exports = {
const usePrettierrc =
!context.options[1] || context.options[1].usePrettierrc !== false;
const sourceCode = context.getSourceCode();
const filepath = context.getFilename();
const source = sourceCode.text;

// The pragma is only valid if it is found in a block comment at the very
Expand Down Expand Up @@ -397,19 +398,64 @@ module.exports = {
context.options[0] === 'fb'
? FB_PRETTIER_OPTIONS
: context.options[0];

const prettierRcOptions =
usePrettierrc &&
prettier.resolveConfig &&
prettier.resolveConfig.sync
? prettier.resolveConfig.sync(context.getFilename(), {
? prettier.resolveConfig.sync(filepath, {
editorconfig: true
})
: null;

// prettier.getFileInfo was added in v1.13
const prettierFileInfo =
prettier.getFileInfo && prettier.getFileInfo.sync
? prettier.getFileInfo.sync(filepath, {
ignorePath: '.prettierignore'
})
: { ignored: false, inferredParser: null };

// Skip if file is ignored using a .prettierignore file
if (prettierFileInfo.ignored) {
return;
}

const initialOptions = {};

// ESLint suppports processors that let you extract and lint JS
// fragments within a non-JS language. In the cases where prettier
// supports the same language as a processor, we want to process
// the provided source code as javascript (as ESLint provides the
// rules with fragments of JS) instead of guessing the parser
// based off the filename. Otherwise, for instance, on a .md file we
// end up trying to run prettier over a fragment of JS using the
// markdown parser, which throws an error.
// If we can't infer the parser from from the filename, either
// because no filename was provided or because there is no parser
// found for the filename, use javascript.
// This is added to the options first, so that
// prettierRcOptions and eslintPrettierOptions can still override
// the parser.
//
// `parserBlocklist` should contain the list of prettier parser
// names for file types where:
// * Prettier supports parsing the file type
// * There is an ESLint processor that extracts JavaScript snippets
// from the file type.
const parserBlocklist = [null, 'graphql', 'markdown', 'html'];
if (
parserBlocklist.indexOf(prettierFileInfo.inferredParser) !== -1
) {
initialOptions.parser = 'babylon';
}

const prettierOptions = Object.assign(
{},
initialOptions,
prettierRcOptions,
eslintPrettierOptions,
{ filepath: context.getFilename() }
{ filepath }
);

const prettierSource = prettier.format(source, prettierOptions);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -43,7 +43,7 @@
"eslint-plugin-self": "^1.0.1",
"mocha": "^3.1.2",
"moment": "^2.18.1",
"prettier": "^1.10.2",
"prettier": "^1.13.0",
"semver": "^5.3.0",
"vue-eslint-parser": "^2.0.2"
},
Expand Down
27 changes: 24 additions & 3 deletions test/prettier.js
Expand Up @@ -65,6 +65,24 @@ ruleTester.run('prettier', rule, {
code: `var foo = {bar: 0};\n`,
filename: getPrettierRcJsFilename('bracket-spacing'),
options: [{ bracketSpacing: false }, { usePrettierrc: false }]
},
// Ignores filenames in .prettierignore
{
code: `("");\n`,
filename: getPrettierRcJsFilename('single-quote', 'ignore-me.js')
},
// Sets a default parser when it can't be inferred from the file extensions
{
code: `('');\n`,
filename: getPrettierRcJsFilename('single-quote', 'dummy.qqq')
},
// Overwrites the parser for file extensions prettier would try to format
// with not the babylon parser
// In the real world, eslint-plugin-markdown would transform file contents
// into JS snippets that would get passed to ESLint
{
code: `('');\n`,
filename: getPrettierRcJsFilename('single-quote', 'dummy.md')
}
],
invalid: [
Expand Down Expand Up @@ -175,9 +193,12 @@ function loadInvalidFixture(name) {

/**
* Builds a dummy javascript file path to trick prettier into resolving a specific .prettierrc file.
* @param {string} name - Prettierrc fixture basename.
* @param {string} dir - Prettierrc fixture basename.
* @returns {string} A javascript filename relative to the .prettierrc config.
*/
function getPrettierRcJsFilename(name) {
return path.resolve(__dirname, `./prettierrc/${name}/dummy.js`);
function getPrettierRcJsFilename(dir, file) {
// Use default parameters when we drop support for node 4
file = typeof file !== 'undefined' ? file : 'dummy.js';

return path.resolve(__dirname, `./prettierrc/${dir}/${file}`);
}
6 changes: 3 additions & 3 deletions yarn.lock
Expand Up @@ -801,9 +801,9 @@ prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"

prettier@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93"
prettier@^1.13.0:
version "1.14.3"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895"

process-nextick-args@~1.0.6:
version "1.0.7"
Expand Down

0 comments on commit 38537ba

Please sign in to comment.