Skip to content

Commit a60aa1e

Browse files
ceolinwillvrcprl
andauthored
fix(cli): preserve Language header when pushing translations (#1662)
* fix: preserve Language header when pushing translations * refactor: remove duplicated `currentSection` * refactor: use ternary * refactor: remove unnecessary comments * refactor: rename headers variable * refactor: preserve original comment * refactor: move comments --------- Co-authored-by: Veronica Prilutskaya <[email protected]>
1 parent 2f83d41 commit a60aa1e

File tree

3 files changed

+62
-11
lines changed

3 files changed

+62
-11
lines changed

.changeset/quiet-clowns-bake.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 language header for PO files

packages/cli/src/cli/loaders/po/index.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,45 @@ msgstr "[upd] Apple"
367367
const result = await loader.push("en", updatedData);
368368
expect(result).toEqual(expectedOutput);
369369
});
370+
371+
it("should preserve existing Language header when pushing translations with metadata in first section", async () => {
372+
const loader = createLoader();
373+
const sourceInput = `msgid ""
374+
msgstr ""
375+
"Language: en\\n"
376+
"Content-Type: text/plain; charset=utf-8\\n"
377+
"Content-Transfer-Encoding: 8bit\\n"
378+
"X-Generator: next-intl\\n"
379+
#: hello.py:1
380+
msgid "Hello world"
381+
msgstr "Hello world"`;
382+
383+
const targetInput = `msgid ""
384+
msgstr ""
385+
"Language: es\\n"
386+
"Content-Type: text/plain; charset=utf-8\\n"
387+
"Content-Transfer-Encoding: 8bit\\n"
388+
"X-Generator: next-intl\\n"
389+
#: hello.py:1
390+
msgid "Hello world"
391+
msgstr ""`;
392+
393+
await loader.pull("en", sourceInput);
394+
await loader.pull("es", targetInput);
395+
396+
const updatedData = {
397+
"Hello world": {
398+
singular: "Hola mundo",
399+
plural: null,
400+
},
401+
};
402+
403+
const result = await loader.push("es", updatedData);
404+
405+
expect(result).toContain('"Language: es\\n"');
406+
expect(result).not.toContain('"Language: en\\n"');
407+
expect(result).toContain('msgstr "Hola mundo"');
408+
});
370409
});
371410

372411
function createLoader(params: PoLoaderParams = { multiline: false }) {

packages/cli/src/cli/loaders/po/index.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,32 @@ export function createPoDataLoader(
6363
const contextKey = _.keys(sectionPo.translations)[0];
6464
const entries = sectionPo.translations[contextKey];
6565
const msgid = Object.keys(entries).find((key) => entries[key].msgid);
66-
if (!msgid) {
67-
// If the section is empty, try to find it in the current sections
68-
const currentSection = currentSections.find((cs) => {
69-
const csPo = gettextParser.po.parse(cs);
70-
const csContextKey = _.keys(csPo.translations)[0];
71-
const csEntries = csPo.translations[csContextKey];
72-
const csMsgid = Object.keys(csEntries).find(
73-
(key) => csEntries[key].msgid,
74-
);
75-
return csMsgid === msgid;
76-
});
66+
67+
// If the section is empty, try to find it in the current sections
68+
const currentSection = currentSections.find((cs) => {
69+
const csPo = gettextParser.po.parse(cs);
70+
const csContextKey = _.keys(csPo.translations)[0];
71+
const csEntries = csPo.translations[csContextKey];
72+
const csMsgid = Object.keys(csEntries).find(
73+
(key) => csEntries[key].msgid,
74+
);
75+
return csMsgid === msgid;
76+
});
7777

78+
if (!msgid) {
7879
if (currentSection) {
7980
return currentSection;
8081
}
8182
return section;
8283
}
8384
if (data[msgid]) {
85+
// Preserve headers from the target file
86+
const headers = currentSection
87+
? gettextParser.po.parse(currentSection).headers
88+
: sectionPo.headers;
89+
8490
const updatedPo = _.merge({}, sectionPo, {
91+
headers,
8592
translations: {
8693
[contextKey]: {
8794
[msgid]: {

0 commit comments

Comments
 (0)