thibaud frere commited on
Commit
91b0400
·
1 Parent(s): e01b523

update template sync

Browse files
Files changed (1) hide show
  1. app/scripts/sync-template.mjs +44 -44
app/scripts/sync-template.mjs CHANGED
@@ -1,13 +1,13 @@
1
  #!/usr/bin/env node
2
 
3
  /**
4
- * Script de synchronisation avec le template de base research-article-template
5
  *
6
- * Ce script :
7
- * 1. Clone ou update le repo template dans un dossier temporaire
8
- * 2. Copie tous les fichiers SAUF ceux dans ./src/content qui contiennent le contenu spécifique
9
- * 3. Préserve les fichiers de configuration locaux importants
10
- * 4. Fait un backup des fichiers qui vont être écrasés
11
  *
12
  * Usage: npm run sync:template [--dry-run] [--backup] [--force]
13
  */
@@ -23,26 +23,26 @@ const PROJECT_ROOT = path.resolve(APP_ROOT, '..');
23
  const TEMP_DIR = path.join(PROJECT_ROOT, '.temp-template-sync');
24
  const TEMPLATE_REPO = 'https://huggingface.co/spaces/tfrere/research-article-template';
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
 
@@ -51,7 +51,7 @@ const PRESERVE_PATHS = [
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',
@@ -61,15 +61,15 @@ const SENSITIVE_FILES = [
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');
68
- console.log(`📁 Répertoire de travail: ${PROJECT_ROOT}`);
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 = {}) {
@@ -86,7 +86,7 @@ async function executeCommand(command, options = {}) {
86
  });
87
  return result;
88
  } catch (error) {
89
- console.error(`❌ Erreur lors de l'exécution: ${command}`);
90
  console.error(error.message);
91
  throw error;
92
  }
@@ -116,28 +116,28 @@ async function createBackup(filePath) {
116
 
117
  try {
118
  await fs.copyFile(filePath, backupPath);
119
- console.log(`💾 Backup créé: ${path.relative(PROJECT_ROOT, backupPath)}`);
120
  } catch (error) {
121
- console.warn(`⚠️ Impossible de créer le backup de ${filePath}: ${error.message}`);
122
  }
123
  }
124
 
125
  async function syncFile(sourcePath, targetPath) {
126
  const relativeTarget = path.relative(PROJECT_ROOT, targetPath);
127
 
128
- // Vérifier si le fichier doit être préservé
129
  if (await isPathPreserved(relativeTarget)) {
130
- console.log(`🔒 PRÉSERVÉ: ${relativeTarget}`);
131
  return;
132
  }
133
 
134
- // Vérifier si c'est un fichier sensible
135
  if (SENSITIVE_FILES.includes(relativeTarget)) {
136
  if (!isForce) {
137
- console.log(`⚠️ SENSIBLE (ignoré): ${relativeTarget} (utilisez --force pour écraser)`);
138
  return;
139
  } else {
140
- console.log(`⚠️ SENSIBLE (forcé): ${relativeTarget}`);
141
  }
142
  }
143
 
@@ -154,7 +154,7 @@ async function syncFile(sourcePath, targetPath) {
154
  }
155
 
156
  if (isDryRun) {
157
- console.log(`[DRY-RUN] COPIE: ${relativeTarget}`);
158
  return;
159
  }
160
 
@@ -165,11 +165,11 @@ async function syncFile(sourcePath, targetPath) {
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
 
@@ -180,7 +180,7 @@ async function syncFile(sourcePath, targetPath) {
180
 
181
  // Copier le fichier
182
  await fs.copyFile(sourcePath, targetPath);
183
- console.log(`✅ COPIÉ: ${relativeTarget}`);
184
  }
185
 
186
  async function syncDirectory(sourceDir, targetDir) {
@@ -208,7 +208,7 @@ async function syncDirectory(sourceDir, targetDir) {
208
  }
209
 
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)) {
@@ -226,10 +226,10 @@ async function cloneOrUpdateTemplate() {
226
  }
227
 
228
  async function showSummary(templateDir) {
229
- console.log('\n📊 RÉSUMÉ DE LA SYNCHRONISATION');
230
  console.log('================================');
231
 
232
- console.log('\n🔒 Fichiers/dossiers préservés:');
233
  for (const preserve of PRESERVE_PATHS) {
234
  const fullPath = path.join(PROJECT_ROOT, preserve);
235
  if (await pathExists(fullPath)) {
@@ -239,7 +239,7 @@ async function showSummary(templateDir) {
239
  }
240
  }
241
 
242
- console.log('\n⚠️ Fichiers sensibles (nécessitent --force):');
243
  for (const sensitive of SENSITIVE_FILES) {
244
  const fullPath = path.join(PROJECT_ROOT, sensitive);
245
  if (await pathExists(fullPath)) {
@@ -248,18 +248,18 @@ async function showSummary(templateDir) {
248
  }
249
 
250
  if (isDryRun) {
251
- console.log('\n🔍 Pour exécuter réellement: npm run sync:template');
252
- console.log('🔧 Pour forcer les fichiers sensibles: npm run sync:template -- --force');
253
  }
254
  }
255
 
256
  async function cleanup() {
257
- console.log('\n🧹 Nettoyage...');
258
  if (await pathExists(TEMP_DIR)) {
259
  if (!isDryRun) {
260
  await fs.rm(TEMP_DIR, { recursive: true, force: true });
261
  }
262
- console.log(`🗑️ Dossier temporaire supprimé: ${TEMP_DIR}`);
263
  }
264
  }
265
 
@@ -281,10 +281,10 @@ async function main() {
281
  // Afficher le résumé
282
  await showSummary(templateDir);
283
 
284
- console.log('\n✅ Synchronisation terminée !');
285
 
286
  } catch (error) {
287
- console.error('\n❌ Erreur durant la synchronisation:');
288
  console.error(error.message);
289
  process.exit(1);
290
  } finally {
@@ -294,13 +294,13 @@ async function main() {
294
 
295
  // Gestion des signaux pour nettoyer en cas d'interruption
296
  process.on('SIGINT', async () => {
297
- console.log('\n\n⚠️ Interruption détectée, nettoyage...');
298
  await cleanup();
299
  process.exit(1);
300
  });
301
 
302
  process.on('SIGTERM', async () => {
303
- console.log('\n\n⚠️ Arrêt demandé, nettoyage...');
304
  await cleanup();
305
  process.exit(1);
306
  });
 
1
  #!/usr/bin/env node
2
 
3
  /**
4
+ * Template synchronization script for research-article-template
5
  *
6
+ * This script:
7
+ * 1. Clones or updates the template repo in a temporary directory
8
+ * 2. Copies all files EXCEPT those in ./src/content which contain specific content
9
+ * 3. Preserves important local configuration files
10
+ * 4. Creates backups of files that will be overwritten
11
  *
12
  * Usage: npm run sync:template [--dry-run] [--backup] [--force]
13
  */
 
23
  const TEMP_DIR = path.join(PROJECT_ROOT, '.temp-template-sync');
24
  const TEMPLATE_REPO = 'https://huggingface.co/spaces/tfrere/research-article-template';
25
 
26
+ // Files and directories to PRESERVE (do not overwrite)
27
  const PRESERVE_PATHS = [
28
+ // Project-specific content
29
  'app/src/content',
30
 
31
+ // Public data (symlink to our data)
32
  'app/public/data',
33
 
34
+ // Local configuration
35
  'app/package-lock.json',
36
  'app/node_modules',
37
 
38
+ // Project-specific scripts (preserve our sync script)
39
  'app/scripts/sync-template.mjs',
40
 
41
+ // Project configuration files
42
  'README.md',
43
  'tools',
44
 
45
+ // Backup and temporary files
46
  '.backup-*',
47
  '.temp-*',
48
 
 
51
  '.gitignore'
52
  ];
53
 
54
+ // Files to handle with caution (require confirmation)
55
  const SENSITIVE_FILES = [
56
  'app/package.json',
57
  'app/astro.config.mjs',
 
61
 
62
  const args = process.argv.slice(2);
63
  const isDryRun = args.includes('--dry-run');
64
+ const shouldBackup = args.includes('--backup'); // Disabled by default, use --backup to enable
65
  const isForce = args.includes('--force');
66
 
67
+ console.log('🔄 Template synchronization script for research-article-template');
68
+ console.log(`📁 Working directory: ${PROJECT_ROOT}`);
69
  console.log(`🎯 Template source: ${TEMPLATE_REPO}`);
70
+ if (isDryRun) console.log('🔍 DRY-RUN mode enabled - no files will be modified');
71
+ if (shouldBackup) console.log('💾 Backup enabled');
72
+ if (!shouldBackup) console.log('🚫 Backup disabled (use --backup to enable)');
73
  console.log('');
74
 
75
  async function executeCommand(command, options = {}) {
 
86
  });
87
  return result;
88
  } catch (error) {
89
+ console.error(`❌ Error during execution: ${command}`);
90
  console.error(error.message);
91
  throw error;
92
  }
 
116
 
117
  try {
118
  await fs.copyFile(filePath, backupPath);
119
+ console.log(`💾 Backup created: ${path.relative(PROJECT_ROOT, backupPath)}`);
120
  } catch (error) {
121
+ console.warn(`⚠️ Unable to create backup for ${filePath}: ${error.message}`);
122
  }
123
  }
124
 
125
  async function syncFile(sourcePath, targetPath) {
126
  const relativeTarget = path.relative(PROJECT_ROOT, targetPath);
127
 
128
+ // Check if the file should be preserved
129
  if (await isPathPreserved(relativeTarget)) {
130
+ console.log(`🔒 PRESERVED: ${relativeTarget}`);
131
  return;
132
  }
133
 
134
+ // Check if it's a sensitive file
135
  if (SENSITIVE_FILES.includes(relativeTarget)) {
136
  if (!isForce) {
137
+ console.log(`⚠️ SENSITIVE (ignored): ${relativeTarget} (use --force to overwrite)`);
138
  return;
139
  } else {
140
+ console.log(`⚠️ SENSITIVE (forced): ${relativeTarget}`);
141
  }
142
  }
143
 
 
154
  }
155
 
156
  if (isDryRun) {
157
+ console.log(`[DRY-RUN] COPY: ${relativeTarget}`);
158
  return;
159
  }
160
 
 
165
  try {
166
  const sourceStats = await fs.lstat(sourcePath);
167
  if (sourceStats.isSymbolicLink()) {
168
+ console.log(`🔗 SYMLINK (ignored): ${relativeTarget}`);
169
  return;
170
  }
171
  } catch (error) {
172
+ console.warn(`⚠️ Unable to check source ${sourcePath}: ${error.message}`);
173
  return;
174
  }
175
 
 
180
 
181
  // Copier le fichier
182
  await fs.copyFile(sourcePath, targetPath);
183
+ console.log(`✅ COPIED: ${relativeTarget}`);
184
  }
185
 
186
  async function syncDirectory(sourceDir, targetDir) {
 
208
  }
209
 
210
  async function cloneOrUpdateTemplate() {
211
+ console.log('📥 Fetching template...');
212
 
213
  // Nettoyer le dossier temporaire s'il existe
214
  if (await pathExists(TEMP_DIR)) {
 
226
  }
227
 
228
  async function showSummary(templateDir) {
229
+ console.log('\n📊 SYNCHRONIZATION SUMMARY');
230
  console.log('================================');
231
 
232
+ console.log('\n🔒 Preserved files/directories:');
233
  for (const preserve of PRESERVE_PATHS) {
234
  const fullPath = path.join(PROJECT_ROOT, preserve);
235
  if (await pathExists(fullPath)) {
 
239
  }
240
  }
241
 
242
+ console.log('\n⚠️ Sensitive files (require --force):');
243
  for (const sensitive of SENSITIVE_FILES) {
244
  const fullPath = path.join(PROJECT_ROOT, sensitive);
245
  if (await pathExists(fullPath)) {
 
248
  }
249
 
250
  if (isDryRun) {
251
+ console.log('\n🔍 To execute for real: npm run sync:template');
252
+ console.log('🔧 To force sensitive files: npm run sync:template -- --force');
253
  }
254
  }
255
 
256
  async function cleanup() {
257
+ console.log('\n🧹 Cleaning up...');
258
  if (await pathExists(TEMP_DIR)) {
259
  if (!isDryRun) {
260
  await fs.rm(TEMP_DIR, { recursive: true, force: true });
261
  }
262
+ console.log(`🗑️ Temporary directory removed: ${TEMP_DIR}`);
263
  }
264
  }
265
 
 
281
  // Afficher le résumé
282
  await showSummary(templateDir);
283
 
284
+ console.log('\n✅ Synchronization completed!');
285
 
286
  } catch (error) {
287
+ console.error('\n❌ Error during synchronization:');
288
  console.error(error.message);
289
  process.exit(1);
290
  } finally {
 
294
 
295
  // Gestion des signaux pour nettoyer en cas d'interruption
296
  process.on('SIGINT', async () => {
297
+ console.log('\n\n⚠️ Interruption detected, cleaning up...');
298
  await cleanup();
299
  process.exit(1);
300
  });
301
 
302
  process.on('SIGTERM', async () => {
303
+ console.log('\n\n⚠️ Shutdown requested, cleaning up...');
304
  await cleanup();
305
  process.exit(1);
306
  });