i18n-js 4.0.0.alpha4 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -2
- data/MIGRATING_FROM_V3_TO_V4.md +191 -0
- data/README.md +73 -17
- data/i18n-js.gemspec +1 -1
- data/lib/guard/i18n-js.rb +21 -4
- data/lib/i18n-js/cli/check_command.rb +37 -3
- data/lib/i18n-js/cli/export_command.rb +17 -3
- data/lib/i18n-js/listen.rb +23 -9
- data/lib/i18n-js/schema.rb +13 -1
- data/lib/i18n-js/version.rb +1 -1
- metadata +9 -10
- data/i18njs.png +0 -0
- data/images/i18njs-check.gif +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb5f60568907f90a59b7d19a6b2f61cf9a3fff95ea419b1b8b31deab16529dc6
|
|
4
|
+
data.tar.gz: ca65b2bf6717b93218092e8c994cdbac8af6bc69fddab421ebef976c87dc5503
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e33c8605b5197cbdc6a8f30ef1cb7e5f911f84dd177d488489fcfc82e5dd2b8fb3e387b0fe89683c3e71c6025ff7b47685163317540c4e2c5c756936660be55
|
|
7
|
+
data.tar.gz: b4367db58b89392c42c94121ccdde7179e1ea455de6c20685ded2c034304ce4c8c44cbfa1a4967610443e4f91116058ee86bc14d2e913a2c6006ee648c189dd9
|
data/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,13 @@ Prefix your message with one of the following:
|
|
|
11
11
|
- [Security] in case of vulnerabilities.
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## v4.0.1
|
|
15
15
|
|
|
16
|
-
-
|
|
16
|
+
- [Fixed] Shell out export to avoid handling I18n reloading heuristics.
|
|
17
|
+
- [Changed] `I18nJS.listen` now accepts a directories list to watch.
|
|
18
|
+
- [Changed] `I18nJS.listen` now accepts
|
|
19
|
+
[listen](https://rubygems.org/gems/listen) options via `:options`.
|
|
20
|
+
|
|
21
|
+
## Jul 29, 2022
|
|
22
|
+
|
|
23
|
+
- Official release of i18n-js v4.0.0.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Migrating from v3 to v4
|
|
2
|
+
|
|
3
|
+
I18n-js v4 is a breaking change release and diverges quite a lot from how the
|
|
4
|
+
previous version worked. This guides summarizes the process of upgrading an app
|
|
5
|
+
that uses i18n-js v3 to v4.
|
|
6
|
+
|
|
7
|
+
## Development
|
|
8
|
+
|
|
9
|
+
Previously, you could use a middleware to export translations (some people even
|
|
10
|
+
used this in production 😬). In development, you can now use whatever your want,
|
|
11
|
+
because i18n-js doesn't make any assumptions. All you need to do is running
|
|
12
|
+
`i18n export`, either manually or by using something that listens to file
|
|
13
|
+
changes.
|
|
14
|
+
|
|
15
|
+
If you like watchman, you can use something like this:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
#!/usr/bin/env bash
|
|
19
|
+
|
|
20
|
+
root=`pwd`
|
|
21
|
+
|
|
22
|
+
watchman watch-del "$root"
|
|
23
|
+
watchman watch-project "$root"
|
|
24
|
+
watchman trigger-del "$root" i18n
|
|
25
|
+
|
|
26
|
+
watchman -j <<-JSON
|
|
27
|
+
[
|
|
28
|
+
"trigger",
|
|
29
|
+
"$root",
|
|
30
|
+
{
|
|
31
|
+
"name": "i18n",
|
|
32
|
+
"expression": [
|
|
33
|
+
"anyof",
|
|
34
|
+
["match", "config/locales/**/*.yml", "wholename"],
|
|
35
|
+
["match", "config/locales/**/*.po", "wholename"],
|
|
36
|
+
["match", "config/i18n.yml", "wholename"]
|
|
37
|
+
],
|
|
38
|
+
"command": ["i18n", "export"]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
JSON
|
|
42
|
+
|
|
43
|
+
# If you're running this through Foreman, then uncomment the following lines:
|
|
44
|
+
# while true; do
|
|
45
|
+
# sleep 1
|
|
46
|
+
# done
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You can also use guard. Make sure you have both
|
|
50
|
+
[guard](https://rubygems.org/packages/guard) and
|
|
51
|
+
[guard-compat](https://rubygems.org/packages/guard-compat) installed and use
|
|
52
|
+
Guardfile file with the following contents:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
guard(:"i18n-js",
|
|
56
|
+
run_on_start: true,
|
|
57
|
+
config_file: "./config/i18n.yml",
|
|
58
|
+
require_file: "./config/environment.rb") do
|
|
59
|
+
watch(%r{^config/locales/.+\.(yml|po)$})
|
|
60
|
+
watch(%r{^config/i18n.yml$})
|
|
61
|
+
watch("Gemfile")
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
To run guard, use `guard start -i`.
|
|
66
|
+
|
|
67
|
+
Finally, you can use [listen](https://rubygems.org/gems/listen). Create the file
|
|
68
|
+
`config/initializers/i18n.rb` with the following content:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
Rails.application.config.after_initialize do
|
|
72
|
+
require "i18n-js/listen"
|
|
73
|
+
# This will only run in development.
|
|
74
|
+
I18nJS.listen
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **Warning**:
|
|
79
|
+
>
|
|
80
|
+
> No matter which approach you choose, the idea is that you _precompile_ your
|
|
81
|
+
> translations when going to production. DO NOT RUN any of the above in
|
|
82
|
+
> production.
|
|
83
|
+
|
|
84
|
+
## Exporting translations
|
|
85
|
+
|
|
86
|
+
The build process for i18n now relies on an external CLI called `i18n`. All you
|
|
87
|
+
need to do is executing `i18n export` in your build step to generate the json
|
|
88
|
+
files for your translations.
|
|
89
|
+
|
|
90
|
+
## Using your translations
|
|
91
|
+
|
|
92
|
+
The JavaScript package is now a separate thing and need to be installed using
|
|
93
|
+
your favorite tooling (e.g. yarn, npm, pnpm, etc).
|
|
94
|
+
|
|
95
|
+
```console
|
|
96
|
+
$ yarn add i18n-js@latest
|
|
97
|
+
$ npm i --save-dev i18n-js@latest
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
From now on, the way you load translations and set up I18n-js is totally up to
|
|
101
|
+
you, but means you need to load the json files and attach to the I18n-js
|
|
102
|
+
instance. This is how I do it in a project I'm doing right now (Rails 7 +
|
|
103
|
+
esbuild + TypeScript). First, we need to load the I18n-js configuration from the
|
|
104
|
+
main JavaScript file:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// app/javascript/application.ts
|
|
108
|
+
import { i18n } from "./config/i18n";
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then we need to load our translations and instantiate the I18n-js class.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// app/javascript/config/i18n.ts
|
|
115
|
+
import { I18n } from "i18n-js";
|
|
116
|
+
import translations from "translations.json";
|
|
117
|
+
|
|
118
|
+
// Fetch user locale from html#lang.
|
|
119
|
+
// This value is being set on `app/views/layouts/application.html.erb` and
|
|
120
|
+
// is inferred from `ACCEPT-LANGUAGE` header.
|
|
121
|
+
const userLocale = document.documentElement.lang;
|
|
122
|
+
|
|
123
|
+
export const i18n = new I18n();
|
|
124
|
+
i18n.store(translations);
|
|
125
|
+
i18n.defaultLocale = "en";
|
|
126
|
+
i18n.enableFallback = true;
|
|
127
|
+
i18n.locale = userLocale;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The best thing about the above is that it is a pretty straightforward pattern in
|
|
131
|
+
the JavaScript community. It doesn't rely on specific parts from Sprockets (I'm
|
|
132
|
+
not even using it on my projects) or eRb files.
|
|
133
|
+
|
|
134
|
+
## Ruby on Rails
|
|
135
|
+
|
|
136
|
+
### Upgrading the configuration file
|
|
137
|
+
|
|
138
|
+
The configuration file loaded from `config/i18nyml` has changed. Given the v3
|
|
139
|
+
configuration below
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
---
|
|
143
|
+
translations:
|
|
144
|
+
- file: "app/assets/javascripts/date_formats.js"
|
|
145
|
+
only: "*.date.formats"
|
|
146
|
+
- file: "app/assets/javascripts/other.js"
|
|
147
|
+
only: ["*.activerecord", "*.admin.*.title"]
|
|
148
|
+
- file: "app/assets/javascripts/everything_else.js"
|
|
149
|
+
except:
|
|
150
|
+
- "*.activerecord"
|
|
151
|
+
- "*.admin.*.title"
|
|
152
|
+
- "*.date.formats"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
the equivalent configuration file for v4 would be
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
---
|
|
159
|
+
translations:
|
|
160
|
+
- file: "app/assets/javascripts/date_formats.js"
|
|
161
|
+
patterns:
|
|
162
|
+
- "*.date.formats"
|
|
163
|
+
- file: "app/assets/javascripts/other.js"
|
|
164
|
+
patterns:
|
|
165
|
+
- "*.activerecord"
|
|
166
|
+
- "*.admin.*.title"
|
|
167
|
+
- file: "app/assets/javascripts/everything_else.js"
|
|
168
|
+
patterns:
|
|
169
|
+
# Notice the exclamation mark.
|
|
170
|
+
- "!*.activerecord"
|
|
171
|
+
- "!*.admin.*.title"
|
|
172
|
+
- "!*.date.formats"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Other configuration options:
|
|
176
|
+
|
|
177
|
+
- `export_i18n_js`: removed without an equivalent
|
|
178
|
+
- `fallbacks`: removed without an equivalent
|
|
179
|
+
- `js_available_locales`: removed (on v4 you can use groups, like in
|
|
180
|
+
`{pt-BR,en}.*`)
|
|
181
|
+
- `namespace`: removed without an equivalent
|
|
182
|
+
- `sort_translation_keys`: removed (on v4 keys will always be sorted)
|
|
183
|
+
- `translations[].prefix`: removed without an equivalent
|
|
184
|
+
- `translations[].pretty_print`: removed (on v4 files will always be exported in
|
|
185
|
+
a readable format)
|
|
186
|
+
|
|
187
|
+
### Placeholders
|
|
188
|
+
|
|
189
|
+
Previously, v3 had the `%{locale}` placeholder, which can be used as part of the
|
|
190
|
+
directory and/or file name. Now, the syntax is just `:locale`. Additionally, you
|
|
191
|
+
can also use `:digest`, which uses a MD5 hex digest of the exported file.
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img width="250" height="58" src="https://github.com/fnando/i18n-js/raw/main/i18njs.png" alt="i18n.js">
|
|
2
|
+
<img width="250" height="58" src="https://github.com/fnando/i18n-js/raw/main/images/i18njs.png" alt="i18n.js">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
<small>
|
|
13
13
|
Oh, you don't use Ruby? No problem! You can still use i18n-js
|
|
14
14
|
<br>
|
|
15
|
-
and the
|
|
16
|
-
<a href="https://www.npmjs.com/package/i18n-js/v/
|
|
15
|
+
and the
|
|
16
|
+
<a href="https://www.npmjs.com/package/i18n-js/v/latest">companion JavaScript package</a>.
|
|
17
17
|
</small>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
@@ -24,8 +24,6 @@
|
|
|
24
24
|
<a href="https://tldrlegal.com/license/mit-license"><img src="https://img.shields.io/:License-MIT-blue.svg" alt="MIT License"></a>
|
|
25
25
|
</p>
|
|
26
26
|
|
|
27
|
-

|
|
28
|
-
|
|
29
27
|
## Installation
|
|
30
28
|
|
|
31
29
|
```bash
|
|
@@ -35,7 +33,7 @@ gem install i18n-js
|
|
|
35
33
|
Or add the following line to your project's Gemfile:
|
|
36
34
|
|
|
37
35
|
```ruby
|
|
38
|
-
gem "i18n-js"
|
|
36
|
+
gem "i18n-js"
|
|
39
37
|
```
|
|
40
38
|
|
|
41
39
|
## Usage
|
|
@@ -47,6 +45,14 @@ About patterns:
|
|
|
47
45
|
- `*.messages.*`
|
|
48
46
|
- Patterns starting with `!` are excluded.
|
|
49
47
|
- `!*.activerecord.*` will exclude all ActiveRecord translations.
|
|
48
|
+
- You can use groups:
|
|
49
|
+
- `{pt-BR,en}.js.*` will include only `pt-BR` and `en` translations, even if
|
|
50
|
+
more languages are available.
|
|
51
|
+
|
|
52
|
+
> **Note**:
|
|
53
|
+
>
|
|
54
|
+
> Patterns use [glob](https://rubygems.org/gems/glob), so check it out for the
|
|
55
|
+
> most up-to-date documentation about what's available.
|
|
50
56
|
|
|
51
57
|
The config file:
|
|
52
58
|
|
|
@@ -111,9 +117,37 @@ default locale. Here's an example:
|
|
|
111
117
|
This command will exist with status 1 whenever there are missing translations.
|
|
112
118
|
This way you can use it as a CI linting.
|
|
113
119
|
|
|
120
|
+
You can ignore keys by adding a list to the config file:
|
|
121
|
+
|
|
122
|
+
```yml
|
|
123
|
+
---
|
|
124
|
+
translations:
|
|
125
|
+
- file: app/frontend/locales/en.json
|
|
126
|
+
patterns:
|
|
127
|
+
- "*"
|
|
128
|
+
- "!*.activerecord"
|
|
129
|
+
- "!*.errors"
|
|
130
|
+
- "!*.number.nth"
|
|
131
|
+
|
|
132
|
+
- file: app/frontend/locales/:locale.:digest.json
|
|
133
|
+
patterns:
|
|
134
|
+
- "*"
|
|
135
|
+
|
|
136
|
+
check:
|
|
137
|
+
ignore:
|
|
138
|
+
- en.mailer.login.subject
|
|
139
|
+
- en.mailer.login.body
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
> **Note**:
|
|
143
|
+
>
|
|
144
|
+
> In order to avoid mistakenly ignoring keys, this configuration option only
|
|
145
|
+
> accepts the full translation scope, rather than accepting a pattern like
|
|
146
|
+
> `pt.ignored.scope.*`.
|
|
147
|
+
|
|
114
148
|
## Automatically export translations
|
|
115
149
|
|
|
116
|
-
### Using watchman
|
|
150
|
+
### Using [watchman](https://facebook.github.io/watchman/)
|
|
117
151
|
|
|
118
152
|
Create a script at `bin/i18n-watch`.
|
|
119
153
|
|
|
@@ -158,11 +192,11 @@ line to your Procfile:
|
|
|
158
192
|
i18n: ./bin/i18n-watch
|
|
159
193
|
```
|
|
160
194
|
|
|
161
|
-
### Using guard
|
|
195
|
+
### Using [guard](https://rubygems.org/gems/guard)
|
|
162
196
|
|
|
163
|
-
Install [guard](https://rubygems.org/
|
|
164
|
-
[guard-compat](https://rubygems.org/
|
|
165
|
-
|
|
197
|
+
Install [guard](https://rubygems.org/gems/guard) and
|
|
198
|
+
[guard-compat](https://rubygems.org/gems/guard-compat). Then create a Guardfile
|
|
199
|
+
with the following configuration:
|
|
166
200
|
|
|
167
201
|
```ruby
|
|
168
202
|
guard(:"i18n-js",
|
|
@@ -180,7 +214,7 @@ accordingly.
|
|
|
180
214
|
|
|
181
215
|
Now you can run `guard start -i`.
|
|
182
216
|
|
|
183
|
-
### Using listen
|
|
217
|
+
### Using [listen](https://rubygems.org/gems/listen)
|
|
184
218
|
|
|
185
219
|
Create a file under `config/initializers/i18n.rb` with the following content:
|
|
186
220
|
|
|
@@ -192,8 +226,21 @@ end
|
|
|
192
226
|
```
|
|
193
227
|
|
|
194
228
|
The code above will watch for changes based on `config/i18n.yml` and
|
|
195
|
-
`config/locales`. You can customize these options
|
|
196
|
-
|
|
229
|
+
`config/locales`. You can customize these options:
|
|
230
|
+
|
|
231
|
+
- `config_file` - i18n-js configuration file
|
|
232
|
+
- `locales_dir` - one or multiple directories to watch for locales changes
|
|
233
|
+
- `options` - passed directly to [listen](https://github.com/guard/listen/#options)
|
|
234
|
+
|
|
235
|
+
Example:
|
|
236
|
+
|
|
237
|
+
```ruby
|
|
238
|
+
I18nJS.listen(
|
|
239
|
+
config_file: "config/i18n.yml",
|
|
240
|
+
locales_dir: ["config/locales", "app/views"],
|
|
241
|
+
options: {only: %r{.yml$}
|
|
242
|
+
)
|
|
243
|
+
```
|
|
197
244
|
|
|
198
245
|
### Integrating with your frontend
|
|
199
246
|
|
|
@@ -203,6 +250,13 @@ that loads all the exported translation.
|
|
|
203
250
|
|
|
204
251
|
### FAQ
|
|
205
252
|
|
|
253
|
+
#### I'm running v3. Is there a migration plan?
|
|
254
|
+
|
|
255
|
+
[There's a document](https://github.com/fnando/i18n-js/tree/main/MIGRATING_FROM_V3_TO_V4.md)
|
|
256
|
+
outlining some of the things you need to do to migrate from v3 to v4. It may not
|
|
257
|
+
be as complete as we'd like it to be, so let's know if you face any issues
|
|
258
|
+
during the migration is not outline is that document.
|
|
259
|
+
|
|
206
260
|
#### How can I export translations without having a database around?
|
|
207
261
|
|
|
208
262
|
Some people may have a build process using something like Docker that don't
|
|
@@ -222,9 +276,11 @@ require "action_view/railtie"
|
|
|
222
276
|
I18n.load_path += Dir["./config/locales/**/*.yml"]
|
|
223
277
|
```
|
|
224
278
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
279
|
+
> **Note**:
|
|
280
|
+
>
|
|
281
|
+
> You may not need to load ActiveSupport and ActionView lines, or even may need
|
|
282
|
+
> to add additional requires for other libs. With this approach you have full
|
|
283
|
+
> control on what's going to be loaded.
|
|
228
284
|
|
|
229
285
|
## Maintainer
|
|
230
286
|
|
data/i18n-js.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
29
29
|
`git ls-files -z`
|
|
30
30
|
.split("\x0")
|
|
31
|
-
.reject {|f| f.match(%r{^(test|spec|features)/}) }
|
|
31
|
+
.reject {|f| f.match(%r{^(test|spec|features|images)/}) }
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
spec.bindir = "exe"
|
data/lib/guard/i18n-js.rb
CHANGED
|
@@ -53,13 +53,30 @@ module Guard
|
|
|
53
53
|
info("Changes detected: #{changes.join(', ')}") if changes
|
|
54
54
|
|
|
55
55
|
@current_thread = Thread.new do
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
capture do
|
|
57
|
+
system "i18n",
|
|
58
|
+
"export",
|
|
59
|
+
"--config",
|
|
60
|
+
config_file.to_s,
|
|
61
|
+
"--require",
|
|
62
|
+
require_file.to_s,
|
|
63
|
+
"--quiet"
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
66
|
|
|
60
67
|
current_thread.join
|
|
61
68
|
end
|
|
62
69
|
|
|
70
|
+
def capture
|
|
71
|
+
original = $stdout
|
|
72
|
+
$stdout = StringIO.new
|
|
73
|
+
yield
|
|
74
|
+
rescue StandardError
|
|
75
|
+
# noop
|
|
76
|
+
ensure
|
|
77
|
+
$stdout = original
|
|
78
|
+
end
|
|
79
|
+
|
|
63
80
|
def validate_file(key, file)
|
|
64
81
|
return true if file && File.file?(file)
|
|
65
82
|
|
|
@@ -68,11 +85,11 @@ module Guard
|
|
|
68
85
|
end
|
|
69
86
|
|
|
70
87
|
def error(message)
|
|
71
|
-
::Guard::UI.error "[
|
|
88
|
+
::Guard::UI.error "[i18n-js] #{message}"
|
|
72
89
|
end
|
|
73
90
|
|
|
74
91
|
def info(message)
|
|
75
|
-
::Guard::UI.info "[
|
|
92
|
+
::Guard::UI.info "[i18n-js] #{message}"
|
|
76
93
|
end
|
|
77
94
|
end
|
|
78
95
|
end
|
|
@@ -69,9 +69,14 @@ module I18nJS
|
|
|
69
69
|
)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
config = Glob::SymbolizeKeys.call(YAML.load_file(config_file))
|
|
73
|
+
Schema.validate!(config)
|
|
74
|
+
|
|
72
75
|
load_require_file!(require_file) if require_file
|
|
76
|
+
|
|
73
77
|
default_locale = I18n.default_locale
|
|
74
78
|
available_locales = I18n.available_locales
|
|
79
|
+
ignored_keys = config.dig(:check, :ignore) || []
|
|
75
80
|
|
|
76
81
|
mapping = available_locales.each_with_object({}) do |locale, buffer|
|
|
77
82
|
buffer[locale] =
|
|
@@ -81,21 +86,50 @@ module I18nJS
|
|
|
81
86
|
|
|
82
87
|
default_locale_keys = mapping.delete(default_locale)
|
|
83
88
|
|
|
89
|
+
if ignored_keys.any?
|
|
90
|
+
ui.stdout_print "=> Check #{options[:config_file].inspect} for " \
|
|
91
|
+
"ignored keys."
|
|
92
|
+
end
|
|
93
|
+
|
|
84
94
|
ui.stdout_print "=> #{default_locale}: #{default_locale_keys.size} " \
|
|
85
95
|
"translations"
|
|
86
96
|
|
|
87
97
|
total_missing_count = 0
|
|
88
98
|
|
|
89
99
|
mapping.each do |locale, partial_keys|
|
|
90
|
-
|
|
91
|
-
|
|
100
|
+
ignored_count = 0
|
|
101
|
+
|
|
102
|
+
# Compute list of filtered keys (i.e. keys not ignored)
|
|
103
|
+
filtered_keys = partial_keys.reject do |key|
|
|
104
|
+
key = "#{locale}.#{key}"
|
|
105
|
+
|
|
106
|
+
ignored = ignored_keys.include?(key)
|
|
107
|
+
ignored_count += 1 if ignored
|
|
108
|
+
ignored
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
extraneous = (partial_keys - default_locale_keys).reject do |key|
|
|
112
|
+
key = "#{locale}.#{key}"
|
|
113
|
+
ignored = ignored_keys.include?(key)
|
|
114
|
+
ignored_count += 1 if ignored
|
|
115
|
+
ignored
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
missing = (default_locale_keys - (filtered_keys - extraneous))
|
|
119
|
+
.reject {|key| ignored_keys.include?("#{locale}.#{key}") }
|
|
120
|
+
|
|
121
|
+
ignored_count += extraneous.size
|
|
92
122
|
total_missing_count += missing.size
|
|
123
|
+
|
|
93
124
|
ui.stdout_print "=> #{locale}: #{missing.size} missing, " \
|
|
94
|
-
"#{extraneous.size} extraneous"
|
|
125
|
+
"#{extraneous.size} extraneous, " \
|
|
126
|
+
"#{ignored_count} ignored"
|
|
95
127
|
|
|
96
128
|
all_keys = (default_locale_keys + extraneous + missing).uniq.sort
|
|
97
129
|
|
|
98
130
|
all_keys.each do |key|
|
|
131
|
+
next if ignored_keys.include?("#{locale}.#{key}")
|
|
132
|
+
|
|
99
133
|
label = if extraneous.include?(key)
|
|
100
134
|
ui.yellow("extraneous")
|
|
101
135
|
elsif missing.include?(key)
|
|
@@ -27,6 +27,14 @@ module I18nJS
|
|
|
27
27
|
options[:require_file] = require_file
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
opts.on(
|
|
31
|
+
"-q",
|
|
32
|
+
"--quiet",
|
|
33
|
+
"A Ruby file that must be loaded"
|
|
34
|
+
) do |quiet|
|
|
35
|
+
options[:quiet] = quiet
|
|
36
|
+
end
|
|
37
|
+
|
|
30
38
|
opts.on("-h", "--help", "Prints this help") do
|
|
31
39
|
ui.exit_with opts.to_s
|
|
32
40
|
end
|
|
@@ -39,11 +47,11 @@ module I18nJS
|
|
|
39
47
|
ui.fail_with("=> ERROR: you need to specify the config file")
|
|
40
48
|
end
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
log("=> Config file:", options[:config_file].inspect)
|
|
43
51
|
config_file = File.expand_path(options[:config_file])
|
|
44
52
|
|
|
45
53
|
if options[:require_file]
|
|
46
|
-
|
|
54
|
+
log("=> Require file:", options[:require_file].inspect)
|
|
47
55
|
require_file = File.expand_path(options[:require_file])
|
|
48
56
|
end
|
|
49
57
|
|
|
@@ -66,7 +74,13 @@ module I18nJS
|
|
|
66
74
|
I18nJS.call(config_file: config_file)
|
|
67
75
|
end
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
log("=> Done in #{time.round(2)}s")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private def log(*args)
|
|
81
|
+
return if options[:quiet]
|
|
82
|
+
|
|
83
|
+
ui.stdout_print(*args)
|
|
70
84
|
end
|
|
71
85
|
|
|
72
86
|
private def set_defaults!
|
data/lib/i18n-js/listen.rb
CHANGED
|
@@ -7,7 +7,8 @@ module I18nJS
|
|
|
7
7
|
|
|
8
8
|
def self.listen(
|
|
9
9
|
config_file: Rails.root.join("config/i18n.yml"),
|
|
10
|
-
locales_dir: Rails.root.join("config/locales")
|
|
10
|
+
locales_dir: Rails.root.join("config/locales"),
|
|
11
|
+
options: {}
|
|
11
12
|
)
|
|
12
13
|
return unless Rails.env.development?
|
|
13
14
|
return if started
|
|
@@ -18,12 +19,14 @@ module I18nJS
|
|
|
18
19
|
|
|
19
20
|
self.started = true
|
|
20
21
|
|
|
22
|
+
locales_dirs = Array(locales_dir)
|
|
23
|
+
|
|
21
24
|
relative_paths =
|
|
22
|
-
[config_file,
|
|
25
|
+
[config_file, *locales_dirs].map {|path| relative_path(path) }
|
|
23
26
|
|
|
24
27
|
debug("Watching #{relative_paths.inspect}")
|
|
25
28
|
|
|
26
|
-
listener(config_file,
|
|
29
|
+
listener(config_file, locales_dirs.map(&:to_s), options).start
|
|
27
30
|
I18nJS.call(config_file: config_file)
|
|
28
31
|
end
|
|
29
32
|
|
|
@@ -43,12 +46,12 @@ module I18nJS
|
|
|
43
46
|
@logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
def self.listener(config_file,
|
|
47
|
-
paths = [File.dirname(config_file),
|
|
49
|
+
def self.listener(config_file, locales_dirs, options)
|
|
50
|
+
paths = [File.dirname(config_file), *locales_dirs]
|
|
48
51
|
|
|
49
|
-
Listen.to(*paths) do |changed, added, removed|
|
|
52
|
+
Listen.to(*paths, options) do |changed, added, removed|
|
|
50
53
|
changes = compute_changes(
|
|
51
|
-
[config_file,
|
|
54
|
+
[config_file, *locales_dirs],
|
|
52
55
|
changed,
|
|
53
56
|
added,
|
|
54
57
|
removed
|
|
@@ -58,11 +61,22 @@ module I18nJS
|
|
|
58
61
|
|
|
59
62
|
debug(changes.map {|key, value| "#{key}=#{value.inspect}" }.join(", "))
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
capture do
|
|
65
|
+
system "i18n", "export", "--config", config_file.to_s
|
|
66
|
+
end
|
|
63
67
|
end
|
|
64
68
|
end
|
|
65
69
|
|
|
70
|
+
def self.capture
|
|
71
|
+
original = $stdout
|
|
72
|
+
$stdout = StringIO.new
|
|
73
|
+
yield
|
|
74
|
+
rescue StandardError
|
|
75
|
+
# noop
|
|
76
|
+
ensure
|
|
77
|
+
$stdout = original
|
|
78
|
+
end
|
|
79
|
+
|
|
66
80
|
def self.compute_changes(paths, changed, added, removed)
|
|
67
81
|
paths = paths.map {|path| relative_path(path) }
|
|
68
82
|
|
data/lib/i18n-js/schema.rb
CHANGED
|
@@ -4,8 +4,9 @@ module I18nJS
|
|
|
4
4
|
class Schema
|
|
5
5
|
InvalidError = Class.new(StandardError)
|
|
6
6
|
|
|
7
|
-
ROOT_KEYS = %i[translations].freeze
|
|
7
|
+
ROOT_KEYS = %i[translations check].freeze
|
|
8
8
|
REQUIRED_ROOT_KEYS = %i[translations].freeze
|
|
9
|
+
REQUIRED_CHECK_KEYS = %i[ignore].freeze
|
|
9
10
|
REQUIRED_TRANSLATION_KEYS = %i[file patterns].freeze
|
|
10
11
|
TRANSLATION_KEYS = %i[file patterns].freeze
|
|
11
12
|
|
|
@@ -25,6 +26,17 @@ module I18nJS
|
|
|
25
26
|
expect_required_keys(REQUIRED_ROOT_KEYS, target)
|
|
26
27
|
reject_extraneous_keys(ROOT_KEYS, target)
|
|
27
28
|
validate_translations
|
|
29
|
+
validate_check
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def validate_check
|
|
33
|
+
return unless target.key?(:check)
|
|
34
|
+
|
|
35
|
+
check = target[:check]
|
|
36
|
+
|
|
37
|
+
expect_type(:check, check, Hash, target)
|
|
38
|
+
expect_required_keys(REQUIRED_CHECK_KEYS, check)
|
|
39
|
+
expect_type(:ignore, check[:ignore], Array, check)
|
|
28
40
|
end
|
|
29
41
|
|
|
30
42
|
def validate_translations
|
data/lib/i18n-js/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: i18n-js
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nando Vieira
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-08-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: glob
|
|
@@ -173,12 +173,11 @@ files:
|
|
|
173
173
|
- CONTRIBUTING.md
|
|
174
174
|
- Gemfile
|
|
175
175
|
- LICENSE.md
|
|
176
|
+
- MIGRATING_FROM_V3_TO_V4.md
|
|
176
177
|
- README.md
|
|
177
178
|
- Rakefile
|
|
178
179
|
- exe/i18n
|
|
179
180
|
- i18n-js.gemspec
|
|
180
|
-
- i18njs.png
|
|
181
|
-
- images/i18njs-check.gif
|
|
182
181
|
- lib/guard/i18n-js.rb
|
|
183
182
|
- lib/guard/i18n-js/templates/Guardfile
|
|
184
183
|
- lib/guard/i18n-js/version.rb
|
|
@@ -200,10 +199,10 @@ metadata:
|
|
|
200
199
|
rubygems_mfa_required: 'true'
|
|
201
200
|
homepage_uri: https://github.com/fnando/i18n-js
|
|
202
201
|
bug_tracker_uri: https://github.com/fnando/i18n-js/issues
|
|
203
|
-
source_code_uri: https://github.com/fnando/i18n-js/tree/v4.0.
|
|
204
|
-
changelog_uri: https://github.com/fnando/i18n-js/tree/v4.0.
|
|
205
|
-
documentation_uri: https://github.com/fnando/i18n-js/tree/v4.0.
|
|
206
|
-
license_uri: https://github.com/fnando/i18n-js/tree/v4.0.
|
|
202
|
+
source_code_uri: https://github.com/fnando/i18n-js/tree/v4.0.1
|
|
203
|
+
changelog_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/CHANGELOG.md
|
|
204
|
+
documentation_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/README.md
|
|
205
|
+
license_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/LICENSE.md
|
|
207
206
|
post_install_message:
|
|
208
207
|
rdoc_options: []
|
|
209
208
|
require_paths:
|
|
@@ -215,9 +214,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
215
214
|
version: 2.6.0
|
|
216
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
216
|
requirements:
|
|
218
|
-
- - "
|
|
217
|
+
- - ">="
|
|
219
218
|
- !ruby/object:Gem::Version
|
|
220
|
-
version:
|
|
219
|
+
version: '0'
|
|
221
220
|
requirements: []
|
|
222
221
|
rubygems_version: 3.3.7
|
|
223
222
|
signing_key:
|
data/i18njs.png
DELETED
|
Binary file
|
data/images/i18njs-check.gif
DELETED
|
Binary file
|