ZachJW34 dd52f3cdca fix(nx): filter non-existing files during format (#1087)
Formatting of uncommitted files errors when the only change is the deletion of files. Checking if
the file exists before writing solves this issue.
2019-02-19 12:40:57 -05:00

116 lines
3.0 KiB
TypeScript

import { execSync } from 'child_process';
import * as path from 'path';
import * as resolve from 'resolve';
import { getProjectRoots, parseFiles } from './shared';
import { YargsAffectedOptions } from './affected';
import { getTouchedProjects } from './touched';
import { fileExists } from '../utils/fileutils';
export interface YargsFormatOptions extends YargsAffectedOptions {
libsAndApps?: boolean;
}
const PRETTIER_EXTENSIONS = ['ts', 'js', 'scss', 'css', 'html', 'json', 'md'];
export function format(command: 'check' | 'write', args: YargsFormatOptions) {
let patterns: string[];
try {
patterns = getPatterns(args);
} catch (e) {
printError(command, e);
process.exit(1);
}
// Chunkify the patterns array to prevent crashing the windows terminal
const chunkList: string[][] = chunkify(patterns, 70);
switch (command) {
case 'write':
chunkList.forEach(chunk => write(chunk));
break;
case 'check':
chunkList.forEach(chunk => check(chunk));
break;
}
}
function getPatterns(args: YargsAffectedOptions) {
try {
if (args.all) {
return getPatternsWithPathPrefix(['{apps,libs,tools}']);
}
const p = parseFiles(args);
let patterns = p.files
.filter(f => fileExists(f))
.filter(f =>
PRETTIER_EXTENSIONS.map(ext => '.' + ext).includes(path.extname(f))
);
const libsAndApp = args.libsAndApps;
return libsAndApp ? getPatternsFromApps(patterns) : patterns;
} catch (e) {
return getPatternsWithPathPrefix(['{apps,libs,tools}']);
}
}
function getPatternsFromApps(affectedFiles: string[]): string[] {
const roots = getProjectRoots(getTouchedProjects(affectedFiles));
return getPatternsWithPathPrefix(roots);
}
function chunkify(target: string[], size: number): string[][] {
return target.reduce((current: string[][], value: string, index: number) => {
if (index % size === 0) current.push([]);
current[current.length - 1].push(value);
return current;
}, []);
}
function getPatternsWithPathPrefix(prefixes: string[]): string[] {
return prefixes.map(
prefix => `"${prefix}/**/*.{${PRETTIER_EXTENSIONS.join(',')}}"`
);
}
function printError(command: string, e: any) {
console.error(
`Pass the SHA range, as follows: npm run format:${command} -- SHA1 SHA2.`
);
console.error(
`Or pass the list of files, as follows: npm run format:${command} -- --files="libs/mylib/index.ts,libs/mylib2/index.ts".`
);
console.error(e.message);
}
function write(patterns: string[]) {
if (patterns.length > 0) {
execSync(`node "${prettierPath()}" --write ${patterns.join(' ')}`, {
stdio: [0, 1, 2]
});
}
}
function check(patterns: string[]) {
if (patterns.length > 0) {
try {
execSync(
`node "${prettierPath()}" --list-different ${patterns.join(' ')}`,
{
stdio: [0, 1, 2]
}
);
} catch (e) {
process.exit(1);
}
}
}
function prettierPath() {
const basePath = path.dirname(
resolve.sync('prettier', { basedir: __dirname })
);
return path.join(basePath, 'bin-prettier.js');
}