Introduce envsubst for config.js, update deps (#3032)

This is the implemenation of envsubst discussed in #1756 

Documentation update will follow after merge.
This commit is contained in:
Karsten Hassel 2023-02-12 22:34:57 +01:00 committed by GitHub
parent 4b478a5a5e
commit a65ee86501
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1914 additions and 833 deletions

View File

@ -17,6 +17,7 @@ _This release is scheduled to be released on 2023-04-01._
- Added Pirate Weather as new weather provider (#3005) - Added Pirate Weather as new weather provider (#3005)
- Added possibility to use your own templates in Alert module - Added possibility to use your own templates in Alert module
- Added error message if `<modulename>.js` file is missing in module folder to get a hint in the logs (#2403) - Added error message if `<modulename>.js` file is missing in module folder to get a hint in the logs (#2403)
- Added possibility to use environment variables in `config.js` (#1756)
### Removed ### Removed

View File

@ -6,6 +6,10 @@
* For more information on how you can configure this file * For more information on how you can configure this file
* see https://docs.magicmirror.builders/configuration/introduction.html * see https://docs.magicmirror.builders/configuration/introduction.html
* and https://docs.magicmirror.builders/modules/configuration.html * and https://docs.magicmirror.builders/modules/configuration.html
*
* You can use environment variables using a `config.js.template` file instead of `config.js`
* which will be converted to `config.js` while starting. For more information
* see https://docs.magicmirror.builders/configuration/introduction.html#enviromnent-variables
*/ */
let config = { let config = {
address: "localhost", // Address to listen on, can be: address: "localhost", // Address to listen on, can be:

View File

@ -14,6 +14,7 @@ const Log = require("logger");
const Server = require(`${__dirname}/server`); const Server = require(`${__dirname}/server`);
const Utils = require(`${__dirname}/utils`); const Utils = require(`${__dirname}/utils`);
const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`); const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`);
const envsub = require("envsub");
// Get version number. // Get version number.
global.version = require(`${__dirname}/../package.json`).version; global.version = require(`${__dirname}/../package.json`).version;
@ -51,25 +52,71 @@ function App() {
let httpServer; let httpServer;
/** /**
* Loads the config file. Combines it with the defaults, and runs the * Loads the config file. Combines it with the defaults and returns the config
* callback with the found config as argument.
*
* @param {Function} callback Function to be called after loading the config
*/ */
function loadConfig(callback) { async function loadConfig() {
Log.log("Loading config ..."); Log.log("Loading config ...");
const defaults = require(`${__dirname}/defaults`); const defaults = require(`${__dirname}/defaults`);
// For this check proposed to TestSuite // For this check proposed to TestSuite
// https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8 // https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8
const configFilename = path.resolve(global.configuration_file || `${global.root_path}/config/config.js`); const configFilename = path.resolve(global.configuration_file || `${global.root_path}/config/config.js`);
let templateFile = configFilename + ".template";
// check if templateFile exists
try {
fs.accessSync(templateFile, fs.F_OK);
} catch (err) {
templateFile = null;
Log.debug("config template file not exists, no envsubst");
}
if (templateFile) {
// save current config.js
try {
if (fs.existsSync(configFilename)) {
fs.copyFileSync(configFilename, configFilename + "_" + Date.now());
}
} catch (err) {
Log.warn("Could not copy " + configFilename + ": " + err.message);
}
// check if config.env exists
const envFiles = [];
const configEnvFile = configFilename.substr(0, configFilename.lastIndexOf(".")) + ".env";
try {
if (fs.existsSync(configEnvFile)) {
envFiles.push(configEnvFile);
}
} catch (err) {
Log.debug(configEnvFile + " does not exist. " + err.message);
}
let options = {
all: true,
diff: false,
envFiles: envFiles,
protect: false,
syntax: "default",
system: true
};
// envsubst variables in templateFile and create new config.js
// naming for envsub must be templateFile and outputFile
const outputFile = configFilename;
try {
await envsub({ templateFile, outputFile, options });
} catch (err) {
Log.error("Could not envsubst variables: " + err.message);
}
}
try { try {
fs.accessSync(configFilename, fs.F_OK); fs.accessSync(configFilename, fs.F_OK);
const c = require(configFilename); const c = require(configFilename);
checkDeprecatedOptions(c); checkDeprecatedOptions(c);
const config = Object.assign(defaults, c); const config = Object.assign(defaults, c);
callback(config); return config;
} catch (e) { } catch (e) {
if (e.code === "ENOENT") { if (e.code === "ENOENT") {
Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration."));
@ -78,7 +125,7 @@ function App() {
} else { } else {
Log.error(Utils.colors.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`)); Log.error(Utils.colors.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`));
} }
callback(defaults); return defaults;
} }
} }
@ -217,7 +264,7 @@ function App() {
* @param {Function} callback Function to be called after start * @param {Function} callback Function to be called after start
*/ */
this.start = function (callback) { this.start = function (callback) {
loadConfig(function (c) { loadConfig().then((c) => {
config = c; config = c;
Log.setLogLevel(config.logLevel); Log.setLogLevel(config.logLevel);

2617
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -51,15 +51,15 @@
"devDependencies": { "devDependencies": {
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.2.1", "eslint-plugin-jest": "^27.2.1",
"eslint-plugin-jsdoc": "^39.6.8", "eslint-plugin-jsdoc": "^39.8.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"express-basic-auth": "^1.2.1", "express-basic-auth": "^1.2.1",
"husky": "^8.0.3", "husky": "^8.0.3",
"jest": "^29.4.0", "jest": "^29.4.2",
"jsdom": "^21.1.0", "jsdom": "^21.1.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"playwright": "^1.30.0", "playwright": "^1.30.0",
"prettier": "^2.8.3", "prettier": "^2.8.4",
"pretty-quick": "^3.1.3", "pretty-quick": "^3.1.3",
"sinon": "^15.0.1", "sinon": "^15.0.1",
"stylelint": "^14.16.1", "stylelint": "^14.16.1",
@ -69,24 +69,25 @@
"suncalc": "^1.9.0" "suncalc": "^1.9.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"electron": "^22.1.0" "electron": "^22.2.0"
}, },
"dependencies": { "dependencies": {
"colors": "^1.4.0", "colors": "^1.4.0",
"console-stamp": "^3.1.0", "console-stamp": "^3.1.0",
"digest-fetch": "^2.0.1", "digest-fetch": "^2.0.1",
"eslint": "^8.32.0", "envsub": "^4.1.0",
"eslint": "^8.33.0",
"express": "^4.18.2", "express": "^4.18.2",
"express-ipfilter": "^1.3.1", "express-ipfilter": "^1.3.1",
"feedme": "^2.0.2", "feedme": "^2.0.2",
"helmet": "^6.0.1", "helmet": "^6.0.1",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"luxon": "^1.28.0", "luxon": "^1.28.1",
"module-alias": "^2.2.2", "module-alias": "^2.2.2",
"moment": "^2.29.4", "moment": "^2.29.4",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.9",
"node-ical": "^0.15.3", "node-ical": "^0.15.3",
"socket.io": "^4.5.4" "socket.io": "^4.6.0"
}, },
"_moduleAliases": { "_moduleAliases": {
"node_helper": "js/node_helper.js", "node_helper": "js/node_helper.js",

View File

@ -0,0 +1 @@
MM_PORT=8090

View File

@ -0,0 +1,13 @@
/* MagicMirror² Test config sample environment set port 8090
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({
port: ${MM_PORT}
});
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@ -0,0 +1,15 @@
const helpers = require("./helpers/global-setup");
describe("templated config with port variable", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/port_variable.js");
});
afterAll(async () => {
await helpers.stopApplication();
});
it("should return 200", async () => {
const res = await helpers.fetch("http://localhost:8090");
expect(res.status).toBe(200);
});
});

14
vendor/package-lock.json generated vendored
View File

@ -7,7 +7,7 @@
"name": "magicmirror-vendors", "name": "magicmirror-vendors",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^6.2.1", "@fortawesome/fontawesome-free": "^6.3.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"moment-timezone": "^0.5.40", "moment-timezone": "^0.5.40",
"nunjucks": "^3.2.3", "nunjucks": "^3.2.3",
@ -16,9 +16,9 @@
} }
}, },
"node_modules/@fortawesome/fontawesome-free": { "node_modules/@fortawesome/fontawesome-free": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz",
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A==", "integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA==",
"hasInstallScript": true, "hasInstallScript": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@ -98,9 +98,9 @@
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": { "@fortawesome/fontawesome-free": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz",
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A==" "integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA=="
}, },
"a-sync-waterfall": { "a-sync-waterfall": {
"version": "1.0.1", "version": "1.0.1",

2
vendor/package.json vendored
View File

@ -10,7 +10,7 @@
"url": "https://github.com/MichMich/MagicMirror/issues" "url": "https://github.com/MichMich/MagicMirror/issues"
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^6.2.1", "@fortawesome/fontawesome-free": "^6.3.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"moment-timezone": "^0.5.40", "moment-timezone": "^0.5.40",
"nunjucks": "^3.2.3", "nunjucks": "^3.2.3",