UNPKG

@git.zone/cli

Version:

A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.

144 lines (116 loc) 4.22 kB
import * as plugins from './mod.plugins.js'; import * as paths from '../paths.js'; export interface IFileCache { path: string; checksum: string; modified: number; size: number; } export interface ICacheManifest { version: string; lastFormat: number; files: IFileCache[]; } export class ChangeCache { private cacheDir: string; private manifestPath: string; private cacheVersion = '1.0.0'; constructor() { this.cacheDir = plugins.path.join(paths.cwd, '.nogit', 'gitzone-cache'); this.manifestPath = plugins.path.join(this.cacheDir, 'manifest.json'); } async initialize(): Promise<void> { await plugins.smartfile.fs.ensureDir(this.cacheDir); } async getManifest(): Promise<ICacheManifest> { const exists = await plugins.smartfile.fs.fileExists(this.manifestPath); if (!exists) { return { version: this.cacheVersion, lastFormat: 0, files: [] }; } const content = await plugins.smartfile.fs.toStringSync(this.manifestPath); return JSON.parse(content); } async saveManifest(manifest: ICacheManifest): Promise<void> { await plugins.smartfile.memory.toFs(JSON.stringify(manifest, null, 2), this.manifestPath); } async hasFileChanged(filePath: string): Promise<boolean> { const absolutePath = plugins.path.isAbsolute(filePath) ? filePath : plugins.path.join(paths.cwd, filePath); // Check if file exists const exists = await plugins.smartfile.fs.fileExists(absolutePath); if (!exists) { return true; // File doesn't exist, so it's "changed" (will be created) } // Get current file stats const stats = await plugins.smartfile.fs.stat(absolutePath); const content = await plugins.smartfile.fs.toStringSync(absolutePath); const currentChecksum = this.calculateChecksum(content); // Get cached info const manifest = await this.getManifest(); const cachedFile = manifest.files.find(f => f.path === filePath); if (!cachedFile) { return true; // Not in cache, so it's changed } // Compare checksums return cachedFile.checksum !== currentChecksum || cachedFile.size !== stats.size || cachedFile.modified !== stats.mtimeMs; } async updateFileCache(filePath: string): Promise<void> { const absolutePath = plugins.path.isAbsolute(filePath) ? filePath : plugins.path.join(paths.cwd, filePath); // Get current file stats const stats = await plugins.smartfile.fs.stat(absolutePath); const content = await plugins.smartfile.fs.toStringSync(absolutePath); const checksum = this.calculateChecksum(content); // Update manifest const manifest = await this.getManifest(); const existingIndex = manifest.files.findIndex(f => f.path === filePath); const cacheEntry: IFileCache = { path: filePath, checksum, modified: stats.mtimeMs, size: stats.size }; if (existingIndex !== -1) { manifest.files[existingIndex] = cacheEntry; } else { manifest.files.push(cacheEntry); } manifest.lastFormat = Date.now(); await this.saveManifest(manifest); } async getChangedFiles(filePaths: string[]): Promise<string[]> { const changedFiles: string[] = []; for (const filePath of filePaths) { if (await this.hasFileChanged(filePath)) { changedFiles.push(filePath); } } return changedFiles; } async clean(): Promise<void> { const manifest = await this.getManifest(); const validFiles: IFileCache[] = []; // Remove entries for files that no longer exist for (const file of manifest.files) { const absolutePath = plugins.path.isAbsolute(file.path) ? file.path : plugins.path.join(paths.cwd, file.path); if (await plugins.smartfile.fs.fileExists(absolutePath)) { validFiles.push(file); } } manifest.files = validFiles; await this.saveManifest(manifest); } private calculateChecksum(content: string | Buffer): string { return plugins.crypto.createHash('sha256').update(content).digest('hex'); } }