UNPKG

grunt-ps-sass

Version:
185 lines (163 loc) 5.65 kB
const fs = require('fs'); /** * Service for detecting file changes based on timestamps * This service is focused solely on change detection - no dependency resolution */ class FileChangeDetector { constructor(options = {}) { this.verbose = options.verbose || false; } /** * Check if any files in the array have been modified after the given timestamp * @param {Array<string>} filePaths - Array of file paths to check * @param {number|Date} baseTimestamp - Timestamp to compare against (can be number or Date) * @param {Object} options - Optional configuration * @returns {Object} Result object with change information */ checkForChanges(filePaths, baseTimestamp, options = {}) { const result = { hasChanges: false, changedFiles: [], errors: [], stats: { totalFiles: filePaths.length, checkedFiles: 0, errorFiles: 0 } }; // Convert timestamp to number if it's a Date const timestamp = baseTimestamp instanceof Date ? baseTimestamp.getTime() : baseTimestamp; if (this.verbose) { console.log(`Checking ${filePaths.length} files for changes since ${new Date(timestamp).toISOString()}`); } for (const filePath of filePaths) { try { const stats = fs.statSync(filePath); result.stats.checkedFiles++; if (stats.mtime.getTime() > timestamp) { result.hasChanges = true; result.changedFiles.push({ path: filePath, modifiedTime: stats.mtime, size: stats.size }); if (this.verbose) { console.log(` Changed: ${filePath} (${stats.mtime.toISOString()})`); } } } catch (err) { result.stats.errorFiles++; result.errors.push({ path: filePath, error: err.message }); if (this.verbose) { console.warn(` Error checking ${filePath}: ${err.message}`); } } } if (this.verbose) { console.log(`Change detection complete: ${result.changedFiles.length} changed files found`); } return result; } /** * Check if a single file has been modified after the given timestamp * @param {string} filePath - Path to the file to check * @param {number|Date} baseTimestamp - Timestamp to compare against * @returns {boolean} True if the file has been modified after the timestamp */ hasFileChanged(filePath, baseTimestamp) { try { const stats = fs.statSync(filePath); const timestamp = baseTimestamp instanceof Date ? baseTimestamp.getTime() : baseTimestamp; return stats.mtime.getTime() > timestamp; } catch (err) { if (this.verbose) { console.warn(`Error checking file ${filePath}: ${err.message}`); } return false; } } /** * Get the modification time of a file * @param {string} filePath - Path to the file * @returns {Date|null} Modification time or null if error */ getModificationTime(filePath) { try { const stats = fs.statSync(filePath); return stats.mtime; } catch (err) { if (this.verbose) { console.warn(`Error getting modification time for ${filePath}: ${err.message}`); } return null; } } /** * Get the latest modification time from an array of files * @param {Array<string>} filePaths - Array of file paths * @returns {Date|null} Latest modification time or null if no valid files */ getLatestModificationTime(filePaths) { let latestTime = null; for (const filePath of filePaths) { try { const stats = fs.statSync(filePath); if (!latestTime || stats.mtime > latestTime) { latestTime = stats.mtime; } } catch (err) { if (this.verbose) { console.warn(`Error checking ${filePath}: ${err.message}`); } } } return latestTime; } /** * Compare modification times of two files * @param {string} file1Path - Path to first file * @param {string} file2Path - Path to second file * @returns {number} -1 if file1 is older, 1 if file1 is newer, 0 if equal, null if error */ compareFiles(file1Path, file2Path) { try { const stats1 = fs.statSync(file1Path); const stats2 = fs.statSync(file2Path); if (stats1.mtime < stats2.mtime) return -1; if (stats1.mtime > stats2.mtime) return 1; return 0; } catch (err) { if (this.verbose) { console.warn(`Error comparing files: ${err.message}`); } return null; } } /** * Filter files that have been modified after a given timestamp * @param {Array<string>} filePaths - Array of file paths to filter * @param {number|Date} baseTimestamp - Timestamp to compare against * @returns {Array<string>} Array of file paths that have been modified */ filterChangedFiles(filePaths, baseTimestamp) { const timestamp = baseTimestamp instanceof Date ? baseTimestamp.getTime() : baseTimestamp; const changedFiles = []; for (const filePath of filePaths) { try { const stats = fs.statSync(filePath); if (stats.mtime.getTime() > timestamp) { changedFiles.push(filePath); } } catch (err) { if (this.verbose) { console.warn(`Error checking ${filePath}: ${err.message}`); } } } return changedFiles; } } module.exports = FileChangeDetector;