refactor: projet stand-alone sans dépendance aoe_technology_radar
- Intégration du code source du framework dans radar-app/ (vendoring) - Suppression de la dépendance npm aoe_technology_radar - Création de scripts build-radar.js et serve-radar.js pour remplacer le CLI techradar - Adaptation de tous les scripts et Docker pour utiliser radar-app/ au lieu de .techradar - Refactorisation complète de Dockerfile.business - Mise à jour de la documentation (architecture, déploiement, développement) - Mise à jour de .gitignore pour ignorer les artefacts de build de radar-app/ - Ajout de postcss dans les dépendances Docker pour le build Next.js Le projet est maintenant complètement indépendant du package externe. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
251
scripts/build-radar.js
Executable file
251
scripts/build-radar.js
Executable file
@@ -0,0 +1,251 @@
|
||||
#!/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(`bash ${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!');
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# Ne pas utiliser set -e car on veut gérer les erreurs manuellement
|
||||
|
||||
TECHRADAR_DIR=".techradar"
|
||||
TECHRADAR_DIR="radar-app"
|
||||
TEAM_PAGE="$TECHRADAR_DIR/src/pages/team.tsx"
|
||||
NAV_FILE="$TECHRADAR_DIR/src/components/Navigation/Navigation.tsx"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Script pour patcher le composant Navigation et ajouter le lien Équipe
|
||||
|
||||
NAV_FILE=".techradar/src/components/Navigation/Navigation.tsx"
|
||||
NAV_FILE="radar-app/src/components/Navigation/Navigation.tsx"
|
||||
|
||||
if [ ! -f "$NAV_FILE" ]; then
|
||||
echo "⚠️ $NAV_FILE non trouvé"
|
||||
|
||||
53
scripts/serve-radar.js
Executable file
53
scripts/serve-radar.js
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Script de serve pour le radar stand-alone
|
||||
* Remplace "techradar serve" en servant soit build/ soit en lançant le dev server Next.js
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const CWD = process.cwd();
|
||||
const BUILD_DIR = path.join(CWD, 'build');
|
||||
const RADAR_APP_DIR = path.join(CWD, 'radar-app');
|
||||
const PORT = process.env.PORT || '3000';
|
||||
|
||||
// Mode: 'build' pour servir build/, 'dev' pour lancer Next.js dev
|
||||
const MODE = process.argv[2] || 'build';
|
||||
|
||||
if (MODE === 'dev') {
|
||||
// Mode développement: lancer Next.js dev dans radar-app
|
||||
console.log('🚀 Démarrage du serveur de développement Next.js...');
|
||||
console.log(`📍 URL: http://localhost:${PORT}/`);
|
||||
try {
|
||||
process.chdir(RADAR_APP_DIR);
|
||||
execSync(`npm run dev -- -p ${PORT}`, { stdio: 'inherit' });
|
||||
} catch (e) {
|
||||
console.error('Erreur lors du démarrage du serveur dev:', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
// Mode production: servir build/
|
||||
if (!fs.existsSync(BUILD_DIR)) {
|
||||
console.error(`❌ Dossier build/ introuvable. Lancez d'abord: npm run build`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`🚀 Démarrage du serveur statique sur http://localhost:${PORT}/`);
|
||||
console.log(`📁 Servant: ${BUILD_DIR}`);
|
||||
try {
|
||||
// Utiliser npx serve si disponible, sinon python http.server
|
||||
try {
|
||||
execSync(`npx serve@latest "${BUILD_DIR}" --listen ${PORT}`, { stdio: 'inherit' });
|
||||
} catch (e) {
|
||||
// Fallback sur python
|
||||
console.log('⚠️ npx serve non disponible, utilisation de python http.server');
|
||||
process.chdir(BUILD_DIR);
|
||||
execSync(`python3 -m http.server ${PORT}`, { stdio: 'inherit' });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erreur lors du démarrage du serveur:', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export NODE_ENV=production
|
||||
|
||||
# En mode production avec output: export, utiliser serve pour servir les fichiers statiques
|
||||
# Vérifier que team.html existe dans out/
|
||||
cd .techradar
|
||||
cd radar-app
|
||||
|
||||
echo "📁 Répertoire actuel: $(pwd)"
|
||||
echo "📁 Contenu de out/ avant vérification:"
|
||||
@@ -20,14 +20,14 @@ copy_team_files() {
|
||||
|
||||
echo "🔍 Recherche de team.html..."
|
||||
|
||||
# Chercher dans public/ (dans .techradar, chemin relatif)
|
||||
# Chercher dans public/ (dans radar-app, chemin relatif)
|
||||
if [ -f "public/team.html" ]; then
|
||||
cp -v public/team.html out/team.html && echo "✅ team.html copié depuis .techradar/public/" && copied=1
|
||||
cp -v public/team.html out/team.html && echo "✅ team.html copié depuis radar-app/public/" && copied=1
|
||||
fi
|
||||
|
||||
# Chercher dans /app/.techradar/public/ (chemin absolu depuis .techradar)
|
||||
if [ $copied -eq 0 ] && [ -f "/app/.techradar/public/team.html" ]; then
|
||||
cp -v /app/.techradar/public/team.html out/team.html && echo "✅ team.html copié depuis /app/.techradar/public/" && copied=1
|
||||
# Chercher dans /app/radar-app/public/ (chemin absolu depuis radar-app)
|
||||
if [ $copied -eq 0 ] && [ -f "/app/radar-app/public/team.html" ]; then
|
||||
cp -v /app/radar-app/public/team.html out/team.html && echo "✅ team.html copié depuis /app/radar-app/public/" && copied=1
|
||||
fi
|
||||
|
||||
# Chercher dans /app/public/ (racine du projet)
|
||||
@@ -39,8 +39,8 @@ copy_team_files() {
|
||||
echo "❌ team.html introuvable dans tous les emplacements testés"
|
||||
echo "📁 Recherche dans public/ (relatif):"
|
||||
ls -la public/ 2>/dev/null | head -5 || echo "public/ non trouvé (relatif)"
|
||||
echo "📁 Recherche dans /app/.techradar/public/:"
|
||||
ls -la /app/.techradar/public/ 2>/dev/null | head -5 || echo "/app/.techradar/public/ non trouvé"
|
||||
echo "📁 Recherche dans /app/radar-app/public/:"
|
||||
ls -la /app/radar-app/public/ 2>/dev/null | head -5 || echo "/app/radar-app/public/ non trouvé"
|
||||
echo "📁 Recherche dans /app/public/:"
|
||||
ls -la /app/public/ 2>/dev/null | head -5 || echo "/app/public/ non trouvé"
|
||||
fi
|
||||
@@ -48,8 +48,8 @@ copy_team_files() {
|
||||
# Copier team-visualization-data.json de la même manière
|
||||
if [ -f "public/team-visualization-data.json" ]; then
|
||||
cp -v public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié"
|
||||
elif [ -f "/app/.techradar/public/team-visualization-data.json" ]; then
|
||||
cp -v /app/.techradar/public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié depuis /app/.techradar/public/"
|
||||
elif [ -f "/app/radar-app/public/team-visualization-data.json" ]; then
|
||||
cp -v /app/radar-app/public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié depuis /app/radar-app/public/"
|
||||
elif [ -f "/app/public/team-visualization-data.json" ]; then
|
||||
cp -v /app/public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié depuis /app/public/"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user