Run Prettier checks on CI (#2212)

Summary:
This will fail CI if we forgot to run `yarn prettier` before committing.
We do the same in React repo. It prevents committing stale files that later cause unexpected changes.
Pull Request resolved: https://github.com/facebook/prepack/pull/2212

Differential Revision: D8784406

Pulled By: gaearon

fbshipit-source-id: ca948b8e088be8886c8ba865f280ba8d72750f69
This commit is contained in:
Dan Abramov 2018-07-10 09:41:08 -07:00 committed by Facebook Github Bot
parent bde8c2eb1e
commit 66351887d3
14 changed files with 83 additions and 71 deletions

View File

@ -90,6 +90,7 @@ jobs:
- run:
name: "Run Checks"
command: |
yarn prettier-ci
yarn lint
yarn flow
yarn depcheck

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"trailingComma": "es5",
"parser": "babylon",
"printWidth": 120
}

View File

@ -58,6 +58,7 @@
"depcheck": "babel-node scripts/detect_bad_deps.js",
"prettier": "node ./scripts/prettier.js write-changed",
"prettier-all": "node ./scripts/prettier.js write",
"prettier-ci": "node ./scripts/prettier.js",
"debug-fb-www": "node --stack_trace_limit=200 --stack_size=10000 --max_old_space_size=16384 ./scripts/debug-fb-www.js"
},
"dependencies": {

View File

@ -13,21 +13,16 @@
// https://github.com/facebook/react/blob/master/scripts/prettier/index.js
const chalk = require("chalk");
const fs = require("fs");
const glob = require("glob");
const path = require("path");
const prettier = require("prettier");
const execFileSync = require("child_process").execFileSync;
const mode = process.argv[2] || "check";
const prettierConfigPath = require.resolve("../.prettierrc");
const shouldWrite = mode === "write" || mode === "write-changed";
const onlyChanged = mode === "check-changed" || mode === "write-changed";
const isWindows = process.platform === "win32";
const prettier = isWindows ? "prettier.cmd" : "prettier";
const prettierCmd = path.resolve(__dirname, "../node_modules/.bin/" + prettier);
const defaultOptions = {
"trailing-comma": "es5",
"print-width": 120,
};
const config = {
default: {
patterns: ["src/**/*.js"],
@ -52,7 +47,6 @@ const changedFiles = new Set(
Object.keys(config).forEach(key => {
const patterns = config[key].patterns;
const options = config[key].options;
const ignore = config[key].ignore;
const globPattern = patterns.length > 1 ? `{${patterns.join(",")}}` : `${patterns.join(",")}`;
@ -62,27 +56,45 @@ Object.keys(config).forEach(key => {
return;
}
const args = Object.keys(defaultOptions).map(k => `--${k}=${(options && options[k]) || defaultOptions[k]}`);
args.push(`--${shouldWrite ? "write" : "l"}`);
let didWarn = false;
let didError = false;
let result;
try {
result = exec(prettierCmd, [...args, ...files]);
} catch (e) {
if (!shouldWrite) {
console.log(
"\n" +
e.output[1] +
"\n" +
chalk.red(` This project uses prettier to format all JavaScript code.\n`) +
chalk.dim(` Please run `) +
chalk.reset("yarn prettier") +
chalk.dim(` and add changes to files listed above to your commit.`) +
`\n`
);
process.exit(1);
files.forEach(file => {
const options = prettier.resolveConfig.sync(file, {
config: prettierConfigPath,
});
try {
const input = fs.readFileSync(file, "utf8");
if (shouldWrite) {
const output = prettier.format(input, options);
if (output !== input) {
fs.writeFileSync(file, output, "utf8");
}
} else {
if (!prettier.check(input, options)) {
if (!didWarn) {
console.log(
"\n" +
chalk.red(` This project uses prettier to format all JavaScript code.\n`) +
chalk.dim(` Please run `) +
chalk.reset("yarn prettier-all") +
chalk.dim(` and add changes to files listed below to your commit:`) +
`\n`
);
didWarn = true;
}
console.log(` ${file}`);
}
}
} catch (error) {
didError = true;
console.log("\n\n" + error.message);
console.log(file);
}
throw e;
});
if (didWarn || didError) {
console.log();
process.exit(1);
}
console.log("\n" + result);
});

View File

@ -4,9 +4,9 @@ function App(props) {
var data = {};
var someProps = Object.assign(data, props, {
text: "Text!",
})
});
var propsWithout = babelHelpers.objectWithoutProperties(data, []);
return <div>{propsWithout.text}</div>
return <div>{propsWithout.text}</div>;
}
App.getTrials = function(renderer, Root, data, isCompiled) {
@ -25,4 +25,4 @@ if (this.__optimizeReactComponentTree) {
__optimizeReactComponentTree(App);
}
module.exports = App;
module.exports = App;

View File

@ -3,9 +3,9 @@ var React = require("react");
function App(props) {
var someProps = Object.assign({}, props, {
text: "Text!",
})
});
var propsWithout = babelHelpers.objectWithoutProperties(someProps, []);
return <div>{propsWithout.text}</div>
return <div>{propsWithout.text}</div>;
}
App.getTrials = function(renderer, Root, data, isCompiled) {
@ -24,4 +24,4 @@ if (this.__optimizeReactComponentTree) {
__optimizeReactComponentTree(App);
}
module.exports = App;
module.exports = App;

View File

@ -26,4 +26,4 @@ it("Simple", async () => {
it("Simple 2", async () => {
runTest(__dirname + "/ReactNative/simple2.js");
});
});

View File

@ -25,9 +25,7 @@ class App extends React.Component {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>
This is a React Native test.
</Text>
<Text style={styles.instructions}>This is a React Native test.</Text>
</View>
);
}
@ -44,4 +42,4 @@ if (this.__optimizeReactComponentTree) {
});
}
module.exports = App;
module.exports = App;

View File

@ -45,4 +45,4 @@ if (this.__optimizeReactComponentTree) {
});
}
module.exports = App;
module.exports = App;

View File

@ -1,5 +1,4 @@
var React = require('react');
this['React'] = React;
var React = require("react");
function Foo(props) {
return [<div ref={props.callback} key="0" />];
@ -31,10 +30,10 @@ App.getTrials = function(renderer, Root) {
renderer.update(<Root callback={callback} foo={true} />);
renderer.update(<Root callback={callback} foo={true} />);
let results = [];
results.push(['ensure ref is called on every change', counter]);
results.push(['ensure refs are cleared', nodes.map(Boolean)]);
results.push(['ensure refs are different', new Set(nodes).size]);
results.push(["ensure ref is called on every change", counter]);
results.push(["ensure refs are cleared", nodes.map(Boolean)]);
results.push(["ensure refs are different", new Set(nodes).size]);
return results;
};
module.exports = App;
module.exports = App;

View File

@ -1,5 +1,4 @@
var React = require('react');
this['React'] = React;
var React = require("react");
function Foo(props) {
return [<div ref={props.callback} key="0" />];
@ -31,10 +30,10 @@ App.getTrials = function(renderer, Root) {
renderer.update(<Root callback={callback} foo={true} />);
renderer.update(<Root callback={callback} foo={true} />);
let results = [];
results.push(['ensure ref is called on every change', counter]);
results.push(['ensure refs are cleared', nodes.map(Boolean)]);
results.push(['ensure refs are different', new Set(nodes).size]);
results.push(["ensure ref is called on every change", counter]);
results.push(["ensure refs are cleared", nodes.map(Boolean)]);
results.push(["ensure refs are different", new Set(nodes).size]);
return results;
};
module.exports = App;
module.exports = App;

View File

@ -1,5 +1,4 @@
var React = require('react');
this['React'] = React;
var React = require("react");
function Foo(props) {
return [[<div ref={props.callback} key="0" />]];
@ -31,10 +30,10 @@ App.getTrials = function(renderer, Root) {
renderer.update(<Root callback={callback} foo={true} />);
renderer.update(<Root callback={callback} foo={true} />);
let results = [];
results.push(['ensure ref is called on every change', counter]);
results.push(['ensure refs are cleared', nodes.map(Boolean)]);
results.push(['ensure refs are different', new Set(nodes).size]);
results.push(["ensure ref is called on every change", counter]);
results.push(["ensure refs are cleared", nodes.map(Boolean)]);
results.push(["ensure refs are different", new Set(nodes).size]);
return results;
};
module.exports = App;
module.exports = App;

View File

@ -1,5 +1,4 @@
var React = require('react');
this['React'] = React;
var React = require("react");
function Foo(props) {
return [[<div ref={props.callback} key="0" />]];
@ -31,10 +30,10 @@ App.getTrials = function(renderer, Root) {
renderer.update(<Root callback={callback} foo={true} />);
renderer.update(<Root callback={callback} foo={true} />);
let results = [];
results.push(['ensure ref is called on every change', counter]);
results.push(['ensure refs are cleared', nodes.map(Boolean)]);
results.push(['ensure refs are different', new Set(nodes).size]);
results.push(["ensure ref is called on every change", counter]);
results.push(["ensure refs are cleared", nodes.map(Boolean)]);
results.push(["ensure refs are different", new Set(nodes).size]);
return results;
};
module.exports = App;
module.exports = App;

View File

@ -1,5 +1,4 @@
var React = require('react');
this['React'] = React;
var React = require("react");
function Foo(props) {
return [<div ref={props.callback} key="0" />];
@ -31,10 +30,10 @@ App.getTrials = function(renderer, Root) {
renderer.update(<Root callback={callback} foo={true} />);
renderer.update(<Root callback={callback} foo={true} />);
let results = [];
results.push(['ensure ref is called on every change', counter]);
results.push(['ensure refs are cleared', nodes.map(Boolean)]);
results.push(['ensure refs are different', new Set(nodes).size]);
results.push(["ensure ref is called on every change", counter]);
results.push(["ensure refs are cleared", nodes.map(Boolean)]);
results.push(["ensure refs are different", new Set(nodes).size]);
return results;
};
module.exports = App;
module.exports = App;