// @ts-check const fs = require("fs"); const path = require("path"); const { execSync } = require("child_process"); const delay = require("../../utils/delay"); /** * * @param {SyncFoldersFnParams} param0 */ async function watchFolders({ folders, options }) { try { const dirs = folders; console.log(`Now handling ${dirs.length} Directories`); for (let i = 0; i < dirs.length; i++) { const dir = dirs[i]; if (!dir) { console.log(`Dir: ${dir} doesn't exist`); continue; } const dirPath = typeof dir == "string" ? dir : dir.path; console.log(`Handling dir ${dirPath}`); if ( (typeof dir == "string" && !fs.existsSync(dirPath)) || (typeof dir == "object" && dir.path && !dir.host && !fs.existsSync(dir.path)) ) { console.log(`Dir ${dirPath} does not exist. Creating ...`); try { const existingDirPath = dirs.find((dr) => { if (typeof dr == "string") return fs.existsSync(dr); if (!dr.host) return fs.existsSync(dr.path); // TODO handle remote return false; }); console.log(`Existing Dir to clone: ${existingDirPath}`); if (!existingDirPath) { throw new Error( "No existing Directories for reference" ); } fs.mkdirSync(dirPath, { recursive: true, }); if (typeof existingDirPath == "string") { sync({ dirPath: existingDirPath, dirs, options, init: true, }); } else { sync({ dirPath: existingDirPath.path, dirs, options, init: true, }); } } catch (error) { console.log("Error:", error.message); throw new Error( `Folder Doesn't exist and couldn't be created. Please check if Directory exists.\nERROR => ${error.message}` ); } } console.log(`Watching dir ${dirPath}`); if (typeof dir == "string") { sync({ dirPath, dirs, options }); await delay(); fs.watch(dirPath, { recursive: true }, (evt, fileName) => { sync({ dirPath, dirs, options }); process.exit(1); }); } } } catch (error) { console.log("ERROR:", error.message); process.exit(0); } } /** * * @param {SyncFoldersSyncFnParams} param0 */ function sync({ options, dirs, dirPath, init }) { let cmdArray = ["rsync", "-avh"]; if (options?.delete) { cmdArray.push("--delete"); } if (options?.exclude?.[0]) { options.exclude.forEach((excl) => { cmdArray.push(`--exclude '${excl}'`); }); } const dstDirs = dirs.filter((dr) => { if (typeof dr == "string") return dr !== dirPath; if (dr?.path) return dr.path !== dirPath; return false; }); for (let j = 0; j < dstDirs.length; j++) { const dstDr = dstDirs[j]; if (typeof dstDr == "string") { if (!fs.existsSync(dstDr)) continue; cmdArray.push( path.normalize(dirPath) + "/", path.normalize(dstDr) + "/" ); const cmd = cmdArray.join(" "); execSync(cmd, { stdio: "inherit", }); } else if (dstDr.path) { if (!dstDr.host && !fs.existsSync(dstDr.path)) continue; if (dstDr.host && dstDr.ssh_key && dstDr.user) { cmdArray.push("-e", `'ssh -i ${dstDr.ssh_key}'`); cmdArray.push( path.normalize(dirPath) + "/", `${dstDr.user}@${dstDr.host}:${dstDr.path}/` ); const cmd = cmdArray.join(" "); execSync(cmd, { stdio: "inherit", }); } else { cmdArray.push( path.normalize(dirPath), path.normalize(dstDr.path) ); const cmd = cmdArray.join(" "); execSync(cmd, { stdio: "inherit", }); } } } } module.exports = watchFolders;