Skip to content

Commit 3e20368

Browse files
authored
Support globs for src and ignoring paths (#165)
* Add glob and is-glob dependencies, regenerates package-lock * Add path resolution util with optional ignore argument * Update extract command to support ignore flag Includes internal refactor to align argument names with CLI flag naming * Update check command to support ignore flag Internal refactor to align argument names with CLI flag naming * Update update command to support ignore flag
1 parent ae870eb commit 3e20368

19 files changed

Lines changed: 885 additions & 148 deletions

File tree

package-lock.json

Lines changed: 568 additions & 142 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@
7171
"cross-spawn": "^7.0.6",
7272
"estree-walker": "^2.0.1",
7373
"gettext-parser": "^6.0.0",
74+
"glob": "13.0.0",
7475
"hunspell-spellchecker": "^1.0.2",
7576
"ignore": "^5.1.8",
77+
"is-glob": "^4.0.3",
7678
"koa": "^2.16.4",
7779
"koa-body": "^7.0.1",
7880
"koa-router": "^14.0.0",

src/commands/check.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { extractAll } from "../lib/extract";
88
import { checkDuplicateKeys } from "../lib/checkDuplicateKeys";
99
import * as c3poTypes from "../types";
1010
import { parse, PoData } from "../lib/parser";
11+
import { resolvePaths } from "../lib/utils";
1112

1213
/*
1314
Run any string in stream through warning first
@@ -61,12 +62,15 @@ Check all keys from pots(keys only files) are present in pofile(files with trans
6162
*/
6263
async function check(
6364
pofile: string,
64-
paths: string[],
65+
src: string[],
66+
ignore: string[] | string | undefined,
6567
lang: string,
6668
overrideOpts?: c3poTypes.TtagOpts,
6769
ttagRcOpts?: c3poTypes.TtagRc,
6870
skip?: "translation"
6971
) {
72+
const paths = resolvePaths(src, ignore);
73+
7074
const progress: c3poTypes.Progress = ora(
7175
`[ttag] checking translations from ${paths} ...`
7276
);

src/commands/extract.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import * as ora from "ora";
22
import * as fs from "fs";
33
import * as c3poTypes from "../types";
44
import { extractAll } from "../lib/extract";
5+
import { resolvePaths } from "../lib/utils";
56

67
async function extract(
78
output: string,
8-
paths: string[],
9+
src: string[],
10+
ignore: string[] | string | undefined,
911
lang: string = "en",
1012
ttagOverrideOpts?: c3poTypes.TtagOpts,
1113
ttagRcOpts?: c3poTypes.TtagRc
1214
) {
1315
const progress: c3poTypes.Progress = ora(
1416
`[ttag] extracting translations to ${output} ...`
1517
);
18+
1619
progress.start();
1720
const result = await extractAll(
18-
paths,
21+
resolvePaths(src, ignore),
1922
lang,
2023
progress,
2124
ttagOverrideOpts,

src/commands/update.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,30 @@ import { updatePo } from "../lib/update";
66
import { parse } from "../lib/parser";
77
import { serialize, SerializeOptions } from "../lib/serializer";
88
import { checkDuplicateKeys } from "../lib/checkDuplicateKeys";
9+
import { resolvePaths } from "../lib/utils";
910

1011
async function update(
1112
pofile: string,
1213
src: string[],
14+
ignore: string[] | string | undefined,
1315
lang: string,
1416
ttagOverrideOpts?: ttagTypes.TtagOpts,
1517
ttagRcOpts?: ttagTypes.TtagRc,
1618
serializeOpts?: SerializeOptions
1719
) {
20+
const paths = resolvePaths(src, ignore);
21+
1822
const progress: ttagTypes.Progress = ora(`[ttag] updating ${pofile} ...`);
1923
progress.start();
2024
try {
2125
const pot = parse(
22-
await extractAll(src, lang, progress, ttagOverrideOpts, ttagRcOpts)
26+
await extractAll(
27+
paths,
28+
lang,
29+
progress,
30+
ttagOverrideOpts,
31+
ttagRcOpts
32+
)
2333
);
2434
const errMessage = checkDuplicateKeys(pot);
2535

src/index.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,22 @@ yargs
8484
default: "en",
8585
description: "sets default lang (ISO format)"
8686
},
87+
src: {
88+
description:
89+
"path to source files/directories (supports glob, but needs to be quoted)"
90+
},
91+
ignore: {
92+
alias: "i",
93+
description:
94+
"paths to ignore (supports glob, but needs to be quoted)"
95+
},
8796
...getTtagOptsForYargs()
8897
},
8998
(argv: any) => {
9099
extract(
91100
argv.output,
92101
argv.src,
102+
argv.ignore,
93103
argv.lang,
94104
parseTtagPluginOpts(argv),
95105
parseTtagRcOpts()
@@ -110,12 +120,22 @@ yargs
110120
choices: ["translation"],
111121
default: undefined
112122
},
123+
src: {
124+
description:
125+
"path to source files/directories (supports glob, but needs to be quoted)"
126+
},
127+
ignore: {
128+
alias: "i",
129+
description:
130+
"paths to ignore (supports glob, but needs to be quoted)"
131+
},
113132
...getTtagOptsForYargs()
114133
},
115134
(argv: any) => {
116135
check(
117136
argv.pofile,
118137
argv.src,
138+
argv.ignore,
119139
argv.lang,
120140
parseTtagPluginOpts(argv),
121141
parseTtagRcOpts(),
@@ -226,7 +246,13 @@ yargs
226246
description: "path to .po file with translations"
227247
},
228248
src: {
229-
description: "path to source files/directories"
249+
description:
250+
"path to source files/directories (supports glob, but needs to be quoted)"
251+
},
252+
ignore: {
253+
alias: "i",
254+
description:
255+
"paths to ignore (supports glob, but needs to be quoted)"
230256
},
231257
...getTtagOptsForYargs(),
232258
foldLength: {
@@ -238,6 +264,7 @@ yargs
238264
update(
239265
argv.pofile,
240266
argv.src,
267+
argv.ignore,
241268
argv.lang,
242269
parseTtagPluginOpts(argv),
243270
parseTtagRcOpts(),

src/lib/utils.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Translations, Message, PoData, PoDataCompact } from "./parser";
22
import generate from "@babel/generator";
33
import { Node } from "@babel/types";
4+
import { globSync } from "glob";
5+
import * as fs from "fs";
6+
const isGlob = require("is-glob");
47

58
const pluralNumRegex = /^nplurals ?= ?(\d);/;
69

@@ -70,3 +73,46 @@ export function convert2Compact(poData: PoData): PoDataCompact {
7073
delete compactPo.contexts[""][""];
7174
return compactPo;
7275
}
76+
77+
/**
78+
* Helper function that calculates all the file paths from a src array with optional ignore paths.
79+
* The folder paths are ignored, since further directory traversing is not necessary.
80+
*/
81+
export function resolvePaths(
82+
/** Regular paths or globs */
83+
src: string[],
84+
/**
85+
* Could be a string or an array of strings, depending on how many paths are passed by the cli.
86+
*
87+
* `--ignore path1` => 'path1'
88+
*
89+
* `--ignore path1 --ignore path2` => ['path1', 'path2']
90+
*/
91+
ignore?: string | string[]
92+
): string[] {
93+
const toGlob = (path: string): string => {
94+
if (fs.lstatSync(path).isDirectory()) {
95+
if (!path.endsWith("/")) {
96+
path = `${path}/`;
97+
}
98+
return `${path}**/*`;
99+
} else {
100+
return path;
101+
}
102+
};
103+
104+
/** All paths are internally transformed to globs, to keep backwards compatibility with 'src' paths */
105+
const srcGlob = src.map(path => (isGlob(path) ? path : toGlob(path)));
106+
if (typeof ignore === "string") {
107+
ignore = [ignore];
108+
}
109+
const ignoreGlob = ignore?.map(path =>
110+
isGlob(path) ? path : toGlob(path)
111+
);
112+
113+
return globSync(srcGlob, {
114+
absolute: true,
115+
nodir: true,
116+
ignore: ignoreGlob
117+
});
118+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

3+
exports[`check from glob source 1`] = `""`;
4+
5+
exports[`check from glob source with ignore 1`] = `""`;
6+
37
exports[`check when all string are translated 1`] = `""`;

tests/commands/__snapshots__/test_extract.ts.snap

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,37 @@ msgstr \\"\\"
1818
"
1919
`;
2020

21+
exports[`extract from glob source with filter (ignore all) 1`] = `
22+
"msgid \\"\\"
23+
msgstr \\"\\"
24+
\\"Content-Type: text/plain; charset=utf-8\\\\n\\"
25+
\\"Plural-Forms: nplurals=2; plural=(n!=1);\\\\n\\"
26+
27+
#: tests/fixtures/baseTest/test1.js:4
28+
#, javascript-format
29+
msgid \\"test translation \${ name }\\"
30+
msgstr \\"\\"
31+
32+
#: tests/fixtures/baseTest/nested/test2.js:4
33+
#, javascript-format
34+
msgid \\"test translation 2 \${ name }\\"
35+
msgstr \\"\\"
36+
"
37+
`;
38+
39+
exports[`extract from glob source with filter 1`] = `
40+
"msgid \\"\\"
41+
msgstr \\"\\"
42+
\\"Content-Type: text/plain; charset=utf-8\\\\n\\"
43+
\\"Plural-Forms: nplurals=2; plural=(n!=1);\\\\n\\"
44+
45+
#: tests/fixtures/baseTest/nested/test2.js:4
46+
#, javascript-format
47+
msgid \\"test translation 2 \${ name }\\"
48+
msgstr \\"\\"
49+
"
50+
`;
51+
2152
exports[`extract from js with another default locale 1`] = `
2253
"msgid \\"\\"
2354
msgstr \\"\\"

tests/commands/__snapshots__/test_update.ts.snap

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,26 @@ msgstr[0] \\"\\"
4545
msgstr[1] \\"\\"
4646
"
4747
`;
48+
49+
exports[`test update po with glob 1`] = `
50+
"msgid \\"\\"
51+
msgstr \\"\\"
52+
\\"Content-Type: text/plain; charset=utf-8\\\\n\\"
53+
\\"Plural-Forms: nplurals=2; plural=(n!=1);\\\\n\\"
54+
55+
#: tests/fixtures/updateTest/test.js:3
56+
msgid \\"test\\"
57+
msgstr \\"\\"
58+
59+
#: tests/fixtures/updateTest/test.js:4
60+
msgid \\"new\\"
61+
msgstr \\"\\"
62+
63+
#: tests/fixtures/updateTest/test.js:6
64+
#, javascript-format
65+
msgid \\"\${ n } banana\\"
66+
msgid_plural \\"\${ n } bananas\\"
67+
msgstr[0] \\"\\"
68+
msgstr[1] \\"\\"
69+
"
70+
`;

0 commit comments

Comments
 (0)