UNPKG

eclint

Version:

Validate or fix code that doesn't adhere to EditorConfig settings or infer settings from existing code.

291 lines 9.95 kB
"use strict"; 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