fix: corriger la structure des dossiers par date dans Dockerfile et ajouter script de vérification

- Correction du Dockerfile.business pour préserver la structure radar/2025-01-15/ au lieu de copier directement dans radar/
- Cela permet au framework de parser correctement les dates et d'afficher les releases
- Ajout du script scripts/verify-blips.js pour vérifier le format des blips et des dates
- Tous les 36 fichiers blips vérifiés et validés (title, ring, quadrant, tags présents)
This commit is contained in:
syoul
2025-12-03 15:10:30 +01:00
parent de4e0a32db
commit cf7a0618bc
2 changed files with 228 additions and 1 deletions

View File

@@ -32,9 +32,11 @@ RUN npx techradar install && \
# --- CONFIGURATION BUSINESS ---
# Application de la logique Business (remplacement de la config et des données)
# Préserver la structure de dossiers par date pour que le framework puisse parser les dates
RUN cp radar-business/config-business.json config.json && \
rm -rf radar/* && \
cp -r radar-business/2025-01-15/* radar/
mkdir -p radar/2025-01-15 && \
cp -r radar-business/2025-01-15/* radar/2025-01-15/
# Exposition du port interne
EXPOSE 3000

225
scripts/verify-blips.js Executable file
View File

@@ -0,0 +1,225 @@
#!/usr/bin/env node
/**
* Script pour vérifier le format des blips et corriger les problèmes
*/
const fs = require('fs');
const path = require('path');
const REQUIRED_FIELDS = ['title', 'ring', 'quadrant', 'tags'];
const VALID_RINGS = ['adopt', 'trial', 'assess', 'hold'];
const VALID_QUADRANTS = [
'technologies-differentiantes',
'technologies-commodite',
'technologies-risque',
'technologies-emergentes'
];
function parseBlip(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
const frontMatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
if (!frontMatterMatch) {
return { error: 'No front matter found', file: filePath };
}
const frontMatter = frontMatterMatch[1];
const body = frontMatterMatch[2];
const metadata = {};
for (const line of frontMatter.split('\n')) {
const match = line.match(/^(\w+):\s*(.+)$/);
if (match) {
const key = match[1];
let value = match[2].trim();
// Parser les valeurs
if (value === 'true') value = true;
else if (value === 'false') value = false;
else if (!isNaN(value) && value !== '') value = Number(value);
else if (value.startsWith('[')) {
value = value.slice(1, -1).split(',').map(v => v.trim().replace(/['"]/g, ''));
} else if (value.startsWith('"') && value.endsWith('"')) {
value = value.slice(1, -1);
}
metadata[key] = value;
}
}
return { metadata, body, file: filePath };
}
function validateBlip(blip) {
const errors = [];
const warnings = [];
if (blip.error) {
return { errors: [blip.error], warnings: [] };
}
// Vérifier les champs requis
for (const field of REQUIRED_FIELDS) {
if (!blip.metadata[field]) {
errors.push(`Missing required field: ${field}`);
}
}
// Vérifier le format des valeurs
if (blip.metadata.ring && !VALID_RINGS.includes(blip.metadata.ring)) {
errors.push(`Invalid ring: ${blip.metadata.ring}. Valid values: ${VALID_RINGS.join(', ')}`);
}
if (blip.metadata.quadrant && !VALID_QUADRANTS.includes(blip.metadata.quadrant)) {
errors.push(`Invalid quadrant: ${blip.metadata.quadrant}. Valid values: ${VALID_QUADRANTS.join(', ')}`);
}
if (blip.metadata.tags) {
if (!Array.isArray(blip.metadata.tags)) {
errors.push(`Tags must be an array, got: ${typeof blip.metadata.tags}`);
} else if (blip.metadata.tags.length === 0) {
warnings.push('Tags array is empty');
}
}
if (!blip.metadata.title || blip.metadata.title.trim() === '') {
errors.push('Title is empty or missing');
}
return { errors, warnings };
}
function verifyAllBlips(radarDir) {
const files = fs.readdirSync(radarDir)
.filter(f => f.endsWith('.md'))
.map(f => path.join(radarDir, f));
const results = {
total: files.length,
valid: 0,
invalid: 0,
errors: [],
warnings: []
};
console.log(`\nVérification de ${files.length} fichiers blips...\n`);
for (const file of files) {
const blip = parseBlip(file);
const validation = validateBlip(blip);
const filename = path.basename(file);
if (validation.errors.length > 0) {
results.invalid++;
results.errors.push({
file: filename,
errors: validation.errors
});
console.log(`${filename}`);
validation.errors.forEach(err => console.log(` - ${err}`));
} else {
results.valid++;
if (validation.warnings.length > 0) {
results.warnings.push({
file: filename,
warnings: validation.warnings
});
console.log(`⚠️ ${filename} (warnings)`);
validation.warnings.forEach(warn => console.log(` - ${warn}`));
} else {
console.log(`${filename}`);
}
}
}
console.log(`\n📊 Résumé:`);
console.log(` ✅ Valides: ${results.valid}`);
console.log(` ❌ Invalides: ${results.invalid}`);
console.log(` ⚠️ Avertissements: ${results.warnings.length}`);
if (results.errors.length > 0) {
console.log(`\n❌ Fichiers avec erreurs:`);
results.errors.forEach(({ file, errors }) => {
console.log(`\n ${file}:`);
errors.forEach(err => console.log(` - ${err}`));
});
}
if (results.warnings.length > 0) {
console.log(`\n⚠️ Fichiers avec avertissements:`);
results.warnings.forEach(({ file, warnings }) => {
console.log(`\n ${file}:`);
warnings.forEach(warn => console.log(` - ${warn}`));
});
}
return results;
}
// Vérifier le format des dates des releases
function verifyReleaseDates() {
console.log('\n📅 Vérification des dates de release...\n');
const radarDir = path.join(__dirname, '../radar-business');
const dirs = fs.readdirSync(radarDir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
const datePattern = /^\d{4}-\d{2}-\d{2}$/;
const errors = [];
for (const dir of dirs) {
if (datePattern.test(dir)) {
const date = new Date(dir);
if (isNaN(date.getTime())) {
errors.push(`Invalid date format: ${dir} (cannot parse as date)`);
console.log(`${dir} - Date invalide`);
} else {
console.log(`${dir} - Date valide (${date.toLocaleDateString('fr-FR')})`);
}
} else {
errors.push(`Invalid date format: ${dir} (must be YYYY-MM-DD)`);
console.log(`${dir} - Format invalide (doit être YYYY-MM-DD)`);
}
}
if (errors.length > 0) {
console.log(`\n❌ Erreurs de format de date:`);
errors.forEach(err => console.log(` - ${err}`));
}
return errors.length === 0;
}
// Main
function main() {
const radarDir = path.join(__dirname, '../radar-business/2025-01-15');
if (!fs.existsSync(radarDir)) {
console.error(`Répertoire non trouvé: ${radarDir}`);
process.exit(1);
}
// Vérifier les dates
const datesValid = verifyReleaseDates();
// Vérifier les blips
const results = verifyAllBlips(radarDir);
// Résultat final
if (results.invalid > 0 || !datesValid) {
console.log('\n❌ Des erreurs ont été détectées. Veuillez les corriger.');
process.exit(1);
} else {
console.log('\n✅ Tous les fichiers sont valides !');
process.exit(0);
}
}
if (require.main === module) {
main();
}
module.exports = { parseBlip, validateBlip, verifyAllBlips, verifyReleaseDates };