[6.x] [precommitHook/caseCheck] require that pacakges directories use kebab-case (#16452) (#16468)

This commit is contained in:
Spencer 2018-02-01 17:00:20 -07:00 committed by GitHub
parent d990f26e50
commit 9697a83947
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 15 deletions

View file

@ -18,6 +18,17 @@ export const IGNORE_FILE_GLOBS = [
];
/**
* These patterns are matched against directories and indicate
* folders that must use kebab case.
*
* @type {Array}
*/
export const KEBAB_CASE_DIRECTORY_GLOBS = [
'packages/*',
];
/**
* These patterns are matched against directories and indicate
* explicit folders that are NOT supposed to use snake_case.
@ -33,9 +44,9 @@ export const IGNORE_FILE_GLOBS = [
* @type {Array}
*/
export const IGNORE_DIRECTORY_GLOBS = [
...KEBAB_CASE_DIRECTORY_GLOBS,
'**/webpackShims',
'src/babel-*',
'packages/eslint-*',
'ui_framework/generator-kui',
'src/ui/public/angular-bootstrap',
'src/ui/public/flot-charts',

View file

@ -1,4 +1,7 @@
import { relative } from 'path';
import { relative, basename } from 'path';
import { dim } from 'chalk';
import { createFailError } from '../run';
import { matchesAnyGlob } from '../globs';
@ -6,13 +9,15 @@ import {
IGNORE_DIRECTORY_GLOBS,
IGNORE_FILE_GLOBS,
TEMPORARILY_IGNORED_PATHS,
KEBAB_CASE_DIRECTORY_GLOBS,
} from './casing_check_config';
const NON_SNAKE_CASE_RE = /[A-Z \-]/;
const NON_KEBAB_CASE_RE = /[A-Z \_]/;
function listFileNames(files) {
return files
.map(file => ` - ${file.getRelativePath()}`)
function listPaths(paths) {
return paths
.map(path => ` - ${path}`)
.join('\n');
}
@ -40,6 +45,33 @@ function getPathWithoutIgnoredParents(file) {
return file.getRelativePath();
}
/**
* Check for directories in the passed File objects which match the
* KEBAB_CASE_DIRECTORY_GLOBS and ensure that those directories use
* keban case
*
* @param {ToolingLog} log
* @param {Array<File>} files
* @return {Promise<undefined>}
*/
async function checkForKebabCase(log, files) {
const errorPaths = files
.reduce((acc, file) => {
const parents = file.getRelativeParentDirs();
return acc.concat(parents.filter(parent => (
matchesAnyGlob(parent, KEBAB_CASE_DIRECTORY_GLOBS) && NON_KEBAB_CASE_RE.test(basename(parent))
)));
}, [])
.reduce((acc, path) => (
acc.includes(path) ? acc : acc.concat(path)
), []);
if (errorPaths.length) {
throw createFailError(`These directories MUST use kebab-case.\n${listPaths(errorPaths)}`);
}
}
/**
* Check that all passed File objects are using valid casing. Every
* file SHOULD be using snake_case but some files are allowed to stray:
@ -54,15 +86,15 @@ function getPathWithoutIgnoredParents(file) {
* @param {Array<File>} files
* @return {Promise<undefined>}
*/
export async function checkFileCasing(log, files) {
const errors = [];
const warnings = [];
async function checkForSnakeCase(log, files) {
const errorPaths = [];
const warningPaths = [];
files.forEach(file => {
const path = file.getRelativePath();
if (TEMPORARILY_IGNORED_PATHS.includes(path)) {
warnings.push(file);
warningPaths.push(file.getRelativePath());
return;
}
@ -72,19 +104,26 @@ export async function checkFileCasing(log, files) {
return;
}
const invalid = NON_SNAKE_CASE_RE.test(getPathWithoutIgnoredParents(file));
const pathToValidate = getPathWithoutIgnoredParents(file);
const invalid = NON_SNAKE_CASE_RE.test(pathToValidate);
if (!invalid) {
log.debug('%j uses valid casing', file);
} else {
errors.push(file);
const ignoredParent = file.getRelativePath().slice(0, -pathToValidate.length);
errorPaths.push(`${dim(ignoredParent)}${pathToValidate}`);
}
});
if (warnings.length) {
log.warning(`Filenames SHOULD be snake_case.\n${listFileNames(warnings)}`);
if (warningPaths.length) {
log.warning(`Filenames SHOULD be snake_case.\n${listPaths(warningPaths)}`);
}
if (errors.length) {
throw createFailError(`Filenames MUST use snake_case.\n${listFileNames(errors)}`);
if (errorPaths.length) {
throw createFailError(`Filenames MUST use snake_case.\n${listPaths(errorPaths)}`);
}
}
export async function checkFileCasing(log, files) {
await checkForKebabCase(log, files);
await checkForSnakeCase(log, files);
}