Skip to content

Commit

Permalink
Add base dir arg for relative paths
Browse files Browse the repository at this point in the history
Previously it always used the process cwd, but in some cases that's not
ideal, and due to how node works you can't just chdir before executing
the command.
  • Loading branch information
ThiefMaster committed Sep 25, 2024
1 parent bb22f55 commit adf13a8
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-jsx-i18n",
"version": "0.6.0",
"version": "0.6.1",
"description": "Provides gettext-enhanced React components, a babel plugin for extracting the strings and a script to compile translated strings to a format usable by the components.",
"main": "client/index.js",
"types": "client/index.d.ts",
Expand Down
8 changes: 7 additions & 1 deletion src/tools/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,16 @@ yargs
coerce: val => val.split(','),
describe: 'file extensions to consider',
});
y.option('base', {
alias: 'b',
default: null,
type: 'string',
describe: 'base dir to generate relative file paths; default to current dir',
});
},
argv => {
const files = flattenPaths(argv.paths, argv.ext);
const {pot, errors} = extractFromFiles(files);
const {pot, errors} = extractFromFiles(files, argv.base || process.cwd());
if (errors) {
errors.forEach(err => console.error(err));
process.exit(1);
Expand Down
30 changes: 15 additions & 15 deletions src/tools/extract-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ const processElement = (path, types, allowParam = false) => {
return string;
};

const getLocation = (path, state) => {
const filename = relative(process.cwd(), state.file.opts.filename);
const getLocation = (base, path, state) => {
const filename = relative(base, state.file.opts.filename);
return `${filename}:${path.node.loc.start.line}`;
};

Expand All @@ -110,16 +110,16 @@ const getContext = path => {
return contextAttr ? contextAttr.value.value : undefined;
};

const processTranslate = (path, state, types) => {
const processTranslate = (base, path, state, types) => {
const translatableString = processElement(path, types, true);
return {
msgid: translatableString,
msgctxt: getContext(path),
reference: getLocation(path, state),
reference: getLocation(base, path, state),
};
};

const processTranslateString = (path, state, funcName, types) => {
const processTranslateString = (base, path, state, funcName, types) => {
const args = path.node.arguments;
if (args.length === 0) {
throw path.buildCodeFrameError('Translate.string() called with no arguments');
Expand All @@ -131,11 +131,11 @@ const processTranslateString = (path, state, funcName, types) => {
return {
msgid,
msgctxt,
reference: getLocation(path, state),
reference: getLocation(base, path, state),
};
};

const processPluralTranslate = (path, state, types) => {
const processPluralTranslate = (base, path, state, types) => {
let singularPath, pluralPath;
path
.get('children')
Expand Down Expand Up @@ -167,11 +167,11 @@ const processPluralTranslate = (path, state, types) => {
msgid: processElement(singularPath, types, true),
msgid_plural: processElement(pluralPath, types, true),
msgctxt: getContext(path),
reference: getLocation(path, state),
reference: getLocation(base, path, state),
};
};

const processPluralTranslateString = (path, state, funcName, types) => {
const processPluralTranslateString = (base, path, state, funcName, types) => {
const args = path.node.arguments;
if (args.length < 2) {
throw path.buildCodeFrameError('PluralTranslate.string() called with less than 2 arguments');
Expand All @@ -186,21 +186,21 @@ const processPluralTranslateString = (path, state, funcName, types) => {
msgid,
msgid_plural,
msgctxt,
reference: getLocation(path, state),
reference: getLocation(base, path, state),
};
};

const makeI18nPlugin = () => {
const makeI18nPlugin = base => {
const entries = [];
const i18nPlugin = ({types}) => {
return {
visitor: {
JSXElement(path, state) {
const elementName = path.node.openingElement.name.name;
if (elementName === 'Translate') {
entries.push(processTranslate(path, state, types));
entries.push(processTranslate(base, path, state, types));
} else if (elementName === 'PluralTranslate') {
entries.push(processPluralTranslate(path, state, types));
entries.push(processPluralTranslate(base, path, state, types));
}
},
CallExpression(path, state) {
Expand All @@ -224,9 +224,9 @@ const makeI18nPlugin = () => {
// we got a proper call of one of our translation functions
const qualifiedFuncName = `${elementName}.${funcName}`;
if (elementName === 'Translate') {
entries.push(processTranslateString(path, state, qualifiedFuncName, types));
entries.push(processTranslateString(base, path, state, qualifiedFuncName, types));
} else if (elementName === 'PluralTranslate') {
entries.push(processPluralTranslateString(path, state, qualifiedFuncName, types));
entries.push(processPluralTranslateString(base, path, state, qualifiedFuncName, types));
}
},
},
Expand Down
4 changes: 2 additions & 2 deletions src/tools/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import moment from 'moment-timezone';
import {mergeEntries} from 'babel-plugin-extract-text/src/builders';
import makeI18nPlugin from './extract-plugin';

const extractFromFiles = (files, headers = undefined, highlightErrors = true) => {
const extractFromFiles = (files, base, headers = undefined, highlightErrors = true) => {
const errors = [];
const {i18nPlugin, entries} = makeI18nPlugin();
const {i18nPlugin, entries} = makeI18nPlugin(base);

files.forEach(file => {
try {
Expand Down
141 changes: 141 additions & 0 deletions tests/__snapshots__/extract.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,147 @@ msgstr \\"\\"",
}
`;
exports[`Messages are properly extracted 3`] = `
Object {
"pot": "msgid \\"\\"
msgstr \\"\\"
\\"POT-Creation-Date: 2018-04-18 22:20+0000\\\\n\\"
\\"Content-Type: text/plain; charset=utf-8\\\\n\\"
\\"Content-Transfer-Encoding: 8bit\\\\n\\"
\\"MIME-Version: 1.0\\\\n\\"
\\"Generated-By: react-jsx-i18n-extract\\\\n\\"
#: example.jsx:37
#: example.jsx:38
#: example.jsx:86
msgid \\"\\\\\\"<strong>Rats.</strong>\\\\\\"\\"
msgstr \\"\\"
#: example.jsx:39
#: example.jsx:40
msgid \\"foobar\\"
msgstr \\"\\"
#: example.jsx:42
msgid \\"You are ugly!\\"
msgstr \\"\\"
#: example.jsx:43
msgid \\"space invader\\"
msgstr \\"\\"
#: example.jsx:44
msgid \\"cat\\"
msgid_plural \\"cats\\"
msgstr[0] \\"\\"
msgstr[1] \\"\\"
#: example.jsx:47
msgid \\"one {foo}\\"
msgid_plural \\"many {foo}\\"
msgstr[0] \\"\\"
msgstr[1] \\"\\"
#: example.jsx:50
msgid \\"foo {weird} bar {hello}{test} xxx\\"
msgstr \\"\\"
#: example.jsx:55
msgid \\"foo: {foo}\\"
msgstr \\"\\"
#: example.jsx:57
msgid \\"mixed: {mixedCase}\\"
msgstr \\"\\"
#: example.jsx:88
#: example.jsx:131
msgid \\"You have {count} rat.\\"
msgid_plural \\"You have {count} rats.\\"
msgstr[0] \\"\\"
msgstr[1] \\"\\"
#: example.jsx:99
msgid \\"Hello & World\\"
msgstr \\"\\"
#: example.jsx:101
msgid \\"Hey {name}, you want to {link}click me{/link} and you know it!\\"
msgstr \\"\\"
#: example.jsx:109
#: example.jsx:111
msgid \\"Bye World\\"
msgstr \\"\\"
#: example.jsx:113
msgid \\"Some <HTML> & entities: → &\\"
msgstr \\"\\"
#: example.jsx:116
msgid \\"Hover me\\"
msgstr \\"\\"
#: example.jsx:119
msgid \\"<HTML> is unescaped when extracted\\"
msgstr \\"\\"
#: example.jsx:121
msgid \\"xxx foo bar{test}{x} y{/x} moo\\"
msgstr \\"\\"
#: example.jsx:141
msgid \\"Little cats:\\"
msgstr \\"\\"
#: example.jsx:143
msgid \\"Little dogs:\\"
msgstr \\"\\"
#: example.jsx:145
msgid \\"This is an emphasized dynamic value: {number}\\"
msgstr \\"\\"
#: example.jsx:149
msgid \\"This is an emphasized translated value: {tag}hello{/tag}\\"
msgstr \\"\\"
#: example.jsx:155
msgid \\"This param is using string literals: {emphasize}hello world{/emphasize}\\"
msgstr \\"\\"
#: example.jsx:41
#: example.jsx:141
msgctxt \\"cat\\"
msgid \\"offspring\\"
msgstr \\"\\"
#: example.jsx:45
msgctxt \\"big\\"
msgid \\"cat\\"
msgid_plural \\"cats\\"
msgstr[0] \\"\\"
msgstr[1] \\"\\"
#: example.jsx:49
msgctxt \\"c\\"
msgid \\"one {foo}\\"
msgid_plural \\"many {foo}\\"
msgstr[0] \\"\\"
msgstr[1] \\"\\"
#: example.jsx:56
msgctxt \\"params-test\\"
msgid \\"foo: {foo}\\"
msgstr \\"\\"
#: example.jsx:143
msgctxt \\"dog\\"
msgid \\"offspring\\"
msgstr \\"\\"",
}
`;
exports[`Non-string call ignored 1`] = `
Object {
"pot": "msgid \\"\\"
Expand Down
4 changes: 3 additions & 1 deletion tests/extract.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import extractFromFiles from '../src/tools/extract';

const expectExtracted = (file, headers) => expect(extractFromFiles([file], headers, false));
const expectExtracted = (file, headers, base) =>
expect(extractFromFiles([file], base || process.cwd(), headers, false));

test('Messages are properly extracted', () => {
expectExtracted('test-data/example.jsx', {Custom: 'Headers'}).toMatchSnapshot();
expectExtracted('test-data/example.jsx').toMatchSnapshot();
expectExtracted('test-data/example.jsx', undefined, 'test-data').toMatchSnapshot();
});

test('Invalid stuff fails', () => {
Expand Down

0 comments on commit adf13a8

Please sign in to comment.