Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): add migration command for catalogs #1686

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions packages/cli/src/lingui-migrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { program } from "commander"

import {
CatalogType,
ExtractedMessageType,
getConfig,
LinguiConfigNormalized,
MessageType,
} from "@lingui/conf"

import { getCatalogs } from "@lingui/cli/api"
import { formatter as createFormatter } from "@lingui/format-po"
import fs from "fs/promises"
import { generateMessageId } from "@lingui/message-utils/generateMessageId"

function _isGeneratedId(id: string, message: ExtractedMessageType): boolean {
return id === generateMessageId(message.message, message.context)
}

export default async function command(
config: LinguiConfigNormalized
): Promise<boolean> {
const catalogs = await getCatalogs(config)

let commandSuccess = true
const formatter = createFormatter({
explicitIdAsDefault: true,
})

await Promise.all(
catalogs.map(async (catalog) => {
const extractedCatalog = await catalog.collect()

for (const locale of config.locales) {
const translationFileName = catalog.getFilename(locale)

const translationCatalog = await formatter.parse(
await fs.readFile(translationFileName, "utf-8"),
{
locale,
sourceLocale: config.sourceLocale,
filename: translationFileName,
}
)

for (const messageId in extractedCatalog) {
const extractedMessage = extractedCatalog[messageId]

const isGeneratedId = _isGeneratedId(messageId, extractedMessage)
const oldId = isGeneratedId ? extractedMessage.message : messageId

if (translationCatalog[oldId]) {
;(extractedMessage as MessageType).translation =
translationCatalog[oldId].translation
}
}

await catalog.write(locale, extractedCatalog as CatalogType)
}
})
)

return commandSuccess
}

type CliOptions = {
config?: string
}

if (require.main === module) {
program
.option("--config <path>", "Path to the config file")
.parse(process.argv)

const options = program.opts<CliOptions>()

const config = getConfig({
configPath: options.config,
})

const result = command(config).then(() => {
if (!result) process.exit(1)
})
}
36 changes: 36 additions & 0 deletions packages/cli/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { makeConfig } from "@lingui/conf"
import { listingToHumanReadable, readFsToJson } from "../src/tests"
import { getConsoleMockCalls, mockConsole } from "@lingui/jest-mocks"
import MockDate from "mockdate"
import migrateCommand from "../src/lingui-migrate"

export function compareFolders(pathA: string, pathB: string) {
const listingA = listingToHumanReadable(readFsToJson(pathA))
Expand Down Expand Up @@ -290,4 +291,39 @@ describe("E2E Extractor Test", () => {
compareFolders(actualPath, expectedPath)
})
})

it("migrate should 'js-lingui-explicit-id' to translations created with v3", async () => {
const rootDir = nodepath.join(__dirname, "migrate-catalog-v4")

const actualPath = nodepath.join(rootDir, "actual")
const expectedPath = nodepath.join(rootDir, "expected")

await fs.rm(actualPath, {
recursive: true,
force: true,
})

await fs.cp(nodepath.join(rootDir, "fixtures/locales"), actualPath, {
recursive: true,
})

const result = await migrateCommand(
makeConfig({
rootDir: rootDir,
locales: ["en", "pl"],
sourceLocale: "en",
format: "po",
catalogs: [
{
path: "<rootDir>/actual/{locale}",
include: ["<rootDir>/fixtures"],
},
],
})
)

expect(result).toBeTruthy()

compareFolders(actualPath, expectedPath)
})
})
23 changes: 23 additions & 0 deletions packages/cli/test/migrate-catalog-v4/expected/en.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2023-03-15 10:00+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: fixtures/file-a.ts:3
msgid "Hello world"
msgstr "Hello world"

#. js-lingui-explicit-id
#: fixtures/file-a.ts:5
msgid "custom.id"
msgstr "custom.id"
23 changes: 23 additions & 0 deletions packages/cli/test/migrate-catalog-v4/expected/pl.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2023-03-15 10:00+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: fixtures/file-a.ts:3
msgid "Hello world"
msgstr "Witaj świecie"

#. js-lingui-explicit-id
#: fixtures/file-a.ts:5
msgid "custom.id"
msgstr "custom id translation"
8 changes: 8 additions & 0 deletions packages/cli/test/migrate-catalog-v4/fixtures/file-a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { t } from "@lingui/macro"

const msg = t`Hello world`

const msg3 = t({
message: "This message has custom id",
id: "custom.id",
})
22 changes: 22 additions & 0 deletions packages/cli/test/migrate-catalog-v4/fixtures/locales/en.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2023-03-15 10:00+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: fixtures/file-a.ts:3
msgid "Hello world"
msgstr "Hello world"

#: fixtures/file-a.ts:5
msgid "custom.id"
msgstr "custom.id"
22 changes: 22 additions & 0 deletions packages/cli/test/migrate-catalog-v4/fixtures/locales/pl.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2023-03-15 10:00+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: fixtures/file-a.ts:3
msgid "Hello world"
msgstr "Witaj świecie"

#: fixtures/file-a.ts:5
msgid "custom.id"
msgstr "custom id translation"