Skip to content

Instantly share code, notes, and snippets.

@richseviora
Last active January 14, 2018 06:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richseviora/67595789329e938ebcbf9a4e356c50e1 to your computer and use it in GitHub Desktop.
Save richseviora/67595789329e938ebcbf9a4e356c50e1 to your computer and use it in GitHub Desktop.
ESLint To-Do Autogenerator
import { CLIEngine, LintReport, LintResult, LintMessage } from "eslint";
import { relative } from "path";
import * as fs from "fs";
import * as YAML from "yamljs";
import * as _ from "underscore";
const newLint = new CLIEngine({
allowInlineConfig: false,
} as any);
interface LintTransformed {
ruleId: string;
filePath: string;
}
interface RuleAggregated {
rule: string;
filePaths: string[];
}
interface OverrideOutput {
rules: Map<string, number>;
files: string[];
}
const result = newLint.executeOnFiles(["."]) as LintReport;
const parserGenerator = (filePath: string) => {
return (message: LintMessage): LintTransformed => ({
ruleId: message.ruleId,
filePath,
});
};
const resultParser = (result: LintResult) => {
return _.uniq(
result.messages.map(parserGenerator(result.filePath)),
false,
obj => JSON.stringify(obj),
) as LintTransformed[];
};
const nestedResults = result.results.map(resultParser);
const flattenedResults = _.flatten(nestedResults) as LintTransformed[];
const groupedByRule = _.groupBy(flattenedResults, "ruleId");
const baseTransformation = _.map(
groupedByRule,
(value: LintTransformed[], rule: string) => {
return {
rule,
filePaths: _.pluck(value, "filePath").map(path =>
relative(__dirname, path),
),
};
},
) as RuleAggregated[];
const sortedRules = _.sortBy(baseTransformation, "rule");
const transformToOverrides = _.map(
sortedRules,
(ruleAggregate: RuleAggregated): OverrideOutput => {
return {
rules: {
[ruleAggregate.rule]: 0,
},
files: ruleAggregate.filePaths,
};
},
);
function loadYAML<T = any>(path: string): T {
return YAML.parse(fs.readFileSync(path, "utf8"));
}
function outputToYaml(object: any): string {
return YAML.stringify(object, 10, 2);
}
function getNewConfig(object: any): any {
const newExtend = _.unique([...object.extends, "./.eslintrc-todo.yml"]);
return {
...baseConfig,
extends: newExtend,
};
}
const baseConfig = loadYAML(".eslintrc.yml");
const updatedBaseConfig = getNewConfig(baseConfig);
const updatedBaseYAML = outputToYaml(updatedBaseConfig);
const newToDoListConfig = outputToYaml({ overrides: transformToOverrides });
fs.writeFileSync(".eslintrc-todo.yml", newToDoListConfig, { encoding: "utf8" });
fs.writeFileSync(".eslintrc.yml", updatedBaseYAML, { encoding: "utf-8" });
declare module "eslint" {
class CLIEngine {
constructor(obj: any);
executeOnFiles(paths: string[]): LintReport;
}
interface LintMessage {
ruleId: string;
severity: number;
message: string;
line: number;
column: number;
nodeType: number;
source: string;
endLine: number;
endColumn: number;
}
interface LintResult {
filePath: string;
messages: LintMessage[];
errorCount: number;
warningCount: number;
fixableErrorCount: number;
fixableWarningCount: number;
source: string;
output: string;
}
interface LintReport {
results: LintResult[];
errorCount: number;
warningCount: number;
fixableErrorCount: number;
fixableWarningCount: number;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment