Skip to content

Commit

Permalink
feat: --watch mode for extract and compile (#974)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack1913 authored Feb 23, 2021
1 parent a584194 commit a4f90ee
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 26 deletions.
18 changes: 16 additions & 2 deletions docs/ref/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Commands
``extract``
-----------

.. lingui-cli:: extract [files...] [--clean] [--overwrite] [--format <format>] [--locale <locale>] [--convert-from <format>] [--verbose]
.. lingui-cli:: extract [files...] [--clean] [--overwrite] [--format <format>] [--locale <locale>] [--convert-from <format>] [--verbose] [--watch]

This command extracts messages from source files and creates a message catalog for
each language using the following steps:
Expand Down Expand Up @@ -101,6 +101,14 @@ Convert message catalogs from previous format (see :conf:`format` option).

Prints additional information.

.. lingui-cli-option:: --watch

Watch mode.

Watches only for changes in files in paths defined in config file or in the command itself.

Remember to use this only in development as this command do not cleans obsolete translations.

``extract-template``
--------------------

Expand All @@ -115,7 +123,7 @@ Prints additional information.
``compile``
-----------

.. lingui-cli:: compile [--strict] [--format <format>] [--verbose] [--namespace <namespace>]
.. lingui-cli:: compile [--strict] [--format <format>] [--verbose] [--namespace <namespace>] [--watch]

This command compiles message catalogs in :conf:`localeDir` and outputs
minified Javascript files. Each message is replaced with a function
Expand Down Expand Up @@ -144,3 +152,9 @@ global configuration).

Is the same as using :conf:`compileNamespace` with the value "ts".
Generates a {compiledFile}.d.ts and the compiled file is generated using the extension .ts

.. lingui-cli-option:: --watch

Watch mode.

Watches only for changes in locale files in your defined locale catalogs. For ex. ``locales\en\messages.po``
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"babel-plugin-macros": "^2.8.0",
"bcp-47": "^1.0.7",
"chalk": "^4.1.0",
"chokidar": "3.5.1",
"cli-table": "^0.3.1",
"commander": "^6.1.0",
"date-fns": "^2.16.1",
Expand Down
44 changes: 38 additions & 6 deletions packages/cli/src/lingui-compile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import chalk from "chalk"
import chokidar from "chokidar"
import fs from "fs"
import * as R from "ramda"
import program from "commander"
Expand Down Expand Up @@ -129,6 +130,7 @@ if (require.main === module) {
"--namespace <namespace>",
"Specify namespace for compiled bundle. Ex: cjs(default) -> module.exports, es -> export, window.test -> window.test"
)
.option("--watch", "Enables Watch Mode")
.on("--help", function () {
console.log("\n Examples:\n")
console.log(
Expand All @@ -153,16 +155,46 @@ if (require.main === module) {
config.format = program.format
}

const results = command(config, {
verbose: program.verbose || false,
const compile = () => command(config, {
verbose: program.watch || program.verbose || false,
allowEmpty: !program.strict,
typescript: program.typescript || config.compileNamespace === "ts" || false,
namespace: program.namespace, // we want this to be undefined if user does not specify so default can be used
})

if (!results) {
process.exit(1)
}
// Check if Watch Mode is enabled
if (program.watch) {
const NAME = "{name}"
const LOCALE = "{locale}"

console.info(chalk.bold("Initializing Watch Mode..."))

const catalogs = getCatalogs(config);
let paths = [];

config.locales.forEach((locale) => {
catalogs.forEach((catalog) => {
paths.push(`${catalog.path.replace(LOCALE, locale).replace(NAME, "*")}.${config.format}`)
})
})

const watcher = chokidar.watch(paths, {
persistent: true,
});

console.log("Done!")
const onReady = () => {
console.info(chalk.green.bold("Watcher is ready!"))
watcher.on('add', () => compile()).on('change', () => compile());
};

watcher.on('ready', () => onReady());
} else {
const results = compile();

if (!results) {
process.exit(1)
}

console.log("Done!")
}
}
75 changes: 57 additions & 18 deletions packages/cli/src/lingui-extract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import chalk from "chalk"
import chokidar from "chokidar"
import program from "commander"

import { getConfig, LinguiConfig } from "@lingui/conf"
Expand All @@ -15,6 +16,7 @@ export type CliExtractOptions = {
overwrite: boolean
locale: string
prevFormat: string | null
watch?: boolean
}

export default function command(
Expand All @@ -33,6 +35,7 @@ export default function command(
process.env.LINGUI_EXTRACT = "1"

options.verbose && console.error("Extracting messages from source files…")

const catalogs = getCatalogs(config)
const catalogStats: { [path: string]: AllCatalogsType } = {}
catalogs.forEach((catalog) => {
Expand All @@ -51,16 +54,19 @@ export default function command(
console.log()
})

console.error(
`(use "${chalk.yellow(
helpRun("extract")
)}" to update catalogs with new messages)`
)
console.error(
`(use "${chalk.yellow(
helpRun("compile")
)}" to compile catalogs for production)`
)
if (!options.watch) {
console.error(
`(use "${chalk.yellow(
helpRun("extract")
)}" to update catalogs with new messages)`
)
console.error(
`(use "${chalk.yellow(
helpRun("compile")
)}" to compile catalogs for production)`
)
}

return true
}

Expand All @@ -75,6 +81,7 @@ if (require.main === module) {
"--convert-from <format>",
"Convert from previous format of message catalogs"
)
.option("--watch", "Enables Watch Mode")
// Obsolete options
.option(
"--babelOptions",
Expand Down Expand Up @@ -127,14 +134,46 @@ if (require.main === module) {
}

if (hasErrors) process.exit(1)

const extract = (filePath?: string) =>
command(config, {
verbose: program.watch || program.verbose || false,
clean: program.watch ? false : program.clean || false,
overwrite: program.watch || program.overwrite || false,
locale: program.locale,
watch: program.watch || false,
files: filePath ? [filePath] : undefined,
prevFormat,
})


const result = command(config, {
verbose: program.verbose || false,
clean: program.clean || false,
overwrite: program.overwrite || false,
locale: program.locale,
prevFormat,
})
// Check if Watch Mode is enabled
if (program.watch) {
console.info(chalk.bold("Initializing Watch Mode..."))

const catalogs = getCatalogs(config)
let paths = [];
let ignored = [];

if (!result) process.exit(1)
catalogs.forEach((catalog) => {
paths.push(...catalog.include);
ignored.push(...catalog.exclude);
})

const watcher = chokidar.watch(paths, {
ignored: ['/(^|[\/\\])\../', ...ignored],
persistent: true,
});

const onReady = () => {
console.info(chalk.green.bold("Watcher is ready!"))
watcher.on('add', (path) => extract(path)).on('change', (path) => extract(path));
};

watcher.on('ready', () => onReady());
} else {
const result = extract();

if (!result) process.exit(1)
}
}
27 changes: 27 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4282,6 +4282,21 @@ chokidar@^3.4.1:
optionalDependencies:
fsevents "~2.1.2"

chokidar@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
dependencies:
anymatch "~3.1.1"
braces "~3.0.2"
glob-parent "~5.1.0"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
readdirp "~3.5.0"
optionalDependencies:
fsevents "~2.3.1"

chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
Expand Down Expand Up @@ -6148,6 +6163,11 @@ fsevents@^2.1.2, fsevents@~2.1.2:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==

fsevents@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==

ftp@~0.3.10:
version "0.3.10"
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
Expand Down Expand Up @@ -10427,6 +10447,13 @@ readdirp@~3.4.0:
dependencies:
picomatch "^2.2.1"

readdirp@~3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
dependencies:
picomatch "^2.2.1"

redent@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
Expand Down

1 comment on commit a4f90ee

@vercel
Copy link

@vercel vercel bot commented on a4f90ee Feb 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.