Skip to content

Commit

Permalink
chore: start fresh
Browse files Browse the repository at this point in the history
Signed-off-by: Charlike Mike Reagent <[email protected]>
  • Loading branch information
tunnckoCore committed Mar 7, 2020
1 parent ac1f722 commit c84e97f
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 439 deletions.
357 changes: 0 additions & 357 deletions packages/eslint/src/api.js
Original file line number Diff line number Diff line change
@@ -1,358 +1 @@
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
/* eslint-disable no-restricted-syntax */
/* eslint-disable max-statements */

'use strict';

const DEFAULT_IGNORE = [
'**/node_modules/**',
'**/bower_components/**',
'flow-typed/**',
'coverage/**',
'**/*fixture*/**',
'{tmp,temp}/**',
'**/*.min.js',
'**/bundle.js',
'**/vendor/**',
'**/dist/**',
];

const OUR_CONFIG_FILENAME = '.lint.config.js';
const DEFAULT_EXTENSIONS = ['js', 'jsx', 'cjs', 'mjs', 'ts', 'tsx'];
const DEFAULT_INPUTS = [
`**/src/**/*.{${DEFAULT_EXTENSIONS.join(',')}}`,
`**/*test*/**/*.{${DEFAULT_EXTENSIONS.join(',')}}`,
];

const fs = require('fs');
const path = require('path');
const memoizeFs = require('memoize-fs');
const codeframe = require('eslint/lib/cli-engine/formatters/codeframe');
const globCache = require('glob-cache');
const { CLIEngine, Linter } = require('eslint');

function resolveConfigSync(filePath, baseConfig, options) {
const { cwd, ...opt } = { /* cwd: process.cwd(), */ ...options };
const doNotUseEslintRC = baseConfig && typeof baseConfig === 'object';

const settings = {
...opt,
baseConfig,
cache: true,
useEslintrc: !doNotUseEslintRC,
cacheLocation: './.cache/custom-eslint-cache',
};
settings.extensions = settings.extensions || DEFAULT_EXTENSIONS;

const engine = new CLIEngine(settings);

const config = engine.getConfigForFile(filePath);

return config;
}

async function resolveConfig(filePath, baseConfig, options) {
const opts = { ...options };
const memoizer = memoizeFs({
cachePath: path.join(process.cwd(), '.cache', 'eslint-resolve-config'),
});

const memoizedFn = await memoizer.fn(
opts.dirname
? (_) => resolveConfigSync(filePath, baseConfig, options)
: resolveConfigSync,
);
const cfg = await memoizedFn(
...(opts.dirname ? [opts.dirname] : [filePath, baseConfig, options]),
);

return cfg;
}

function formatCodeframe(rep, log) {
const res = codeframe(rep.results || rep);
return log ? console.log(res) : res;
}

function injectIntoLinter(config, linter) {
if (!config) {
return linter;
}

const linterInstance = linter || new Linter();

[]
.concat(config.plugins)
.filter(Boolean)
.forEach((pluginName) => {
let plugin = null;

if (pluginName.startsWith('@')) {
plugin = require(pluginName);
} else {
plugin = require(`eslint-plugin-${pluginName}`);
}

// note: defineRules is buggy
Object.keys(plugin.rules).forEach((ruleName) => {
linterInstance.defineRule(
`${pluginName}/${ruleName}`,
plugin.rules[ruleName],
);
});

// note: otherwise this should work
// linterInstance.defineRules(
// Object.keys(plugin.rules).reduce((acc, ruleName) => {
// acc[`${pluginName}/${ruleName}`] = plugin.rules[ruleName];

// return acc;
// }, {}),
// );
});

if (config.parser && config.parser.startsWith('/')) {
if (config.parser.includes('babel-eslint')) {
config.parser = 'babel-eslint';
} else if (config.parser.includes('@typescript-eslint/parser')) {
config.parser = '@typescript-eslint/parser';
}
// NOTE: more parsers
}

// define only when we are passed with "raw" (not processed) config
if (config.parser && !config.parser.startsWith('/')) {
linterInstance.defineParser(config.parser, require(config.parser));
}

return linterInstance;
}

async function* lintFiles(patterns, options) {
const opts = { dirs: [], cwd: process.cwd(), ...options };
opts.exclude = opts.exclude || DEFAULT_IGNORE;
opts.extensions = opts.extensions || DEFAULT_EXTENSIONS;
opts.cacheLocation =
typeof opts.cacheLocation === 'string'
? opts.cacheLocation
: path.join(opts.cwd, '.cache', 'hela-eslint-cache');

const iterable = await globCache(patterns, opts);

const engine = new CLIEngine();
let linter = opts.linter || new Linter();
let eslintConfig = await tryLoadLintConfig();

linter = injectIntoLinter(eslintConfig, linter);

// TODO use `cacache` for caching `options` and
// based on that force `ctx.changed` if it is `false`

for await (const ctx of iterable) {
const meta = ctx.cacheFile && ctx.cacheFile.metadata;

if (engine.isPathIgnored(ctx.file.path)) {
// eslint-disable-next-line no-continue
continue;
}

if (ctx.changed) {
const dirname = path.dirname(ctx.file.path);
if (opts.dirs.includes(dirname)) {
eslintConfig = await resolveConfig(ctx.file.path, 0, {
...opts,
dirname,
});
}

const contents = ctx.file.contents.toString();
const { source, messages } = lint({
...opts,
linter,
filename: ctx.file.path,
contents,
config: eslintConfig || (meta && meta.eslintConfig),
});

const res = createReportOrResult('messages', messages, {
filePath: ctx.file.path,
});

const diff = JSON.stringify(res) !== JSON.stringify(meta && meta.report);

// NOTE: `source` property seems deprecated but formatters need it so..
yield {
...ctx,
result: { ...res, source },
eslintConfig: (meta && meta.eslintConfig) || eslintConfig,
};

if (diff) {
// todo update cache with cacache.put
await ctx.cacache.put(ctx.cacheLocation, ctx.file.path, source, {
metadata: { report: { ...res, source }, eslintConfig },
});
}

// if (opts.report) {
// formatCodeframe([res]);
// }
}

if (ctx.changed === false && ctx.notFound === false) {
yield {
...ctx,
result: meta.report,
eslintConfig: meta.eslintConfig || eslintConfig,
};
// if (opts.report) {
// formatCodeframe([meta.report]);
// }
}
}
}

lintFiles.promise = async function lintFilesPromise(patterns, options) {
const opts = { ...options };
const results = [];
const iterable = await lintFiles(patterns, opts);

for await (const { result } of iterable) {
results.push(result);
}

return createReportOrResult('results', results);
};

function lint(options) {
const opts = { ...options };
const cfg = { ...opts.config, filename: opts.filename };
const linter = opts.linter || new Linter();
const filter = (x) =>
opts.warnings ? true : !opts.warnings && x.severity === 2;

if (!opts.contents && !opts.text) {
opts.contents = fs.readFileSync(cfg.filename, 'utf8');
}
if (opts.text) {
cfg.filename = opts.filename || '<text32>';
}
if (opts.fix) {
const { output, messages } = linter.verifyAndFix(opts.contents, cfg);
if (!opts.text) {
fs.writeFileSync(cfg.filename, output);
}

return { source: output, messages: messages.filter(filter) };
}

const messages = linter.verify(opts.contents, cfg);
return {
source: opts.contents,
messages: messages.filter(filter),
};
}

async function lintText(contents, options) {
const opts = { ...options };
let linter = opts.linter || new Linter();

const eslintConfig = opts.config || (await tryLoadLintConfig());

linter = injectIntoLinter(eslintConfig, linter);
const { source, messages } = lint({
...opts,
config: eslintConfig,
linter,
contents,
text: true,
});

const result = createReportOrResult('messages', messages, {
filePath: opts.filename || '<text>',
source,
});
const report = createReportOrResult('results', [result]);

return { ...report, source };
}

function createReportOrResult(type, results, extra) {
const ret = {
...extra,
errorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
};

ret[type] = [];

if (type === 'messages') {
ret.errorCount = calculateCount('error', results);
ret.warningCount = calculateCount('warning', results);
}

return results.reduce((acc, res) => {
ret[type].push(res);

if (type === 'results') {
acc.errorCount += res.errorCount || 0;
acc.warningCount += res.warningCount || 0;
acc.fixableErrorCount += res.fixableErrorCount || 0;
acc.fixableWarningCount += res.fixableWarningCount || 0;
}

return acc;
}, ret);
}

async function tryLoadLintConfig() {
const rootDir = process.cwd();
let cfg = null;

try {
cfg = await require(path.join(rootDir, OUR_CONFIG_FILENAME));
} catch (err) {
return null;
}

return cfg;
}

function calculateCount(type, items) {
return []
.concat(items)
.filter(Boolean)
.filter((x) => (type === 'error' ? x.severity === 2 : x.severity === 1))
.reduce((acc) => acc + 1, 0);
}

module.exports = {
injectIntoLinter,
tryLoadLintConfig,
resolveConfigSync,
resolveConfig,
formatCodeframe,
calculateCount,
createReportOrResult,
lintFiles,
lintText,
lint,

DEFAULT_IGNORE,
DEFAULT_INPUT: DEFAULT_INPUTS,
DEFAULT_INPUTS,
DEFAULT_EXTENSIONS,
OUR_CONFIG_FILENAME,
};

// (async () => {
// // const patterns = 'packages/eslint/src/**/*.js';
// // const report = await lintFiles(patterns, { fix: true });
// const report = await lintText('var foo = 123', { fix: true });

// formatCodeframe(report.results);
// console.log(report.source); // fixed source code text
// })();
Loading

0 comments on commit c84e97f

Please sign in to comment.