Initial commit
This commit is contained in:
141
skills/tdd-automation/scripts/rollback-tdd.js
Executable file
141
skills/tdd-automation/scripts/rollback-tdd.js
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* TDD Automation Rollback Utility
|
||||
*
|
||||
* Restores previous CLAUDE.md from backup and optionally removes all TDD automation.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Import utilities from parent directory
|
||||
const projectRoot = process.cwd();
|
||||
const skillRoot = path.join(__dirname, '..');
|
||||
|
||||
// Try to load ClaudeMdValidator from skill location
|
||||
let ClaudeMdValidator;
|
||||
try {
|
||||
ClaudeMdValidator = require(path.join(skillRoot, 'utils', 'validate-claude-md.js'));
|
||||
} catch {
|
||||
// If skill utils not available, use local copy in .tdd-automation
|
||||
try {
|
||||
ClaudeMdValidator = require(path.join(projectRoot, '.tdd-automation', 'utils', 'validate-claude-md.js'));
|
||||
} catch {
|
||||
console.error('❌ Error: ClaudeMdValidator not found');
|
||||
console.error(' This script must be run from project root or .tdd-automation directory');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function rollbackTddAutomation() {
|
||||
console.log('🔄 TDD Automation Rollback Utility\n');
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
const validator = new ClaudeMdValidator(projectRoot);
|
||||
|
||||
// List available backups
|
||||
const backups = validator.listBackups();
|
||||
|
||||
if (backups.length === 0) {
|
||||
console.log('❌ No backup files found');
|
||||
console.log(' Cannot rollback without backup');
|
||||
console.log('');
|
||||
console.log(' Backup files should be in: .claude/CLAUDE.md.backup.*');
|
||||
console.log('');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`📋 Found ${backups.length} backup(s):\n`);
|
||||
|
||||
backups.forEach((backup, i) => {
|
||||
const age = getTimeAgo(backup.created);
|
||||
console.log(`${i + 1}. ${backup.name}`);
|
||||
console.log(` Created: ${backup.created.toISOString()} (${age})`);
|
||||
console.log(` Size: ${formatBytes(backup.size)}\n`);
|
||||
});
|
||||
|
||||
// Use most recent backup
|
||||
const latestBackup = backups[0];
|
||||
console.log(`🔄 Rolling back to most recent backup:\n`);
|
||||
console.log(` ${latestBackup.name}`);
|
||||
console.log(` Created: ${latestBackup.created.toISOString()}\n`);
|
||||
|
||||
// Create backup of current state before rollback
|
||||
console.log('🔒 Creating safety backup of current state...');
|
||||
const currentBackup = validator.createBackup();
|
||||
|
||||
if (currentBackup.success) {
|
||||
console.log(`✅ Current state backed up to:`);
|
||||
console.log(` ${path.basename(currentBackup.path)}\n`);
|
||||
} else {
|
||||
console.log(`⚠️ Could not backup current state: ${currentBackup.reason}`);
|
||||
console.log(` Proceeding with rollback anyway...\n`);
|
||||
}
|
||||
|
||||
// Perform rollback
|
||||
console.log('🔄 Performing rollback...');
|
||||
const result = validator.rollback(latestBackup.path);
|
||||
|
||||
if (result.success) {
|
||||
console.log('✅ Rollback successful!\n');
|
||||
console.log(' CLAUDE.md has been restored from:');
|
||||
console.log(` ${path.basename(result.restoredFrom)}`);
|
||||
console.log(` Size: ${formatBytes(result.size)}\n`);
|
||||
|
||||
if (currentBackup.success) {
|
||||
console.log(' Your previous state was saved to:');
|
||||
console.log(` ${path.basename(currentBackup.path)}\n`);
|
||||
}
|
||||
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
console.log('⚠️ TDD automation configuration has been removed from CLAUDE.md\n');
|
||||
console.log(' Other TDD automation components remain:');
|
||||
console.log(' • .tdd-automation/ directory');
|
||||
console.log(' • npm scripts (test:tdd, validate:tdd, etc.)');
|
||||
console.log(' • git hooks (.git/hooks/pre-commit)');
|
||||
console.log(' • Claude hooks (.claude/hooks/tdd-auto-enforcer.sh)\n');
|
||||
console.log(' To remove all TDD automation components:');
|
||||
console.log(' node .tdd-automation/scripts/uninstall-tdd.js\n');
|
||||
console.log(' To reinstall TDD automation:');
|
||||
console.log(' Run the tdd-automation skill again\n');
|
||||
} else {
|
||||
console.error('❌ Rollback failed:', result.reason);
|
||||
console.error('');
|
||||
console.error(' You may need to manually restore CLAUDE.md from backup');
|
||||
console.error(` Backup location: ${latestBackup.path}`);
|
||||
console.error('');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function getTimeAgo(date) {
|
||||
const now = new Date();
|
||||
const diff = now - date;
|
||||
|
||||
const seconds = Math.floor(diff / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
const days = Math.floor(hours / 24);
|
||||
|
||||
if (days > 0) return `${days} day${days > 1 ? 's' : ''} ago`;
|
||||
if (hours > 0) return `${hours} hour${hours > 1 ? 's' : ''} ago`;
|
||||
if (minutes > 0) return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
|
||||
return `${seconds} second${seconds > 1 ? 's' : ''} ago`;
|
||||
}
|
||||
|
||||
function formatBytes(bytes) {
|
||||
if (bytes < 1024) return `${bytes} bytes`;
|
||||
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
||||
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
}
|
||||
|
||||
// Run if called directly
|
||||
if (require.main === module) {
|
||||
rollbackTddAutomation().catch(error => {
|
||||
console.error('❌ Unexpected error:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { rollbackTddAutomation };
|
||||
Reference in New Issue
Block a user