diff --git a/package-lock.json b/package-lock.json index 05bad2f..191270e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5645,17 +5645,22 @@ "requires": { "ansi-regex": "^5.0.0" } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" } } } diff --git a/package.json b/package.json index 9b1ce7a..ca15f7f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "sqlite3": "^5.0.0", "tmp": "^0.1.0", "transliteration": "^2.1.11", - "uuid": "^8.3.0" + "uuid": "^8.3.0", + "yargs-parser": "^20.2.4" }, "devDependencies": { "eslint": "^7.7.0", diff --git a/src/cfg.js b/src/cfg.js index e559d13..be33128 100644 --- a/src/cfg.js +++ b/src/cfg.js @@ -2,12 +2,13 @@ const fs = require("fs"); const path = require("path"); const Ajv = require("ajv"); const schema = require("./data/cfg.schema.json"); +const cliOpts = require("./cliOpts"); /** @type {ModmailConfig} */ let config = {}; -// Config files to search for, in priority order -const configFiles = [ +// Auto-detected config files, in priority order +const configFilesToSearch = [ "config.ini", "config.json", "config.json5", @@ -20,24 +21,46 @@ const configFiles = [ "config.json.txt", ]; -let foundConfigFile; -for (const configFile of configFiles) { +let configFileToLoad; + +const requestedConfigFile = cliOpts.config || cliOpts.c; // CLI option --config/-c +if (requestedConfigFile) { try { - fs.accessSync(__dirname + "/../" + configFile); - foundConfigFile = configFile; - break; - } catch (e) {} + // Config files specified with --config/-c are loaded from cwd + fs.accessSync(requestedConfigFile); + configFileToLoad = requestedConfigFile; + } catch (e) { + if (e.code === "ENOENT") { + console.error(`Specified config file was not found: ${requestedConfigFile}`); + } else { + console.error(`Error reading specified config file ${requestedConfigFile}: ${e.message}`); + } + + process.exit(1); + } +} else { + for (const configFile of configFilesToSearch) { + try { + // Auto-detected config files are always loaded from the bot's folder, even if the cwd differs + const relativePath = path.relative(process.cwd(), path.resolve(__dirname, "..", configFile)); + fs.accessSync(relativePath); + configFileToLoad = relativePath; + break; + } catch (e) {} + } } // Load config values from a config file (if any) -if (foundConfigFile) { - console.log(`Loading configuration from ${foundConfigFile}...`); +if (configFileToLoad) { + const srcRelativePath = path.resolve(__dirname, process.cwd(), configFileToLoad); + console.log(`Loading configuration from ${configFileToLoad}...`); + try { - if (foundConfigFile.endsWith(".js")) { - config = require(`../${foundConfigFile}`); + if (configFileToLoad.endsWith(".js")) { + config = require(srcRelativePath); } else { - const raw = fs.readFileSync(__dirname + "/../" + foundConfigFile, {encoding: "utf8"}); - if (foundConfigFile.endsWith(".ini") || foundConfigFile.endsWith(".ini.txt")) { + const raw = fs.readFileSync(configFileToLoad, {encoding: "utf8"}); + if (configFileToLoad.endsWith(".ini") || configFileToLoad.endsWith(".ini.txt")) { config = require("ini").decode(raw); } else { config = require("json5").parse(raw); diff --git a/src/cliOpts.js b/src/cliOpts.js new file mode 100644 index 0000000..f920e40 --- /dev/null +++ b/src/cliOpts.js @@ -0,0 +1 @@ +module.exports = require("yargs-parser")(process.argv.slice(2));