main
js 110 lines 3.01 KB
Raw
1 'use strict';
2
3 /* eslint-disable no-for-of-loops/no-for-of-loops */
4
5 const path = require('path');
6 const {promisify} = require('util');
7 const glob = promisify(require('glob'));
8 const {ESLint} = require('eslint');
9
10 // Lint the final build artifacts. Helps catch bugs in our build pipeline.
11
12 function getFormat(filepath) {
13 if (filepath.includes('facebook')) {
14 if (filepath.includes('shims')) {
15 // We don't currently lint these shims. We rely on the downstream Facebook
16 // repo to transform them.
17 // TODO: Should we lint them?
18 return null;
19 }
20 if (filepath.includes('ESLintPluginReactHooks')) {
21 // The ESLint plugin bundles compiler code with modern syntax that
22 // doesn't need to conform to the ES5 www lint rules.
23 return null;
24 }
25 return 'fb';
26 }
27 if (filepath.includes('react-native')) {
28 if (filepath.includes('shims')) {
29 // We don't currently lint these shims. We rely on the downstream Facebook
30 // repo to transform them.
31 // TODO: Should we lint them?
32 return null;
33 }
34 return 'rn';
35 }
36 if (filepath.includes('cjs')) {
37 if (
38 filepath.includes('react-server-dom-webpack-plugin') ||
39 filepath.includes('react-server-dom-webpack-node-register') ||
40 filepath.includes('react-suspense-test-utils')
41 ) {
42 return 'cjs2015';
43 }
44 return 'cjs';
45 }
46 if (filepath.includes('esm')) {
47 return 'esm';
48 }
49 if (
50 filepath.includes('oss-experimental') ||
51 filepath.includes('oss-stable')
52 ) {
53 // If a file in one of the open source channels doesn't match an earlier,
54 // more specific rule, then assume it's CommonJS.
55 return 'cjs';
56 }
57 throw new Error('Could not find matching lint format for file: ' + filepath);
58 }
59
60 function getESLintInstance(format) {
61 return new ESLint({
62 useEslintrc: false,
63 overrideConfigFile: path.join(__dirname, `eslintrc.${format}.js`),
64 ignore: false,
65 });
66 }
67
68 async function lint(eslint, filepaths) {
69 const results = await eslint.lintFiles(filepaths);
70 if (
71 results.some(result => result.errorCount > 0 || result.warningCount > 0)
72 ) {
73 process.exitCode = 1;
74 console.log(`Lint failed`);
75 const formatter = await eslint.loadFormatter('stylish');
76 const resultText = formatter.format(results);
77 console.log(resultText);
78 }
79 }
80
81 async function lintEverything() {
82 console.log(`Linting build artifacts...`);
83
84 const allFilepaths = await glob('build/**/*.js');
85
86 const pathsByFormat = new Map();
87 for (const filepath of allFilepaths) {
88 const format = getFormat(filepath);
89 if (format !== null) {
90 const paths = pathsByFormat.get(format);
91 if (paths === undefined) {
92 pathsByFormat.set(format, [filepath]);
93 } else {
94 paths.push(filepath);
95 }
96 }
97 }
98
99 const promises = [];
100 for (const [format, filepaths] of pathsByFormat) {
101 const eslint = getESLintInstance(format);
102 promises.push(lint(eslint, filepaths));
103 }
104 await Promise.all(promises);
105 }
106
107 lintEverything().catch(error => {
108 process.exitCode = 1;
109 console.error(error);
110 });