From 043a8e659f3395f5ae1f28419a21b7841bb9a0a3 Mon Sep 17 00:00:00 2001 From: Sylvan Mably Date: Wed, 15 May 2019 12:34:45 -0400 Subject: [PATCH 1/5] chore: rename "write"/"format" to "process" --- bin/pretty-quick.js | 2 +- src/__tests__/scm-git.test.js | 60 ++++++++++++------------- src/__tests__/scm-hg.test.js | 58 ++++++++++++------------ src/index.js | 10 ++--- src/{formatFiles.js => processFiles.js} | 4 +- 5 files changed, 67 insertions(+), 67 deletions(-) rename src/{formatFiles.js => processFiles.js} (86%) diff --git a/bin/pretty-quick.js b/bin/pretty-quick.js index 780a4d4..3e7690f 100755 --- a/bin/pretty-quick.js +++ b/bin/pretty-quick.js @@ -32,7 +32,7 @@ const prettyQuickResult = prettyQuick( console.log(`✗ Found ${chalk.bold('partially')} staged file ${file}.`); }, - onWriteFile: file => { + onProcessFile: file => { console.log(`✍️ Fixing up ${chalk.bold(file)}.`); }, diff --git a/src/__tests__/scm-git.test.js b/src/__tests__/scm-git.test.js index 48979ba..905b828 100644 --- a/src/__tests__/scm-git.test.js +++ b/src/__tests__/scm-git.test.js @@ -150,63 +150,63 @@ describe('with git', () => { expect(onFoundChangedFiles).toHaveBeenCalledWith(['./foo.js', './bar.md']); }); - test('calls onWriteFile with changed files', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files', () => { + const onProcessFile = jest.fn(); mockGitFs(); - prettyQuick('root', { since: 'banana', onWriteFile }); + prettyQuick('root', { since: 'banana', onProcessFile }); - expect(onWriteFile).toHaveBeenCalledWith('./foo.js'); - expect(onWriteFile).toHaveBeenCalledWith('./bar.md'); - expect(onWriteFile.mock.calls.length).toBe(2); + expect(onProcessFile).toHaveBeenCalledWith('./foo.js'); + expect(onProcessFile).toHaveBeenCalledWith('./bar.md'); + expect(onProcessFile.mock.calls.length).toBe(2); }); - test('calls onWriteFile with changed files for the given pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given pattern', () => { + const onProcessFile = jest.fn(); mockGitFs(); - prettyQuick('root', { pattern: '*.md', since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + prettyQuick('root', { pattern: '*.md', since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); - test('calls onWriteFile with changed files for the given globstar pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given globstar pattern', () => { + const onProcessFile = jest.fn(); mockGitFs(); prettyQuick('root', { pattern: '**/*.md', since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); - test('calls onWriteFile with changed files for the given extglob pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given extglob pattern', () => { + const onProcessFile = jest.fn(); mockGitFs(); prettyQuick('root', { pattern: '*.*(md|foo|bar)', since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); - test('calls onWriteFile with changed files for an array of globstar patterns', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for an array of globstar patterns', () => { + const onProcessFile = jest.fn(); mockGitFs(); prettyQuick('root', { pattern: ['**/*.foo', '**/*.md', '**/*.bar'], since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); test('writes formatted files to disk', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockGitFs(); - prettyQuick('root', { since: 'banana', onWriteFile }); + prettyQuick('root', { since: 'banana', onProcessFile }); expect(fs.readFileSync('/foo.js', 'utf8')).toEqual('formatted:foo()'); expect(fs.readFileSync('/bar.md', 'utf8')).toEqual('formatted:# foo'); @@ -316,20 +316,20 @@ describe('with git', () => { }); test('ignore files matching patterns from the repositories root .prettierignore', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockGitFs('', { '/.prettierignore': '*.md', }); - prettyQuick('/sub-directory/', { since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./foo.js']]); + prettyQuick('/sub-directory/', { since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./foo.js']]); }); test('ignore files matching patterns from the working directories .prettierignore', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockGitFs('', { '/sub-directory/.prettierignore': '*.md', }); - prettyQuick('/sub-directory/', { since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./foo.js']]); + prettyQuick('/sub-directory/', { since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./foo.js']]); }); }); diff --git a/src/__tests__/scm-hg.test.js b/src/__tests__/scm-hg.test.js index e87b2e1..2d8b30d 100644 --- a/src/__tests__/scm-hg.test.js +++ b/src/__tests__/scm-hg.test.js @@ -106,51 +106,51 @@ describe('with hg', () => { expect(onFoundChangedFiles).toHaveBeenCalledWith(['./foo.js', './bar.md']); }); - test('calls onWriteFile with changed files', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files', () => { + const onProcessFile = jest.fn(); mockHgFs(); - prettyQuick('root', { since: 'banana', onWriteFile }); + prettyQuick('root', { since: 'banana', onProcessFile }); - expect(onWriteFile).toHaveBeenCalledWith('./foo.js'); - expect(onWriteFile).toHaveBeenCalledWith('./bar.md'); + expect(onProcessFile).toHaveBeenCalledWith('./foo.js'); + expect(onProcessFile).toHaveBeenCalledWith('./bar.md'); }); - test('calls onWriteFile with changed files for the given pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given pattern', () => { + const onProcessFile = jest.fn(); mockHgFs(); - prettyQuick('root', { pattern: '*.md', since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + prettyQuick('root', { pattern: '*.md', since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); - test('calls onWriteFile with changed files for the given globstar pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given globstar pattern', () => { + const onProcessFile = jest.fn(); mockHgFs(); prettyQuick('root', { pattern: '**/*.md', since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); - test('calls onWriteFile with changed files for the given extglob pattern', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for the given extglob pattern', () => { + const onProcessFile = jest.fn(); mockHgFs(); prettyQuick('root', { pattern: '*.*(md|foo|bar)', since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); test('writes formatted files to disk', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockHgFs(); - prettyQuick('root', { since: 'banana', onWriteFile }); + prettyQuick('root', { since: 'banana', onProcessFile }); expect(fs.readFileSync('/foo.js', 'utf8')).toEqual('formatted:foo()'); expect(fs.readFileSync('/bar.md', 'utf8')).toEqual('formatted:# foo'); @@ -172,15 +172,15 @@ describe('with hg', () => { expect(result).toEqual({ errors: ['BAIL_ON_WRITE'], success: false }); }); - test('calls onWriteFile with changed files for an array of globstar patterns', () => { - const onWriteFile = jest.fn(); + test('calls onProcessFile with changed files for an array of globstar patterns', () => { + const onProcessFile = jest.fn(); mockHgFs(); prettyQuick('root', { pattern: ['**/*.foo', '**/*.md', '**/*.bar'], since: 'banana', - onWriteFile, + onProcessFile, }); - expect(onWriteFile.mock.calls).toEqual([['./bar.md']]); + expect(onProcessFile.mock.calls).toEqual([['./bar.md']]); }); test('without --staged does NOT stage changed files', () => { @@ -215,20 +215,20 @@ describe('with hg', () => { }); test('ignore files matching patterns from the repositories root .prettierignore', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockHgFs({ '/.prettierignore': '*.md', }); - prettyQuick('/sub-directory/', { since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./foo.js']]); + prettyQuick('/sub-directory/', { since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./foo.js']]); }); test('ignore files matching patterns from the working directories .prettierignore', () => { - const onWriteFile = jest.fn(); + const onProcessFile = jest.fn(); mockHgFs({ '/sub-directory/.prettierignore': '*.md', }); - prettyQuick('/sub-directory/', { since: 'banana', onWriteFile }); - expect(onWriteFile.mock.calls).toEqual([['./foo.js']]); + prettyQuick('/sub-directory/', { since: 'banana', onProcessFile }); + expect(onProcessFile.mock.calls).toEqual([['./foo.js']]); }); }); diff --git a/src/index.js b/src/index.js index c91c507..3a760ce 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import scms from './scms'; -import formatFiles from './formatFiles'; +import processFiles from './processFiles'; import createIgnorer from './createIgnorer'; import createMatcher from './createMatcher'; import isSupportedExtension from './isSupportedExtension'; @@ -18,7 +18,7 @@ export default ( onFoundSinceRevision, onFoundChangedFiles, onPartiallyStagedFile, - onWriteFile, + onProcessFile, onExamineFile, } = {} ) => { @@ -60,10 +60,10 @@ export default ( const failReasons = new Set(); - formatFiles(directory, changedFiles, { + processFiles(directory, changedFiles, { config, - onWriteFile: file => { - onWriteFile && onWriteFile(file); + onProcessFile: file => { + onProcessFile && onProcessFile(file); if (bail) { failReasons.add('BAIL_ON_WRITE'); } diff --git a/src/formatFiles.js b/src/processFiles.js similarity index 86% rename from src/formatFiles.js rename to src/processFiles.js index 92a8afd..0704840 100644 --- a/src/formatFiles.js +++ b/src/processFiles.js @@ -5,7 +5,7 @@ import { join } from 'path'; export default ( directory, files, - { config, onWriteFile, onExamineFile } = {} + { config, onProcessFile, onExamineFile } = {} ) => { for (const relative of files) { onExamineFile && onExamineFile(relative); @@ -21,7 +21,7 @@ export default ( if (output !== input) { writeFileSync(file, output); - onWriteFile && onWriteFile(relative); + onProcessFile && onProcessFile(relative); } } }; From d4e9f762cb7daf2f73aff3dae78f5469b849c939 Mon Sep 17 00:00:00 2001 From: Sylvan Mably Date: Wed, 15 May 2019 12:31:29 -0400 Subject: [PATCH 2/5] feat: add --check CLI option --- bin/pretty-quick.js | 11 ++++++++++- src/index.js | 6 ++++++ src/processFiles.js | 26 +++++++++++++++++--------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/bin/pretty-quick.js b/bin/pretty-quick.js index 3e7690f..f9d36bb 100755 --- a/bin/pretty-quick.js +++ b/bin/pretty-quick.js @@ -33,7 +33,11 @@ const prettyQuickResult = prettyQuick( }, onProcessFile: file => { - console.log(`✍️ Fixing up ${chalk.bold(file)}.`); + if (args.check) { + console.log(`👀 Checking ${chalk.bold(file)}.`); + } else { + console.log(`✍️ Fixing up ${chalk.bold(file)}.`); + } }, onExamineFile: file => { @@ -56,5 +60,10 @@ if (prettyQuickResult.success) { '✗ File had to be prettified and prettyQuick was set to bail mode.' ); } + if (prettyQuickResult.errors.indexOf('CHECK_FAILED') !== -1) { + console.log( + '✗ Code style issues found in the above file(s). Forgot to run Prettier?' + ); + } process.exit(1); // ensure git hooks abort } diff --git a/src/index.js b/src/index.js index 3a760ce..2822e61 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ export default ( restage = true, branch, bail, + check, verbose, onFoundSinceRevision, onFoundChangedFiles, @@ -61,9 +62,14 @@ export default ( const failReasons = new Set(); processFiles(directory, changedFiles, { + check, config, onProcessFile: file => { onProcessFile && onProcessFile(file); + if (check) { + failReasons.add('CHECK_FAILED'); + return; + } if (bail) { failReasons.add('BAIL_ON_WRITE'); } diff --git a/src/processFiles.js b/src/processFiles.js index 0704840..7021462 100644 --- a/src/processFiles.js +++ b/src/processFiles.js @@ -1,23 +1,31 @@ import { readFileSync, writeFileSync } from 'fs'; -import { resolveConfig, format } from 'prettier'; +import * as prettier from 'prettier'; import { join } from 'path'; export default ( directory, files, - { config, onProcessFile, onExamineFile } = {} + { check, config, onProcessFile, onExamineFile } = {} ) => { for (const relative of files) { onExamineFile && onExamineFile(relative); const file = join(directory, relative); - const options = resolveConfig.sync(file, { config, editorconfig: true }); - const input = readFileSync(file, 'utf8'); - const output = format( - input, - Object.assign({}, options, { - filepath: file, - }) + const options = Object.assign( + {}, + prettier.resolveConfig.sync(file, { + config, + editorconfig: true, + }), + { filepath: file } ); + const input = readFileSync(file, 'utf8'); + + if (check && !prettier.check(input, options)) { + onProcessFile && onProcessFile(relative); + return; + } + + const output = prettier.format(input, options); if (output !== input) { writeFileSync(file, output); From d5f1f23c456fecd0514680deeac87a01c770500e Mon Sep 17 00:00:00 2001 From: Sylvan Mably Date: Wed, 15 May 2019 13:11:44 -0400 Subject: [PATCH 3/5] docs: add --check to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b7f0709..67bece6 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ Outputs the name of each file right before it is proccessed. This can be useful Prevent `git commit` if any files are fixed. +### `--check` + +Check that files are correctly formatted, but don't format them. This is useful on CI to verify that all changed files in the current branch were correctly formatted. +