From f56a63b2f237f258998dab83d28eefde3e81238f Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Wed, 16 Oct 2024 09:40:21 +0100 Subject: [PATCH] Major update: Add Environment variables support --- README.md | 11 ++++++++++ index.js | 26 ++++++++-------------- lib/sync.js | 4 +--- lib/watch/files.js | 15 +++++++++++++ lib/watch/folders.js | 15 +++++++++++++ types.js | 5 +++++ utils/delay.js | 4 ++-- utils/env.js | 52 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 utils/env.js diff --git a/README.md b/README.md index 9616a92..4ac9ab6 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,14 @@ The config file is a json file that contains all the information needed to run t } ] ``` + +You can also use environment variables in the config file. Example: + +```json +[ + { + "title": "Sync Folders", + "folders": ["$FOLDER_1", "$FOLDER_2"] + } +] +``` diff --git a/index.js b/index.js index ed17da6..3249490 100644 --- a/index.js +++ b/index.js @@ -3,10 +3,8 @@ const fs = require("fs"); const path = require("path"); -const { execSync, spawn, ChildProcess } = require("child_process"); - -/** @type {string[]} */ -let dirs = []; +const { spawn } = require("child_process"); +const handleEnvVars = require("./utils/env"); const confFileProvidedPath = process.argv[process.argv.length - 1]; @@ -23,7 +21,7 @@ if (confFileProvidedPath === "--version" || confFileProvidedPath === "-v") { ); } - process.exit(); + process.exit(6); } console.log("Running Folder Sync ..."); @@ -56,9 +54,6 @@ if ( process.exit(); } -// /** @type {ChildProcess[]} */ -// const childProcesses = []; - try { const configJSON = fs.existsSync(defaultConfigFilePath) ? fs.readFileSync(defaultConfigFilePath, "utf8") @@ -71,8 +66,10 @@ try { "Config JSON could not be resolved. Please check your files." ); + const parsedConfigJSON = handleEnvVars({ json: configJSON }); + /** @type {TurboSyncConfigArray} */ - const configArray = JSON.parse(configJSON); + const configArray = JSON.parse(parsedConfigJSON); for (let i = 0; i < configArray.length; i++) { const config = configArray[i]; @@ -96,12 +93,7 @@ try { } setInterval(() => { - console.log("Turbo Sync Running ..."); + console.log( + `Turbo Sync Running for ${process.uptime().toLocaleString()}s ...` + ); }, 60000); - -// process.on("exit", () => { -// for (let i = 0; i < childProcesses.length; i++) { -// const childProcess = childProcesses[i]; -// childProcess.kill("SIGTERM"); -// } -// }); diff --git a/lib/sync.js b/lib/sync.js index c8dd6a4..b6ac208 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -2,9 +2,7 @@ // @ts-check -const fs = require("fs"); -const path = require("path"); -const { execSync, spawn } = require("child_process"); +const { spawn } = require("child_process"); const watchFiles = require("./watch/files"); const watchFolders = require("./watch/folders"); diff --git a/lib/watch/files.js b/lib/watch/files.js index ea13e44..815bc17 100644 --- a/lib/watch/files.js +++ b/lib/watch/files.js @@ -111,6 +111,14 @@ function sync({ options, filePath, files }) { const dstFl = destFiles[j]; if (typeof dstFl == "string") { if (!fs.existsSync(dstFl)) continue; + + if (filePath === dstFl) { + console.log( + `You can't sync the same paths. Please check your configuration and resolve duplicate paths` + ); + process.exit(6); + } + cmdArray.push(filePath, dstFl); const cmd = cmdArray.join(" "); execSync(cmd, { @@ -119,6 +127,13 @@ function sync({ options, filePath, files }) { } else if (dstFl.path) { if (!dstFl.host && !fs.existsSync(dstFl.path)) continue; + if (filePath === dstFl.path) { + console.log( + `You can't sync the same paths. Please check your configuration and resolve duplicate paths` + ); + process.exit(6); + } + if (dstFl.host && dstFl.ssh_key && dstFl.user) { cmdArray.push("-e", `'ssh -i ${dstFl.ssh_key}'`); cmdArray.push( diff --git a/lib/watch/folders.js b/lib/watch/folders.js index 6385462..78e105e 100644 --- a/lib/watch/folders.js +++ b/lib/watch/folders.js @@ -120,6 +120,14 @@ function sync({ options, dirs, dirPath, init }) { const dstDr = dstDirs[j]; if (typeof dstDr == "string") { if (!fs.existsSync(dstDr)) continue; + + if (dirPath === dstDr) { + console.log( + `You can't sync the same paths. Please check your configuration and resolve duplicate paths` + ); + process.exit(6); + } + cmdArray.push( path.normalize(dirPath) + "/", path.normalize(dstDr) + "/" @@ -131,6 +139,13 @@ function sync({ options, dirs, dirPath, init }) { } else if (dstDr.path) { if (!dstDr.host && !fs.existsSync(dstDr.path)) continue; + if (dirPath === dstDr.path) { + console.log( + `You can't sync the same paths. Please check your configuration and resolve duplicate paths` + ); + process.exit(6); + } + if (dstDr.host && dstDr.ssh_key && dstDr.user) { cmdArray.push("-e", `'ssh -i ${dstDr.ssh_key}'`); cmdArray.push( diff --git a/types.js b/types.js index 5c4b6ce..f5ff099 100644 --- a/types.js +++ b/types.js @@ -53,3 +53,8 @@ * @property {string} dirPath * @property {boolean} [init] - is this an initialization phase? */ + +/** + * @typedef {object} HandleEnvVarsFnParams + * @property {string} json + */ diff --git a/utils/delay.js b/utils/delay.js index 116f008..183092b 100644 --- a/utils/delay.js +++ b/utils/delay.js @@ -5,11 +5,11 @@ * @param {number} [time] * @returns */ -async function delay(time) { +async function delay(time = 500) { return new Promise((resolve) => { setTimeout(() => { resolve(true); - }, time || 500); + }, time); }); } diff --git a/utils/env.js b/utils/env.js new file mode 100644 index 0000000..8d80717 --- /dev/null +++ b/utils/env.js @@ -0,0 +1,52 @@ +// @ts-check + +const fs = require("fs"); +const path = require("path"); + +/** + * + * @param {HandleEnvVarsFnParams} param0 + * @returns {string} + */ +function handleEnvVars({ json }) { + let newJson = json; + try { + let envVars = { ...process.env }; + const localEnvFilePath = path.resolve(process.cwd(), "./.env"); + + if (fs.existsSync(localEnvFilePath)) { + const localEnvText = fs.readFileSync(localEnvFilePath, "utf8"); + const localEnvKeyPairArray = localEnvText + .split("\n") + .filter( + (keyPair) => + keyPair && + keyPair.match(/.{3,}/) && + !keyPair.match(/^\#/) + ) + .map((keyPair) => keyPair.trim()); + + localEnvKeyPairArray.forEach((keyPair) => { + let keyPairArray = keyPair.split("="); + const key = keyPairArray.shift(); + const value = keyPairArray.join("="); + + const newEnvObject = {}; + newEnvObject[key] = value; + + envVars = { ...envVars, ...newEnvObject }; + }); + } + + for (let key in envVars) { + newJson = newJson.replaceAll(`$${key}`, String(envVars[key])); + } + } catch (error) { + console.log(`Error replacing Environment variables`, error.message); + return json; + } + + return newJson; +} + +module.exports = handleEnvVars;