diff --git a/.prettierignore b/.prettierignore index bdd4a15ec..e577968eb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ **/test/**/expected.js **/locale/* **/fixtures/* +**/expected/* coverage/ website/ .github diff --git a/packages/cli/src/api/catalog/getCatalogs.ts b/packages/cli/src/api/catalog/getCatalogs.ts index 80902fbb3..cc7c3fa5c 100644 --- a/packages/cli/src/api/catalog/getCatalogs.ts +++ b/packages/cli/src/api/catalog/getCatalogs.ts @@ -5,6 +5,7 @@ import { Catalog } from "../catalog" import { normalizeRelativePath, PATHSEP, replacePlaceholders } from "../utils" import micromatch from "micromatch" import { getFormat } from "../formats" +import { getExperimentalCatalogs } from "../../extract-experimental/getExperimentalCatalogs" const NAME_PH = "{name}" const LOCALE_PH = "{locale}" @@ -78,6 +79,10 @@ export function getCatalogs(config: LinguiConfigNormalized): Catalog[] { }) }) + if (config.experimental?.extractor?.entries.length) { + catalogs.push(...getExperimentalCatalogs(config)) + } + return catalogs } diff --git a/packages/cli/src/extract-experimental/getEntryPoints.ts b/packages/cli/src/extract-experimental/getEntryPoints.ts new file mode 100644 index 000000000..8b224e7b9 --- /dev/null +++ b/packages/cli/src/extract-experimental/getEntryPoints.ts @@ -0,0 +1,7 @@ +import glob from "glob" + +export function getEntryPoints(entries: string[]) { + const patterns = entries.length > 1 ? `{${entries.join(",")}}` : entries[0] + + return glob.sync(patterns, { mark: true }) +} diff --git a/packages/cli/src/extract-experimental/getExperimentalCatalogs.ts b/packages/cli/src/extract-experimental/getExperimentalCatalogs.ts new file mode 100644 index 000000000..eeb1218ba --- /dev/null +++ b/packages/cli/src/extract-experimental/getExperimentalCatalogs.ts @@ -0,0 +1,40 @@ +import { LinguiConfigNormalized } from "@lingui/conf" +import { getEntryPoints } from "./getEntryPoints" +import { resolveCatalogPath } from "./resolveCatalogPath" +import { Catalog } from "../api/catalog" +import { resolveTemplatePath } from "./resolveTemplatePath" +import { getFormat } from "@lingui/cli/api" + +export function getExperimentalCatalogs(linguiConfig: LinguiConfigNormalized) { + const config = linguiConfig.experimental.extractor + const entryPoints = getEntryPoints(config.entries) + + return entryPoints.map((entryPoint) => { + const catalogPath = resolveCatalogPath( + config.output, + entryPoint, + linguiConfig.rootDir, + undefined, + "" + ) + + const format = getFormat(linguiConfig.format) + const templatePath = resolveTemplatePath( + entryPoint, + config.output, + linguiConfig.rootDir, + format.templateExtension || format.catalogExtension + ) + + return new Catalog( + { + name: undefined, + path: catalogPath, + templatePath, + include: [], + exclude: [], + }, + linguiConfig + ) + }) +} diff --git a/packages/cli/src/lingui-extract-experimental.ts b/packages/cli/src/lingui-extract-experimental.ts index a4574b386..0dcc4447d 100644 --- a/packages/cli/src/lingui-extract-experimental.ts +++ b/packages/cli/src/lingui-extract-experimental.ts @@ -2,7 +2,6 @@ import { program } from "commander" import { getConfig, LinguiConfigNormalized } from "@lingui/conf" import nodepath from "path" -import glob from "glob" import os from "os" import { getFormat } from "./api/formats" import fs from "fs/promises" @@ -13,6 +12,7 @@ import { writeCatalogs, writeTemplate, } from "./extract-experimental/writeCatalogs" +import { getEntryPoints } from "./extract-experimental/getEntryPoints" export type CliExtractTemplateOptions = { verbose: boolean @@ -37,19 +37,12 @@ export default async function command( ) } - const patterns = - config.entries.length > 1 - ? `{${config.entries.join(",")}}` - : config.entries[0] - - const entryPoints = glob.sync(patterns, { mark: true }) - const tempDir = nodepath.join(os.tmpdir(), "js-lingui-extract") await fs.rm(tempDir, { recursive: true, force: true }) const bundleResult = await bundleSource( config, - entryPoints, + getEntryPoints(config.entries), tempDir, linguiConfig.rootDir ) diff --git a/packages/cli/test/extractor-experimental-template/expected/about.page.en.js b/packages/cli/test/extractor-experimental-template/expected/about.page.en.js new file mode 100644 index 000000000..27712b5b8 --- /dev/null +++ b/packages/cli/test/extractor-experimental-template/expected/about.page.en.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"1TzdHc\":\"aliased module message\",\"8Pj7KC\":\"JSX: about page message\",\"LGGfGX\":\"header message\",\"u5PTM8\":\"about page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental-template/expected/about.page.pl.js b/packages/cli/test/extractor-experimental-template/expected/about.page.pl.js new file mode 100644 index 000000000..27712b5b8 --- /dev/null +++ b/packages/cli/test/extractor-experimental-template/expected/about.page.pl.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"1TzdHc\":\"aliased module message\",\"8Pj7KC\":\"JSX: about page message\",\"LGGfGX\":\"header message\",\"u5PTM8\":\"about page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental-template/expected/index.page.en.js b/packages/cli/test/extractor-experimental-template/expected/index.page.en.js new file mode 100644 index 000000000..2a705af1b --- /dev/null +++ b/packages/cli/test/extractor-experimental-template/expected/index.page.en.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"D+XV65\":\"index page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental-template/expected/index.page.pl.js b/packages/cli/test/extractor-experimental-template/expected/index.page.pl.js new file mode 100644 index 000000000..2a705af1b --- /dev/null +++ b/packages/cli/test/extractor-experimental-template/expected/index.page.pl.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"D+XV65\":\"index page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental/expected/about.page.en.js b/packages/cli/test/extractor-experimental/expected/about.page.en.js new file mode 100644 index 000000000..367c18ed2 --- /dev/null +++ b/packages/cli/test/extractor-experimental/expected/about.page.en.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"LGGfGX\":\"header message\",\"u5PTM8\":\"about page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental/expected/about.page.pl.js b/packages/cli/test/extractor-experimental/expected/about.page.pl.js new file mode 100644 index 000000000..5922a2c3a --- /dev/null +++ b/packages/cli/test/extractor-experimental/expected/about.page.pl.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"LGGfGX\":\"translation: header message\",\"u5PTM8\":\"about page message\",\"nPi9F1\":\"this should be marked as obsolete\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental/expected/index.page.en.js b/packages/cli/test/extractor-experimental/expected/index.page.en.js new file mode 100644 index 000000000..2a705af1b --- /dev/null +++ b/packages/cli/test/extractor-experimental/expected/index.page.en.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"D+XV65\":\"index page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/extractor-experimental/expected/index.page.pl.js b/packages/cli/test/extractor-experimental/expected/index.page.pl.js new file mode 100644 index 000000000..2a705af1b --- /dev/null +++ b/packages/cli/test/extractor-experimental/expected/index.page.pl.js @@ -0,0 +1 @@ +/*eslint-disable*/module.exports={messages:JSON.parse("{\"D+XV65\":\"index page message\"}")}; \ No newline at end of file diff --git a/packages/cli/test/index.test.ts b/packages/cli/test/index.test.ts index 8ed92b6a4..c2b92283c 100644 --- a/packages/cli/test/index.test.ts +++ b/packages/cli/test/index.test.ts @@ -1,6 +1,7 @@ import extractTemplateCommand from "../src/lingui-extract-template" import extractCommand from "../src/lingui-extract" import extractExperimentalCommand from "../src/lingui-extract-experimental" +import { command as compileCommand } from "../src/lingui-compile" import fs from "fs/promises" import nodepath from "path" import { makeConfig } from "@lingui/conf" @@ -124,27 +125,31 @@ describe("E2E Extractor Test", () => { ) await mockConsole(async (console) => { - const result = await extractExperimentalCommand( - makeConfig( - { - rootDir: rootDir, - locales: ["en", "pl"], - sourceLocale: "en", - format: "po", - catalogs: [], - experimental: { - extractor: { - entries: ["/fixtures/pages/**/*.page.{ts,tsx}"], - output: "/actual/{entryName}.{locale}", - }, + const config = makeConfig( + { + rootDir: rootDir, + locales: ["en", "pl"], + sourceLocale: "en", + format: "po", + catalogs: [], + experimental: { + extractor: { + entries: ["/fixtures/pages/**/*.page.{ts,tsx}"], + output: "/actual/{entryName}.{locale}", }, }, - { skipValidation: true } - ), - { - template: true, - } + }, + { skipValidation: true } ) + + const result = await extractExperimentalCommand(config, { + template: true, + }) + + await compileCommand(config, { + allowEmpty: true, + }) + expect(getConsoleMockCalls(console.error)).toBeFalsy() expect(result).toBeTruthy() expect(getConsoleMockCalls(console.log)).toMatchInlineSnapshot(` @@ -154,6 +159,7 @@ describe("E2E Extractor Test", () => { Catalog statistics for fixtures/pages/index.page.ts: 1 message(s) extracted + Compiling message catalogs… `) }) @@ -168,26 +174,29 @@ describe("E2E Extractor Test", () => { copy(nodepath.join(rootDir, "existing"), nodepath.join(rootDir, "actual")) await mockConsole(async (console) => { - const result = await extractExperimentalCommand( - makeConfig( - { - rootDir: rootDir, - locales: ["en", "pl"], - sourceLocale: "en", - format: "po", - catalogs: [], - experimental: { - extractor: { - entries: ["/fixtures/pages/**/*.page.{ts,tsx}"], - output: "/actual/{entryName}.{locale}", - }, + const config = makeConfig( + { + rootDir: rootDir, + locales: ["en", "pl"], + sourceLocale: "en", + format: "po", + catalogs: [], + experimental: { + extractor: { + entries: ["/fixtures/pages/**/*.page.{ts,tsx}"], + output: "/actual/{entryName}.{locale}", }, }, - { skipValidation: true } - ), - {} + }, + { skipValidation: true } ) + const result = await extractExperimentalCommand(config, {}) + + await compileCommand(config, { + allowEmpty: true, + }) + expect(getConsoleMockCalls(console.error)).toBeFalsy() expect(result).toBeTruthy() expect(getConsoleMockCalls(console.log)).toMatchInlineSnapshot(` @@ -207,6 +216,7 @@ describe("E2E Extractor Test", () => { │ pl │ 1 │ 1 │ └─────────────┴─────────────┴─────────┘ + Compiling message catalogs… `) })