···11+/**
22+ * Test script for the updater's change statistics functionality
33+ */
44+const updater = require('./utils/updater');
55+66+// Log test title
77+console.log('=== Testing Updater Change Statistics ===');
88+99+// Test with different commit ranges
1010+async function runTests() {
1111+ // Test with the most recent commit
1212+ await updater.testChangeStats(1);
1313+1414+ // Test with the last 3 commits if they exist
1515+ await updater.testChangeStats(3);
1616+1717+ // For testing the actual update functionality:
1818+ // Uncomment the following line to test the manual update with real fetching
1919+ // const updateResult = await updater.manualUpdate();
2020+ // console.log('Update result:', updateResult ? 'Updates applied' : 'No updates available');
2121+}
2222+2323+runTests().then(() => {
2424+ console.log('Tests completed');
2525+});
+153-4
utils/updater.js
···57575858 // Fetch latest changes from origin without merging
5959 const fetchResult = await execAsync('git fetch origin main');
6060- console.log('Fetch result:', fetchResult.stdout || 'No output');
6060+ if (fetchResult.stdout) {
6161+ console.log(fetchResult.stdout);
6262+ }
61636264 // Check if there are any changes to pull
6365 const statusResult = await execAsync('git rev-list HEAD..origin/main --count');
···6668 if (changeCount > 0) {
6769 console.log(`Found ${changeCount} new commit(s), pulling updates...`);
68707171+ // Save current HEAD for comparison after pull
7272+ const oldHead = await execAsync('git rev-parse HEAD');
7373+ const oldHeadHash = oldHead.stdout.trim();
7474+6975 // Pull the changes
7076 const pullResult = await execAsync('git pull origin main');
7171- console.log('Pull result:', pullResult.stdout);
7777+ console.log(pullResult.stdout);
7878+7979+ // Get the new HEAD
8080+ const newHead = await execAsync('git rev-parse HEAD');
8181+ const newHeadHash = newHead.stdout.trim();
8282+8383+ // Show change statistics
8484+ if (oldHeadHash !== newHeadHash) {
8585+ const changeStats = await this.getChangeStats(oldHeadHash, newHeadHash);
8686+ if (changeStats) {
8787+ console.log(changeStats);
8888+ }
8989+ }
72907391 // Restart the bot using PM2
7492 console.log('Restarting bot with PM2...');
···83101 }
8410285103 /**
104104+ * Get statistics about changes between current and updated code
105105+ * @param {string} fromRef - Starting reference (e.g., HEAD)
106106+ * @param {string} toRef - Ending reference (e.g., origin/main)
107107+ * @returns {Promise<string>} Formatted string showing changes
108108+ */
109109+ async getChangeStats(fromRef, toRef) {
110110+ try {
111111+ // Get the abbreviated hashes for display
112112+ const shortFromRef = await execAsync(`git rev-parse --short ${fromRef}`);
113113+ const shortToRef = await execAsync(`git rev-parse --short ${toRef}`);
114114+ const fromRefShort = shortFromRef.stdout.trim();
115115+ const toRefShort = shortToRef.stdout.trim();
116116+117117+ // Show what we're updating from/to
118118+ let output = `Updating ${fromRefShort}..${toRefShort}\n`;
119119+120120+ // Add the fast-forward indicator that Git shows
121121+ output += "Fast-forward\n";
122122+123123+ // Use git diff --stat which shows the files changed and +/- indicators
124124+ // Use --numstat to get the raw numbers for insertions and deletions
125125+ const numstatResult = await execAsync(`git diff --numstat ${fromRef} ${toRef}`);
126126+ const numstatLines = numstatResult.stdout.trim().split('\n').filter(Boolean);
127127+128128+ // Track total insertions and deletions
129129+ let totalInsertions = 0;
130130+ let totalDeletions = 0;
131131+132132+ // Process each line to format it like Git's output
133133+ const fileChanges = [];
134134+ for (const line of numstatLines) {
135135+ const [insertions, deletions, path] = line.split('\t');
136136+137137+ // Skip binary files or files with unusual output
138138+ if (insertions === '-' || deletions === '-') continue;
139139+140140+ const insCount = parseInt(insertions, 10) || 0;
141141+ const delCount = parseInt(deletions, 10) || 0;
142142+143143+ totalInsertions += insCount;
144144+ totalDeletions += delCount;
145145+146146+ // Format file name with change counts
147147+ const plusMinus = '+'.repeat(Math.min(insCount, 70)) + '-'.repeat(Math.min(delCount, 70));
148148+ const changeStats = `${plusMinus}`;
149149+150150+ // Calculate the proper width for the file path (similar to Git's output)
151151+ const maxWidth = 80; // approximate width for console
152152+ const reserved = 10; // space reserved for the stats part
153153+ const width = Math.min(path.length, maxWidth - reserved - changeStats.length);
154154+ const truncatedPath = path.length > width ? path.substring(0, width) : path;
155155+ const paddedPath = truncatedPath.padEnd(width);
156156+157157+ fileChanges.push(`${paddedPath} | ${changeStats}`);
158158+ }
159159+160160+ // Add each file's changes to the output
161161+ fileChanges.forEach(fc => {
162162+ output += ` ${fc}\n`;
163163+ });
164164+165165+ // Add the summary line
166166+ const filesChanged = numstatLines.length;
167167+ output += `\n ${filesChanged} file${filesChanged !== 1 ? 's' : ''} changed, `;
168168+ output += `${totalInsertions} insertion${totalInsertions !== 1 ? 's' : ''}(+), `;
169169+ output += `${totalDeletions} deletion${totalDeletions !== 1 ? 's' : ''}(-)`;
170170+171171+ return output;
172172+ } catch (error) {
173173+ console.error('Error getting change stats:', error);
174174+ return '';
175175+ }
176176+ }
177177+178178+ /**
86179 * Check if an update is available (without applying it)
87180 * @returns {Promise<boolean>} True if updates are available
88181 */
···104197 */
105198 async manualUpdate() {
106199 try {
107107- await execAsync('git fetch origin main');
200200+ // Fetch changes from remote
201201+ const fetchResult = await execAsync('git fetch origin main');
202202+ if (fetchResult.stdout) {
203203+ console.log(fetchResult.stdout);
204204+ }
205205+108206 const statusResult = await execAsync('git rev-list HEAD..origin/main --count');
109207 const changeCount = parseInt(statusResult.stdout.trim(), 10);
110208111209 if (changeCount > 0) {
210210+ // Save current HEAD for comparison
211211+ const oldHead = await execAsync('git rev-parse HEAD');
212212+ const oldHeadHash = oldHead.stdout.trim();
213213+214214+ // Pull the changes
112215 const pullResult = await execAsync('git pull origin main');
113113- console.log('Manual update result:', pullResult.stdout);
216216+ console.log(pullResult.stdout);
217217+218218+ // Get the new HEAD
219219+ const newHead = await execAsync('git rev-parse HEAD');
220220+ const newHeadHash = newHead.stdout.trim();
221221+222222+ // Show change statistics
223223+ if (oldHeadHash !== newHeadHash) {
224224+ const changeStats = await this.getChangeStats(oldHeadHash, newHeadHash);
225225+ if (changeStats) {
226226+ console.log(changeStats);
227227+ }
228228+ }
229229+114230 return true;
115231 }
116232 return false;
117233 } catch (error) {
118234 console.error('Error during manual update:', error);
119235 return false;
236236+ }
237237+ }
238238+239239+ /**
240240+ * Test function to display change statistics between commits
241241+ * @param {number} [commitRange=1] - Number of commits to go back from HEAD
242242+ * @returns {Promise<void>}
243243+ */
244244+ async testChangeStats(commitRange = 1) {
245245+ try {
246246+ console.log(`Testing change statistics for the last ${commitRange} commit(s)...`);
247247+248248+ // Get the current HEAD
249249+ const head = await execAsync('git rev-parse HEAD');
250250+ const headHash = head.stdout.trim();
251251+252252+ // Get the commit before HEAD~n
253253+ const prevHead = await execAsync(`git rev-parse HEAD~${commitRange}`);
254254+ const prevHeadHash = prevHead.stdout.trim();
255255+256256+ console.log(`Comparing changes between ${prevHeadHash.substring(0, 7)} and ${headHash.substring(0, 7)}`);
257257+258258+ // Get and display the change statistics
259259+ const changeStats = await this.getChangeStats(prevHeadHash, headHash);
260260+ if (changeStats) {
261261+ console.log('\n--- Change Statistics ---');
262262+ console.log(changeStats);
263263+ console.log('------------------------\n');
264264+ } else {
265265+ console.log('No change statistics available');
266266+ }
267267+ } catch (error) {
268268+ console.error('Error testing change stats:', error);
120269 }
121270 }
122271}