Major updates: Create new files and folders if they do not exist
This commit is contained in:
		
							parent
							
								
									727beb0760
								
							
						
					
					
						commit
						285568deb2
					
				
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							| @ -22,10 +22,20 @@ npm update --registry="https://git.tben.me/api/packages/Moduletrace/npm/" -g tur | |||||||
| 
 | 
 | ||||||
| ## Usage | ## Usage | ||||||
| 
 | 
 | ||||||
|  | Turbo Sync requires a `JSON` file with the correct configuration. example: | ||||||
|  | 
 | ||||||
| ```bash | ```bash | ||||||
| turbosync ./turbosync.config.json | turbosync ./project/sync/config.json | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | However if you have a file named `turbosync.config.json` in the working directory simply run: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | turbosync | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | In this case Turbo Sync will automatically look for a file named `turbosync.config.json` in the working directory for config params. | ||||||
|  | 
 | ||||||
| ### Config File | ### Config File | ||||||
| 
 | 
 | ||||||
| The config file is a json file that contains all the information needed to run turbosync. Example: | The config file is a json file that contains all the information needed to run turbosync. Example: | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								index.js
									
									
									
									
									
								
							| @ -8,6 +8,24 @@ const { execSync, spawn, ChildProcess } = require("child_process"); | |||||||
| /** @type {string[]} */ | /** @type {string[]} */ | ||||||
| let dirs = []; | let dirs = []; | ||||||
| 
 | 
 | ||||||
|  | const confFileProvidedPath = process.argv[process.argv.length - 1]; | ||||||
|  | 
 | ||||||
|  | if (confFileProvidedPath === "--version" || confFileProvidedPath === "-v") { | ||||||
|  |     try { | ||||||
|  |         const packageJson = fs.readFileSync( | ||||||
|  |             path.resolve(__dirname, "package.json"), | ||||||
|  |             "utf8" | ||||||
|  |         ); | ||||||
|  |         console.log(`Turbo Sync Version: ${JSON.parse(packageJson).version}`); | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log( | ||||||
|  |             "Turbo Sync Version fetch failed! \nNo Worries, Turbo Sync is still installed properly" | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     process.exit(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| console.log("Running Folder Sync ..."); | console.log("Running Folder Sync ..."); | ||||||
| 
 | 
 | ||||||
| const defaultConfigFilePath = path.resolve( | const defaultConfigFilePath = path.resolve( | ||||||
| @ -15,7 +33,6 @@ const defaultConfigFilePath = path.resolve( | |||||||
|     "turbosync.config.json" |     "turbosync.config.json" | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const confFileProvidedPath = process.argv[process.argv.length - 1]; |  | ||||||
| const confFileComputedPath = | const confFileComputedPath = | ||||||
|     typeof confFileProvidedPath == "string" && |     typeof confFileProvidedPath == "string" && | ||||||
|     confFileProvidedPath.endsWith(".json") |     confFileProvidedPath.endsWith(".json") | ||||||
|  | |||||||
							
								
								
									
										173
									
								
								lib/sync.js
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								lib/sync.js
									
									
									
									
									
								
							| @ -5,6 +5,8 @@ | |||||||
| const fs = require("fs"); | const fs = require("fs"); | ||||||
| const path = require("path"); | const path = require("path"); | ||||||
| const { execSync, spawn } = require("child_process"); | const { execSync, spawn } = require("child_process"); | ||||||
|  | const watchFiles = require("./watch/files"); | ||||||
|  | const watchFolders = require("./watch/folders"); | ||||||
| 
 | 
 | ||||||
| const confFileProvidedJSON = process.argv[process.argv.length - 1]; | const confFileProvidedJSON = process.argv[process.argv.length - 1]; | ||||||
| 
 | 
 | ||||||
| @ -28,173 +30,16 @@ try { | |||||||
| 
 | 
 | ||||||
|     const options = configFileObject.options; |     const options = configFileObject.options; | ||||||
| 
 | 
 | ||||||
|     if (firstFile && files) { |     console.log("firstFolder", firstFolder); | ||||||
|         for (let i = 0; i < files.length; i++) { |     console.log("folders", folders); | ||||||
|             const file = files[i]; |  | ||||||
|             const filePath = |  | ||||||
|                 typeof file == "string" ? file : file?.path ? file.path : null; |  | ||||||
|             const interval = typeof file == "object" ? file.interval : null; |  | ||||||
|             if (!filePath) continue; |  | ||||||
| 
 | 
 | ||||||
|             if (typeof file == "string" && !fs.existsSync(filePath)) |     console.log("firstFolder", firstFolder); | ||||||
|                 throw new Error("File Doesn't exist"); |     console.log("isFolders", Boolean(folders?.[0])); | ||||||
|             if (typeof file == "string" && !fs.statSync(filePath).isFile()) { |  | ||||||
|                 throw new Error(`'${filePath}' is not a File!`); |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             if (typeof file == "object" && file.host) { |     if (firstFile && files?.[0]) { | ||||||
|                 // TODO Handle SSH
 |         watchFiles({ files, options }); | ||||||
|             } else if (typeof file == "string") { |  | ||||||
|                 fs.watchFile( |  | ||||||
|                     filePath, |  | ||||||
|                     { |  | ||||||
|                         interval: interval || 500, |  | ||||||
|                     }, |  | ||||||
|                     (curr, prev) => { |  | ||||||
|                         let cmdArray = ["rsync", "-avh"]; |  | ||||||
| 
 |  | ||||||
|                         if (options?.delete) { |  | ||||||
|                             cmdArray.push("--delete"); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         if (options?.exclude?.[0]) { |  | ||||||
|                             options.exclude.forEach((excl) => { |  | ||||||
|                                 cmdArray.push(`--exclude '${excl}'`); |  | ||||||
|                             }); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         const destFiles = files.filter((fl) => { |  | ||||||
|                             if (typeof fl == "string") return fl !== filePath; |  | ||||||
|                             if (fl?.path) return fl.path !== filePath; |  | ||||||
|                             return false; |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         for (let j = 0; j < destFiles.length; j++) { |  | ||||||
|                             const dstFl = destFiles[j]; |  | ||||||
|                             if (typeof dstFl == "string") { |  | ||||||
|                                 if (!fs.existsSync(dstFl)) continue; |  | ||||||
|                                 cmdArray.push(filePath, dstFl); |  | ||||||
|                                 const cmd = cmdArray.join(" "); |  | ||||||
|                                 execSync(cmd, { |  | ||||||
|                                     stdio: "inherit", |  | ||||||
|                                 }); |  | ||||||
|                             } else if (dstFl.path) { |  | ||||||
|                                 if (!dstFl.host && !fs.existsSync(dstFl.path)) |  | ||||||
|                                     continue; |  | ||||||
| 
 |  | ||||||
|                                 if (dstFl.host && dstFl.ssh_key && dstFl.user) { |  | ||||||
|                                     cmdArray.push( |  | ||||||
|                                         "-e", |  | ||||||
|                                         `'ssh -i ${dstFl.ssh_key}'` |  | ||||||
|                                     ); |  | ||||||
|                                     cmdArray.push( |  | ||||||
|                                         filePath, |  | ||||||
|                                         `${dstFl.user}@${dstFl.host}:${dstFl.path}` |  | ||||||
|                                     ); |  | ||||||
|                                     const cmd = cmdArray.join(" "); |  | ||||||
|                                     execSync(cmd, { |  | ||||||
|                                         stdio: "inherit", |  | ||||||
|                                     }); |  | ||||||
|                                 } else { |  | ||||||
|                                     cmdArray.push(filePath, dstFl.path); |  | ||||||
|                                     const cmd = cmdArray.join(" "); |  | ||||||
|                                     execSync(cmd, { |  | ||||||
|                                         stdio: "inherit", |  | ||||||
|                                     }); |  | ||||||
|                                 } |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         process.exit(1); |  | ||||||
|                     } |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } else if (firstFolder && folders?.[0]) { |     } else if (firstFolder && folders?.[0]) { | ||||||
|         const dirs = folders; |         watchFolders({ folders, options }); | ||||||
| 
 |  | ||||||
|         for (let i = 0; i < dirs.length; i++) { |  | ||||||
|             const dir = dirs[i]; |  | ||||||
| 
 |  | ||||||
|             if (!dir) continue; |  | ||||||
| 
 |  | ||||||
|             const dirPath = typeof dir == "string" ? dir : dir.path; |  | ||||||
| 
 |  | ||||||
|             if (typeof dir == "string") { |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (typeof dir == "string" && !fs.existsSync(dirPath)) { |  | ||||||
|                 fs.mkdirSync(dirPath, { |  | ||||||
|                     recursive: true, |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (typeof dir == "string") { |  | ||||||
|                 fs.watch(dirPath, { recursive: true }, (evt, fileName) => { |  | ||||||
|                     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", |  | ||||||
|                                 }); |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     process.exit(1); |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } catch (error) { | } catch (error) { | ||||||
|     console.log(error); |     console.log(error); | ||||||
|  | |||||||
							
								
								
									
										143
									
								
								lib/watch/files.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								lib/watch/files.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | // @ts-check
 | ||||||
|  | 
 | ||||||
|  | const { execSync } = require("child_process"); | ||||||
|  | const fs = require("fs"); | ||||||
|  | const path = require("path"); | ||||||
|  | const delay = require("../../utils/delay"); | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @param {SyncFilesFnParams} param0 | ||||||
|  |  */ | ||||||
|  | async function watchFiles({ files, options }) { | ||||||
|  |     try { | ||||||
|  |         for (let i = 0; i < files.length; i++) { | ||||||
|  |             const file = files[i]; | ||||||
|  |             const filePath = | ||||||
|  |                 typeof file == "string" ? file : file?.path ? file.path : null; | ||||||
|  |             const interval = typeof file == "object" ? file.interval : null; | ||||||
|  |             if (!filePath) continue; | ||||||
|  | 
 | ||||||
|  |             if (typeof file == "string" && !fs.existsSync(filePath)) { | ||||||
|  |                 try { | ||||||
|  |                     const existingFilePath = files.find((fl) => { | ||||||
|  |                         if (typeof fl == "string") return fs.existsSync(fl); | ||||||
|  |                         if (!fl.host) return fs.existsSync(fl.path); // TODO handle remote
 | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                     if (!existingFilePath) { | ||||||
|  |                         throw new Error("No existing Files for reference"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     const fileDirPath = | ||||||
|  |                         typeof existingFilePath == "string" | ||||||
|  |                             ? existingFilePath | ||||||
|  |                             : existingFilePath.path; | ||||||
|  | 
 | ||||||
|  |                     if (!fs.existsSync(fileDirPath)) { | ||||||
|  |                         fs.mkdirSync(fileDirPath, { recursive: true }); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     fs.writeFileSync(filePath, ""); | ||||||
|  | 
 | ||||||
|  |                     if (typeof existingFilePath == "string") { | ||||||
|  |                         sync({ filePath: existingFilePath, files, options }); | ||||||
|  |                     } else { | ||||||
|  |                         sync({ | ||||||
|  |                             filePath: existingFilePath.path, | ||||||
|  |                             files, | ||||||
|  |                             options, | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  |                 } catch (error) { | ||||||
|  |                     throw new Error( | ||||||
|  |                         `File Doesn't exist and couldn't be created. Please check if Directory exists.\nERROR => ${error.message}` | ||||||
|  |                     ); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (typeof file == "string" && !fs.statSync(filePath).isFile()) { | ||||||
|  |                 throw new Error(`'${filePath}' is not a File!`); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (typeof file == "object" && file.host) { | ||||||
|  |                 // TODO Handle SSH
 | ||||||
|  |             } else if (typeof file == "string") { | ||||||
|  |                 sync({ options, filePath, files }); | ||||||
|  | 
 | ||||||
|  |                 await delay(); | ||||||
|  | 
 | ||||||
|  |                 fs.watchFile( | ||||||
|  |                     filePath, | ||||||
|  |                     { | ||||||
|  |                         interval: interval || 500, | ||||||
|  |                     }, | ||||||
|  |                     (curr, prev) => { | ||||||
|  |                         sync({ options, filePath, files }); | ||||||
|  |                         process.exit(1); | ||||||
|  |                     } | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log("ERROR:", error.message); | ||||||
|  |         process.exit(0); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @param {SyncFilesSyncFnParams} param0 | ||||||
|  |  */ | ||||||
|  | function sync({ options, filePath, files }) { | ||||||
|  |     let cmdArray = ["rsync", "-avh"]; | ||||||
|  | 
 | ||||||
|  |     if (options?.delete) { | ||||||
|  |         cmdArray.push("--delete"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (options?.exclude?.[0]) { | ||||||
|  |         options.exclude.forEach((excl) => { | ||||||
|  |             cmdArray.push(`--exclude '${excl}'`); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const destFiles = files.filter((fl) => { | ||||||
|  |         if (typeof fl == "string") return fl !== filePath; | ||||||
|  |         if (fl?.path) return fl.path !== filePath; | ||||||
|  |         return false; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     for (let j = 0; j < destFiles.length; j++) { | ||||||
|  |         const dstFl = destFiles[j]; | ||||||
|  |         if (typeof dstFl == "string") { | ||||||
|  |             if (!fs.existsSync(dstFl)) continue; | ||||||
|  |             cmdArray.push(filePath, dstFl); | ||||||
|  |             const cmd = cmdArray.join(" "); | ||||||
|  |             execSync(cmd, { | ||||||
|  |                 stdio: "inherit", | ||||||
|  |             }); | ||||||
|  |         } else if (dstFl.path) { | ||||||
|  |             if (!dstFl.host && !fs.existsSync(dstFl.path)) continue; | ||||||
|  | 
 | ||||||
|  |             if (dstFl.host && dstFl.ssh_key && dstFl.user) { | ||||||
|  |                 cmdArray.push("-e", `'ssh -i ${dstFl.ssh_key}'`); | ||||||
|  |                 cmdArray.push( | ||||||
|  |                     filePath, | ||||||
|  |                     `${dstFl.user}@${dstFl.host}:${dstFl.path}` | ||||||
|  |                 ); | ||||||
|  |                 const cmd = cmdArray.join(" "); | ||||||
|  |                 execSync(cmd, { | ||||||
|  |                     stdio: "inherit", | ||||||
|  |                 }); | ||||||
|  |             } else { | ||||||
|  |                 cmdArray.push(filePath, dstFl.path); | ||||||
|  |                 const cmd = cmdArray.join(" "); | ||||||
|  |                 execSync(cmd, { | ||||||
|  |                     stdio: "inherit", | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = watchFiles; | ||||||
							
								
								
									
										162
									
								
								lib/watch/folders.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								lib/watch/folders.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | |||||||
|  | // @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; | ||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "turbosync", |     "name": "turbosync", | ||||||
|     "version": "1.1.0", |     "version": "1.2.0", | ||||||
|     "module": "index.js", |     "module": "index.js", | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "start": "node index.ts", |         "start": "node index.ts", | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								types.js
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								types.js
									
									
									
									
									
								
							| @ -26,3 +26,30 @@ | |||||||
|  * @property {boolean} [delete] - Should files removed be deleted in all destinations? |  * @property {boolean} [delete] - Should files removed be deleted in all destinations? | ||||||
|  * @property {string[]} [exclude] - Patterns that should be ignored. Eg "*.log" |  * @property {string[]} [exclude] - Patterns that should be ignored. Eg "*.log" | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef {object} SyncFilesFnParams | ||||||
|  |  * @property {string[] | TurboSyncFileObject[]} files | ||||||
|  |  * @property {TurboSyncOptions | undefined} options | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef {object} SyncFilesSyncFnParams | ||||||
|  |  * @property {string[] | TurboSyncFileObject[]} files | ||||||
|  |  * @property {TurboSyncOptions | undefined} options | ||||||
|  |  * @property {string} filePath | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef {object} SyncFoldersFnParams | ||||||
|  |  * @property {string[] | TurboSyncFileObject[]} folders | ||||||
|  |  * @property {TurboSyncOptions | undefined} options | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef {object} SyncFoldersSyncFnParams | ||||||
|  |  * @property {string[] | TurboSyncFileObject[]} dirs | ||||||
|  |  * @property {TurboSyncOptions | undefined} options | ||||||
|  |  * @property {string} dirPath | ||||||
|  |  * @property {boolean} [init] - is this an initialization phase? | ||||||
|  |  */ | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								utils/delay.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								utils/delay.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | // @ts-check
 | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @param {number} [time] | ||||||
|  |  * @returns | ||||||
|  |  */ | ||||||
|  | async function delay(time) { | ||||||
|  |     return new Promise((resolve) => { | ||||||
|  |         setTimeout(() => { | ||||||
|  |             resolve(true); | ||||||
|  |         }, time || 500); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = delay; | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Benjamin Toby
						Benjamin Toby