diff --git a/bin/prettier.js b/bin/prettier.js index ac29bb505..34a5001ec 100755 --- a/bin/prettier.js +++ b/bin/prettier.js @@ -10,6 +10,7 @@ const globby = require("globby"); const minimist = require("minimist"); const path = require("path"); const readline = require("readline"); +const ignore = require("ignore"); const prettier = eval("require")("../index"); const cleanAST = require("../src/clean-ast").cleanAST; @@ -55,10 +56,12 @@ const argv = minimist(args, { "range-end", "stdin-filepath", "config", - "resolve-config" + "resolve-config", + "ignore-path" ], default: { - color: true + color: true, + "ignore-path": ".prettierignore" }, alias: { help: "h", @@ -89,6 +92,7 @@ const write = argv["write"]; const stdin = argv["stdin"] || (!filepatterns.length && !process.stdin.isTTY); const ignoreNodeModules = argv["with-node-modules"] === false; const ignoreNodeModulesGlobs = ["!**/node_modules/**", "!./node_modules/**"]; +const ignorePath = argv["ignore-path"]; const globOptions = { dot: true }; @@ -283,6 +287,8 @@ if ( " --list-different or -l Print filenames of files that are different from Prettier formatting.\n" + " --config Path to a prettier configuration file (.prettierrc, package.json, prettier.config.js).\n" + " --resolve-config Resolve the path to a configuration file for a given input file.\n" + + " --ignore-path Path to a file containing patterns that describe files to ignore.\n" + + " Defaults to ./.prettierignore.\n" + " --stdin Read input from stdin.\n" + " --stdin-filepath Path to the file used to read from stdin.\n" + " --print-width Specify the length of line that the printer will wrap on. Defaults to 80.\n" + @@ -446,6 +452,26 @@ function writeOutput(result, options) { } function eachFilename(patterns, callback) { + // The ignorer will be used to filter file paths after the glob is checked, + // before any files are actually read + const ignoreFilePath = path.resolve(ignorePath); + let ignoreText = ""; + + try { + ignoreText = fs.readFileSync(ignoreFilePath, "utf8"); + } catch (readError) { + if (readError.code !== "ENOENT") { + console.error(`Unable to read ${ignoreFilePath}:`, readError); + process.exit(2); + } + } + + const ignorer = ignore(); + + if (ignoreText.trim()) { + ignorer.add(ignoreText.split(/\r?\n/)); + } + if (ignoreNodeModules) { patterns = patterns.concat(ignoreNodeModulesGlobs); } @@ -460,7 +486,7 @@ function eachFilename(patterns, callback) { return; } // Use map series to ensure idempotency - mapSeries(filePaths, filePath => { + mapSeries(ignorer.filter(filePaths), filePath => { return getOptionsForFile(filePath).then(options => callback(filePath, options) ); diff --git a/package.json b/package.json index d6b164fb1..c075f1d9e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "get-stream": "3.0.0", "globby": "^6.1.0", "graphql": "0.10.1", + "ignore": "^3.3.3", "jest-validate": "20.0.3", "json-to-ast": "2.0.0-alpha1.2", "minimatch": "3.0.4", diff --git a/tests_integration/__tests__/__snapshots__/ignore-path.js.snap b/tests_integration/__tests__/__snapshots__/ignore-path.js.snap new file mode 100644 index 000000000..d88c338b8 --- /dev/null +++ b/tests_integration/__tests__/__snapshots__/ignore-path.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ignore path 1`] = ` +"regular-module.js +" +`; + +exports[`support .prettierignore 1`] = ` +"other-regular-modules.js +" +`; diff --git a/tests_integration/__tests__/ignore-path.js b/tests_integration/__tests__/ignore-path.js new file mode 100644 index 000000000..fd7fba0e5 --- /dev/null +++ b/tests_integration/__tests__/ignore-path.js @@ -0,0 +1,22 @@ +"use strict"; + +const runPrettier = require("../runPrettier"); + +test("ignore path", () => { + const result = runPrettier("cli/ignore-path", [ + "**/*.js", + "--ignore-path", + ".gitignore", + "-l" + ]); + + expect(result.stdout).toMatchSnapshot(); + expect(result.status).toEqual(1); +}); + +test("support .prettierignore", () => { + const result = runPrettier("cli/ignore-path", ["**/*.js", "-l"]); + + expect(result.stdout).toMatchSnapshot(); + expect(result.status).toEqual(1); +}); diff --git a/tests_integration/cli/ignore-path/.gitignore b/tests_integration/cli/ignore-path/.gitignore new file mode 100644 index 000000000..507af97f1 --- /dev/null +++ b/tests_integration/cli/ignore-path/.gitignore @@ -0,0 +1 @@ +other-regular-modules.js diff --git a/tests_integration/cli/ignore-path/.prettierignore b/tests_integration/cli/ignore-path/.prettierignore new file mode 100644 index 000000000..ca3fffe64 --- /dev/null +++ b/tests_integration/cli/ignore-path/.prettierignore @@ -0,0 +1 @@ +regular-module.js diff --git a/tests_integration/cli/ignore-path/other-regular-modules.js b/tests_integration/cli/ignore-path/other-regular-modules.js new file mode 100644 index 000000000..3d0ca1bd1 --- /dev/null +++ b/tests_integration/cli/ignore-path/other-regular-modules.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +'use strict'; diff --git a/tests_integration/cli/ignore-path/regular-module.js b/tests_integration/cli/ignore-path/regular-module.js new file mode 100644 index 000000000..3d0ca1bd1 --- /dev/null +++ b/tests_integration/cli/ignore-path/regular-module.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +'use strict';