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:
@@ -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
225
scripts/verify-blips.js
Executable 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 };
|
||||
|
||||
Reference in New Issue
Block a user