| /** | |
| * @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 }); | |
| 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 })};`; | |
| 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": | |
| 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 | |
| }; |