| /** |
| * @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 |
| }; |