You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.4 KiB
145 lines
4.4 KiB
3 years ago
|
/**
|
||
|
* @fileoverview Helper to locate and load configuration files.
|
||
|
* @author Nicholas C. Zakas
|
||
|
*/
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Requirements
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
const fs = require("fs"),
|
||
|
path = require("path"),
|
||
|
stringify = require("json-stable-stringify-without-jsonify");
|
||
|
|
||
|
const debug = require("debug")("eslint:config-file");
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Helpers
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Determines sort order for object keys for json-stable-stringify
|
||
|
*
|
||
|
* see: https://github.com/samn/json-stable-stringify#cmp
|
||
|
* @param {Object} a The first comparison object ({key: akey, value: avalue})
|
||
|
* @param {Object} b The second comparison object ({key: bkey, value: bvalue})
|
||
|
* @returns {number} 1 or -1, used in stringify cmp method
|
||
|
*/
|
||
|
function sortByKey(a, b) {
|
||
|
return a.key > b.key ? 1 : -1;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Private
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Writes a configuration file in JSON format.
|
||
|
* @param {Object} config The configuration object to write.
|
||
|
* @param {string} filePath The filename to write to.
|
||
|
* @returns {void}
|
||
|
* @private
|
||
|
*/
|
||
|
function writeJSONConfigFile(config, filePath) {
|
||
|
debug(`Writing JSON config file: ${filePath}`);
|
||
|
|
||
|
const content = `${stringify(config, { cmp: sortByKey, space: 4 })}\n`;
|
||
|
|
||
|
fs.writeFileSync(filePath, content, "utf8");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes a configuration file in YAML format.
|
||
|
* @param {Object} config The configuration object to write.
|
||
|
* @param {string} filePath The filename to write to.
|
||
|
* @returns {void}
|
||
|
* @private
|
||
|
*/
|
||
|
function writeYAMLConfigFile(config, filePath) {
|
||
|
debug(`Writing YAML config file: ${filePath}`);
|
||
|
|
||
|
// lazy load YAML to improve performance when not used
|
||
|
const yaml = require("js-yaml");
|
||
|
|
||
|
const content = yaml.safeDump(config, { sortKeys: true });
|
||
|
|
||
|
fs.writeFileSync(filePath, content, "utf8");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes a configuration file in JavaScript format.
|
||
|
* @param {Object} config The configuration object to write.
|
||
|
* @param {string} filePath The filename to write to.
|
||
|
* @throws {Error} If an error occurs linting the config file contents.
|
||
|
* @returns {void}
|
||
|
* @private
|
||
|
*/
|
||
|
function writeJSConfigFile(config, filePath) {
|
||
|
debug(`Writing JS config file: ${filePath}`);
|
||
|
|
||
|
let contentToWrite;
|
||
|
const stringifiedContent = `module.exports = ${stringify(config, { cmp: sortByKey, space: 4 })};\n`;
|
||
|
|
||
|
try {
|
||
|
const { CLIEngine } = require("../cli-engine");
|
||
|
const linter = new CLIEngine({
|
||
|
baseConfig: config,
|
||
|
fix: true,
|
||
|
useEslintrc: false
|
||
|
});
|
||
|
const report = linter.executeOnText(stringifiedContent);
|
||
|
|
||
|
contentToWrite = report.results[0].output || stringifiedContent;
|
||
|
} catch (e) {
|
||
|
debug("Error linting JavaScript config file, writing unlinted version");
|
||
|
const errorMessage = e.message;
|
||
|
|
||
|
contentToWrite = stringifiedContent;
|
||
|
e.message = "An error occurred while generating your JavaScript config file. ";
|
||
|
e.message += "A config file was still generated, but the config file itself may not follow your linting rules.";
|
||
|
e.message += `\nError: ${errorMessage}`;
|
||
|
throw e;
|
||
|
} finally {
|
||
|
fs.writeFileSync(filePath, contentToWrite, "utf8");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes a configuration file.
|
||
|
* @param {Object} config The configuration object to write.
|
||
|
* @param {string} filePath The filename to write to.
|
||
|
* @returns {void}
|
||
|
* @throws {Error} When an unknown file type is specified.
|
||
|
* @private
|
||
|
*/
|
||
|
function write(config, filePath) {
|
||
|
switch (path.extname(filePath)) {
|
||
|
case ".js":
|
||
|
case ".cjs":
|
||
|
writeJSConfigFile(config, filePath);
|
||
|
break;
|
||
|
|
||
|
case ".json":
|
||
|
writeJSONConfigFile(config, filePath);
|
||
|
break;
|
||
|
|
||
|
case ".yaml":
|
||
|
case ".yml":
|
||
|
writeYAMLConfigFile(config, filePath);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
throw new Error("Can't write to unknown file type.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Public Interface
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
module.exports = {
|
||
|
write
|
||
|
};
|