Stijnus
commited on
Commit
·
f50ebc6
1
Parent(s):
3dd3faf
Update api.update.ts
Browse files- app/routes/api.update.ts +79 -18
app/routes/api.update.ts
CHANGED
@@ -19,6 +19,9 @@ interface UpdateProgress {
|
|
19 |
additions?: number;
|
20 |
deletions?: number;
|
21 |
commitMessages?: string[];
|
|
|
|
|
|
|
22 |
};
|
23 |
}
|
24 |
|
@@ -83,41 +86,95 @@ export const action: ActionFunction = async ({ request }) => {
|
|
83 |
throw new Error(`Remote branch 'origin/${defaultBranch}' not found. Please push your changes first.`);
|
84 |
}
|
85 |
|
86 |
-
// Get current commit hash
|
87 |
const { stdout: currentCommit } = await execAsync('git rev-parse HEAD');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
// Initialize variables
|
90 |
let changedFiles: string[] = [];
|
91 |
let commitMessages: string[] = [];
|
92 |
let stats: RegExpMatchArray | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
-
|
|
|
|
|
|
|
95 |
try {
|
96 |
-
const { stdout: diffOutput } = await execAsync(
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
103 |
});
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
107 |
|
108 |
-
// Get commit messages
|
109 |
try {
|
110 |
const { stdout: logOutput } = await execAsync(
|
111 |
-
`git log --oneline ${currentCommit.trim()}
|
112 |
);
|
113 |
commitMessages = logOutput.split('\n').filter(Boolean);
|
114 |
} catch {
|
115 |
// Handle silently - empty commitMessages array will be used
|
116 |
}
|
117 |
|
118 |
-
// Get diff stats
|
119 |
try {
|
120 |
-
const { stdout: diffStats } = await execAsync(
|
|
|
|
|
121 |
stats = diffStats.match(
|
122 |
/(\d+) files? changed(?:, (\d+) insertions?\\(\\+\\))?(?:, (\d+) deletions?\\(-\\))?/,
|
123 |
);
|
@@ -125,25 +182,29 @@ export const action: ActionFunction = async ({ request }) => {
|
|
125 |
// Handle silently - null stats will be used
|
126 |
}
|
127 |
|
128 |
-
// If no changes detected
|
129 |
if (!stats && changedFiles.length === 0) {
|
130 |
sendProgress({
|
131 |
stage: 'complete',
|
132 |
-
message:
|
133 |
progress: 100,
|
134 |
});
|
135 |
return;
|
136 |
}
|
137 |
|
|
|
138 |
sendProgress({
|
139 |
stage: 'fetch',
|
140 |
-
message:
|
141 |
progress: 100,
|
142 |
details: {
|
143 |
changedFiles,
|
144 |
additions: stats?.[2] ? parseInt(stats[2]) : 0,
|
145 |
deletions: stats?.[3] ? parseInt(stats[3]) : 0,
|
146 |
commitMessages,
|
|
|
|
|
|
|
147 |
},
|
148 |
});
|
149 |
|
|
|
19 |
additions?: number;
|
20 |
deletions?: number;
|
21 |
commitMessages?: string[];
|
22 |
+
totalSize?: string;
|
23 |
+
currentCommit?: string;
|
24 |
+
remoteCommit?: string;
|
25 |
};
|
26 |
}
|
27 |
|
|
|
86 |
throw new Error(`Remote branch 'origin/${defaultBranch}' not found. Please push your changes first.`);
|
87 |
}
|
88 |
|
89 |
+
// Get current commit hash and remote commit hash
|
90 |
const { stdout: currentCommit } = await execAsync('git rev-parse HEAD');
|
91 |
+
const { stdout: remoteCommit } = await execAsync(`git rev-parse origin/${defaultBranch}`);
|
92 |
+
|
93 |
+
// If we're on the same commit, no update is available
|
94 |
+
if (currentCommit.trim() === remoteCommit.trim()) {
|
95 |
+
sendProgress({
|
96 |
+
stage: 'complete',
|
97 |
+
message: 'No updates available. You are on the latest version.',
|
98 |
+
progress: 100,
|
99 |
+
});
|
100 |
+
return;
|
101 |
+
}
|
102 |
|
103 |
// Initialize variables
|
104 |
let changedFiles: string[] = [];
|
105 |
let commitMessages: string[] = [];
|
106 |
let stats: RegExpMatchArray | null = null;
|
107 |
+
let totalSizeInBytes = 0;
|
108 |
+
|
109 |
+
// Format size for display
|
110 |
+
const formatSize = (bytes: number) => {
|
111 |
+
if (bytes === 0) {
|
112 |
+
return '0 B';
|
113 |
+
}
|
114 |
+
|
115 |
+
const k = 1024;
|
116 |
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
117 |
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
118 |
|
119 |
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
120 |
+
};
|
121 |
+
|
122 |
+
// Get list of changed files and their sizes
|
123 |
try {
|
124 |
+
const { stdout: diffOutput } = await execAsync(
|
125 |
+
`git diff --name-status ${currentCommit.trim()}..${remoteCommit.trim()}`,
|
126 |
+
);
|
127 |
+
const files = diffOutput.split('\n').filter(Boolean);
|
128 |
+
|
129 |
+
if (files.length === 0) {
|
130 |
+
sendProgress({
|
131 |
+
stage: 'complete',
|
132 |
+
message: `No file changes detected between your version and origin/${defaultBranch}. You might be on a different branch.`,
|
133 |
+
progress: 100,
|
134 |
});
|
135 |
+
return;
|
136 |
+
}
|
137 |
+
|
138 |
+
// Get size information for each changed file
|
139 |
+
for (const line of files) {
|
140 |
+
const [status, file] = line.split('\t');
|
141 |
+
|
142 |
+
if (status !== 'D') {
|
143 |
+
// Skip deleted files
|
144 |
+
try {
|
145 |
+
const { stdout: sizeOutput } = await execAsync(`git cat-file -s ${remoteCommit.trim()}:${file}`);
|
146 |
+
const size = parseInt(sizeOutput) || 0;
|
147 |
+
totalSizeInBytes += size;
|
148 |
+
} catch {
|
149 |
+
console.debug(`Could not get size for file: ${file}`);
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
changedFiles = files.map((line) => {
|
155 |
+
const [status, file] = line.split('\t');
|
156 |
+
return `${status === 'M' ? 'Modified' : status === 'A' ? 'Added' : 'Deleted'}: ${file}`;
|
157 |
+
});
|
158 |
+
} catch (err) {
|
159 |
+
console.debug('Failed to get changed files:', err);
|
160 |
+
throw new Error(`Failed to compare changes with origin/${defaultBranch}. Are you on the correct branch?`);
|
161 |
}
|
162 |
|
163 |
+
// Get commit messages between current and remote
|
164 |
try {
|
165 |
const { stdout: logOutput } = await execAsync(
|
166 |
+
`git log --oneline ${currentCommit.trim()}..${remoteCommit.trim()}`,
|
167 |
);
|
168 |
commitMessages = logOutput.split('\n').filter(Boolean);
|
169 |
} catch {
|
170 |
// Handle silently - empty commitMessages array will be used
|
171 |
}
|
172 |
|
173 |
+
// Get diff stats using the specific commits
|
174 |
try {
|
175 |
+
const { stdout: diffStats } = await execAsync(
|
176 |
+
`git diff --shortstat ${currentCommit.trim()}..${remoteCommit.trim()}`,
|
177 |
+
);
|
178 |
stats = diffStats.match(
|
179 |
/(\d+) files? changed(?:, (\d+) insertions?\\(\\+\\))?(?:, (\d+) deletions?\\(-\\))?/,
|
180 |
);
|
|
|
182 |
// Handle silently - null stats will be used
|
183 |
}
|
184 |
|
185 |
+
// If we somehow still have no changes detected
|
186 |
if (!stats && changedFiles.length === 0) {
|
187 |
sendProgress({
|
188 |
stage: 'complete',
|
189 |
+
message: `No changes detected between your version and origin/${defaultBranch}. This might be unexpected - please check your git status.`,
|
190 |
progress: 100,
|
191 |
});
|
192 |
return;
|
193 |
}
|
194 |
|
195 |
+
// We have changes, send the details
|
196 |
sendProgress({
|
197 |
stage: 'fetch',
|
198 |
+
message: `Changes detected on origin/${defaultBranch}`,
|
199 |
progress: 100,
|
200 |
details: {
|
201 |
changedFiles,
|
202 |
additions: stats?.[2] ? parseInt(stats[2]) : 0,
|
203 |
deletions: stats?.[3] ? parseInt(stats[3]) : 0,
|
204 |
commitMessages,
|
205 |
+
totalSize: formatSize(totalSizeInBytes),
|
206 |
+
currentCommit: currentCommit.trim().substring(0, 7),
|
207 |
+
remoteCommit: remoteCommit.trim().substring(0, 7),
|
208 |
},
|
209 |
});
|
210 |
|