eclint
Version:
Validate or fix code that doesn't adhere to EditorConfig settings or infer settings from existing code.
291 lines • 9.95 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var editorconfig = require("editorconfig");
var linez = require("linez");
var _ = require("lodash");
var os = require("os");
var PluginError = require("plugin-error");
var through = require("through2");
var File = require("vinyl");
var doc = require("./doc");
exports.charsets = {
'\u0000\u0000\u00FE\u00FF': 'utf_32be',
'\u00EF\u00BB\u00BF': 'utf_8_bom',
'\u00FE\u00FF': 'utf_16be',
'\u00FF\u00FE': 'utf_16le',
'\u00FF\u00FE\u0000\u0000': 'utf_32le',
};
function configure(options) {
options = options || {};
if (options.newlines) {
linez.configure({ newlines: options.newlines });
}
}
exports.configure = configure;
var PLUGIN_NAME = 'ECLint';
function createPluginError(err, options) {
return new PluginError(PLUGIN_NAME, err, options);
}
exports.ruleNames = [
'charset',
'indent_style',
'indent_size',
'tab_width',
'trim_trailing_whitespace',
'end_of_line',
'insert_final_newline',
'max_line_length',
"block_comment",
'block_comment_start',
'block_comment_end',
];
var rules = {};
_.without(exports.ruleNames, 'tab_width', "block_comment", 'block_comment_start', 'block_comment_end').forEach(function (name) {
rules[name] = require('./rules/' + name);
});
function getSettings(fileSettings, commandSettings) {
return _.pickBy(_.omit(_.assign(fileSettings, commandSettings), ['tab_width']), function (value) { return value !== 'unset'; });
}
function updateResult(file, options) {
if (file.editorconfig) {
_.assign(file.editorconfig, options);
}
else {
file.editorconfig = options;
}
}
function check(options) {
var _this = this;
options = options || {};
var commandSettings = options.settings || {};
return through.obj(function (file, _enc, done) {
if (file.isNull()) {
done(null, file);
return;
}
if (file.isStream()) {
done(createPluginError('Streams are not supported'));
return;
}
editorconfig.parse(file.path)
.then(function (fileSettings) {
var errors = [];
var settings = getSettings(fileSettings, commandSettings);
var document = doc.create(file.contents, settings);
function addError(error) {
if (error) {
error.fileName = file.path;
errors.push(error);
}
}
Object.keys(settings).forEach(function (setting) {
var rule = rules[setting];
if (_.isUndefined(rule)) {
return;
}
if (rule.type === 'DocumentRule') {
rule.check(settings, document).forEach(addError);
}
else {
var checkFn_1 = rule.check;
document.lines.forEach(function (line) {
addError(checkFn_1(settings, line));
});
}
});
updateResult(file, {
config: fileSettings,
errors: errors,
fixed: !!(_.get(file, 'editorconfig.fixed')),
});
if (options.reporter && errors.length) {
errors.forEach(options.reporter.bind(_this, file));
}
done(null, file);
}).catch(function (err) {
done(createPluginError(err));
});
});
}
exports.check = check;
function fix(options) {
options = options || {};
var commandSettings = options.settings || {};
return through.obj(function (file, _enc, done) {
if (file.isNull()) {
done(null, file);
return;
}
if (file.isStream()) {
done(createPluginError('Streams are not supported'));
return;
}
editorconfig.parse(file.path)
.then(function (fileSettings) {
if ((commandSettings.indent_style || fileSettings.indent_style) === 'tab') {
fileSettings = _.omit(fileSettings, [
'tab_width',
'indent_size',
]);
}
var settings = getSettings(fileSettings, commandSettings);
var document = doc.create(file.contents, settings);
Object.keys(settings).forEach(function (setting) {
var rule = rules[setting];
if (_.isUndefined(rule)) {
return;
}
if (rule.type === 'DocumentRule') {
rule.fix(settings, document);
}
else {
var fixFn_1 = rule.fix;
document.lines.forEach(function (line) {
fixFn_1(settings, line);
});
}
});
file.contents = document.toBuffer();
updateResult(file, {
config: fileSettings,
errors: _.get(file, 'editorconfig.errors') || [],
fixed: true,
});
done(null, file);
}).catch(function (err) {
done(createPluginError(err));
});
});
}
exports.fix = fix;
function infer(options) {
options = options || {};
if (options.score && options.ini) {
throw createPluginError('Cannot generate tallied scores as ini file format');
}
var settings = {};
function bufferContents(file, _enc, done) {
if (file.isNull()) {
done();
return;
}
if (file.isStream()) {
done(createPluginError('Streaming not supported'));
return;
}
function incrementSetting(setting, value) {
setting[value] = setting[value] || 0;
setting[value]++;
}
var document = doc.create(file.contents);
Object.keys(rules).forEach(function (key) {
if (key === 'max_line_length') {
settings.max_line_length = 0;
}
else {
settings[key] = {};
}
var setting = settings[key];
var rule = rules[key];
try {
if (rule.type === 'DocumentRule') {
incrementSetting(setting, rule.infer(document));
}
else {
var inferFn_1 = rule.infer;
if (key === 'max_line_length') {
document.lines.forEach(function (line) {
var inferredSetting = inferFn_1(line);
if (inferredSetting > settings.max_line_length) {
settings.max_line_length = inferredSetting;
}
});
}
else {
document.lines.forEach(function (line) {
incrementSetting(setting, inferFn_1(line));
});
}
}
}
catch (err) {
done(createPluginError(err));
}
});
done();
}
function resolveScores() {
function parseValue(value) {
try {
return JSON.parse(value);
}
catch (err) {
return value;
}
}
var result = {};
Object.keys(rules).forEach(function (rule) {
if (rule === 'max_line_length') {
result.max_line_length = Math.ceil(settings.max_line_length / 10) * 10;
return;
}
var maxScore = 0;
var setting = settings[rule];
Object.keys(setting).forEach(function (value) {
var score = setting[value];
var parsedValue = parseValue(value);
if (score >= maxScore && !_.isUndefined(parsedValue)) {
maxScore = score;
result[rule] = parsedValue;
}
});
});
return result;
}
function endStream(done) {
function emitContents(contents) {
this.push(new File({ contents: new Buffer(contents) }));
done();
}
if (options.score) {
emitContents.call(this, JSON.stringify(settings));
return;
}
var resolved = resolveScores();
if (options.ini) {
var lines = [
'# EditorConfig is awesome: http://EditorConfig.org',
'',
];
if (options.root) {
[].push.apply(lines, [
'# top-most EditorConfig file',
'root = true',
'',
]);
}
[].push.apply(lines, [
'[*]',
Object.keys(resolved).map(function (key) {
return key + ' = ' + resolved[key];
}).join(os.EOL),
]);
emitContents.call(this, lines.join(os.EOL) + os.EOL);
return;
}
emitContents.call(this, JSON.stringify(resolved));
}
return through.obj(bufferContents, endStream);
}
exports.infer = infer;
function eclint(options) {
if (options && options.fix) {
return fix(options);
}
else {
return check(options);
}
}
exports.default = eclint;
module.exports = Object.assign(eclint, exports);
//# sourceMappingURL=eclint.js.map
;