Skip to content

Instantly share code, notes, and snippets.

@Shariar-Hasan
Last active February 8, 2026 06:17
Show Gist options
  • Select an option

  • Save Shariar-Hasan/d5835a48fd56696477d1e20a1aac10c6 to your computer and use it in GitHub Desktop.

Select an option

Save Shariar-Hasan/d5835a48fd56696477d1e20a1aac10c6 to your computer and use it in GitHub Desktop.
A small script for syncing two folders / files to detect changes, additions, deletions of the src folder files
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// ES module এ __dirname তৈরি
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// console colors
const colors = {
reset: "\x1b[0m",
green: "\x1b[32m",
yellow: "\x1b[33m",
red: "\x1b[31m",
blue: "\x1b[34m"
};
// helper: relative → absolute
function resolvePath(p) {
return path.isAbsolute(p) ? p : path.resolve(__dirname, p);
}
// ---------- FILE SYNC ----------
function syncFile(src, dest) {
const destDir = path.dirname(dest);
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}
if (!fs.existsSync(dest)) {
fs.copyFileSync(src, dest);
console.log(`${colors.green}New file created:${colors.reset} ${path.basename(dest)}`);
return;
}
const srcContent = fs.readFileSync(src, 'utf-8');
const destContent = fs.readFileSync(dest, 'utf-8');
if (srcContent !== destContent) {
fs.copyFileSync(src, dest);
console.log(`${colors.yellow}Updated file:${colors.reset} ${path.basename(dest)}`);
} else {
console.log(`${colors.blue}No change:${colors.reset} ${path.basename(dest)}`);
}
}
// ---------- FOLDER SYNC ----------
function syncFolder(src, dest) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
const srcEntries = fs.readdirSync(src);
const destEntries = fs.existsSync(dest) ? fs.readdirSync(dest) : [];
// delete removed files/folders
for (const entry of destEntries) {
if (!srcEntries.includes(entry)) {
const target = path.join(dest, entry);
fs.rmSync(target, { recursive: true, force: true });
console.log(`${colors.red}Deleted:${colors.reset} ${entry}`);
}
}
// copy/update
for (const entry of srcEntries) {
const srcPath = path.join(src, entry);
const destPath = path.join(dest, entry);
const stat = fs.statSync(srcPath);
if (stat.isDirectory()) {
syncFolder(srcPath, destPath);
} else {
syncFile(srcPath, destPath);
}
}
}
// ---------- SMART ENTRY ----------
function syncPath(src, dest) {
if (!fs.existsSync(src)) {
console.log(`${colors.red}Source not found:${colors.reset} ${src}`);
return;
}
const stat = fs.statSync(src);
if (stat.isDirectory()) {
syncFolder(src, dest);
} else {
syncFile(src, dest);
}
}
// ---------- CONFIG ----------
const paths = [
{
src: "E:/DEV/school-management-api/src/entities",
dest: "E:/DEV/hic-school-web-api/src/entities"
},
{
src: "E:/DEV/school-management-api/src/common/enums",
dest: "E:/DEV/hic-school-web-api/src/common/enums"
},
{
src: "E:/DEV/school-management/src/models",
dest: "E:/DEV/hic-school-web/src/models"
},
{
src: "E:/DEV/school-management-api/src/constants/role-constant.ts",
dest: "E:/DEV/school-management/src/constants/roles.ts"
},
];
// ---------- RUN ----------
for (const p of paths) {
const src = resolvePath(p.src);
const dest = resolvePath(p.dest);
console.log(`\nSyncing ${src} → ${dest}`);
syncPath(src, dest);
}
console.log(`${colors.green}\nAll sync completed!${colors.reset}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment