Skip to content

fix(compile): remove verbose output when using template (*.pot) #1388

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

Merged
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@testing-library/react": "^11.0.4",
"@types/babel-types": "^7.0.9",
"@types/jest": "^26.0.14",
"@types/mock-fs": "^4.13.1",
"@types/node": "14.14.31",
"@types/ramda": "^0.27.23",
"@types/react": "^16.9.51",
Expand Down Expand Up @@ -74,7 +75,7 @@
"lint-staged": "^13.1.0",
"memory-fs": "^0.5.0",
"minimist": "^1.2.5",
"mock-fs": "^4.13.0",
"mock-fs": "^5.2.0",
"mockdate": "^3.0.2",
"ncp": "^2.0.0",
"npm-cli-login": "^0.1.1",
Expand Down
5 changes: 0 additions & 5 deletions packages/cli/src/api/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,6 @@ export class Catalog {
) {
const catalog = catalogs[locale] || {}

if (!catalog.hasOwnProperty(key)) {
console.error(`Message with key ${key} is missing in locale ${locale}`)
}

const getTranslation = (_locale: string) => {
const configLocales = this.config.locales.join('", "')
const localeCatalog = catalogs[_locale] || {}
Expand All @@ -299,7 +295,6 @@ export class Catalog {
return null
}
if (!localeCatalog.hasOwnProperty(key)) {
console.error(`Message with key ${key} is missing in locale ${_locale}`)
return null
}

Expand Down
30 changes: 20 additions & 10 deletions packages/cli/src/lingui-compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,18 @@ const noMessages: (catalogs: Object[]) => boolean = R.pipe(
R.all(R.equals<any>(true))
)

function command(config: LinguiConfig, options) {
export type CliCompileOptions = {
verbose?: boolean
allowEmpty?: boolean,
typescript?: boolean,
watch?: boolean
namespace?: string,
}

export function command(config: LinguiConfig, options: CliCompileOptions) {
const catalogs = getCatalogs(config)

// fixme: this is definitely doesn't work
if (noMessages(catalogs)) {
console.error("Nothing to compile, message catalogs are empty!\n")
console.error(
Expand All @@ -35,23 +44,24 @@ function command(config: LinguiConfig, options) {
const doMerge = !!config.catalogsMergePath
let mergedCatalogs = {}

console.error("Compiling message catalogs…")
console.log("Compiling message catalogs…")

config.locales.forEach((locale) => {
for (const locale of config.locales) {
const [language] = locale.split(/[_-]/)
// todo: this validation should be in @lingui/conf
if (locale !== config.pseudoLocale && !plurals[language]) {
console.log(
console.error(
chalk.red(
`Error: Invalid locale ${chalk.bold(locale)} (missing plural rules)!`
)
)
console.error()
}

catalogs.forEach((catalog) => {
for (const catalog of catalogs) {
const messages = catalog.getTranslations(locale, {
fallbackLocales: config.fallbackLocales,
sourceLocale: config.sourceLocale,
sourceLocale: config.sourceLocale
})

if (!options.allowEmpty) {
Expand All @@ -68,14 +78,14 @@ function command(config: LinguiConfig, options) {

if (options.verbose) {
console.error(chalk.red("Missing translations:"))
missingMsgIds.forEach((msgId) => console.log(msgId))
missingMsgIds.forEach((msgId) => console.error(msgId))
} else {
console.error(
chalk.red(`Missing ${missingMsgIds.length} translation(s)`)
)
}
console.error()
process.exit(1)
return false
}
}

Expand Down Expand Up @@ -112,7 +122,7 @@ function command(config: LinguiConfig, options) {
options.verbose &&
console.error(chalk.green(`${locale} ⇒ ${compiledPath}`))
}
})
}

if (doMerge) {
const compileCatalog = getCatalogForMerge(config)
Expand All @@ -130,7 +140,7 @@ function command(config: LinguiConfig, options) {
)
options.verbose && console.log(chalk.green(`${locale} ⇒ ${compiledPath}`))
}
})
}
return true
}

Expand Down
34 changes: 34 additions & 0 deletions packages/cli/src/test/__snapshots__/compile.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`CLI Command: Compile Locales Validation Should throw error for invalid locale 1`] = `
Error: Invalid locale abra (missing plural rules)!

`;

exports[`CLI Command: Compile allowEmpty = false Should show error and stop compilation of catalog if message doesnt have a translation (with template) 1`] = `
Object {
en: /*eslint-disable*/module.exports={messages:JSON.parse("{\\"Hello World\\":\\"Hello World\\"}")};,
pl: undefined,
}
`;

exports[`CLI Command: Compile allowEmpty = false Should show error and stop compilation of catalog if message doesnt have a translation (with template) 2`] = `
Error: Failed to compile catalog for locale pl!
Missing 1 translation(s)

`;

exports[`CLI Command: Compile allowEmpty = false Should show error and stop compilation of catalog if message doesnt have a translation (no template) 1`] = `
Error: Failed to compile catalog for locale pl!
Missing 1 translation(s)

`;

exports[`CLI Command: Compile allowEmpty = false Should show missing messages verbosely when verbose = true 1`] = `
en ⇒ /test/en.js
Error: Failed to compile catalog for locale pl!
Missing translations:
Hello World
Test String

`;
203 changes: 203 additions & 0 deletions packages/cli/src/test/compile.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import {command} from "../lingui-compile"
import {makeConfig} from "@lingui/conf"
import path from "path"
import {getConsoleMockCalls, mockConsole} from "@lingui/jest-mocks"
import mockFs from "mock-fs"
import fs from 'fs'

function readFsToJson(directory: string, filter?: (filename: string) => boolean) {
const out = {}

fs
.readdirSync(directory)
.map((filename) => {
const filepath = path.join(directory, filename)

if (fs.lstatSync(filepath).isDirectory()) {
out[filename] = readFsToJson(filepath)
return out
}

if (!filter || filter(filename)) {
out[filename] = fs.readFileSync(filepath).toString()
}
})

return out
}

describe('CLI Command: Compile', () => {
xit('Should return error if no messages', () => {
const config = makeConfig({
locales: ['en', 'pl'],
rootDir: path.join(__dirname, 'fixtures/compile'),
catalogs: [{
path: '<rootDir>/{locale}',
include: ['<rootDir>']
}]
})

const result = command(config, {})
expect(result).toBeFalsy()
})

describe('Merge Catalogs', () => {
// todo
})

describe('Locales Validation', () => {
// todo: should be moved to @lingui/conf
it('Should throw error for invalid locale', () => {
const config = makeConfig({
locales: ['abra'],
rootDir: '/test',
catalogs: [{
path: '<rootDir>/{locale}',
include: ['<rootDir>'],
exclude: []
}]
})

mockFs()

mockConsole((console) => {
const result = command(config, {})
mockFs.restore()
const log = getConsoleMockCalls(console.error)
expect(log).toMatchSnapshot()

expect(result).toBeTruthy()
})
})

it('Should not throw error for pseudolocale', () => {
const config = makeConfig({
locales: ['abracadabra'],
rootDir: '/test',
pseudoLocale: 'abracadabra',
catalogs: [{
path: '<rootDir>/{locale}',
include: ['<rootDir>'],
exclude: []
}]
})

mockFs()

mockConsole((console) => {
const result = command(config, {})
mockFs.restore()
expect(console.error).not.toBeCalled()
expect(result).toBeTruthy()
})
})
})

describe('allowEmpty = false', () => {
const config = makeConfig({
locales: ['en', 'pl'],
sourceLocale: 'en',
rootDir: '/test',
catalogs: [{
path: '<rootDir>/{locale}',
include: ['<rootDir>'],
exclude: []
}]
})

it('Should show error and stop compilation of catalog ' +
'if message doesnt have a translation (no template)', () => {
mockFs({
'/test': {
'en.po': `
msgid "Hello World"
msgstr "Hello World"
`,
'pl.po': `
msgid "Hello World"
msgstr "Cześć świat"

msgid "Test String"
msgstr ""
`
}
})

mockConsole((console) => {
const result = command(config, {
allowEmpty: false
})
const actualFiles = readFsToJson('/test')

expect(actualFiles['pl.js']).toBeFalsy()
expect(actualFiles['en.js']).toBeTruthy()
mockFs.restore()

const log = getConsoleMockCalls(console.error)
expect(log).toMatchSnapshot()
expect(result).toBeFalsy()
})
})

it('Should show error and stop compilation of catalog ' +
' if message doesnt have a translation (with template)', () => {
mockFs({
'/test': {
'messages.pot': `
msgid "Hello World"
msgstr ""
`,
'pl.po': ``
}
})

mockConsole((console) => {
const result = command(config, {
allowEmpty: false
})

const actualFiles = readFsToJson('/test')

expect({
pl: actualFiles['pl.js'],
en: actualFiles['en.js']
}).toMatchSnapshot()

mockFs.restore()

const log = getConsoleMockCalls(console.error)
expect(log).toMatchSnapshot()
expect(result).toBeFalsy()
})
})


it('Should show missing messages verbosely when verbose = true', () => {
mockFs({
'/test': {
'pl.po': `
msgid "Hello World"
msgstr ""

msgid "Test String"
msgstr ""
`
}
})

mockConsole((console) => {
const result = command(config, {
allowEmpty: false,
verbose: true
})

mockFs.restore()

const log = getConsoleMockCalls(console.error)
expect(log).toMatchSnapshot()
expect(result).toBeFalsy()
})
})

})
})
5 changes: 5 additions & 0 deletions packages/conf/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ export declare function getConfig({ cwd, configPath, skipValidation, }?: {
configPath?: string;
skipValidation?: boolean;
}): LinguiConfig;

export declare function makeConfig(userConfig: Partial<LinguiConfig>, opts?: {
skipValidation?: boolean
}): LinguiConfig;

export declare const configValidation: {
exampleConfig: {
extractBabelOptions: {
Expand Down
Loading