Repository: prettier/prettier-atom
Pull request #110 (2017-03-31 03:15:26)

feat(options): add prettierLast option for prettier-eslint
Adds a new `Run Prettier Last` option (see prettier/prettier-eslint#58 and prettier/prettier-eslint#59).

robwise: @spudly This is great code, could you just add `// $FlowFixMe` before line 68 so it passes flow and then we can merge?

spudly: done.
codecov-io: # [Codecov](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=h1) Report
> Merging [#110](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=desc) into [master](https://codecov.io/gh/prettier/prettier-atom/commit/045f12f209950cf94856c936c04e4871e6cd316a?src=pr&el=desc) will **increase** coverage by `0.4%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/prettier/prettier-atom/pull/110/graphs/tree.svg?token=Pdibkvk5Zo&width=650&src=pr&height=150)](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master     #110     +/-   ##
=========================================
+ Coverage   78.57%   78.98%   +0.4%     
=========================================
  Files           6        6             
  Lines         154      157      +3     
=========================================
+ Hits          121      124      +3     
  Misses         33       33
```


| [Impacted Files](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/executePrettier.js](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=tree#diff-c3JjL2V4ZWN1dGVQcmV0dGllci5qcw==) | `100% <100%> (ø)` | :arrow_up: |
| [src/helpers.js](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=tree#diff-c3JjL2hlbHBlcnMuanM=) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=footer). Last update [045f12f...2c0ebdf](https://codecov.io/gh/prettier/prettier-atom/pull/110?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
robwise: @spudly awesome, can you squash down that commit?

Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index aa5298b..febb97e 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -143,6 +143,15 @@
       "contributions": [
         "code"
       ]
+    },
+    {
+      "login": "spudly",
+      "name": "Stephen John Sorensen",
+      "avatar_url": "https://avatars3.githubusercontent.com/u/487068?v=3",
+      "profile": "http://www.stephenjohnsorensen.com/",
+      "contributions": [
+        "code"
+      ]
     }
   ]
 }
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e0a7bca..1df25a2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -54,10 +54,14 @@ pre-commit
 
 ## Help needed
 
-Please watch the repo and respond to questions/bug reports/feature requests! Thanks!
+Please checkout the [ROADMAP.md][ROADMAP] and raise an issue to discuss
+any of the items in the want to do or might do list.
+
+Also, please watch the repo and respond to questions/bug reports/feature requests! Thanks!
 
 [egghead]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
 [semantic-release]: https://npmjs.com/package/semantic-release
 [convention]: https://github.com/conventional-changelog/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md
 [all-contributors]: https://github.com/kentcdodds/all-contributors
+[ROADMAP]: ./ROADMAP.md
 [nps]: https://www.npmjs.com/package/nps
diff --git a/README.md b/README.md
index 5ab7cd7..36ec16c 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ Thanks goes to these people ([emoji key][emojis]):
 | [<img src="https://avatars.githubusercontent.com/u/17031?v=3" width="100px;"/><br /><sub>James Long</sub>](http://jlongster.com)<br />💬 [💻](https://github.com/prettier/prettier-atom/commits?author=jlongster) [📖](https://github.com/prettier/prettier-atom/commits?author=jlongster) 🔌 👀 | [<img src="https://avatars.githubusercontent.com/u/6173488?v=3" width="100px;"/><br /><sub>Rob Wise</sub>](https://robwise.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=robwise) [📖](https://github.com/prettier/prettier-atom/commits?author=robwise) 💬 💡 👀 [⚠️](https://github.com/prettier/prettier-atom/commits?author=robwise) | [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub>Kent C. Dodds</sub>](https://kentcdodds.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=kentcdodds) [📖](https://github.com/prettier/prettier-atom/commits?author=kentcdodds) 🚇 | [<img src="https://avatars.githubusercontent.com/u/1144075?v=3" width="100px;"/><br /><sub>Luca Barone</sub>](https://github.com/cloud-walker)<br /> | [<img src="https://avatars.githubusercontent.com/u/4514159?v=3" width="100px;"/><br /><sub>Arnar Þór Sveinsson</sub>](https://github.com/arnarthor)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=arnarthor) | [<img src="https://avatars.githubusercontent.com/u/131916?v=3" width="100px;"/><br /><sub>Adam Miskiewicz</sub>](http://www.adammiskiewicz.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=skevy) | [<img src="https://avatars.githubusercontent.com/u/2685242?v=3" width="100px;"/><br /><sub>Ori Livni</sub>](http://www.orilivni.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=oriSomething) |
 | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
 | [<img src="https://avatars.githubusercontent.com/u/6182852?v=3" width="100px;"/><br /><sub>Leon Chen</sub>](https://transcranial.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=transcranial) | [<img src="https://avatars.githubusercontent.com/u/197597?v=3" width="100px;"/><br /><sub>Christopher Chedeau</sub>](http://blog.vjeux.com/)<br />💬 [💻](https://github.com/prettier/prettier-atom/commits?author=vjeux) 🔌 | [<img src="https://avatars.githubusercontent.com/u/646693?v=3" width="100px;"/><br /><sub>Christoph Geschwind</sub>](http://christoph-geschwind.de)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=1st8) | [<img src="https://avatars.githubusercontent.com/u/35026?v=3" width="100px;"/><br /><sub>Andrew Hutchings</sub>](https://andrewhutchings.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ahutchings) | [<img src="https://avatars.githubusercontent.com/u/875591?v=3" width="100px;"/><br /><sub>David Schnurr</sub>](http://davidschnurr.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=schnerd) | [<img src="https://avatars.githubusercontent.com/u/484801?v=3" width="100px;"/><br /><sub>Ryan Cole</sub>](http://rycole.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ryancole) | [<img src="https://avatars0.githubusercontent.com/u/11488612?v=3" width="100px;"/><br /><sub>Dara Hak</sub>](https://github.com/darahak)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=darahak) |
+| [<img src="https://avatars3.githubusercontent.com/u/487068?v=3" width="100px;"/><br /><sub>Stephen John Sorensen</sub>](http://www.stephenjohnsorensen.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=spudly) |
 <!-- ALL-CONTRIBUTORS-LIST:END -->
 
 This project follows the [all-contributors][all-contributors] specification. Contributions of any kind welcome!
diff --git a/dist/config-schema.json b/dist/config-schema.json
index 68ead28..99ceeaa 100644
--- a/dist/config-schema.json
+++ b/dist/config-schema.json
@@ -129,5 +129,18 @@
         "order": 7
       }
     }
+  },
+  "prettierEslintOptions": {
+    "type": "object",
+    "order": 5,
+    "properties": {
+      "prettierLast": {
+        "title": "Run Prettier Last",
+        "description": "Run eslint => prettier (instead of prettier => eslint)",
+        "type": "boolean",
+        "default": false,
+        "order": 1
+      }
+    }
   }
 }
diff --git a/dist/executePrettier.js b/dist/executePrettier.js
index 20cfcdf..49da17e 100644
--- a/dist/executePrettier.js
+++ b/dist/executePrettier.js
@@ -1,5 +1,7 @@
 'use strict';
 
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
 var prettierEslint = require('prettier-eslint');
 var prettier = require('prettier');
 
@@ -8,6 +10,7 @@ var _require = require('loophole'),
 
 var _require2 = require('./helpers'),
     getPrettierOptions = _require2.getPrettierOptions,
+    getPrettierEslintOptions = _require2.getPrettierEslintOptions,
     getCurrentFilePath = _require2.getCurrentFilePath,
     shouldDisplayErrors = _require2.shouldDisplayErrors,
     shouldUseEslint = _require2.shouldUseEslint,
@@ -31,7 +34,10 @@ var executePrettier = function executePrettier(editor, text) {
   try {
     if (shouldUseEslint()) {
       return allowUnsafeNewFunction(function () {
-        return prettierEslint({ text: text, filePath: getCurrentFilePath(editor) });
+        return prettierEslint(_extends({}, getPrettierEslintOptions(), {
+          text: text,
+          filePath: getCurrentFilePath(editor)
+        }));
       });
     }
     return prettier.format(text, getPrettierOptions(editor));
diff --git a/dist/helpers.js b/dist/helpers.js
index 709f277..86585f9 100644
--- a/dist/helpers.js
+++ b/dist/helpers.js
@@ -88,6 +88,10 @@ var getPrettierOption = function getPrettierOption(key) {
   return getConfigOption('prettierOptions.' + key);
 };
 
+var getPrettierEslintOption = function getPrettierEslintOption(key) {
+  return getConfigOption('prettierEslintOptions.' + key);
+};
+
 var getCurrentFilePath = function getCurrentFilePath(editor) {
   return editor.buffer.file ? editor.buffer.file.path : undefined;
 };
@@ -148,6 +152,12 @@ var getPrettierOptions = function getPrettierOptions(editor) {
   };
 };
 
+var getPrettierEslintOptions = function getPrettierEslintOptions() {
+  return {
+    prettierLast: getPrettierEslintOption('prettierLast')
+  };
+};
+
 var runLinter = function runLinter(editor) {
   return isLinterLintCommandDefined(editor) ? atom.commands.dispatch(atom.views.getView(editor), LINTER_LINT_COMMAND) : undefined;
 };
@@ -156,6 +166,7 @@ module.exports = {
   getConfigOption: getConfigOption,
   shouldDisplayErrors: shouldDisplayErrors,
   getPrettierOption: getPrettierOption,
+  getPrettierEslintOption: getPrettierEslintOption,
   getCurrentFilePath: getCurrentFilePath,
   isInScope: isInScope,
   isCurrentScopeEmbeddedScope: isCurrentScopeEmbeddedScope,
@@ -168,5 +179,6 @@ module.exports = {
   shouldUseEslint: shouldUseEslint,
   shouldRespectEslintignore: shouldRespectEslintignore,
   getPrettierOptions: getPrettierOptions,
+  getPrettierEslintOptions: getPrettierEslintOptions,
   runLinter: runLinter
 };
\ No newline at end of file
diff --git a/package.json b/package.json
index 1a5519e..efa064f 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
     "loophole": "^1.1.0",
     "minimatch": "^3.0.3",
     "prettier": "^0.22.0",
-    "prettier-eslint": "^4.3.2"
+    "prettier-eslint": "^4.4.0"
   },
   "devDependencies": {
     "all-contributors-cli": "^4.0.1",
diff --git a/src/config-schema.json b/src/config-schema.json
index 68ead28..99ceeaa 100644
--- a/src/config-schema.json
+++ b/src/config-schema.json
@@ -129,5 +129,18 @@
         "order": 7
       }
     }
+  },
+  "prettierEslintOptions": {
+    "type": "object",
+    "order": 5,
+    "properties": {
+      "prettierLast": {
+        "title": "Run Prettier Last",
+        "description": "Run eslint => prettier (instead of prettier => eslint)",
+        "type": "boolean",
+        "default": false,
+        "order": 1
+      }
+    }
   }
 }
diff --git a/src/executePrettier.js b/src/executePrettier.js
index 6d868b6..c8d7dcd 100644
--- a/src/executePrettier.js
+++ b/src/executePrettier.js
@@ -5,6 +5,7 @@ const { allowUnsafeNewFunction } = require('loophole');
 
 const {
   getPrettierOptions,
+  getPrettierEslintOptions,
   getCurrentFilePath,
   shouldDisplayErrors,
   shouldUseEslint,
@@ -28,7 +29,12 @@ const handleError = (error) => {
 const executePrettier = (editor, text) => {
   try {
     if (shouldUseEslint()) {
-      return allowUnsafeNewFunction(() => prettierEslint({ text, filePath: getCurrentFilePath(editor) }));
+      return allowUnsafeNewFunction(() =>
+        prettierEslint({
+          ...getPrettierEslintOptions(),
+          text,
+          filePath: getCurrentFilePath(editor),
+        }));
     }
     return prettier.format(text, getPrettierOptions(editor));
   } catch (error) {
diff --git a/src/helpers.js b/src/helpers.js
index 655b322..7feaf66 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -61,6 +61,8 @@ const shouldDisplayErrors = () => !getConfigOption('silenceErrors');
 
 const getPrettierOption = (key: string) => getConfigOption(`prettierOptions.${key}`);
 
+const getPrettierEslintOption = (key: string) => getConfigOption(`prettierEslintOptions.${key}`);
+
 const getCurrentFilePath = (editor: TextEditor) => editor.buffer.file ? editor.buffer.file.path : undefined;
 
 const isInScope = (editor: TextEditor) =>
@@ -105,6 +107,10 @@ const getPrettierOptions = (editor: TextEditor) => ({
   jsxBracketSameLine: getPrettierOption('jsxBracketSameLine'),
 });
 
+const getPrettierEslintOptions = () => ({
+  prettierLast: getPrettierEslintOption('prettierLast'),
+});
+
 const runLinter = (editor: TextEditor) =>
   isLinterLintCommandDefined(editor)
     ? atom.commands.dispatch(atom.views.getView(editor), LINTER_LINT_COMMAND)
@@ -114,6 +120,7 @@ module.exports = {
   getConfigOption,
   shouldDisplayErrors,
   getPrettierOption,
+  getPrettierEslintOption,
   getCurrentFilePath,
   isInScope,
   isCurrentScopeEmbeddedScope,
@@ -126,5 +133,6 @@ module.exports = {
   shouldUseEslint,
   shouldRespectEslintignore,
   getPrettierOptions,
+  getPrettierEslintOptions,
   runLinter,
 };
diff --git a/yarn.lock b/yarn.lock
index 91473c3..ce0901f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3197,7 +3197,7 @@ prettier-eslint-cli@^3.1.3:
     rxjs "^5.2.0"
     yargs "^6.6.0"
 
-prettier-eslint@^4.1.3, prettier-eslint@^4.3.2:
+prettier-eslint@^4.1.3:
   version "4.3.2"
   resolved "https://registry.yarnpkg.com/prettier-eslint/-/prettier-eslint-4.3.2.tgz#24c6361f514442506ee2019ca45484e97884e558"
   dependencies:
@@ -3211,6 +3211,20 @@ prettier-eslint@^4.1.3, prettier-eslint@^4.3.2:
     pretty-format "^19.0.0"
     require-relative "^0.8.7"
 
+prettier-eslint@^4.4.0:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/prettier-eslint/-/prettier-eslint-4.4.0.tgz#ded965da6a4d32bef72bfff992afbee0c0cf0443"
+  dependencies:
+    common-tags "^1.4.0"
+    dlv "^1.1.0"
+    eslint "^3.17.0"
+    indent-string "^3.1.0"
+    lodash.merge "^4.6.0"
+    loglevel-colored-level-prefix "^1.0.0"
+    prettier "^0.22.0"
+    pretty-format "^19.0.0"
+    require-relative "^0.8.7"
+
 prettier@^0.22.0:
   version "0.22.0"
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-0.22.0.tgz#7b37c4480d0858180407e5a8e13f0f47da7385d2"


Test patch:
diff --git a/src/__snapshots__/helpers.test.js.snap b/src/__snapshots__/helpers.test.js.snap
index 9a2e2a5..8787d3b 100644
--- a/src/__snapshots__/helpers.test.js.snap
+++ b/src/__snapshots__/helpers.test.js.snap
@@ -1,5 +1,11 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`getPrettierEslintOptions returns all prettier-eslint options 1`] = `
+Object {
+  "prettierLast": true,
+}
+`;
+
 exports[`getPrettierOptions returns all prettier options 1`] = `
 Object {
   "bracketSpacing": true,
diff --git a/src/executePrettier.test.js b/src/executePrettier.test.js
index b685dfa..c509b38 100644
--- a/src/executePrettier.test.js
+++ b/src/executePrettier.test.js
@@ -60,6 +60,23 @@ describe('executePrettierOnBufferRange()', () => {
     expect(prettierEslint).toHaveBeenCalledWith({ filePath: 'foo.js', text: 'untransformed text' });
   });
 
+  test('passes prettierLast option to prettier-eslint', () => {
+    // $FlowFixMe
+    helpers.shouldUseEslint.mockImplementation(() => true);
+    // $FlowFixMe
+    helpers.getCurrentFilePath.mockImplementation(() => 'foo.js');
+    // $FlowFixMe
+    helpers.getPrettierEslintOptions.mockImplementation(() => ({ prettierLast: true }));
+
+    executePrettierOnBufferRange(editor, bufferRangeFixture);
+
+    expect(prettierEslint).toHaveBeenCalledWith({
+      prettierLast: true,
+      filePath: 'foo.js',
+      text: 'untransformed text',
+    });
+  });
+
   describe('when prettier throws an error', () => {
     beforeEach(() => {
       prettier.format.mockImplementation(() => {
diff --git a/src/helpers.test.js b/src/helpers.test.js
index 54c09e8..b45c70b 100644
--- a/src/helpers.test.js
+++ b/src/helpers.test.js
@@ -7,6 +7,7 @@ const {
   getConfigOption,
   shouldDisplayErrors,
   getPrettierOption,
+  getPrettierEslintOption,
   getCurrentFilePath,
   isInScope,
   isFilePathEslintignored,
@@ -17,6 +18,7 @@ const {
   isLinterEslintAutofixEnabled,
   shouldUseEslint,
   getPrettierOptions,
+  getPrettierEslintOptions,
   runLinter,
 } = require('./helpers');
 
@@ -61,6 +63,19 @@ describe('getPrettierOption', () => {
   });
 });
 
+describe('getPrettierEslintOption', () => {
+  test('retrieves the given prettier-eslint option from the prettier-atom config', () => {
+    const mockGet = jest.fn(() => true);
+    atom = { config: { get: mockGet } };
+
+    const actual = getPrettierEslintOption('prettierLast');
+    const expected = true;
+
+    expect(mockGet).lastCalledWith('prettier-atom.prettierEslintOptions.prettierLast');
+    expect(actual).toBe(expected);
+  });
+});
+
 describe('getCurrentFilePath', () => {
   test("returns the editor's current filePath", () => {
     const editor = textEditor();
@@ -312,6 +327,19 @@ describe('getPrettierOptions', () => {
   });
 });
 
+describe('getPrettierEslintOptions', () => {
+  test('returns all prettier-eslint options', () => {
+    const mockGet = option =>
+      ({
+        'prettier-atom.prettierEslintOptions.prettierLast': true,
+      }[option]);
+    atom = { config: { get: mockGet } };
+    const actual = getPrettierEslintOptions();
+
+    expect(actual).toMatchSnapshot();
+  });
+});
+
 describe('runLinter()', () => {
   test('runs `linter:lint` command', () => {
     const editor = textEditor();