266 lines
8.5 KiB
TypeScript
266 lines
8.5 KiB
TypeScript
#!/usr/bin/env node
|
|
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { execSync } from 'child_process';
|
|
|
|
interface CleanupPlan {
|
|
directories: string[];
|
|
files: string[];
|
|
backupPath?: string;
|
|
totalSize: number;
|
|
}
|
|
|
|
class LegacyCleanup {
|
|
private repoRoot: string;
|
|
private vezaDocsRoot: string;
|
|
private reportsDir: string;
|
|
|
|
constructor(repoRoot: string) {
|
|
this.repoRoot = repoRoot;
|
|
this.vezaDocsRoot = path.join(repoRoot, 'veza-docs');
|
|
this.reportsDir = path.join(this.vezaDocsRoot, '_reports');
|
|
console.log(`Repo root: ${this.repoRoot}`);
|
|
console.log(`Veza docs root: ${this.vezaDocsRoot}`);
|
|
console.log(`Reports dir: ${this.reportsDir}`);
|
|
}
|
|
|
|
async createCleanupPlan(): Promise<CleanupPlan> {
|
|
console.log('📋 Création du plan de nettoyage...');
|
|
|
|
// Lire la liste des dossiers legacy
|
|
const legacyDirsPath = path.join(this.reportsDir, 'legacy_doc_dirs.json');
|
|
console.log(`Recherche du fichier: ${legacyDirsPath}`);
|
|
if (!fs.existsSync(legacyDirsPath)) {
|
|
throw new Error(`Fichier legacy_doc_dirs.json manquant à ${legacyDirsPath}. Exécutez d'abord le scan global.`);
|
|
}
|
|
|
|
const legacyData = JSON.parse(fs.readFileSync(legacyDirsPath, 'utf-8'));
|
|
|
|
// Filtrer les dossiers à nettoyer (exclure veza-docs-backup pour l'instant)
|
|
const directoriesToClean = legacyData.legacyDirs.filter((dir: string) =>
|
|
!dir.includes('veza-docs-backup') &&
|
|
!dir.includes('node_modules') &&
|
|
!dir.includes('.git') &&
|
|
!dir.includes('dist') &&
|
|
!dir.includes('build')
|
|
);
|
|
|
|
// Calculer la taille totale
|
|
let totalSize = 0;
|
|
const filesToClean: string[] = [];
|
|
|
|
for (const dir of directoriesToClean) {
|
|
const fullPath = path.join(this.repoRoot, dir);
|
|
if (fs.existsSync(fullPath)) {
|
|
const stats = this.getDirSize(fullPath);
|
|
totalSize += stats.size;
|
|
filesToClean.push(...stats.files);
|
|
}
|
|
}
|
|
|
|
const plan: CleanupPlan = {
|
|
directories: directoriesToClean,
|
|
files: filesToClean,
|
|
totalSize
|
|
};
|
|
|
|
// Créer un backup si demandé
|
|
if (process.argv.includes('--backup')) {
|
|
plan.backupPath = await this.createBackup(plan);
|
|
}
|
|
|
|
return plan;
|
|
}
|
|
|
|
private getDirSize(dirPath: string): { size: number; files: string[] } {
|
|
let totalSize = 0;
|
|
const files: string[] = [];
|
|
|
|
const walkDir = (currentPath: string) => {
|
|
const items = fs.readdirSync(currentPath);
|
|
|
|
for (const item of items) {
|
|
const itemPath = path.join(currentPath, item);
|
|
const stats = fs.statSync(itemPath);
|
|
|
|
if (stats.isDirectory()) {
|
|
walkDir(itemPath);
|
|
} else {
|
|
totalSize += stats.size;
|
|
files.push(itemPath);
|
|
}
|
|
}
|
|
};
|
|
|
|
walkDir(dirPath);
|
|
return { size: totalSize, files };
|
|
}
|
|
|
|
private async createBackup(plan: CleanupPlan): Promise<string> {
|
|
console.log('💾 Création du backup...');
|
|
|
|
const backupPath = path.join(this.reportsDir, 'legacy_docs_backup.tar.gz');
|
|
|
|
try {
|
|
// Créer un tar.gz des dossiers à nettoyer
|
|
const dirsToBackup = plan.directories.join(' ');
|
|
const command = `cd "${this.repoRoot}" && tar -czf "${backupPath}" ${dirsToBackup}`;
|
|
|
|
execSync(command, { stdio: 'pipe' });
|
|
|
|
console.log(`✅ Backup créé: ${backupPath}`);
|
|
return backupPath;
|
|
} catch (error) {
|
|
console.warn('⚠️ Impossible de créer le backup:', error);
|
|
return '';
|
|
}
|
|
}
|
|
|
|
async generateCleanupReport(plan: CleanupPlan): Promise<void> {
|
|
console.log('📊 Génération du rapport de nettoyage...');
|
|
|
|
const sizeMB = Math.round(plan.totalSize / (1024 * 1024) * 100) / 100;
|
|
|
|
let md = `# 🧹 Plan de Nettoyage - Documentation Veza\n\n`;
|
|
md += `**Date** : ${new Date().toLocaleDateString('fr-FR')}\n\n`;
|
|
|
|
md += `## 📊 Résumé\n\n`;
|
|
md += `- **Dossiers à nettoyer** : ${plan.directories.length}\n`;
|
|
md += `- **Fichiers à supprimer** : ${plan.files.length}\n`;
|
|
md += `- **Taille totale** : ${sizeMB} MB\n`;
|
|
if (plan.backupPath) {
|
|
md += `- **Backup créé** : \`${plan.backupPath}\`\n`;
|
|
}
|
|
md += `\n`;
|
|
|
|
md += `## 📁 Dossiers à Supprimer\n\n`;
|
|
md += `| Dossier | Taille | Fichiers |\n`;
|
|
md += `|---------|--------|----------|\n`;
|
|
|
|
for (const dir of plan.directories) {
|
|
const fullPath = path.join(this.repoRoot, dir);
|
|
if (fs.existsSync(fullPath)) {
|
|
const stats = this.getDirSize(fullPath);
|
|
const dirSizeMB = Math.round(stats.size / (1024 * 1024) * 100) / 100;
|
|
md += `| \`${dir}\` | ${dirSizeMB} MB | ${stats.files.length} |\n`;
|
|
}
|
|
}
|
|
|
|
md += `\n## ⚠️ Avertissements\n\n`;
|
|
md += `- **Vérifiez** que tous les fichiers importants ont été migrés vers \`veza-docs/\`\n`;
|
|
md += `- **Sauvegardez** vos données avant d'appliquer le nettoyage\n`;
|
|
md += `- **Testez** le build après nettoyage : \`npm run build\`\n\n`;
|
|
|
|
md += `## 🚀 Commandes de Nettoyage\n\n`;
|
|
md += `\`\`\`bash\n`;
|
|
md += `# Dry-run (simulation)\n`;
|
|
md += `npx ts-node scripts/cleanup_legacy.ts --dry-run\n\n`;
|
|
md += `# Application réelle\n`;
|
|
md += `npx ts-node scripts/cleanup_legacy.ts --apply\n`;
|
|
md += `\`\`\`\n`;
|
|
|
|
fs.writeFileSync(
|
|
path.join(this.reportsDir, 'cleanup_plan.md'),
|
|
md
|
|
);
|
|
|
|
// Sauvegarder le plan en JSON
|
|
fs.writeFileSync(
|
|
path.join(this.reportsDir, 'cleanup_plan.json'),
|
|
JSON.stringify(plan, null, 2)
|
|
);
|
|
|
|
console.log('✅ Rapport de nettoyage généré');
|
|
}
|
|
|
|
async dryRun(): Promise<void> {
|
|
console.log('🔍 Simulation du nettoyage (dry-run)...');
|
|
|
|
const plan = await this.createCleanupPlan();
|
|
await this.generateCleanupReport(plan);
|
|
|
|
console.log('📋 Plan de nettoyage créé:');
|
|
console.log(` - ${plan.directories.length} dossiers à supprimer`);
|
|
console.log(` - ${plan.files.length} fichiers à supprimer`);
|
|
console.log(` - ${Math.round(plan.totalSize / (1024 * 1024) * 100) / 100} MB à libérer`);
|
|
|
|
if (plan.backupPath) {
|
|
console.log(` - Backup: ${plan.backupPath}`);
|
|
}
|
|
}
|
|
|
|
async apply(): Promise<void> {
|
|
console.log('🧹 Application du nettoyage...');
|
|
|
|
// Vérifier que le plan existe
|
|
const planPath = path.join(this.reportsDir, 'cleanup_plan.json');
|
|
if (!fs.existsSync(planPath)) {
|
|
throw new Error('Plan de nettoyage manquant. Exécutez d\'abord --dry-run');
|
|
}
|
|
|
|
const plan: CleanupPlan = JSON.parse(fs.readFileSync(planPath, 'utf-8'));
|
|
|
|
console.log(`🗑️ Suppression de ${plan.directories.length} dossiers...`);
|
|
|
|
let deletedCount = 0;
|
|
let errorCount = 0;
|
|
|
|
for (const dir of plan.directories) {
|
|
const fullPath = path.join(this.repoRoot, dir);
|
|
|
|
if (fs.existsSync(fullPath)) {
|
|
try {
|
|
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
console.log(` ✅ Supprimé: ${dir}`);
|
|
deletedCount++;
|
|
} catch (error) {
|
|
console.error(` ❌ Erreur: ${dir} - ${error}`);
|
|
errorCount++;
|
|
}
|
|
} else {
|
|
console.log(` ⚠️ Déjà supprimé: ${dir}`);
|
|
}
|
|
}
|
|
|
|
console.log(`\n📊 Résultat:`);
|
|
console.log(` - Dossiers supprimés: ${deletedCount}`);
|
|
console.log(` - Erreurs: ${errorCount}`);
|
|
|
|
// Vérifier le build après nettoyage
|
|
console.log('\n🔍 Vérification du build après nettoyage...');
|
|
try {
|
|
execSync('npm run build', { cwd: this.vezaDocsRoot, stdio: 'pipe' });
|
|
console.log('✅ Build réussi après nettoyage');
|
|
} catch (error) {
|
|
console.error('❌ Build échoué après nettoyage:', error);
|
|
throw new Error('Le build a échoué après nettoyage. Vérifiez les fichiers supprimés.');
|
|
}
|
|
}
|
|
|
|
async run(): Promise<void> {
|
|
const args = process.argv.slice(2);
|
|
|
|
if (args.includes('--dry-run')) {
|
|
await this.dryRun();
|
|
} else if (args.includes('--apply')) {
|
|
await this.apply();
|
|
} else {
|
|
console.log('Usage:');
|
|
console.log(' --dry-run : Simulation du nettoyage');
|
|
console.log(' --apply : Application du nettoyage');
|
|
console.log(' --backup : Créer un backup (avec --dry-run)');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Exécution du script
|
|
if (require.main === module) {
|
|
// Trouver le premier argument qui n'est pas un flag et qui n'est pas ts-node
|
|
const args = process.argv.slice(2); // Ignorer 'ts-node' et le nom du script
|
|
const repoRoot = args.find(arg => !arg.startsWith('--')) || path.join(__dirname, '../..');
|
|
const cleanup = new LegacyCleanup(repoRoot);
|
|
cleanup.run();
|
|
}
|
|
|
|
export { LegacyCleanup };
|