Skip to content

Commit a933b81

Browse files
authored
fix: retranslation with run command (#1208)
* fix: use initial checksums for all retranslation buckets * chore: add changeset * chore: fix formatting
1 parent f3d4987 commit a933b81

4 files changed

Lines changed: 93 additions & 22 deletions

File tree

.changeset/six-forks-bathe.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"lingo.dev": patch
3+
---
4+
5+
Fix run retranslation with run command

packages/cli/src/cli/cmd/run/_types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export type CmdRunContext = {
1818
export type CmdRunTaskResult = {
1919
status: "success" | "error" | "skipped";
2020
error?: Error;
21+
pathPattern?: string;
22+
sourceLocale?: string;
23+
targetLocale?: string;
2124
};
2225

2326
export type CmdRunTask = {

packages/cli/src/cli/cmd/run/execute.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,24 @@ export default async function execute(input: CmdRunContext) {
3434
title: `Processing localization tasks ${chalk.dim(
3535
`(tasks: ${input.tasks.length}, concurrency: ${effectiveConcurrency})`,
3636
)}`,
37-
task: (ctx, task) => {
37+
task: async (ctx, task) => {
3838
if (input.tasks.length < 1) {
3939
task.title = `Skipping, nothing to localize.`;
4040
task.skip();
4141
return;
4242
}
4343

44+
// Preload checksums for all unique bucket path patterns before starting any workers
45+
const initialChecksumsMap = new Map<string, Record<string, string>>();
46+
const uniqueBucketPatterns = _.uniq(
47+
ctx.tasks.map((t) => t.bucketPathPattern),
48+
);
49+
for (const bucketPathPattern of uniqueBucketPatterns) {
50+
const deltaProcessor = createDeltaProcessor(bucketPathPattern);
51+
const checksums = await deltaProcessor.loadChecksums();
52+
initialChecksumsMap.set(bucketPathPattern, checksums);
53+
}
54+
4455
const i18nLimiter = pLimit(effectiveConcurrency);
4556
const ioLimiter = pLimit(1);
4657
const workersCount = effectiveConcurrency;
@@ -56,6 +67,7 @@ export default async function execute(input: CmdRunContext) {
5667
assignedTasks,
5768
ioLimiter,
5869
i18nLimiter,
70+
initialChecksumsMap,
5971
onDone() {
6072
task.title = createExecutionProgressMessage(ctx);
6173
},
@@ -140,6 +152,7 @@ function createWorkerTask(args: {
140152
ioLimiter: LimitFunction;
141153
i18nLimiter: LimitFunction;
142154
onDone: () => void;
155+
initialChecksumsMap: Map<string, Record<string, string>>;
143156
}): ListrTask {
144157
return {
145158
title: "Initializing...",
@@ -154,6 +167,10 @@ function createWorkerTask(args: {
154167
assignedTask.bucketPathPattern,
155168
);
156169

170+
// Get initial checksums from the preloaded map
171+
const initialChecksums =
172+
args.initialChecksumsMap.get(assignedTask.bucketPathPattern) || {};
173+
157174
const taskResult = await args.i18nLimiter(async () => {
158175
try {
159176
const sourceData = await bucketLoader.pull(
@@ -163,11 +180,10 @@ function createWorkerTask(args: {
163180
const targetData = await bucketLoader.pull(
164181
assignedTask.targetLocale,
165182
);
166-
const checksums = await deltaProcessor.loadChecksums();
167183
const delta = await deltaProcessor.calculateDelta({
168184
sourceData,
169185
targetData,
170-
checksums,
186+
checksums: initialChecksums,
171187
});
172188

173189
const processableData = _.chain(sourceData)
@@ -193,7 +209,12 @@ function createWorkerTask(args: {
193209
// re-push in case some of the unlocalizable / meta data changed
194210
await bucketLoader.push(assignedTask.targetLocale, targetData);
195211
});
196-
return { status: "skipped" } satisfies CmdRunTaskResult;
212+
return {
213+
status: "skipped",
214+
pathPattern: assignedTask.bucketPathPattern,
215+
sourceLocale: assignedTask.sourceLocale,
216+
targetLocale: assignedTask.targetLocale,
217+
} satisfies CmdRunTaskResult;
197218
}
198219

199220
const relevantHints = _.pick(hints, Object.keys(processableData));
@@ -268,11 +289,19 @@ function createWorkerTask(args: {
268289
}
269290
});
270291

271-
return { status: "success" } satisfies CmdRunTaskResult;
292+
return {
293+
status: "success",
294+
pathPattern: assignedTask.bucketPathPattern,
295+
sourceLocale: assignedTask.sourceLocale,
296+
targetLocale: assignedTask.targetLocale,
297+
} satisfies CmdRunTaskResult;
272298
} catch (error) {
273299
return {
274300
status: "error",
275301
error: error as Error,
302+
pathPattern: assignedTask.bucketPathPattern,
303+
sourceLocale: assignedTask.sourceLocale,
304+
targetLocale: assignedTask.targetLocale,
276305
} satisfies CmdRunTaskResult;
277306
}
278307
});

packages/cli/src/cli/utils/ui.ts

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,28 +77,62 @@ export async function pauseIfDebug(debug: boolean) {
7777
export async function renderSummary(results: Map<any, any>) {
7878
console.log(chalk.hex(colors.green)("[Done]"));
7979

80-
const skippedTasksCount = Array.from(results.values()).filter(
80+
const skippedResults = Array.from(results.values()).filter(
8181
(r) => r.status === "skipped",
82-
).length;
83-
console.log(`• ${chalk.hex(colors.yellow)(skippedTasksCount)} from cache`);
84-
85-
const succeededTasksCount = Array.from(results.values()).filter(
82+
);
83+
const succeededResults = Array.from(results.values()).filter(
8684
(r) => r.status === "success",
87-
).length;
88-
console.log(`• ${chalk.hex(colors.yellow)(succeededTasksCount)} processed`);
89-
90-
const failedTasksCount = Array.from(results.values()).filter(
85+
);
86+
const failedResults = Array.from(results.values()).filter(
9187
(r) => r.status === "error",
92-
).length;
93-
console.log(`• ${chalk.hex(colors.yellow)(failedTasksCount)} failed`);
88+
);
89+
90+
console.log(
91+
`• ${chalk.hex(colors.yellow)(skippedResults.length)} from cache`,
92+
);
93+
console.log(
94+
`• ${chalk.hex(colors.yellow)(succeededResults.length)} processed`,
95+
);
96+
console.log(`• ${chalk.hex(colors.yellow)(failedResults.length)} failed`);
97+
98+
// Show processed files
99+
if (succeededResults.length > 0) {
100+
console.log(chalk.hex(colors.green)("\n[Processed Files]"));
101+
for (const result of succeededResults) {
102+
const displayPath =
103+
result.pathPattern?.replace("[locale]", result.targetLocale) ||
104+
"unknown";
105+
console.log(
106+
` ✓ ${chalk.dim(displayPath)} ${chalk.hex(colors.yellow)(`(${result.sourceLocale}${result.targetLocale})`)}`,
107+
);
108+
}
109+
}
94110

95-
if (failedTasksCount > 0) {
96-
console.log(chalk.hex(colors.orange)("\n[Failed]"));
97-
for (const result of Array.from(results.values()).filter(
98-
(r) => r.status === "error",
99-
)) {
111+
// Show cached files
112+
if (skippedResults.length > 0) {
113+
console.log(chalk.hex(colors.blue)("\n[Cached Files]"));
114+
for (const result of skippedResults) {
115+
const displayPath =
116+
result.pathPattern?.replace("[locale]", result.targetLocale) ||
117+
"unknown";
118+
console.log(
119+
` ⚡ ${chalk.dim(displayPath)} ${chalk.hex(colors.yellow)(`(${result.sourceLocale}${result.targetLocale})`)}`,
120+
);
121+
}
122+
}
123+
124+
// Show failed files
125+
if (failedResults.length > 0) {
126+
console.log(chalk.hex(colors.orange)("\n[Failed Files]"));
127+
for (const result of failedResults) {
128+
const displayPath =
129+
result.pathPattern?.replace("[locale]", result.targetLocale) ||
130+
"unknown";
131+
console.log(
132+
` ❌ ${chalk.dim(displayPath)} ${chalk.hex(colors.yellow)(`(${result.sourceLocale}${result.targetLocale})`)}`,
133+
);
100134
console.log(
101-
`${chalk.hex(colors.white)(String(result.error.message))}\n`,
135+
` ${chalk.hex(colors.white)(String(result.error?.message || "Unknown error"))}`,
102136
);
103137
}
104138
}

0 commit comments

Comments
 (0)