Skip to content

Commit fe67e0f

Browse files
authored
feat: allow to disable lineNumbers (#1007)
1 parent ebaa87d commit fe67e0f

9 files changed

Lines changed: 160 additions & 17 deletions

File tree

docs/ref/conf.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,14 @@ Origin is filename and line number from where the message was extracted.
388388
Note that origins may produce a large amount of merge conflicts. Origins can be
389389
disabled by setting ``origins: false`` in :conf:`formatOptions`.
390390

391+
Also, you can disable just ``lineNumbers`` but keep ``origins``
392+
391393
.. config:: formatOptions
392394

393395
formatOptions
394396
-------------
395397

396-
Default: ``{ origins: true }``
398+
Default: ``{ origins: true, lineNumbers: true }``
397399

398400
Object for configuring message catalog output. See individual formats for options.
399401

packages/cli/src/api/catalog.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export type MessageType = ExtractedMessageType & {
3636
translation: string
3737
}
3838

39-
type ExtractedCatalogType = {
39+
export type ExtractedCatalogType = {
4040
[msgId: string]: ExtractedMessageType
4141
}
4242

packages/cli/src/api/formats/lingui.test.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ describe("lingui format", function () {
3838
},
3939
withDescription: {
4040
translation: "Message with description",
41-
extractedComments: ["Description is comment from developers to translators"],
41+
extractedComments: [
42+
"Description is comment from developers to translators",
43+
],
4244
},
4345
withComments: {
4446
comments: ["Translator comment", "This one might come from developer"],
@@ -122,4 +124,59 @@ describe("lingui format", function () {
122124
const linguiOriginProperty = '"origin"'
123125
expect(lingui).toEqual(expect.not.stringContaining(linguiOriginProperty))
124126
})
127+
128+
it("should not include lineNumbers if lineNumbers option is false", function () {
129+
mockFs({
130+
locale: {
131+
en: mockFs.directory(),
132+
},
133+
})
134+
135+
const filename = path.join("locale", "en", "messages.json")
136+
const catalog: CatalogType = {
137+
static: {
138+
translation: "Static message",
139+
},
140+
withOrigin: {
141+
translation: "Message with origin",
142+
origin: [["src/App.js", 4]],
143+
},
144+
withMultipleOrigins: {
145+
translation: "Message with multiple origin",
146+
origin: [
147+
["src/App.js", 4],
148+
["src/Component.js", 2],
149+
],
150+
},
151+
}
152+
format.write(filename, catalog, { lineNumbers: false, locale: "en" })
153+
const lingui = fs.readFileSync(filename).toString()
154+
mockFs.restore()
155+
expect(lingui).toMatchInlineSnapshot(`
156+
{
157+
"static": {
158+
"translation": "Static message"
159+
},
160+
"withOrigin": {
161+
"translation": "Message with origin",
162+
"origin": [
163+
[
164+
"src/App.js"
165+
]
166+
]
167+
},
168+
"withMultipleOrigins": {
169+
"translation": "Message with multiple origin",
170+
"origin": [
171+
[
172+
"src/App.js"
173+
],
174+
[
175+
"src/Component.js"
176+
]
177+
]
178+
}
179+
}
180+
`)
181+
})
125182
})

packages/cli/src/api/formats/lingui.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from "fs"
22
import * as R from "ramda"
33

44
import { writeFileIfChanged } from "../utils"
5-
import { CatalogType } from "../catalog"
5+
import { ExtractedMessageType, CatalogType } from "../catalog"
66
import { CatalogFormatter } from "."
77

88
type NoOriginsCatalogType = {
@@ -13,6 +13,16 @@ const removeOrigins = (R.map(
1313
({ origin, ...message }) => message
1414
) as unknown) as (catalog: CatalogType) => NoOriginsCatalogType
1515

16+
const removeLineNumbers = (R.map(
17+
(message: ExtractedMessageType) => {
18+
if (message.origin) {
19+
message.origin.map(originValue => originValue.pop())
20+
}
21+
return message
22+
}
23+
) as unknown) as (catalog: ExtractedMessageType) => NoOriginsCatalogType
24+
25+
1626
const lingui: CatalogFormatter = {
1727
catalogExtension: ".json",
1828

@@ -21,6 +31,9 @@ const lingui: CatalogFormatter = {
2131
if (options.origins === false) {
2232
outputCatalog = removeOrigins(catalog)
2333
}
34+
if (options.origins !== false && options.lineNumbers === false) {
35+
outputCatalog = removeLineNumbers(outputCatalog)
36+
}
2437
writeFileIfChanged(filename, JSON.stringify(outputCatalog, null, 2))
2538
},
2639

packages/cli/src/api/formats/po.test.ts

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ import mockFs from "mock-fs"
44
import mockDate from "mockdate"
55
import PO from "pofile"
66
import { mockConsole } from "@lingui/jest-mocks"
7+
import { format as formatDate } from "date-fns"
78

89
import format from "./po"
910
import { CatalogType } from "../catalog"
1011

11-
describe("pofile format", function () {
12+
describe("pofile format", () => {
1213
afterEach(() => {
1314
mockFs.restore()
1415
mockDate.reset()
1516
})
1617

17-
it("should write catalog in pofile format", function () {
18+
it("should write catalog in pofile format", () => {
1819
mockFs({
1920
locale: {
2021
en: mockFs.directory(),
2122
},
2223
})
23-
mockDate.set(new Date(2018,7,27,10,0,0).toUTCString())
24+
mockDate.set(new Date(2018, 7, 27, 10, 0, 0).toUTCString())
2425

2526
const filename = path.join("locale", "en", "messages.po")
2627
const catalog: CatalogType = {
@@ -40,7 +41,9 @@ describe("pofile format", function () {
4041
},
4142
withDescription: {
4243
translation: "Message with description",
43-
extractedComments: ["Description is comment from developers to translators"],
44+
extractedComments: [
45+
"Description is comment from developers to translators",
46+
],
4447
},
4548
withComments: {
4649
comments: ["Translator comment", "This one might come from developer"],
@@ -73,7 +76,7 @@ describe("pofile format", function () {
7376
expect(pofile).toMatchSnapshot()
7477
})
7578

76-
it("should read catalog in pofile format", function () {
79+
it("should read catalog in pofile format", () => {
7780
const pofile = fs
7881
.readFileSync(
7982
path.join(path.resolve(__dirname), "fixtures", "messages.po")
@@ -94,7 +97,7 @@ describe("pofile format", function () {
9497
expect(actual).toMatchSnapshot()
9598
})
9699

97-
it("should correct badly used comments", function () {
100+
it("should correct badly used comments", () => {
98101
const po = PO.parse(`
99102
#. First description
100103
#. Second comment
@@ -123,7 +126,7 @@ describe("pofile format", function () {
123126
expect(actual).toMatchSnapshot()
124127
})
125128

126-
it("should throw away additional msgstr if present", function () {
129+
it("should throw away additional msgstr if present", () => {
127130
const po = PO.parse(`
128131
msgid "withMultipleTranslation"
129132
msgstr[0] "This is just fine"
@@ -150,7 +153,7 @@ describe("pofile format", function () {
150153
})
151154
})
152155

153-
it("should write the same catalog as it was read", function () {
156+
it("should write the same catalog as it was read", () => {
154157
const pofile = fs
155158
.readFileSync(
156159
path.join(path.resolve(__dirname), "fixtures", "messages.po")
@@ -172,10 +175,12 @@ describe("pofile format", function () {
172175
mockFs.restore()
173176
// on windows mockFs adds ··· to multiline string, so this strictly equal comparison can't be done
174177
// we test that the content if the same inlined...
175-
expect(actual.replace(/(\r\n|\n|\r)/gm,"")).toEqual(pofile.replace(/(\r\n|\n|\r)/gm,""))
178+
expect(actual.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
179+
pofile.replace(/(\r\n|\n|\r)/gm, "")
180+
)
176181
})
177182

178-
it("should not include origins if origins option is false", function () {
183+
it("should not include origins if origins option is false", () => {
179184
mockFs({
180185
locale: {
181186
en: mockFs.directory(),
@@ -205,4 +210,60 @@ describe("pofile format", function () {
205210
const pofileOriginPrefix = "#:"
206211
expect(pofile).toEqual(expect.not.stringContaining(pofileOriginPrefix))
207212
})
213+
214+
it("should not include lineNumbers if lineNumbers option is false", () => {
215+
mockFs({
216+
locale: {
217+
en: mockFs.directory(),
218+
},
219+
})
220+
221+
const filename = path.join("locale", "en", "messages.po")
222+
const catalog: CatalogType = {
223+
static: {
224+
translation: "Static message",
225+
},
226+
withOrigin: {
227+
translation: "Message with origin",
228+
origin: [["src/App.js", 4]],
229+
},
230+
withMultipleOrigins: {
231+
translation: "Message with multiple origin",
232+
origin: [
233+
["src/App.js", 4],
234+
["src/Component.js", 2],
235+
],
236+
},
237+
}
238+
format.write(filename, catalog, {
239+
origins: true,
240+
lineNumbers: false,
241+
locale: "en",
242+
})
243+
const pofile = fs.readFileSync(filename).toString()
244+
mockFs.restore()
245+
expect(pofile).toMatchInlineSnapshot(`
246+
msgid ""
247+
msgstr ""
248+
"POT-Creation-Date: ${formatDate(new Date(), "yyyy-MM-dd HH:mmxxxx")}\\n"
249+
"Mime-Version: 1.0\\n"
250+
"Content-Type: text/plain; charset=utf-8\\n"
251+
"Content-Transfer-Encoding: 8bit\\n"
252+
"X-Generator: @lingui/cli\\n"
253+
"Language: en\\n"
254+
255+
msgid "static"
256+
msgstr "Static message"
257+
258+
#: src/App.js
259+
msgid "withOrigin"
260+
msgstr "Message with origin"
261+
262+
#: src/App.js
263+
#: src/Component.js
264+
msgid "withMultipleOrigins"
265+
msgstr "Message with multiple origin"
266+
267+
`)
268+
})
208269
})

packages/cli/src/api/formats/po.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@ const serialize = (items: CatalogType, options) =>
2525
item.msgstr = [message.translation]
2626
item.comments = message.comments || []
2727
item.extractedComments = message.extractedComments || []
28-
if (options.origins) {
29-
item.references = message.origin ? message.origin.map(joinOrigin) : []
28+
if (options.origins !== false) {
29+
if (message.origin && options.lineNumbers === false) {
30+
item.references = message.origin.map(msg => {
31+
msg.pop()
32+
return msg
33+
}).map(joinOrigin)
34+
} else {
35+
item.references = message.origin ? message.origin.map(joinOrigin) : []
36+
}
3037
}
3138
// @ts-ignore: Figure out how to set this flag
3239
item.obsolete = message.obsolete

packages/conf/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { GeneratorOptions } from "@babel/core";
33
export declare type CatalogFormat = "lingui" | "minimal" | "po" | "csv" | "po-gettext";
44
export type CatalogFormatOptions = {
55
origins?: boolean;
6+
lineNumbers?: boolean;
67
}
78
export declare type OrderBy = "messageId" | "origin";
89
declare type CatalogConfig = {

packages/conf/src/__snapshots__/index.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ Object {
125125
},
126126
format: po,
127127
formatOptions: Object {
128+
lineNumbers: true,
128129
origins: true,
129130
},
130131
locales: Array [

packages/conf/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type CatalogFormat = "lingui" | "minimal" | "po" | "csv"
1010

1111
export type CatalogFormatOptions = {
1212
origins?: boolean
13+
lineNumbers?: boolean
1314
}
1415

1516
export type OrderBy = "messageId" | "origin"
@@ -76,7 +77,7 @@ export const defaultConfig: LinguiConfig = {
7677
extractBabelOptions: { plugins: [], presets: [] },
7778
fallbackLocales: {},
7879
format: "po",
79-
formatOptions: { origins: true },
80+
formatOptions: { origins: true, lineNumbers: true },
8081
locales: [],
8182
orderBy: "messageId",
8283
pseudoLocale: "",

0 commit comments

Comments
 (0)