Spaces:
Running
Running
thibaud frere
commited on
Commit
·
af53fac
1
Parent(s):
8c7d8bb
update sync template
Browse files- app/scripts/sync-template.mjs +57 -24
app/scripts/sync-template.mjs
CHANGED
|
@@ -25,27 +25,43 @@ const TEMPLATE_REPO = 'https://huggingface.co/spaces/tfrere/research-article-tem
|
|
| 25 |
|
| 26 |
// Fichiers et dossiers à PRÉSERVER (ne pas écraser)
|
| 27 |
const PRESERVE_PATHS = [
|
| 28 |
-
// Contenu spécifique au projet
|
| 29 |
'app/src/content',
|
| 30 |
|
| 31 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
'app/node_modules',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
'.backup-*',
|
| 34 |
'.temp-*',
|
| 35 |
-
'.template-sync*',
|
| 36 |
|
| 37 |
-
// Git
|
| 38 |
'.git',
|
| 39 |
-
'.gitignore'
|
| 40 |
-
'.gitattributes'
|
| 41 |
];
|
| 42 |
|
| 43 |
// Fichiers à traiter avec précaution (demander confirmation)
|
| 44 |
-
const SENSITIVE_FILES = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
const args = process.argv.slice(2);
|
| 47 |
const isDryRun = args.includes('--dry-run');
|
| 48 |
-
const shouldBackup = args.includes('--backup')
|
| 49 |
const isForce = args.includes('--force');
|
| 50 |
|
| 51 |
console.log('🔄 Script de synchronisation avec le template research-article-template');
|
|
@@ -53,6 +69,7 @@ console.log(`📁 Répertoire de travail: ${PROJECT_ROOT}`);
|
|
| 53 |
console.log(`🎯 Template source: ${TEMPLATE_REPO}`);
|
| 54 |
if (isDryRun) console.log('🔍 Mode DRY-RUN activé - aucun fichier ne sera modifié');
|
| 55 |
if (shouldBackup) console.log('💾 Backup activé');
|
|
|
|
| 56 |
console.log('');
|
| 57 |
|
| 58 |
async function executeCommand(command, options = {}) {
|
|
@@ -85,20 +102,9 @@ async function pathExists(filePath) {
|
|
| 85 |
}
|
| 86 |
|
| 87 |
async function isPathPreserved(relativePath) {
|
| 88 |
-
// Protection CRITIQUE: Ne jamais toucher aux fichiers Git
|
| 89 |
-
if (relativePath.startsWith('.git') ||
|
| 90 |
-
relativePath === '.gitignore' ||
|
| 91 |
-
relativePath === '.gitattributes') {
|
| 92 |
-
return true;
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
return PRESERVE_PATHS.some(preserve =>
|
| 96 |
-
// Correspondance exacte
|
| 97 |
relativePath === preserve ||
|
| 98 |
-
// Le chemin est dans un dossier préservé
|
| 99 |
relativePath.startsWith(preserve + '/')
|
| 100 |
-
// Suppression de la condition qui préservait les parents
|
| 101 |
-
// preserve.startsWith(relativePath + '/') - PROBLÈME : préservait tout 'app/' si 'app/src/content' était préservé
|
| 102 |
);
|
| 103 |
}
|
| 104 |
|
|
@@ -135,9 +141,16 @@ async function syncFile(sourcePath, targetPath) {
|
|
| 135 |
}
|
| 136 |
}
|
| 137 |
|
| 138 |
-
// Créer un backup si le fichier existe déjà
|
| 139 |
if (await pathExists(targetPath)) {
|
| 140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
}
|
| 142 |
|
| 143 |
if (isDryRun) {
|
|
@@ -148,6 +161,23 @@ async function syncFile(sourcePath, targetPath) {
|
|
| 148 |
// Assurer que le répertoire parent existe
|
| 149 |
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
| 150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
// Copier le fichier
|
| 152 |
await fs.copyFile(sourcePath, targetPath);
|
| 153 |
console.log(`✅ COPIÉ: ${relativeTarget}`);
|
|
@@ -180,10 +210,13 @@ async function syncDirectory(sourceDir, targetDir) {
|
|
| 180 |
async function cloneOrUpdateTemplate() {
|
| 181 |
console.log('📥 Récupération du template...');
|
| 182 |
|
| 183 |
-
// Nettoyer le dossier temporaire s'il existe
|
| 184 |
if (await pathExists(TEMP_DIR)) {
|
| 185 |
-
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
| 187 |
}
|
| 188 |
|
| 189 |
// Cloner le repo template (même en dry-run pour pouvoir comparer)
|
|
|
|
| 25 |
|
| 26 |
// Fichiers et dossiers à PRÉSERVER (ne pas écraser)
|
| 27 |
const PRESERVE_PATHS = [
|
| 28 |
+
// Contenu spécifique au projet SmolLM
|
| 29 |
'app/src/content',
|
| 30 |
|
| 31 |
+
// Données publiques (lien symbolique vers nos données)
|
| 32 |
+
'app/public/data',
|
| 33 |
+
|
| 34 |
+
// Configuration locale
|
| 35 |
+
'app/package-lock.json',
|
| 36 |
'app/node_modules',
|
| 37 |
+
|
| 38 |
+
// Scripts spécifiques (préserver notre script de sync)
|
| 39 |
+
'app/scripts/sync-template.mjs',
|
| 40 |
+
|
| 41 |
+
// Fichiers de configuration du projet
|
| 42 |
+
'README.md',
|
| 43 |
+
'tools',
|
| 44 |
+
|
| 45 |
+
// Fichiers de backup et temporaires
|
| 46 |
'.backup-*',
|
| 47 |
'.temp-*',
|
|
|
|
| 48 |
|
| 49 |
+
// Git
|
| 50 |
'.git',
|
| 51 |
+
'.gitignore'
|
|
|
|
| 52 |
];
|
| 53 |
|
| 54 |
// Fichiers à traiter avec précaution (demander confirmation)
|
| 55 |
+
const SENSITIVE_FILES = [
|
| 56 |
+
'app/package.json',
|
| 57 |
+
'app/astro.config.mjs',
|
| 58 |
+
'Dockerfile',
|
| 59 |
+
'nginx.conf'
|
| 60 |
+
];
|
| 61 |
|
| 62 |
const args = process.argv.slice(2);
|
| 63 |
const isDryRun = args.includes('--dry-run');
|
| 64 |
+
const shouldBackup = args.includes('--backup'); // Désactivé par défaut, utiliser --backup pour l'activer
|
| 65 |
const isForce = args.includes('--force');
|
| 66 |
|
| 67 |
console.log('🔄 Script de synchronisation avec le template research-article-template');
|
|
|
|
| 69 |
console.log(`🎯 Template source: ${TEMPLATE_REPO}`);
|
| 70 |
if (isDryRun) console.log('🔍 Mode DRY-RUN activé - aucun fichier ne sera modifié');
|
| 71 |
if (shouldBackup) console.log('💾 Backup activé');
|
| 72 |
+
if (!shouldBackup) console.log('🚫 Backup désactivé (utilisez --backup pour l\'activer)');
|
| 73 |
console.log('');
|
| 74 |
|
| 75 |
async function executeCommand(command, options = {}) {
|
|
|
|
| 102 |
}
|
| 103 |
|
| 104 |
async function isPathPreserved(relativePath) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
return PRESERVE_PATHS.some(preserve =>
|
|
|
|
| 106 |
relativePath === preserve ||
|
|
|
|
| 107 |
relativePath.startsWith(preserve + '/')
|
|
|
|
|
|
|
| 108 |
);
|
| 109 |
}
|
| 110 |
|
|
|
|
| 141 |
}
|
| 142 |
}
|
| 143 |
|
| 144 |
+
// Créer un backup si le fichier existe déjà (et que ce n'est pas un lien symbolique)
|
| 145 |
if (await pathExists(targetPath)) {
|
| 146 |
+
try {
|
| 147 |
+
const stats = await fs.lstat(targetPath);
|
| 148 |
+
if (!stats.isSymbolicLink()) {
|
| 149 |
+
await createBackup(targetPath);
|
| 150 |
+
}
|
| 151 |
+
} catch (error) {
|
| 152 |
+
console.warn(`⚠️ Impossible de vérifier ${targetPath}: ${error.message}`);
|
| 153 |
+
}
|
| 154 |
}
|
| 155 |
|
| 156 |
if (isDryRun) {
|
|
|
|
| 161 |
// Assurer que le répertoire parent existe
|
| 162 |
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
| 163 |
|
| 164 |
+
// Vérifier si la source est un lien symbolique
|
| 165 |
+
try {
|
| 166 |
+
const sourceStats = await fs.lstat(sourcePath);
|
| 167 |
+
if (sourceStats.isSymbolicLink()) {
|
| 168 |
+
console.log(`🔗 LIEN SYMBOLIQUE (ignoré): ${relativeTarget}`);
|
| 169 |
+
return;
|
| 170 |
+
}
|
| 171 |
+
} catch (error) {
|
| 172 |
+
console.warn(`⚠️ Impossible de vérifier la source ${sourcePath}: ${error.message}`);
|
| 173 |
+
return;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
// Supprimer le fichier cible s'il existe (pour gérer les liens symboliques)
|
| 177 |
+
if (await pathExists(targetPath)) {
|
| 178 |
+
await fs.rm(targetPath, { recursive: true, force: true });
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
// Copier le fichier
|
| 182 |
await fs.copyFile(sourcePath, targetPath);
|
| 183 |
console.log(`✅ COPIÉ: ${relativeTarget}`);
|
|
|
|
| 210 |
async function cloneOrUpdateTemplate() {
|
| 211 |
console.log('📥 Récupération du template...');
|
| 212 |
|
| 213 |
+
// Nettoyer le dossier temporaire s'il existe
|
| 214 |
if (await pathExists(TEMP_DIR)) {
|
| 215 |
+
if (!isDryRun) {
|
| 216 |
+
await fs.rm(TEMP_DIR, { recursive: true, force: true });
|
| 217 |
+
} else {
|
| 218 |
+
console.log(`[DRY-RUN] Suppression: ${TEMP_DIR}`);
|
| 219 |
+
}
|
| 220 |
}
|
| 221 |
|
| 222 |
// Cloner le repo template (même en dry-run pour pouvoir comparer)
|