- 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)
226 lines
6.3 KiB
JavaScript
Executable File
226 lines
6.3 KiB
JavaScript
Executable File
#!/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 };
|
|
|