commit 2e5b42fd8233ebba20f0701ab1792cfe092ae8a8
parent 8860c548be31ed04eb4c3fd1af420bd358ccd8b3
Author: Florian Dold <dold@taler.net>
Date: Tue, 1 Sep 2026 14:58:22 +0200
pogen: format emitted catalogs with Prettier
Diffstat:
6 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/packages/pogen/bin/pogen b/packages/pogen/bin/pogen
@@ -1,2 +1,2 @@
#!/usr/bin/env -S node --trace-deprecation
-(await import ('../lib/pogen.js')).main();
+(await import("../lib/pogen.js")).main();
diff --git a/packages/pogen/package.json b/packages/pogen/package.json
@@ -22,6 +22,7 @@
"@types/node": "^20.19.41",
"gettext-parser": "^8.0.0",
"glob": "^13.0.6",
+ "prettier": "^3.8.3",
"tslib": "^2.8.1"
}
}
diff --git a/packages/pogen/src/po2ts.test.ts b/packages/pogen/src/po2ts.test.ts
@@ -16,7 +16,10 @@
import { test } from "node:test";
import assert from "node:assert";
-import { CONTEXT_DELIMITER, poToStrings } from "./po2ts.js";
+import * as fs from "node:fs";
+import * as path from "node:path";
+import { format, resolveConfig } from "prettier";
+import { CONTEXT_DELIMITER, po2ts, poToStrings } from "./po2ts.js";
function header(
lang: string,
@@ -213,3 +216,39 @@ test("the header carries lang and plural forms through", () => {
assert.equal(s.plural_forms, "nplurals=2; plural=(n > 1);");
assert.equal(s.domain, "messages");
});
+
+test("po2ts formats generated catalogues with the repository's Prettier rules", async () => {
+ const originalCwd = process.cwd();
+ const projectDir = fs.mkdtempSync(
+ path.join(originalCwd, ".pogen-format-test-"),
+ );
+ const i18nDir = path.join(projectDir, "src", "i18n");
+ const outputPath = path.join(i18nDir, "strings.ts");
+ fs.mkdirSync(i18nDir, { recursive: true });
+ fs.writeFileSync(
+ path.join(i18nDir, "de.po"),
+ header("de") +
+ `msgid "required"
+msgstr "erforderlich"
+`,
+ );
+
+ try {
+ process.chdir(projectDir);
+ await po2ts();
+ process.chdir(originalCwd);
+
+ const generated = fs.readFileSync(outputPath, "utf-8");
+ const prettierConfig = (await resolveConfig(outputPath)) ?? {};
+ assert.equal(
+ generated,
+ await format(generated, { ...prettierConfig, filepath: outputPath }),
+ );
+ assert.match(generated, /Record<string, StringsType>/);
+ assert.match(generated, /strings\["de"\] =/);
+ assert.match(generated, /"required": \["erforderlich"\]/);
+ } finally {
+ process.chdir(originalCwd);
+ fs.rmSync(projectDir, { recursive: true, force: true });
+ }
+});
diff --git a/packages/pogen/src/po2ts.ts b/packages/pogen/src/po2ts.ts
@@ -19,7 +19,9 @@
*/
import * as gettextParser from "gettext-parser";
+import { execFileSync } from "node:child_process";
import * as fs from "node:fs";
+import { fileURLToPath } from "node:url";
import * as glob from "glob";
//types defined by the po2json library
@@ -234,7 +236,19 @@ export function po2ts(): void {
chunks.push(s);
}
- const tsContents = chunks.join("");
+ const outputPath = "src/i18n/strings.ts";
+ const prettierCli = fileURLToPath(
+ import.meta.resolve("prettier/bin/prettier.cjs"),
+ );
+ const tsContents = execFileSync(
+ process.execPath,
+ [prettierCli, "--stdin-filepath", outputPath],
+ {
+ encoding: "utf-8",
+ input: chunks.join(""),
+ maxBuffer: 16 * 1024 * 1024,
+ },
+ );
- fs.writeFileSync("src/i18n/strings.ts", tsContents);
+ fs.writeFileSync(outputPath, tsContents);
}
diff --git a/packages/pogen/src/pogen.ts b/packages/pogen/src/pogen.ts
@@ -27,7 +27,7 @@ function requireGettextTool(tool: string): void {
}
}
-export function main() {
+export function main(): void {
const subcommand = process.argv[2];
if (process.argv.includes("--help") || !subcommand) {
usage();
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
@@ -245,6 +245,9 @@ importers:
glob:
specifier: ^13.0.6
version: 13.0.6
+ prettier:
+ specifier: ^3.8.3
+ version: 3.8.3
tslib:
specifier: ^2.8.1
version: 2.8.1