UNPKG

@mikezimm/fps-core-v7

Version:

Library of reusable core interfaces, types and constants migrated from fps-library-v2

169 lines 7.4 kB
/** * This utility script helps to: * 1. Identify local changes to specific npm packages. * 2. Back up only the locally changed files to a backup folder for reference or debugging. * * Usage in 'Backup' mode: * ts-node backup-node-mods.ts --backup * * Usage in 'Identify' mode (just highlights changes): * ts-node backup-node-mods.ts */ const fs = require('fs'); const path = require('path'); const readline = require('readline'); // Configuration constants // const NODE_MODULES_DIR = path.resolve('node_modules'); // const MODS_DIR = path.resolve('node_modules_mods'); // Use process.cwd() for the root directory instead of __dirname const rootDir = path.resolve(process.cwd(), ''); // Or your desired directory relative to the project root // Configuration constants const NODE_MODULES_DIR = path.join(rootDir, 'node_modules'); const MODS_DIR = path.resolve(rootDir, 'node_modules_mods'); const MODS_DIR_Clear = path.resolve(rootDir, 'node_modules_mods/@mikezimm'); const PACKAGE_FOLDERS = [ '@mikezimm/fps-library-v2', '@mikezimm/fps-core-v7', '@mikezimm/fps-styles', '@mikezimm/fps-Pnp2', ]; const TIME_DIFFERENCE_THRESHOLD = 5 * 60 * 1000; // 5 minutes in milliseconds // Default mode: 'identify' let OPERATION_MODE = (process.argv.includes('--backup') ? 'backup' : 'identify'); // Function to log messages with optional color function logMessage(message, color) { const colorCodes = { red: '\x1b[31m', yellow: '\x1b[33m', blue: '\x1b[34m', green: '\x1b[32m', }; console.log(colorCodes[color] || '', message, '\x1b[0m'); } // Function to prompt the user for backup confirmation async function promptForBackupConfirmation() { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { rl.question('Are you sure you want to back up the changes? (yes/no) ', (answer) => { rl.close(); resolve(answer.trim().toLowerCase() === 'yes'); }); }); } // Get the last modified time of a file function getModifiedTime(filePath) { return fs.statSync(filePath).mtimeMs; } // Copy a file to the destination, creating directories as needed function copyFileWithMinimalStructure(src, dest) { const destDir = path.dirname(dest); fs.mkdirSync(destDir, { recursive: true }); fs.copyFileSync(src, dest); } // Append a message to the log file function appendToLogFile(filePath, content) { fs.appendFileSync(filePath, content + '\n'); } function make2DigitNum(str) { return !str ? '--' : `${str.length === 1 ? '0' : ''}${str}`; } // Function to format the current date and time in a sortable format function getFormattedDate() { const now = new Date(); const year = now.getFullYear(); const month = (now.getMonth() + 1).toString(); const day = make2DigitNum(now.getDate().toString()); const hours = make2DigitNum(now.getHours().toString()); const minutes = make2DigitNum(now.getMinutes().toString()); const seconds = make2DigitNum(now.getSeconds().toString()); return `${year}-${month}-${day} ${hours}_${minutes}_${seconds}`; } // Function to remove all files and subdirectories in a directory function clearBackupFolder(dir) { if (fs.existsSync(dir)) { fs.readdirSync(dir).forEach((file) => { const fullPath = path.join(dir, file); if (fs.lstatSync(fullPath).isDirectory()) { clearBackupFolder(fullPath); // Recursive delete for subdirectories fs.rmdirSync(fullPath); // Remove empty directory } else { fs.unlinkSync(fullPath); // Delete file } }); } } // Function to find and handle modified files async function findModifiedFiles() { if (OPERATION_MODE === 'backup') { const confirmed = await promptForBackupConfirmation(); if (!confirmed) { logMessage('Backup operation canceled.', 'yellow'); return; } else { // Clear the backup folder at the beginning of the run (but not the log folder) if (fs.existsSync(MODS_DIR_Clear)) { clearBackupFolder(MODS_DIR_Clear); } } } logMessage(`Starting in ${OPERATION_MODE.toUpperCase()} mode...\n`, 'blue'); if (!fs.existsSync(MODS_DIR)) { fs.mkdirSync(MODS_DIR); } const logFileName = `modified-files-${getFormattedDate()}.log`; const logFilePath = path.join(MODS_DIR, logFileName); fs.writeFileSync(logFilePath, 'Modified files log:\n'); let iP = 0; PACKAGE_FOLDERS.forEach((packageName) => { const packagePath = path.join(NODE_MODULES_DIR, packageName); const packageJsonPath = path.join(packagePath, 'package.json'); if (!fs.existsSync(packageJsonPath)) { logMessage(`\n\npackage.json not found for ${packageName}\n\n`, 'yellow'); return; } const packageModifiedTime = getModifiedTime(packageJsonPath); // if ( iP > 0 ) appendToLogFile(logFilePath, `\n===== ${packageName} =====\n`); logMessage(`${iP > 0 ? '\n\n' : ''}Checking package: ${packageName}\n`, 'blue'); appendToLogFile(logFilePath, `\n===== ${packageName} =====\n`); const collectFiles = (dir, baseDir) => { fs.readdirSync(dir, { withFileTypes: true }).forEach((entry) => { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { // Ensure we're not traversing into unwanted directories like `@types` if (!fullPath.includes('@types')) { collectFiles(fullPath, baseDir); } } else if (entry.isFile()) { const fileModifiedTime = getModifiedTime(fullPath); if (fileModifiedTime > packageModifiedTime + TIME_DIFFERENCE_THRESHOLD) { const relativePath = path.relative(baseDir, fullPath); if (OPERATION_MODE === 'identify') { logMessage(`Identified changed file: ${packageName}\\${relativePath}`, 'yellow'); appendToLogFile(logFilePath, `Identified changes: ${packageName}\\${relativePath}`); } else if (OPERATION_MODE === 'backup') { const destPath = path.join(MODS_DIR, packageName, relativePath); copyFileWithMinimalStructure(fullPath, destPath); appendToLogFile(logFilePath, `Backed up changes: ${packageName}\\${relativePath}`); logMessage(`Backed up changed file: ${relativePath}`, 'red'); } } } }); }; collectFiles(packagePath, packagePath); iP++; }); logMessage(`Log file of changed files created at: ${logFilePath}`, 'green'); } // Run the main function findModifiedFiles().catch((error) => { logMessage(`Error: ${error.message}`, 'red'); }); //# sourceMappingURL=backup-node-mods.js.map