main
js 123 lines 3.34 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7 'use strict';
8
9 // Based on similar script in Jest
10 // https://github.com/facebook/jest/blob/a7acc5ae519613647ff2c253dd21933d6f94b47f/scripts/prettier.js
11
12 const chalk = require('chalk');
13 const glob = require('glob');
14 const prettier = require('prettier');
15 const fs = require('fs');
16 const path = require('path');
17 const listChangedFiles = require('../shared/listChangedFiles');
18 const prettierConfigPath = require.resolve('../../.prettierrc');
19
20 const mode = process.argv[2] || 'check';
21 const shouldWrite = mode === 'write' || mode === 'write-changed';
22 const onlyChanged = mode === 'check-changed' || mode === 'write-changed';
23
24 const changedFiles = onlyChanged ? listChangedFiles() : null;
25
26 const prettierIgnoreFilePath = path.join(
27 __dirname,
28 '..',
29 '..',
30 '.prettierignore'
31 );
32 const prettierIgnore = fs.readFileSync(prettierIgnoreFilePath, {
33 encoding: 'utf8',
34 });
35 const ignoredPathsListedInPrettierIgnore = prettierIgnore
36 .toString()
37 .replace(/\r\n/g, '\n')
38 .split('\n')
39 .filter(line => !!line && !line.startsWith('#'));
40
41 const ignoredPathsListedInPrettierIgnoreInGlobFormat =
42 ignoredPathsListedInPrettierIgnore.map(ignoredPath => {
43 const existsAndDirectory =
44 fs.existsSync(ignoredPath) && fs.lstatSync(ignoredPath).isDirectory();
45
46 if (existsAndDirectory) {
47 return path.join(ignoredPath, '/**');
48 }
49
50 return ignoredPath;
51 });
52
53 const files = glob
54 .sync('**/*.{js,jsx,ts,tsx}', {
55 ignore: [
56 '**/*.d.ts',
57 '**/node_modules/**',
58 '**/cjs/**',
59 '**/dist/**',
60 '**/__snapshots__/**',
61 'packages/**/*.ts', // runtime prettier uses Flow parser
62 ...ignoredPathsListedInPrettierIgnoreInGlobFormat,
63 ],
64 })
65 .filter(f => !onlyChanged || changedFiles.has(f));
66
67 if (!files.length) {
68 process.exit(0);
69 }
70
71 async function main() {
72 let didWarn = false;
73 let didError = false;
74
75 await Promise.all(
76 files.map(async file => {
77 const options = await prettier.resolveConfig(file, {
78 config: prettierConfigPath,
79 });
80 try {
81 const input = fs.readFileSync(file, 'utf8');
82 if (shouldWrite) {
83 const output = await prettier.format(input, options);
84 if (output !== input) {
85 fs.writeFileSync(file, output, 'utf8');
86 }
87 } else {
88 const isFormatted = await prettier.check(input, options);
89 if (!isFormatted) {
90 if (!didWarn) {
91 console.log(
92 '\n' +
93 chalk.red(
94 ` This project uses prettier to format all JavaScript code.\n`
95 ) +
96 chalk.dim(` Please run `) +
97 chalk.reset('yarn prettier-all') +
98 chalk.dim(
99 ` and add changes to files listed below to your commit:`
100 ) +
101 `\n\n`
102 );
103 didWarn = true;
104 }
105 console.log(file);
106 }
107 }
108 } catch (error) {
109 didError = true;
110 console.log('\n\n' + error.message);
111 console.log(file);
112 }
113 })
114 );
115 if (didWarn || didError) {
116 process.exit(1);
117 }
118 }
119
120 main().catch(error => {
121 console.error(error);
122 process.exit(1);
123 });