UNPKG

prettier-eslint-cli

Version:
301 lines (298 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _path = _interopRequireDefault(require("path")); var _fs = _interopRequireDefault(require("fs")); var _glob = require("glob"); var _rxjs = require("rxjs"); var _operators = require("rxjs/operators"); var _chalk = _interopRequireDefault(require("chalk")); var _getStdin = _interopRequireDefault(require("get-stdin")); var _ignore = _interopRequireDefault(require("ignore")); var _findUp = _interopRequireDefault(require("find-up")); var _lodash = _interopRequireDefault(require("lodash.memoize")); var _indentString = _interopRequireDefault(require("indent-string")); var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix")); var _prettierEslint = _interopRequireDefault(require("./prettier-eslint")); var messages = _interopRequireWildcard(require("./messages")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint no-console:0 */ /* eslint complexity:[1, 7] */ const LINE_SEPERATOR_REGEX = /(\r|\n|\r\n)/; const rxReadFile = (0, _rxjs.bindNodeCallback)(_fs.default.readFile); const rxWriteFile = (0, _rxjs.bindNodeCallback)(_fs.default.writeFile); const findUpEslintignoreSyncMemoized = (0, _lodash.default)(findUpEslintignoreSync, findUpMemoizeResolver); const findUpPrettierignoreSyncMemoized = (0, _lodash.default)(findUpPrettierignoreSync, findUpMemoizeResolver); const getIsIgnoredMemoized = (0, _lodash.default)(getIsIgnored); const logger = (0, _loglevelColoredLevelPrefix.default)({ prefix: 'prettier-eslint-cli' }); var _default = exports.default = formatFilesFromArgv; function formatFilesFromArgv({ _: fileGlobs, $0: _$0, //eslint-disable-line help: _help, h: _help_, version: _version, logLevel = logger.getLevel(), l: _logLevelAlias, config: _config, listDifferent, stdin, stdinFilepath, write, eslintPath, prettierPath, ignore: ignoreGlobs = [], eslintIgnore: applyEslintIgnore = true, prettierIgnore: applyPrettierIgnore = true, eslintConfigPath, prettierLast, includeDotFiles, ...prettierOptions }) { logger.setLevel(logLevel); const prettierESLintOptions = { logLevel, eslintPath, prettierPath, prettierLast, prettierOptions }; if (eslintConfigPath) { prettierESLintOptions.eslintConfig = { overrideConfigFile: eslintConfigPath }; } const cliOptions = { write, listDifferent, includeDotFiles }; if (stdin) { return formatStdin({ filePath: stdinFilepath, ...prettierESLintOptions }); } else { return formatFilesFromGlobs({ fileGlobs, ignoreGlobs: [...ignoreGlobs], // make a copy to avoid manipulation cliOptions, prettierESLintOptions, applyEslintIgnore, applyPrettierIgnore }); } } async function formatStdin(prettierESLintOptions) { const stdinValue = (await (0, _getStdin.default)()).trim(); try { const formatted = await (0, _prettierEslint.default)({ text: stdinValue, ...prettierESLintOptions }); process.stdout.write(formatted); return Promise.resolve(formatted); } catch (error) { logger.error('There was a problem trying to format the stdin text', `\n${(0, _indentString.default)(error.stack, 4)}`); process.exitCode = 1; return Promise.resolve(stdinValue); } } function formatFilesFromGlobs({ fileGlobs, ignoreGlobs, cliOptions, prettierESLintOptions, applyEslintIgnore, applyPrettierIgnore }) { const concurrentGlobs = 3; const concurrentFormats = 10; return new Promise(resolve => { const successes = []; const failures = []; const unchanged = []; (0, _rxjs.from)(fileGlobs).pipe((0, _operators.mergeMap)(fileGlob => getFilesFromGlob(ignoreGlobs, applyEslintIgnore, applyPrettierIgnore, fileGlob, cliOptions), null, concurrentGlobs), (0, _operators.concatAll)(), (0, _operators.distinct)(), (0, _operators.mergeMap)(filePathToFormatted, null, concurrentFormats)).subscribe(onNext, onError, onComplete); function filePathToFormatted(filePath) { const absoluteFilePath = _path.default.resolve(filePath); return formatFile(absoluteFilePath, prettierESLintOptions, cliOptions); } function onNext(info) { if (info.error) { failures.push(info); } else if (info.unchanged) { unchanged.push(info); } else { successes.push(info); } } function onError(error) { logger.error('There was an unhandled error while formatting the files', `\n${(0, _indentString.default)(error.stack, 4)}`); process.exitCode = 1; resolve({ error, successes, failures }); } function onComplete() { const isSilent = logger.getLevel() === logger.levels.SILENT || cliOptions.listDifferent; /* use console.error directly here because * - we don't want these messages prefixed * - we want them to go to stderr, not stdout */ if (!isSilent) { if (successes.length) { console.error(messages.success({ success: _chalk.default.green('success'), count: successes.length, countString: _chalk.default.bold(successes.length) })); } if (failures.length) { process.exitCode = 1; console.error(messages.failure({ failure: _chalk.default.red('failure'), count: failures.length, countString: _chalk.default.bold(failures.length) })); } if (unchanged.length) { console.error(messages.unchanged({ unchanged: _chalk.default.gray('unchanged'), count: unchanged.length, countString: _chalk.default.bold(unchanged.length) })); } } resolve({ successes, failures }); } }); } function getFilesFromGlob(ignoreGlobs, applyEslintIgnore, applyPrettierIgnore, fileGlob, cliOptions) { const globOptions = { dot: cliOptions.includeDotFiles, ignore: ignoreGlobs }; if (!fileGlob.includes('node_modules')) { // basically, we're going to protect you from doing something // not smart unless you explicitly include it in your glob globOptions.ignore.push('**/node_modules/**'); } return (0, _rxjs.from)((0, _glob.glob)(fileGlob, globOptions)).pipe((0, _operators.map)(filePaths => { return filePaths.filter(filePath => { if (applyEslintIgnore && isFilePathMatchedByEslintignore(filePath)) { return false; } if (applyPrettierIgnore && isFilePathMatchedByPrettierignore(filePath)) { return false; } return true; }); })); } function formatFile(filePath, prettierESLintOptions, cliOptions) { const fileInfo = { filePath }; let format$ = rxReadFile(filePath, 'utf8').pipe((0, _operators.mergeMap)(async text => { fileInfo.text = text; fileInfo.formatted = await (0, _prettierEslint.default)({ text, filePath, ...prettierESLintOptions }); fileInfo.unchanged = fileInfo.text === fileInfo.formatted; return fileInfo; })); if (cliOptions.write) { format$ = format$.pipe((0, _operators.mergeMap)(info => { if (info.unchanged) { return (0, _rxjs.of)(info); } else { return rxWriteFile(filePath, info.formatted).pipe((0, _operators.map)(() => info)); } })); } else if (cliOptions.listDifferent) { format$ = format$.pipe((0, _operators.map)(info => { if (!info.unchanged) { process.exitCode = 1; console.log(info.filePath); } return info; })); } else { format$ = format$.pipe((0, _operators.map)(info => { process.stdout.write(info.formatted); return info; })); } return format$.pipe((0, _operators.catchError)(error => { logger.error(`There was an error formatting "${fileInfo.filePath}":`, `\n${(0, _indentString.default)(error.stack, 4)}`); return (0, _rxjs.of)(Object.assign(fileInfo, { error })); })); } function getNearestEslintignorePath(filePath) { const { dir } = _path.default.parse(filePath); return findUpEslintignoreSyncMemoized('.eslintignore', dir); } function isFilePathMatchedByEslintignore(filePath) { const eslintignorePath = getNearestEslintignorePath(filePath); if (!eslintignorePath) { return false; } const eslintignoreDir = _path.default.parse(eslintignorePath).dir; const filePathRelativeToEslintignoreDir = _path.default.relative(eslintignoreDir, filePath); const isIgnored = getIsIgnoredMemoized(eslintignorePath); return isIgnored(filePathRelativeToEslintignoreDir); } function getNearestPrettierignorePath(filePath) { const { dir } = _path.default.parse(filePath); return findUpPrettierignoreSyncMemoized('.prettierignore', dir); } function isFilePathMatchedByPrettierignore(filePath) { const prettierignorePath = getNearestPrettierignorePath(filePath); if (!prettierignorePath) { return false; } const prettierignoreDir = _path.default.parse(prettierignorePath).dir; const filePathRelativeToPrettierignoreDir = _path.default.relative(prettierignoreDir, filePath); const isIgnored = getIsIgnoredMemoized(prettierignorePath); return isIgnored(filePathRelativeToPrettierignoreDir); } function findUpMemoizeResolver(...args) { return args.join('::'); } function findUpEslintignoreSync(filename, cwd) { return _findUp.default.sync('.eslintignore', { cwd }); } function findUpPrettierignoreSync(filename, cwd) { return _findUp.default.sync('.prettierignore', { cwd }); } function getIsIgnored(filename) { const ignoreLines = _fs.default.readFileSync(filename, 'utf8').split(LINE_SEPERATOR_REGEX).filter(line => Boolean(line.trim())); const instance = (0, _ignore.default)(); instance.add(ignoreLines); return instance.ignores.bind(instance); }