#!/usr/bin/env node /** * Script de build pour le radar stand-alone * Remplace la logique du CLI techradar en utilisant radar-app/ directement */ const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const CWD = process.cwd(); const RADAR_APP_DIR = path.join(CWD, 'radar-app'); const BUILD_DIR = path.join(CWD, 'build'); function info(message) { console.log(`\x1b[32m${message}\x1b[0m`); } function error(message) { console.error(`\x1b[31mError: ${message}\x1b[0m`); process.exit(1); } function ensureDir(dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } // Vérifier que radar-app existe if (!fs.existsSync(RADAR_APP_DIR)) { error(`radar-app/ introuvable. Assurez-vous que le code du framework est présent dans ${RADAR_APP_DIR}`); } info('🔄 Préparation des données pour radar-app...'); // 1. Copier config-business.json vers radar-app/data/config.json const configSource = path.join(CWD, 'radar-business', 'config-business.json'); const configDest = path.join(RADAR_APP_DIR, 'data', 'config.json'); if (fs.existsSync(configSource)) { fs.copyFileSync(configSource, configDest); info('✅ Config copiée'); } else { error(`config-business.json introuvable: ${configSource}`); } // 2. Préparer radar-app/data/radar/ const radarDataDir = path.join(RADAR_APP_DIR, 'data', 'radar'); if (fs.existsSync(radarDataDir)) { // Supprimer le contenu existant sauf la release actuelle const releases = fs.readdirSync(radarDataDir); releases.forEach(release => { if (release !== '2025-01-15') { fs.rmSync(path.join(radarDataDir, release), { recursive: true, force: true }); } }); } // Copier radar-business/2025-01-15/ vers radar-app/data/radar/2025-01-15/ const radarSource = path.join(CWD, 'radar-business', '2025-01-15'); const radarDest = path.join(radarDataDir, '2025-01-15'); if (fs.existsSync(radarSource)) { ensureDir(radarDest); // Supprimer le contenu existant de la destination if (fs.existsSync(radarDest)) { fs.rmSync(radarDest, { recursive: true, force: true }); } fs.mkdirSync(radarDest, { recursive: true }); // Copier récursivement const files = fs.readdirSync(radarSource); files.forEach(file => { const srcPath = path.join(radarSource, file); const destPath = path.join(radarDest, file); const stat = fs.statSync(srcPath); if (stat.isDirectory()) { fs.cpSync(srcPath, destPath, { recursive: true }); } else { fs.copyFileSync(srcPath, destPath); } }); info('✅ Données radar copiées'); } else { error(`radar-business/2025-01-15/ introuvable: ${radarSource}`); } // 3. Copier public/* vers radar-app/public/ const publicSource = path.join(CWD, 'public'); const publicDest = path.join(RADAR_APP_DIR, 'public'); if (fs.existsSync(publicSource)) { ensureDir(publicDest); const files = fs.readdirSync(publicSource); files.forEach(file => { const srcPath = path.join(publicSource, file); const destPath = path.join(publicDest, file); const stat = fs.statSync(srcPath); if (stat.isDirectory()) { if (fs.existsSync(destPath)) { fs.rmSync(destPath, { recursive: true, force: true }); } fs.cpSync(srcPath, destPath, { recursive: true }); } else { fs.copyFileSync(srcPath, destPath); } }); info('✅ Fichiers public copiés'); } // 4. Copier about.md et custom.css si présents const aboutSource = path.join(CWD, 'about.md'); const aboutDest = path.join(RADAR_APP_DIR, 'data', 'about.md'); if (fs.existsSync(aboutSource)) { fs.copyFileSync(aboutSource, aboutDest); info('✅ about.md copié'); } const customCssSource = path.join(CWD, 'custom.css'); const customCssDest = path.join(RADAR_APP_DIR, 'src', 'styles', 'custom.css'); if (fs.existsSync(customCssSource)) { ensureDir(path.dirname(customCssDest)); fs.copyFileSync(customCssSource, customCssDest); info('✅ custom.css copié'); } // 5. Générer team-visualization-data.json et le copier info('🔄 Génération des données de visualisation équipe...'); try { execSync('node scripts/generate-team-visualization-data.js', { cwd: CWD, stdio: 'inherit' }); const teamDataSource = path.join(CWD, 'public', 'team-visualization-data.json'); const teamDataDest = path.join(RADAR_APP_DIR, 'public', 'team-visualization-data.json'); if (fs.existsSync(teamDataSource)) { fs.copyFileSync(teamDataSource, teamDataDest); info('✅ team-visualization-data.json généré et copié'); } } catch (e) { console.warn('⚠️ Erreur lors de la génération des données équipe:', e.message); } // 6. Appliquer les patches info('🔄 Application des patches...'); try { // Créer la page team.tsx const teamPageSource = path.join(CWD, 'docker', 'team-page.tsx'); const teamPageDest = path.join(RADAR_APP_DIR, 'src', 'pages', 'team.tsx'); if (fs.existsSync(teamPageSource)) { ensureDir(path.dirname(teamPageDest)); fs.copyFileSync(teamPageSource, teamPageDest); info('✅ Page team.tsx créée'); } // Modifier _document.tsx const patchDocumentScript = path.join(CWD, 'docker', 'patch_document.py'); if (fs.existsSync(patchDocumentScript)) { execSync(`python3 ${patchDocumentScript}`, { cwd: CWD, stdio: 'inherit' }); info('✅ _document.tsx modifié'); } // Modifier Navigation.tsx const patchNavScript = path.join(CWD, 'docker', 'add_team_link.sh'); if (fs.existsSync(patchNavScript)) { execSync(`sh ${patchNavScript}`, { cwd: CWD, stdio: 'inherit' }); info('✅ Navigation.tsx modifié'); } } catch (e) { console.warn('⚠️ Erreur lors de l\'application des patches:', e.message); } // 7. Installer les dépendances de radar-app si nécessaire const radarAppNodeModules = path.join(RADAR_APP_DIR, 'node_modules'); if (!fs.existsSync(radarAppNodeModules)) { info('🔄 Installation des dépendances de radar-app...'); try { process.chdir(RADAR_APP_DIR); // Désactiver le script prepare (husky) const pkgPath = path.join(RADAR_APP_DIR, 'package.json'); const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); pkg.scripts = pkg.scripts || {}; const originalPrepare = pkg.scripts.prepare; pkg.scripts.prepare = ''; fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); execSync('npm install --legacy-peer-deps', { stdio: 'inherit' }); // Restaurer le script prepare si nécessaire (optionnel) // pkg.scripts.prepare = originalPrepare; // fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); info('✅ Dépendances installées'); } catch (e) { error(`Erreur lors de l'installation des dépendances: ${e.message}`); } } // 8. Build dans radar-app info('🔄 Build des données...'); try { process.chdir(RADAR_APP_DIR); execSync('npm run build:data', { stdio: 'inherit' }); } catch (e) { error(`Erreur lors du build:data: ${e.message}`); } info('🔄 Build Next.js...'); try { execSync('npm run build', { stdio: 'inherit' }); } catch (e) { error(`Erreur lors du build Next.js: ${e.message}`); } // 9. Copier radar-app/out vers build/ const outDir = path.join(RADAR_APP_DIR, 'out'); if (!fs.existsSync(outDir)) { error('radar-app/out/ introuvable après le build'); } if (fs.existsSync(BUILD_DIR)) { fs.rmSync(BUILD_DIR, { recursive: true, force: true }); } fs.renameSync(outDir, BUILD_DIR); info(`✅ Build copié vers ${BUILD_DIR}`); // Copier les fichiers additionnels depuis radar-app/public vers build/ const additionalFiles = ['_team-content', 'team-visualization-data.json']; const teamDir = path.join(RADAR_APP_DIR, 'public', 'team'); if (fs.existsSync(teamDir)) { const buildTeamDir = path.join(BUILD_DIR, 'team'); ensureDir(buildTeamDir); fs.cpSync(teamDir, buildTeamDir, { recursive: true }); info('✅ Dossier team copié vers build/'); } additionalFiles.forEach(file => { const src = path.join(RADAR_APP_DIR, 'public', file); const dest = path.join(BUILD_DIR, file); if (fs.existsSync(src)) { fs.copyFileSync(src, dest); info(`✅ ${file} copié vers build/`); } }); info('✅ Build terminé avec succès!');