ultimate-jekyll-manager 0.0.54 → 0.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/js/modules/redirect.js +1 -31
- package/dist/gulp/tasks/imagemin.js +30 -31
- package/dist/gulp/tasks/sass.js +3 -0
- package/dist/gulp/tasks/translation.js +20 -2
- package/dist/gulp/tasks/utils/github-cache.js +104 -84
- package/dist/gulp/tasks/webpack.js +12 -38
- package/package.json +1 -1
|
@@ -5,28 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const performRedirect = () => {
|
|
8
|
-
// Debug: Log initial state
|
|
9
|
-
console.log('[Redirect] Script started at', new Date().toISOString());
|
|
10
|
-
console.log('[Redirect] Document readyState:', document.readyState);
|
|
11
|
-
console.log('[Redirect] Current URL:', window.location.href);
|
|
12
|
-
console.log('[Redirect] User Agent:', navigator.userAgent);
|
|
13
|
-
|
|
14
|
-
// Check for spinner element to verify DOM is loaded
|
|
15
|
-
const $spinner = document.querySelector('.spinner-border');
|
|
16
|
-
console.log('[Redirect] Spinner element found:', !!$spinner);
|
|
17
|
-
if ($spinner) {
|
|
18
|
-
console.log('[Redirect] Spinner classes:', $spinner.className);
|
|
19
|
-
console.log('[Redirect] Spinner computed display:', window.getComputedStyle($spinner).display);
|
|
20
|
-
console.log('[Redirect] Spinner computed visibility:', window.getComputedStyle($spinner).visibility);
|
|
21
|
-
console.log('[Redirect] Spinner animation:', window.getComputedStyle($spinner).animation);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
8
|
// Get redirect configuration element
|
|
25
9
|
const $redirectConfig = document.getElementById('redirect-config');
|
|
26
10
|
if (!$redirectConfig) {
|
|
27
11
|
console.error('[Redirect] Configuration element #redirect-config not found');
|
|
28
|
-
console.error('[Redirect] Available IDs in document:',
|
|
29
|
-
Array.from(document.querySelectorAll('[id]')).map(el => el.id));
|
|
30
12
|
return;
|
|
31
13
|
}
|
|
32
14
|
|
|
@@ -51,8 +33,6 @@ const performRedirect = () => {
|
|
|
51
33
|
// Parse URLs
|
|
52
34
|
const currentUrl = new URL(window.location.href);
|
|
53
35
|
const siteUrl = new URL(config.siteUrl);
|
|
54
|
-
console.log('[Redirect] Current URL:', currentUrl.toString());
|
|
55
|
-
console.log('[Redirect] Site URL:', siteUrl.toString());
|
|
56
36
|
|
|
57
37
|
// Parse modifier function
|
|
58
38
|
let modifierFunction = (url) => url;
|
|
@@ -60,7 +40,6 @@ const performRedirect = () => {
|
|
|
60
40
|
try {
|
|
61
41
|
// Safely evaluate modifier function
|
|
62
42
|
modifierFunction = new Function('url', `return (${config.modifier})(url)`);
|
|
63
|
-
console.log('[Redirect] Modifier function parsed successfully');
|
|
64
43
|
} catch (error) {
|
|
65
44
|
console.warn('[Redirect] Failed to parse modifier function:', error);
|
|
66
45
|
console.warn('[Redirect] Modifier string:', config.modifier);
|
|
@@ -70,8 +49,6 @@ const performRedirect = () => {
|
|
|
70
49
|
// Determine redirect delay
|
|
71
50
|
const isDevelopment = config.environment === 'development';
|
|
72
51
|
const timeout = isDevelopment ? 3000 : 1;
|
|
73
|
-
console.log('[Redirect] Environment:', config.environment);
|
|
74
|
-
console.log('[Redirect] Timeout:', timeout, 'ms');
|
|
75
52
|
|
|
76
53
|
// Build redirect URL
|
|
77
54
|
let redirectUrl;
|
|
@@ -90,7 +67,6 @@ const performRedirect = () => {
|
|
|
90
67
|
// Default to site home page
|
|
91
68
|
redirectUrl = new URL(siteUrl);
|
|
92
69
|
}
|
|
93
|
-
console.log('[Redirect] Redirect URL built:', redirectUrl.toString());
|
|
94
70
|
} catch (error) {
|
|
95
71
|
console.error('[Redirect] Invalid redirect URL:', config.url, error);
|
|
96
72
|
redirectUrl = new URL(siteUrl);
|
|
@@ -117,7 +93,7 @@ const performRedirect = () => {
|
|
|
117
93
|
}
|
|
118
94
|
|
|
119
95
|
// Log redirect details
|
|
120
|
-
console.group('[Redirect]
|
|
96
|
+
console.group('[Redirect] Configuration');
|
|
121
97
|
console.log('Original URL:', config.url);
|
|
122
98
|
console.log('Querystring forwarding:', shouldForwardQuerystring);
|
|
123
99
|
console.log('Modifier:', config.modifier);
|
|
@@ -132,23 +108,17 @@ const performRedirect = () => {
|
|
|
132
108
|
}
|
|
133
109
|
|
|
134
110
|
// Perform the redirect
|
|
135
|
-
console.log('[Redirect] Setting timeout for redirect');
|
|
136
111
|
setTimeout(() => {
|
|
137
|
-
console.log('[Redirect] Timeout fired, redirecting to:', finalUrl);
|
|
138
112
|
window.location.href = finalUrl;
|
|
139
113
|
}, timeout);
|
|
140
114
|
};
|
|
141
115
|
|
|
142
116
|
// Initialize based on Manager availability and DOM state
|
|
143
|
-
console.log('[Redirect] Initial document.readyState:', document.readyState);
|
|
144
|
-
|
|
145
117
|
if (document.readyState === 'loading') {
|
|
146
118
|
// Wait for DOM if still loading
|
|
147
|
-
console.log('[Redirect] Waiting for DOMContentLoaded');
|
|
148
119
|
document.addEventListener('DOMContentLoaded', performRedirect);
|
|
149
120
|
} else {
|
|
150
121
|
// DOM is already ready
|
|
151
|
-
console.log('[Redirect] Document already loaded, running immediately');
|
|
152
122
|
performRedirect();
|
|
153
123
|
}
|
|
154
124
|
|
|
@@ -169,6 +169,8 @@ async function imagemin(complete) {
|
|
|
169
169
|
if (githubCache && githubCache.hasCredentials()) {
|
|
170
170
|
githubCache.saveMetadata(metaPath, meta);
|
|
171
171
|
|
|
172
|
+
logger.log(`📊 Updating cache with ${stats.optimized} new optimizations and README stats...`);
|
|
173
|
+
|
|
172
174
|
// Collect all cache files to push (metadata will be auto-included)
|
|
173
175
|
const allCacheFiles = glob(path.join(CACHE_DIR, '**/*'), { nodir: true });
|
|
174
176
|
|
|
@@ -367,37 +369,34 @@ async function handleCacheOnlyUpdate(githubCache, metaPath, meta, validCachePath
|
|
|
367
369
|
// Save metadata
|
|
368
370
|
githubCache.saveMetadata(metaPath, meta);
|
|
369
371
|
|
|
370
|
-
//
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
}
|
|
372
|
+
// ALWAYS update README with latest stats, even if no orphans
|
|
373
|
+
logger.log(`📊 Updating cache README with latest statistics...`);
|
|
374
|
+
|
|
375
|
+
// Collect all valid cache files
|
|
376
|
+
const allCacheFiles = glob(path.join(CACHE_DIR, '**/*'), { nodir: true });
|
|
377
|
+
|
|
378
|
+
// Push to GitHub (will update README even if no file changes)
|
|
379
|
+
await githubCache.pushBranch(allCacheFiles, {
|
|
380
|
+
validFiles: validCachePaths,
|
|
381
|
+
stats: {
|
|
382
|
+
timestamp: new Date().toISOString(),
|
|
383
|
+
sourceCount: fileCount,
|
|
384
|
+
cachedCount: allCacheFiles.length - 1, // Subtract meta.json
|
|
385
|
+
processedNow: stats.totalImages,
|
|
386
|
+
fromCache: stats.fromCache,
|
|
387
|
+
newlyProcessed: stats.optimized,
|
|
388
|
+
timing: timing,
|
|
389
|
+
imageStats: {
|
|
390
|
+
totalImages: stats.totalImages,
|
|
391
|
+
optimized: stats.optimized,
|
|
392
|
+
skipped: stats.fromCache,
|
|
393
|
+
totalSizeBefore: stats.sizeBefore,
|
|
394
|
+
totalSizeAfter: stats.sizeAfter,
|
|
395
|
+
totalSaved: stats.sizeBefore - stats.sizeAfter
|
|
396
|
+
},
|
|
397
|
+
details: `All ${fileCount} images served from cache`
|
|
398
|
+
}
|
|
399
|
+
});
|
|
401
400
|
}
|
|
402
401
|
|
|
403
402
|
// Log image statistics
|
package/dist/gulp/tasks/sass.js
CHANGED
|
@@ -555,11 +555,14 @@ async function processTranslation() {
|
|
|
555
555
|
|
|
556
556
|
// Push updated translation cache back to cache branch
|
|
557
557
|
if (githubCache && githubCache.hasCredentials()) {
|
|
558
|
+
logger.log(`📊 Updating translation cache README with latest statistics...`);
|
|
559
|
+
|
|
558
560
|
// Collect all cache files to push
|
|
559
561
|
const allCacheFiles = glob(path.join(CACHE_DIR, '**/*'), { nodir: true });
|
|
560
562
|
|
|
561
|
-
//
|
|
563
|
+
// ALWAYS force recreate the branch (fresh branch with no history)
|
|
562
564
|
await githubCache.pushBranch(allCacheFiles, {
|
|
565
|
+
forceRecreate: true, // ALWAYS create a fresh branch - no history needed
|
|
563
566
|
stats: {
|
|
564
567
|
timestamp: new Date().toISOString(),
|
|
565
568
|
sourceCount: allFiles.length,
|
|
@@ -580,7 +583,22 @@ async function processTranslation() {
|
|
|
580
583
|
outputCost,
|
|
581
584
|
totalCost
|
|
582
585
|
} : undefined,
|
|
583
|
-
|
|
586
|
+
languageBreakdown: languages.map(lang => ({
|
|
587
|
+
language: lang,
|
|
588
|
+
total: stats.totalProcessed / languages.length,
|
|
589
|
+
fromCache: stats.cachedFiles.filter(f => f.startsWith(`[${lang}]`)).length,
|
|
590
|
+
newlyTranslated: stats.processedFiles.filter(f => f.startsWith(`[${lang}]`)).length,
|
|
591
|
+
failed: stats.failedFiles.filter(f => f.startsWith(`[${lang}]`)).length
|
|
592
|
+
})),
|
|
593
|
+
details: `Translated ${allFiles.length} pages to ${languages.length} languages (${languages.join(', ')})\n\n### Language Breakdown:\n${languages.map(lang => {
|
|
594
|
+
const langStats = {
|
|
595
|
+
total: stats.totalProcessed / languages.length,
|
|
596
|
+
fromCache: stats.cachedFiles.filter(f => f.startsWith(`[${lang}]`)).length,
|
|
597
|
+
newlyTranslated: stats.processedFiles.filter(f => f.startsWith(`[${lang}]`)).length,
|
|
598
|
+
failed: stats.failedFiles.filter(f => f.startsWith(`[${lang}]`)).length
|
|
599
|
+
};
|
|
600
|
+
return `**${lang.toUpperCase()}:** ${langStats.total} total (${langStats.fromCache} cached, ${langStats.newlyTranslated} new${langStats.failed > 0 ? `, ${langStats.failed} failed` : ''})`;
|
|
601
|
+
}).join('\n')}\n\n### Files from cache:\n${stats.cachedFiles.length > 0 ? stats.cachedFiles.slice(0, 10).map(f => `- ${f}`).join('\n') + (stats.cachedFiles.length > 10 ? `\n- ... and ${stats.cachedFiles.length - 10} more` : '') : 'None'}\n\n### Newly translated files:\n${stats.processedFiles.length > 0 ? stats.processedFiles.slice(0, 10).map(f => `- ${f}`).join('\n') + (stats.processedFiles.length > 10 ? `\n- ... and ${stats.processedFiles.length - 10} more` : '') : 'None'}${stats.failedFiles.length > 0 ? `\n\n### Failed translations:\n${stats.failedFiles.slice(0, 10).map(f => `- ${f}`).join('\n') + (stats.failedFiles.length > 10 ? `\n- ... and ${stats.failedFiles.length - 10} more` : '')}` : ''}`
|
|
584
602
|
}
|
|
585
603
|
});
|
|
586
604
|
}
|
|
@@ -150,49 +150,20 @@ class GitHubCache {
|
|
|
150
150
|
const readme = options.stats ? this.generateReadme(options.stats) :
|
|
151
151
|
options.branchReadme || this.generateDefaultReadme();
|
|
152
152
|
|
|
153
|
-
// If forceRecreate is true,
|
|
153
|
+
// If forceRecreate is true, we'll handle it in uploadFilesViaGit
|
|
154
154
|
if (forceRecreate) {
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
this.logger.log(`🔄 Creating temporary branch for safe replacement...`);
|
|
160
|
-
|
|
161
|
-
// Temporarily use temp branch name
|
|
162
|
-
this.branchName = tempBranch;
|
|
163
|
-
|
|
164
|
-
// Create new branch with clean files
|
|
165
|
-
await this.ensureBranchExists(readme);
|
|
166
|
-
const uploadedCount = await this.uploadFilesViaGit(files, true, readme);
|
|
167
|
-
|
|
168
|
-
// Restore original branch name
|
|
169
|
-
this.branchName = originalBranch;
|
|
170
|
-
|
|
171
|
-
// Atomically replace old branch with new one
|
|
172
|
-
await this.replaceBranch(tempBranch, originalBranch);
|
|
173
|
-
|
|
174
|
-
this.logger.log(`🎉 Safely replaced cache branch with ${uploadedCount} file(s)`);
|
|
175
|
-
return uploadedCount;
|
|
176
|
-
} catch (error) {
|
|
177
|
-
// Restore original branch name
|
|
178
|
-
this.branchName = originalBranch;
|
|
179
|
-
|
|
180
|
-
// Try to clean up temp branch if it exists
|
|
181
|
-
try {
|
|
182
|
-
await this.deleteBranch(tempBranch);
|
|
183
|
-
} catch (e) {
|
|
184
|
-
// Ignore cleanup errors
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
this.logger.error(`❌ Failed to recreate cache branch, original remains intact`);
|
|
188
|
-
throw error;
|
|
189
|
-
}
|
|
155
|
+
this.logger.log(`🔄 Force recreating cache branch with clean files...`);
|
|
156
|
+
const uploadedCount = await this.uploadFilesViaGit(files, true, readme);
|
|
157
|
+
this.logger.log(`🎉 Recreated cache branch with ${uploadedCount} file(s)`);
|
|
158
|
+
return uploadedCount;
|
|
190
159
|
} else {
|
|
191
160
|
// Normal update
|
|
192
161
|
await this.ensureBranchExists(readme);
|
|
193
162
|
const uploadedCount = await this.uploadFilesViaGit(files, false, readme);
|
|
194
163
|
|
|
195
|
-
|
|
164
|
+
if (uploadedCount > 0) {
|
|
165
|
+
this.logger.log(`🎉 Pushed ${uploadedCount} file(s) to cache branch`);
|
|
166
|
+
}
|
|
196
167
|
return uploadedCount;
|
|
197
168
|
}
|
|
198
169
|
}
|
|
@@ -399,87 +370,117 @@ class GitHubCache {
|
|
|
399
370
|
// Upload files using git commands (much faster for multiple files)
|
|
400
371
|
async uploadFilesViaGit(files, forceRecreate = false, readme = null) {
|
|
401
372
|
const { execSync } = require('child_process');
|
|
402
|
-
const tempDir = path.join(this.cacheDir, '../git-temp');
|
|
403
373
|
|
|
404
374
|
this.logger.log(`🚀 Using fast git upload for ${files.length} files`);
|
|
405
375
|
|
|
406
376
|
try {
|
|
407
|
-
//
|
|
408
|
-
|
|
409
|
-
jetpack.dir(tempDir);
|
|
377
|
+
// Work directly in the cache directory
|
|
378
|
+
const gitDir = path.join(this.cacheDir, '.git');
|
|
410
379
|
|
|
411
380
|
if (forceRecreate) {
|
|
412
|
-
// For force recreate,
|
|
413
|
-
this.logger.log(`🆕 Initializing fresh repository...`);
|
|
414
|
-
|
|
415
|
-
execSync(
|
|
416
|
-
execSync(`git
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
381
|
+
// For force recreate, remove git dir and init fresh
|
|
382
|
+
this.logger.log(`🆕 Initializing fresh repository in ${this.cacheDir}...`);
|
|
383
|
+
jetpack.remove(gitDir);
|
|
384
|
+
execSync('git init', { cwd: this.cacheDir, stdio: 'ignore' });
|
|
385
|
+
execSync(`git remote add origin https://${process.env.GH_TOKEN}@github.com/${this.owner}/${this.repo}.git`, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
386
|
+
execSync(`git checkout -b ${this.branchName}`, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
387
|
+
} else if (!jetpack.exists(gitDir)) {
|
|
388
|
+
// If no git dir exists, clone the branch
|
|
389
|
+
this.logger.log(`📥 Initializing git in cache directory...`);
|
|
390
|
+
|
|
391
|
+
// Save current files temporarily
|
|
392
|
+
const tempBackup = path.join(path.dirname(this.cacheDir), `${path.basename(this.cacheDir)}-backup-${Date.now()}`);
|
|
393
|
+
if (jetpack.exists(this.cacheDir)) {
|
|
394
|
+
jetpack.move(this.cacheDir, tempBackup);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Clone the branch
|
|
420
398
|
execSync(
|
|
421
|
-
`git clone --depth 1 --branch ${this.branchName} https://${process.env.GH_TOKEN}@github.com/${this.owner}/${this.repo}.git
|
|
422
|
-
{
|
|
399
|
+
`git clone --depth 1 --branch ${this.branchName} https://${process.env.GH_TOKEN}@github.com/${this.owner}/${this.repo}.git "${this.cacheDir}"`,
|
|
400
|
+
{ stdio: 'ignore' }
|
|
423
401
|
);
|
|
402
|
+
|
|
403
|
+
// Restore backed up files (overwriting cloned files)
|
|
404
|
+
if (jetpack.exists(tempBackup)) {
|
|
405
|
+
jetpack.copy(tempBackup, this.cacheDir, { overwrite: true });
|
|
406
|
+
jetpack.remove(tempBackup);
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
// Git dir exists, just pull latest
|
|
410
|
+
this.logger.log(`📥 Pulling latest changes...`);
|
|
411
|
+
try {
|
|
412
|
+
execSync('git fetch origin ' + this.branchName, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
413
|
+
execSync('git reset --hard origin/' + this.branchName, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
414
|
+
} catch (e) {
|
|
415
|
+
// If pull fails, continue anyway - we'll force push if needed
|
|
416
|
+
this.logger.warn('⚠️ Pull failed, will force push if needed');
|
|
417
|
+
}
|
|
424
418
|
}
|
|
425
419
|
|
|
426
420
|
// Add README if provided
|
|
421
|
+
let readmeChanged = false;
|
|
427
422
|
if (readme) {
|
|
428
|
-
const readmePath = path.join(
|
|
429
|
-
jetpack.
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Copy all files to the temp directory
|
|
433
|
-
let copiedCount = 0;
|
|
434
|
-
for (const filePath of files) {
|
|
435
|
-
const fullPath = path.resolve(filePath);
|
|
436
|
-
if (!jetpack.exists(fullPath)) {
|
|
437
|
-
continue;
|
|
438
|
-
}
|
|
423
|
+
const readmePath = path.join(this.cacheDir, 'README.md');
|
|
424
|
+
const existingReadme = jetpack.exists(readmePath) ? jetpack.read(readmePath) : '';
|
|
439
425
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
continue;
|
|
426
|
+
if (existingReadme !== readme) {
|
|
427
|
+
this.logger.log('📝 README content has changed, updating...');
|
|
428
|
+
readmeChanged = true;
|
|
444
429
|
}
|
|
445
430
|
|
|
446
|
-
|
|
447
|
-
jetpack.copy(fullPath, destPath, { overwrite: true });
|
|
448
|
-
copiedCount++;
|
|
431
|
+
jetpack.write(readmePath, readme);
|
|
449
432
|
}
|
|
450
433
|
|
|
451
434
|
// Check if there are changes
|
|
452
|
-
const status = execSync('git status --porcelain', { cwd:
|
|
435
|
+
const status = execSync('git status --porcelain', { cwd: this.cacheDir }).toString();
|
|
453
436
|
if (!status.trim()) {
|
|
454
|
-
this.logger.log('⏭️ No changes to commit');
|
|
437
|
+
this.logger.log('⏭️ No changes to commit (including README)');
|
|
455
438
|
return 0;
|
|
456
439
|
}
|
|
457
440
|
|
|
441
|
+
// Log what changed
|
|
442
|
+
const changedFiles = status.trim().split('\n').length;
|
|
443
|
+
if (readmeChanged && changedFiles === 1) {
|
|
444
|
+
this.logger.log('📄 Only README.md has changed, committing update...');
|
|
445
|
+
} else if (readmeChanged) {
|
|
446
|
+
this.logger.log(`📄 README.md and ${changedFiles - 1} cache files have changed`);
|
|
447
|
+
} else {
|
|
448
|
+
this.logger.log(`📝 ${changedFiles} files have changed`);
|
|
449
|
+
}
|
|
450
|
+
|
|
458
451
|
// Add all changes
|
|
459
|
-
this.logger.log(`📝 Staging
|
|
460
|
-
execSync('git add -A', { cwd:
|
|
452
|
+
this.logger.log(`📝 Staging changes...`);
|
|
453
|
+
execSync('git add -A', { cwd: this.cacheDir, stdio: 'ignore' });
|
|
454
|
+
|
|
455
|
+
// Create commit message based on what changed
|
|
456
|
+
let commitMessage;
|
|
457
|
+
if (readmeChanged && changedFiles === 1) {
|
|
458
|
+
commitMessage = '📊 Update cache statistics in README';
|
|
459
|
+
} else if (readmeChanged) {
|
|
460
|
+
commitMessage = `📦 Update cache: ${changedFiles - 1} files + README stats`;
|
|
461
|
+
} else {
|
|
462
|
+
commitMessage = `📦 Update cache: ${changedFiles} files`;
|
|
463
|
+
}
|
|
461
464
|
|
|
462
465
|
// Commit
|
|
463
466
|
execSync(
|
|
464
|
-
`git -c user.name="GitHub Actions" -c user.email="actions@github.com" commit -m "
|
|
465
|
-
{ cwd:
|
|
467
|
+
`git -c user.name="GitHub Actions" -c user.email="actions@github.com" commit -m "${commitMessage}"`,
|
|
468
|
+
{ cwd: this.cacheDir, stdio: 'ignore' }
|
|
466
469
|
);
|
|
467
470
|
|
|
468
471
|
// Push
|
|
469
472
|
this.logger.log(`📤 Pushing to GitHub...`);
|
|
470
|
-
|
|
471
|
-
execSync('git push
|
|
472
|
-
}
|
|
473
|
-
|
|
473
|
+
try {
|
|
474
|
+
execSync('git push origin ' + this.branchName, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
475
|
+
} catch (e) {
|
|
476
|
+
// If normal push fails, try force push
|
|
477
|
+
this.logger.warn('⚠️ Normal push failed, attempting force push...');
|
|
478
|
+
execSync('git push --force origin ' + this.branchName, { cwd: this.cacheDir, stdio: 'ignore' });
|
|
474
479
|
}
|
|
475
480
|
|
|
476
|
-
|
|
477
|
-
jetpack.remove(tempDir);
|
|
478
|
-
|
|
479
|
-
return copiedCount;
|
|
481
|
+
return changedFiles;
|
|
480
482
|
} catch (error) {
|
|
481
483
|
this.logger.error(`❌ Git command failed: ${error.message}`);
|
|
482
|
-
jetpack.remove(tempDir);
|
|
483
484
|
throw error; // No fallback - git is required
|
|
484
485
|
}
|
|
485
486
|
}
|
|
@@ -587,6 +588,25 @@ This branch stores ${this.description}.
|
|
|
587
588
|
}
|
|
588
589
|
}
|
|
589
590
|
|
|
591
|
+
// Add language breakdown for translation
|
|
592
|
+
if (stats.languageBreakdown && stats.languageBreakdown.length > 0) {
|
|
593
|
+
readme += `
|
|
594
|
+
## Language Breakdown
|
|
595
|
+
|
|
596
|
+
`;
|
|
597
|
+
stats.languageBreakdown.forEach(lang => {
|
|
598
|
+
const cacheRate = lang.total > 0 ? ((lang.fromCache / lang.total) * 100).toFixed(1) : 0;
|
|
599
|
+
readme += `### ${lang.language.toUpperCase()}\n`;
|
|
600
|
+
readme += `- **Total Files:** ${Math.round(lang.total)}\n`;
|
|
601
|
+
readme += `- **From Cache:** ${lang.fromCache} (${cacheRate}%)\n`;
|
|
602
|
+
readme += `- **Newly Translated:** ${lang.newlyTranslated}\n`;
|
|
603
|
+
if (lang.failed > 0) {
|
|
604
|
+
readme += `- **Failed:** ${lang.failed}\n`;
|
|
605
|
+
}
|
|
606
|
+
readme += '\n';
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
590
610
|
// Add token usage and costs for translation
|
|
591
611
|
if (stats.tokenUsage) {
|
|
592
612
|
const { inputTokens, outputTokens, totalTokens, inputCost, outputCost, totalCost } = stats.tokenUsage;
|
|
@@ -67,12 +67,11 @@ const delay = 250;
|
|
|
67
67
|
// Bundle naming configuration
|
|
68
68
|
const bundleNaming = {
|
|
69
69
|
// Files that should have stable (non-hashed) names
|
|
70
|
-
stable:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
},
|
|
70
|
+
stable: [
|
|
71
|
+
/^main$/, // Main bundle
|
|
72
|
+
/^service-worker$/, // Service worker
|
|
73
|
+
/^modules\//, // All module files get stable names
|
|
74
|
+
],
|
|
76
75
|
// Special output paths (relative to dist/assets/js/)
|
|
77
76
|
specialPaths: {
|
|
78
77
|
'service-worker': '../../service-worker.js'
|
|
@@ -221,13 +220,7 @@ const settings = {
|
|
|
221
220
|
|
|
222
221
|
// Helper function to determine if a bundle should have a stable name
|
|
223
222
|
function shouldHaveStableName(name) {
|
|
224
|
-
|
|
225
|
-
if (bundleNaming.stable.exact.includes(name)) {
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Check patterns
|
|
230
|
-
return bundleNaming.stable.patterns.some(pattern => pattern.test(name));
|
|
223
|
+
return bundleNaming.stable.some(pattern => pattern.test(name));
|
|
231
224
|
}
|
|
232
225
|
|
|
233
226
|
// Task
|
|
@@ -360,37 +353,18 @@ function updateEntryPoints(inputArray) {
|
|
|
360
353
|
|
|
361
354
|
// Update from src
|
|
362
355
|
const entries = files.reduce((acc, file) => {
|
|
363
|
-
|
|
364
|
-
const root = isProject ? rootPathProject : rootPathPackage;
|
|
365
|
-
const relativePath = path.relative(root, file).replace(/\\/g, '/').replace(/\.js$/, '');
|
|
366
|
-
|
|
367
|
-
// Remove known base paths
|
|
368
|
-
let name = relativePath
|
|
369
|
-
.replace(/^dist\/assets\/js\//, '')
|
|
370
|
-
.replace(/^src\/assets\/js\//, '')
|
|
371
|
-
.replace(/^src\//, '');
|
|
356
|
+
let name;
|
|
372
357
|
|
|
373
358
|
// Determine naming based on file type
|
|
374
|
-
if (
|
|
375
|
-
|
|
376
|
-
name += isProject ? '.project' : '.main';
|
|
377
|
-
} else if (name.includes('modules/')) {
|
|
378
|
-
// Modules: keep the full path structure for clarity
|
|
379
|
-
// This ensures modules/redirect becomes modules/redirect
|
|
380
|
-
// and modules/analytics/tracker becomes modules/analytics/tracker
|
|
359
|
+
if (file.includes('/assets/js/modules/')) {
|
|
360
|
+
name = file.split('/assets/js/')[1];
|
|
381
361
|
} else {
|
|
382
362
|
// Everything else: just use the base filename
|
|
383
|
-
name = path.basename(
|
|
363
|
+
name = path.basename(file);
|
|
384
364
|
}
|
|
385
365
|
|
|
386
|
-
//
|
|
387
|
-
|
|
388
|
-
// file.includes('assets/js/pages/')
|
|
389
|
-
// || file.includes('assets/js/global.js')
|
|
390
|
-
// || file.includes('assets/themes/')
|
|
391
|
-
// ) {
|
|
392
|
-
// return acc;
|
|
393
|
-
// }
|
|
366
|
+
// Strip .js extension
|
|
367
|
+
name = name.replace(/\.js$/, '');
|
|
394
368
|
|
|
395
369
|
// Update entry points
|
|
396
370
|
acc[name] = file;
|