Commit 3e3d8f11 authored by Clement Ho's avatar Clement Ho

Merge branch 'mg-update-prettier-script' into 'master'

Fix/update prettier script

See merge request gitlab-org/gitlab-ce!22476
parents 97fe4779 a3251169
...@@ -3,3 +3,7 @@ ...@@ -3,3 +3,7 @@
/public/ /public/
/vendor/ /vendor/
/tmp/ /tmp/
# ignore stylesheets for now as this clashes with our linter
*.css
*.scss
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
"karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js", "karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js",
"karma-start": "BABEL_ENV=karma karma start config/karma.config.js", "karma-start": "BABEL_ENV=karma karma start config/karma.config.js",
"postinstall": "node ./scripts/frontend/postinstall.js", "postinstall": "node ./scripts/frontend/postinstall.js",
"prettier-staged": "node ./scripts/frontend/prettier.js", "prettier-staged": "node ./scripts/frontend/prettier.js check",
"prettier-staged-save": "node ./scripts/frontend/prettier.js save", "prettier-staged-save": "node ./scripts/frontend/prettier.js save",
"prettier-all": "node ./scripts/frontend/prettier.js check-all", "prettier-all": "node ./scripts/frontend/prettier.js check-all",
"prettier-all-save": "node ./scripts/frontend/prettier.js save-all", "prettier-all-save": "node ./scripts/frontend/prettier.js save-all",
...@@ -126,7 +126,6 @@ ...@@ -126,7 +126,6 @@
"eslint-plugin-jasmine": "^2.10.1", "eslint-plugin-jasmine": "^2.10.1",
"gettext-extractor": "^3.3.2", "gettext-extractor": "^3.3.2",
"gettext-extractor-vue": "^4.0.1", "gettext-extractor-vue": "^4.0.1",
"ignore": "^3.3.7",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"jasmine-core": "^2.9.0", "jasmine-core": "^2.9.0",
"jasmine-diff": "^0.1.3", "jasmine-diff": "^0.1.3",
......
...@@ -13,7 +13,8 @@ const execGitCmd = args => ...@@ -13,7 +13,8 @@ const execGitCmd = args =>
exec('git', args) exec('git', args)
.trim() .trim()
.toString() .toString()
.split('\n'); .split('\n')
.filter(Boolean);
module.exports = { module.exports = {
getStagedFiles: fileExtensionFilter => { getStagedFiles: fileExtensionFilter => {
......
const glob = require('glob'); const glob = require('glob');
const prettier = require('prettier'); const prettier = require('prettier');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const { getStagedFiles } = require('./frontend_script_utils');
const prettierIgnore = require('ignore')();
const getStagedFiles = require('./frontend_script_utils').getStagedFiles; const matchExtensions = ['js', 'vue'];
// This will improve glob performance by excluding certain directories.
// The .prettierignore file will also be respected, but after the glob has executed.
const globIgnore = ['**/node_modules/**', 'vendor/**', 'public/**'];
const readFileAsync = (file, options) =>
new Promise((resolve, reject) => {
fs.readFile(file, options, function(err, data) {
if (err) reject(err);
else resolve(data);
});
});
const writeFileAsync = (file, data, options) =>
new Promise((resolve, reject) => {
fs.writeFile(file, data, options, function(err) {
if (err) reject(err);
else resolve();
});
});
const mode = process.argv[2] || 'check'; const mode = process.argv[2] || 'check';
const shouldSave = mode === 'save' || mode === 'save-all'; const shouldSave = mode === 'save' || mode === 'save-all';
const allFiles = mode === 'check-all' || mode === 'save-all'; const allFiles = mode === 'check-all' || mode === 'save-all';
let dirPath = process.argv[3] || ''; let globDir = process.argv[3] || '';
if (dirPath && dirPath.charAt(dirPath.length - 1) !== '/') dirPath += '/'; if (globDir && globDir.charAt(globDir.length - 1) !== '/') globDir += '/';
const config = {
patterns: ['**/*.js', '**/*.vue', '**/*.scss'],
/*
* The ignore patterns below are just to reduce search time with glob, as it includes the
* folders with the most ignored assets, the actual `.prettierignore` will be used later on
*/
ignore: ['**/node_modules/**', '**/vendor/**', '**/public/**'],
parsers: {
js: 'babylon',
vue: 'vue',
scss: 'css',
},
};
/* console.log(
* Unfortunately the prettier API does not expose support for `.prettierignore` files, they however `Loading all ${allFiles ? '' : 'staged '}files ${globDir ? `within ${globDir} ` : ''}...`
* use the ignore package, so we do the same. We simply cannot use the glob package, because
* gitignore style is not compatible with globs ignore style.
*/
prettierIgnore.add(
fs
.readFileSync(path.join(__dirname, '../../', '.prettierignore'))
.toString()
.trim()
.split(/\r?\n/)
); );
const availableExtensions = Object.keys(config.parsers); const globPatterns = matchExtensions.map(ext => `${globDir}**/*.${ext}`);
const matchedFiles = allFiles
console.log(`Loading ${allFiles ? 'All' : 'Selected'} Files ...`); ? glob.sync(`{${globPatterns.join(',')}}`, { ignore: globIgnore })
: getStagedFiles(globPatterns);
const matchedCount = matchedFiles.length;
const stagedFiles = if (!matchedCount) {
allFiles || dirPath ? null : getStagedFiles(availableExtensions.map(ext => `*.${ext}`)); console.log('No files found to process with prettier');
process.exit(0);
if (stagedFiles) {
if (!stagedFiles.length || (stagedFiles.length === 1 && !stagedFiles[0])) {
console.log('No matching staged files.');
process.exit(1);
}
console.log(`Matching staged Files : ${stagedFiles.length}`);
} }
let didWarn = false; let didWarn = false;
let didError = false; let passedCount = 0;
let failedCount = 0;
let files; let ignoredCount = 0;
if (allFiles) {
const ignore = config.ignore; console.log(`${shouldSave ? 'Updating' : 'Checking'} ${matchedCount} file(s)`);
const patterns = config.patterns;
const globPattern = patterns.length > 1 ? `{${patterns.join(',')}}` : `${patterns.join(',')}`; const fixCommand = `yarn prettier-${allFiles ? 'all' : 'staged'}-save`;
files = glob.sync(globPattern, { ignore }).filter(f => allFiles || stagedFiles.includes(f)); const warningMessage = `
} else if (dirPath) { ===============================
const ignore = config.ignore; GitLab uses Prettier to format all JavaScript code.
const patterns = config.patterns.map(item => { Please format each file listed below or run "${fixCommand}"
return dirPath + item; ===============================
}); `;
const globPattern = patterns.length > 1 ? `{${patterns.join(',')}}` : `${patterns.join(',')}`;
files = glob.sync(globPattern, { ignore }); const checkFileWithOptions = (filePath, options) =>
} else { readFileAsync(filePath, 'utf8').then(input => {
files = stagedFiles.filter(f => availableExtensions.includes(f.split('.').pop())); if (shouldSave) {
} const output = prettier.format(input, options);
if (input === output) {
files = prettierIgnore.filter(files); passedCount += 1;
} else {
if (!files.length) { return writeFileAsync(filePath, output, 'utf8').then(() => {
console.log('No Files found to process with Prettier'); console.log(`Prettified : ${filePath}`);
process.exit(1); failedCount += 1;
}
console.log(`${shouldSave ? 'Updating' : 'Checking'} ${files.length} file(s)`);
files.forEach(file => {
try {
prettier
.resolveConfig(file)
.then(options => {
const fileExtension = file.split('.').pop();
Object.assign(options, {
parser: config.parsers[fileExtension],
}); });
}
const input = fs.readFileSync(file, 'utf8'); } else {
if (prettier.check(input, options)) {
if (shouldSave) { passedCount += 1;
const output = prettier.format(input, options); } else {
if (output !== input) { if (!didWarn) {
fs.writeFileSync(file, output, 'utf8'); console.log(warningMessage);
console.log(`Prettified : ${file}`); didWarn = true;
}
} else if (!prettier.check(input, options)) {
if (!didWarn) {
console.log(
'\n===============================\nGitLab uses Prettier to format all JavaScript code.\nPlease format each file listed below or run "yarn prettier-staged-save"\n===============================\n'
);
didWarn = true;
}
console.log(`Prettify Manually : ${file}`);
} }
}) console.log(`Prettify Manually : ${filePath}`);
.catch(e => { failedCount += 1;
console.log(`Error on loading the Config File: ${e.message}`); }
process.exit(1); }
}); });
} catch (error) {
didError = true;
console.log(`\n\nError with ${file}: ${error.message}`);
}
});
if (didWarn || didError) { const checkFileWithPrettierConfig = filePath =>
process.exit(1); prettier
} .getFileInfo(filePath, { ignorePath: '.prettierignore' })
.then(({ ignored, inferredParser }) => {
if (ignored || !inferredParser) {
ignoredCount += 1;
return;
}
return prettier.resolveConfig(filePath).then(fileOptions => {
const options = { ...fileOptions, parser: inferredParser };
return checkFileWithOptions(filePath, options);
});
});
Promise.all(matchedFiles.map(checkFileWithPrettierConfig))
.then(() => {
const failAction = shouldSave ? 'fixed' : 'failed';
console.log(
`\nSummary:\n ${matchedCount} files processed (${passedCount} passed, ${failedCount} ${failAction}, ${ignoredCount} ignored)\n`
);
if (didWarn) process.exit(1);
})
.catch(e => {
console.log(`\nAn error occured while processing files with prettier: ${e.message}\n`);
process.exit(1);
});
...@@ -4181,11 +4181,6 @@ ignore-walk@^3.0.1: ...@@ -4181,11 +4181,6 @@ ignore-walk@^3.0.1:
dependencies: dependencies:
minimatch "^3.0.4" minimatch "^3.0.4"
ignore@^3.3.7:
version "3.3.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b"
integrity sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==
ignore@^4.0.6: ignore@^4.0.6:
version "4.0.6" version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment