i18n_flow 0.1.0
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +13 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +22 -0
- data/README.md +103 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/rules.md +316 -0
- data/doc/tags.md +488 -0
- data/example/example.en.yml +14 -0
- data/example/example.ja.yml +9 -0
- data/exe/i18n_flow +11 -0
- data/i18n_flow.gemspec +28 -0
- data/i18n_flow.yml +8 -0
- data/lib/i18n_flow/cli/color.rb +18 -0
- data/lib/i18n_flow/cli/command_base.rb +33 -0
- data/lib/i18n_flow/cli/copy_command.rb +69 -0
- data/lib/i18n_flow/cli/help_command.rb +29 -0
- data/lib/i18n_flow/cli/lint_command/ascii.erb +45 -0
- data/lib/i18n_flow/cli/lint_command/ascii_renderer.rb +58 -0
- data/lib/i18n_flow/cli/lint_command/markdown.erb +49 -0
- data/lib/i18n_flow/cli/lint_command/markdown_renderer.rb +55 -0
- data/lib/i18n_flow/cli/lint_command.rb +55 -0
- data/lib/i18n_flow/cli/read_config_command.rb +20 -0
- data/lib/i18n_flow/cli/search_command/default.erb +11 -0
- data/lib/i18n_flow/cli/search_command/default_renderer.rb +67 -0
- data/lib/i18n_flow/cli/search_command/oneline.erb +5 -0
- data/lib/i18n_flow/cli/search_command/oneline_renderer.rb +39 -0
- data/lib/i18n_flow/cli/search_command.rb +59 -0
- data/lib/i18n_flow/cli/split_command.rb +20 -0
- data/lib/i18n_flow/cli/version_command.rb +9 -0
- data/lib/i18n_flow/cli.rb +42 -0
- data/lib/i18n_flow/configuration.rb +205 -0
- data/lib/i18n_flow/parser.rb +34 -0
- data/lib/i18n_flow/repository.rb +39 -0
- data/lib/i18n_flow/search.rb +176 -0
- data/lib/i18n_flow/splitter/merger.rb +60 -0
- data/lib/i18n_flow/splitter/strategy.rb +66 -0
- data/lib/i18n_flow/splitter.rb +5 -0
- data/lib/i18n_flow/util.rb +57 -0
- data/lib/i18n_flow/validator/errors.rb +99 -0
- data/lib/i18n_flow/validator/file_scope.rb +58 -0
- data/lib/i18n_flow/validator/multiplexer.rb +58 -0
- data/lib/i18n_flow/validator/symmetry.rb +154 -0
- data/lib/i18n_flow/validator.rb +4 -0
- data/lib/i18n_flow/version.rb +7 -0
- data/lib/i18n_flow/yaml_ast_proxy/mapping.rb +72 -0
- data/lib/i18n_flow/yaml_ast_proxy/node.rb +128 -0
- data/lib/i18n_flow/yaml_ast_proxy/node_meta_data.rb +86 -0
- data/lib/i18n_flow/yaml_ast_proxy/sequence.rb +29 -0
- data/lib/i18n_flow/yaml_ast_proxy.rb +57 -0
- data/lib/i18n_flow.rb +15 -0
- data/spec/lib/i18n_flow/cli/command_base_spec.rb +46 -0
- data/spec/lib/i18n_flow/cli/help_command_spec.rb +13 -0
- data/spec/lib/i18n_flow/cli/version_command_spec.rb +13 -0
- data/spec/lib/i18n_flow/configuration_spec.rb +334 -0
- data/spec/lib/i18n_flow/repository_spec.rb +40 -0
- data/spec/lib/i18n_flow/splitter/merger_spec.rb +149 -0
- data/spec/lib/i18n_flow/util_spec.rb +194 -0
- data/spec/lib/i18n_flow/validator/file_scope_spec.rb +74 -0
- data/spec/lib/i18n_flow/validator/multiplexer_spec.rb +68 -0
- data/spec/lib/i18n_flow/validator/symmetry_spec.rb +511 -0
- data/spec/lib/i18n_flow/yaml_ast_proxy/node_spec.rb +151 -0
- data/spec/lib/i18n_flow_spec.rb +21 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/repository_examples.rb +60 -0
- data/spec/support/util_macro.rb +14 -0
- metadata +214 -0
data/doc/tags.md
ADDED
@@ -0,0 +1,488 @@
|
|
1
|
+
Tags
|
2
|
+
====
|
3
|
+
|
4
|
+
!only
|
5
|
+
-----
|
6
|
+
|
7
|
+
With `!only`, you can explicitly claim that a key *may* not exist on both files.
|
8
|
+
Linter won't complain even if a key *does* exist. If you don't prefer this behavior, use stricter `!only:LOCALES`.
|
9
|
+
|
10
|
+
It comes in handy when you have texts that don't need to be translated into another language, still want to manage in a locale file.
|
11
|
+
|
12
|
+
<table><thead><tr>
|
13
|
+
<th></th>
|
14
|
+
<th>master</th>
|
15
|
+
<th>foreign</th>
|
16
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
17
|
+
|
18
|
+
```yaml
|
19
|
+
en:
|
20
|
+
title: 'Non zero sum'
|
21
|
+
desc: 'A situation in...'
|
22
|
+
```
|
23
|
+
|
24
|
+
</td><td>
|
25
|
+
|
26
|
+
```yaml
|
27
|
+
ja:
|
28
|
+
title: '非ゼロ和'
|
29
|
+
|
30
|
+
```
|
31
|
+
|
32
|
+
</td></tr><tr><td colspan=3>
|
33
|
+
|
34
|
+
Missing `ja.desc`
|
35
|
+
|
36
|
+
</td></tr></tbody></table>
|
37
|
+
|
38
|
+
|
39
|
+
<table><thead><tr>
|
40
|
+
<th></th>
|
41
|
+
<th>master</th>
|
42
|
+
<th>foreign</th>
|
43
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
44
|
+
|
45
|
+
```yaml
|
46
|
+
en:
|
47
|
+
title: 'Non zero sum'
|
48
|
+
desc: !only 'A situation in...'
|
49
|
+
```
|
50
|
+
|
51
|
+
</td><td>
|
52
|
+
|
53
|
+
```yaml
|
54
|
+
ja:
|
55
|
+
title: '非ゼロ和'
|
56
|
+
|
57
|
+
```
|
58
|
+
|
59
|
+
</td></tr><tr><td colspan=3>
|
60
|
+
|
61
|
+
Linter won't complain about `ja.desc` even if it doesn't exist
|
62
|
+
|
63
|
+
</td></tr></tbody></table>
|
64
|
+
|
65
|
+
<table><thead><tr>
|
66
|
+
<th></th>
|
67
|
+
<th>master</th>
|
68
|
+
<th>foreign</th>
|
69
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
70
|
+
|
71
|
+
```yaml
|
72
|
+
en:
|
73
|
+
title: 'Non zero sum'
|
74
|
+
desc: !only 'A situation in...'
|
75
|
+
```
|
76
|
+
|
77
|
+
</td><td>
|
78
|
+
|
79
|
+
```yaml
|
80
|
+
ja:
|
81
|
+
title: '非ゼロ和'
|
82
|
+
desc: '複数の人が相互...'
|
83
|
+
```
|
84
|
+
|
85
|
+
</td></tr><tr><td colspan=3>
|
86
|
+
|
87
|
+
Linter won't complain about `ja.desc` even if it does exist
|
88
|
+
|
89
|
+
</td></tr></tbody></table>
|
90
|
+
|
91
|
+
|
92
|
+
<table><thead><tr>
|
93
|
+
<th></th>
|
94
|
+
<th>master</th>
|
95
|
+
<th>foreign</th>
|
96
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
97
|
+
|
98
|
+
```yaml
|
99
|
+
en:
|
100
|
+
title: 'Non zero sum'
|
101
|
+
|
102
|
+
```
|
103
|
+
|
104
|
+
</td><td>
|
105
|
+
|
106
|
+
```yaml
|
107
|
+
ja:
|
108
|
+
title: '非ゼロ和'
|
109
|
+
desc: '複数の人が相互...'
|
110
|
+
```
|
111
|
+
|
112
|
+
</td></tr><tr><td colspan=3>
|
113
|
+
|
114
|
+
Having the extra `ja.desc`
|
115
|
+
|
116
|
+
</td></tr></tbody></table>
|
117
|
+
|
118
|
+
<table><thead><tr>
|
119
|
+
<th></th>
|
120
|
+
<th>master</th>
|
121
|
+
<th>foreign</th>
|
122
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
123
|
+
|
124
|
+
```yaml
|
125
|
+
en:
|
126
|
+
title: 'Non zero sum'
|
127
|
+
|
128
|
+
```
|
129
|
+
|
130
|
+
</td><td>
|
131
|
+
|
132
|
+
```yaml
|
133
|
+
ja:
|
134
|
+
title: '非ゼロ和'
|
135
|
+
desc: !only '複数の人が相互...'
|
136
|
+
```
|
137
|
+
|
138
|
+
</td></tr><tr><td colspan=3>
|
139
|
+
|
140
|
+
Linter won't complain about `ja.desc`
|
141
|
+
|
142
|
+
</td></tr></tbody></table>
|
143
|
+
|
144
|
+
<table><thead><tr>
|
145
|
+
<th></th>
|
146
|
+
<th>master</th>
|
147
|
+
<th>foreign</th>
|
148
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
149
|
+
|
150
|
+
```yaml
|
151
|
+
en:
|
152
|
+
title: 'Non zero sum'
|
153
|
+
desc: 'A situation in...'
|
154
|
+
```
|
155
|
+
|
156
|
+
</td><td>
|
157
|
+
|
158
|
+
```yaml
|
159
|
+
ja:
|
160
|
+
title: '非ゼロ和'
|
161
|
+
desc: !only '複数の人が相互...'
|
162
|
+
```
|
163
|
+
|
164
|
+
</td></tr><tr><td colspan=3>
|
165
|
+
|
166
|
+
Linter won't complain about `ja.desc`
|
167
|
+
|
168
|
+
</td></tr></tbody></table>
|
169
|
+
|
170
|
+
|
171
|
+
!only:LOCALES
|
172
|
+
-------------
|
173
|
+
|
174
|
+
It's similar to `!only`, but is stricter.
|
175
|
+
It can take comma-separated locales as a parameter just like `!only:en` or `!only:en,ja,zh-HK`, and ensures that a key only exists in files of the specified locales.
|
176
|
+
|
177
|
+
<table><thead><tr>
|
178
|
+
<th></th>
|
179
|
+
<th>master</th>
|
180
|
+
<th>foreign</th>
|
181
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
182
|
+
|
183
|
+
```yaml
|
184
|
+
en:
|
185
|
+
title: 'Non zero sum'
|
186
|
+
desc: !only:en 'A situation in...'
|
187
|
+
```
|
188
|
+
|
189
|
+
</td><td>
|
190
|
+
|
191
|
+
```yaml
|
192
|
+
ja:
|
193
|
+
title: '非ゼロ和'
|
194
|
+
desc: '複数の人が相互...'
|
195
|
+
```
|
196
|
+
|
197
|
+
</td></tr><tr><td colspan=3>
|
198
|
+
|
199
|
+
Linter will complain about `ja.desc`, because the key is supposed to exist only in `en`.
|
200
|
+
|
201
|
+
</td></tr></tbody></table>
|
202
|
+
|
203
|
+
<table><thead><tr>
|
204
|
+
<th></th>
|
205
|
+
<th>master</th>
|
206
|
+
<th>foreign</th>
|
207
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
208
|
+
|
209
|
+
```yaml
|
210
|
+
en:
|
211
|
+
title: 'Non zero sum'
|
212
|
+
desc: 'A situation in...'
|
213
|
+
```
|
214
|
+
|
215
|
+
</td><td>
|
216
|
+
|
217
|
+
```yaml
|
218
|
+
ja:
|
219
|
+
title: '非ゼロ和'
|
220
|
+
desc: !only:ja '複数の人が相互...'
|
221
|
+
```
|
222
|
+
|
223
|
+
</td></tr><tr><td colspan=3>
|
224
|
+
|
225
|
+
Linter will complain about `en.desc`, because the key is supposed to exist only in `ja`.
|
226
|
+
|
227
|
+
</td></tr></tbody></table>
|
228
|
+
|
229
|
+
<table><thead><tr>
|
230
|
+
<th></th>
|
231
|
+
<th>master</th>
|
232
|
+
<th>foreign</th>
|
233
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
234
|
+
|
235
|
+
```yaml
|
236
|
+
en:
|
237
|
+
title: 'Non zero sum'
|
238
|
+
desc: !only:en,ja 'A situation in...'
|
239
|
+
```
|
240
|
+
|
241
|
+
</td><td>
|
242
|
+
|
243
|
+
```yaml
|
244
|
+
ja:
|
245
|
+
title: '非ゼロ和'
|
246
|
+
desc: '複数の人が相互...'
|
247
|
+
```
|
248
|
+
|
249
|
+
</td></tr><tr><td colspan=3>
|
250
|
+
|
251
|
+
The key can exist in the specified locales `en,ja`
|
252
|
+
|
253
|
+
</td></tr></tbody></table>
|
254
|
+
|
255
|
+
<table><thead><tr>
|
256
|
+
<th></th>
|
257
|
+
<th>master</th>
|
258
|
+
<th>foreign</th>
|
259
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
260
|
+
|
261
|
+
```yaml
|
262
|
+
en:
|
263
|
+
title: 'Non zero sum'
|
264
|
+
desc: !only:en,ja 'A situation in...'
|
265
|
+
```
|
266
|
+
|
267
|
+
</td><td>
|
268
|
+
|
269
|
+
```yaml
|
270
|
+
ja:
|
271
|
+
title: '非ゼロ和'
|
272
|
+
|
273
|
+
```
|
274
|
+
|
275
|
+
</td></tr><tr><td colspan=3>
|
276
|
+
|
277
|
+
Note that it doesn't mean to ensure existance of the key.
|
278
|
+
|
279
|
+
</td></tr></tbody></table>
|
280
|
+
|
281
|
+
|
282
|
+
!ignore:key
|
283
|
+
-----------
|
284
|
+
|
285
|
+
With `!ignore:key`, you can suppress any error on a certain key.
|
286
|
+
|
287
|
+
<table><thead><tr>
|
288
|
+
<th></th>
|
289
|
+
<th>master</th>
|
290
|
+
<th>foreign</th>
|
291
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
292
|
+
|
293
|
+
```yaml
|
294
|
+
en:
|
295
|
+
title: 'Non zero sum'
|
296
|
+
|
297
|
+
```
|
298
|
+
|
299
|
+
</td><td>
|
300
|
+
|
301
|
+
```yaml
|
302
|
+
ja:
|
303
|
+
title: '非ゼロ和'
|
304
|
+
desc: !ignore:key '複数の人が相互...'
|
305
|
+
```
|
306
|
+
|
307
|
+
</td></tr><tr><td colspan=3>
|
308
|
+
|
309
|
+
Linter won't complain about an asymmetric key
|
310
|
+
|
311
|
+
</td></tr></tbody></table>
|
312
|
+
|
313
|
+
|
314
|
+
<table><thead><tr>
|
315
|
+
<th></th>
|
316
|
+
<th>master</th>
|
317
|
+
<th>foreign</th>
|
318
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
319
|
+
|
320
|
+
```yaml
|
321
|
+
en:
|
322
|
+
follower_count:
|
323
|
+
one: '1 follower'
|
324
|
+
other: '%{count} followers'
|
325
|
+
```
|
326
|
+
|
327
|
+
</td><td>
|
328
|
+
|
329
|
+
```yaml
|
330
|
+
ja:
|
331
|
+
follower_count: !ignore:key '%{count} フォロワ'
|
332
|
+
|
333
|
+
|
334
|
+
```
|
335
|
+
|
336
|
+
</td></tr><tr><td colspan=3>
|
337
|
+
|
338
|
+
Linter won't complain about a structural mismatch
|
339
|
+
|
340
|
+
</td></tr></tbody></table>
|
341
|
+
|
342
|
+
|
343
|
+
<table><thead><tr>
|
344
|
+
<th></th>
|
345
|
+
<th>master</th>
|
346
|
+
<th>foreign</th>
|
347
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
348
|
+
|
349
|
+
```yaml
|
350
|
+
en:
|
351
|
+
key: !ignore:key '%{alpha}'
|
352
|
+
```
|
353
|
+
|
354
|
+
</td><td>
|
355
|
+
|
356
|
+
```yaml
|
357
|
+
ja:
|
358
|
+
key: '%{gamma}'
|
359
|
+
```
|
360
|
+
|
361
|
+
</td></tr><tr><td colspan=3>
|
362
|
+
|
363
|
+
Linter won't complain about a difference in interpolation arguments
|
364
|
+
|
365
|
+
</td></tr></tbody></table>
|
366
|
+
|
367
|
+
|
368
|
+
!ignore:args
|
369
|
+
------------
|
370
|
+
|
371
|
+
With `!ignore:args`, you can suppress an error of asymmetric interpolation arguments.
|
372
|
+
|
373
|
+
<table><thead><tr>
|
374
|
+
<th></th>
|
375
|
+
<th>master</th>
|
376
|
+
<th>foreign</th>
|
377
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
378
|
+
|
379
|
+
```yaml
|
380
|
+
en:
|
381
|
+
key: '%{alpha}'
|
382
|
+
```
|
383
|
+
|
384
|
+
</td><td>
|
385
|
+
|
386
|
+
```yaml
|
387
|
+
ja:
|
388
|
+
key: !ignore:args '%{gamma}'
|
389
|
+
```
|
390
|
+
|
391
|
+
</td></tr><tr><td colspan=3>
|
392
|
+
|
393
|
+
Linter won't complain about a difference in interpolation arguments
|
394
|
+
|
395
|
+
</td></tr></tbody></table>
|
396
|
+
|
397
|
+
|
398
|
+
!todo
|
399
|
+
-----
|
400
|
+
|
401
|
+
With `!todo`, you can annotate that a key needs to be translated in the future.
|
402
|
+
It can be only annotated on scalar values, mappings and sequences are not accepted.
|
403
|
+
|
404
|
+
<table><thead><tr>
|
405
|
+
<th></th>
|
406
|
+
<th>master</th>
|
407
|
+
<th>foreign</th>
|
408
|
+
</tr></thead><tbody><tr><th>✅</th><td>
|
409
|
+
|
410
|
+
```yaml
|
411
|
+
en:
|
412
|
+
follower_count:
|
413
|
+
one: '1 follower'
|
414
|
+
other: '%{count} followers'
|
415
|
+
```
|
416
|
+
|
417
|
+
</td><td>
|
418
|
+
|
419
|
+
```yaml
|
420
|
+
ja:
|
421
|
+
follower_count:
|
422
|
+
one: !todo '1 follower'
|
423
|
+
other: !todo '%{count} followers'
|
424
|
+
```
|
425
|
+
|
426
|
+
</td></tr><tr><td colspan=3>
|
427
|
+
|
428
|
+
Two keys need to be translated
|
429
|
+
|
430
|
+
</td></tr></tbody></table>
|
431
|
+
|
432
|
+
<table><thead><tr>
|
433
|
+
<th></th>
|
434
|
+
<th>master</th>
|
435
|
+
<th>foreign</th>
|
436
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
437
|
+
|
438
|
+
```yaml
|
439
|
+
en:
|
440
|
+
follower_count:
|
441
|
+
one: '1 follower'
|
442
|
+
other: '%{count} followers'
|
443
|
+
```
|
444
|
+
|
445
|
+
</td><td>
|
446
|
+
|
447
|
+
```yaml
|
448
|
+
ja:
|
449
|
+
follower_count: !todo
|
450
|
+
one: '1 follower'
|
451
|
+
other: '%{count} followers'
|
452
|
+
```
|
453
|
+
|
454
|
+
</td></tr><tr><td colspan=3>
|
455
|
+
|
456
|
+
You can't annotate on a mapping or a sequence.
|
457
|
+
|
458
|
+
</td></tr></tbody></table>
|
459
|
+
|
460
|
+
|
461
|
+
<table><thead><tr>
|
462
|
+
<th></th>
|
463
|
+
<th>master</th>
|
464
|
+
<th>foreign</th>
|
465
|
+
</tr></thead><tbody><tr><th>👎</th><td>
|
466
|
+
|
467
|
+
```yaml
|
468
|
+
en:
|
469
|
+
follower_count:
|
470
|
+
one: 'a follower'
|
471
|
+
other: '%{count} followers'
|
472
|
+
```
|
473
|
+
|
474
|
+
</td><td>
|
475
|
+
|
476
|
+
```yaml
|
477
|
+
ja:
|
478
|
+
follower_count:
|
479
|
+
one: !todo '1 follower'
|
480
|
+
other: !todo '%{count} followers'
|
481
|
+
```
|
482
|
+
|
483
|
+
</td></tr><tr><td colspan=3>
|
484
|
+
|
485
|
+
Linter will complain `ja.follower_count.one` has different content.
|
486
|
+
This usually indicates that there has been updates on the master file, or that it has been translated but forgotten to remove `!todo`.
|
487
|
+
|
488
|
+
</td></tr></tbody></table>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
en:
|
2
|
+
example:
|
3
|
+
title: 'Example'
|
4
|
+
|
5
|
+
# Use first name in English
|
6
|
+
greeting: 'Hello %{first_name},'
|
7
|
+
|
8
|
+
# Might be hard to translate into other langs
|
9
|
+
serendipity: 'serendipity'
|
10
|
+
|
11
|
+
# Only available in English version
|
12
|
+
follower_count: !only:en
|
13
|
+
one: '1 follower'
|
14
|
+
other: '%{count} followers'
|
data/exe/i18n_flow
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# enable local usage from cloned repo
|
4
|
+
root = File.expand_path('../..', __FILE__)
|
5
|
+
$LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
|
6
|
+
|
7
|
+
require 'i18n_flow'
|
8
|
+
require 'i18n_flow/cli'
|
9
|
+
|
10
|
+
I18nFlow.config.auto_configure!
|
11
|
+
I18nFlow::CLI.new(ARGV).run
|
data/i18n_flow.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'i18n_flow/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'i18n_flow'
|
7
|
+
spec.version = I18nFlow::VERSION
|
8
|
+
spec.authors = ['Yuki Iwanaga']
|
9
|
+
spec.email = ['yuki@creasty.com']
|
10
|
+
|
11
|
+
spec.summary = %q{Manage translation status in yaml file}
|
12
|
+
spec.description = %q{Manage translation status in yaml file}
|
13
|
+
spec.homepage = 'https://github.com/creasty/i18n_flow'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.bindir = 'exe'
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'psych', '>= 3.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.7'
|
26
|
+
spec.add_development_dependency 'fakefs'
|
27
|
+
spec.add_development_dependency 'pry'
|
28
|
+
end
|
data/i18n_flow.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../util'
|
2
|
+
|
3
|
+
class I18nFlow::CLI
|
4
|
+
class CommandBase
|
5
|
+
attr_reader(*%i[
|
6
|
+
args
|
7
|
+
options
|
8
|
+
])
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@args = args.dup
|
12
|
+
@options = I18nFlow::Util::parse_options(@args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def invoke!
|
16
|
+
raise 'Not implemented'
|
17
|
+
end
|
18
|
+
|
19
|
+
def exit_with_message(status, *args)
|
20
|
+
if status.zero?
|
21
|
+
puts(*args)
|
22
|
+
else
|
23
|
+
$stderr.puts(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
exit status
|
27
|
+
end
|
28
|
+
|
29
|
+
def color_enabled?
|
30
|
+
options['nocolor'].nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'psych'
|
2
|
+
require_relative 'command_base'
|
3
|
+
require_relative '../util'
|
4
|
+
require_relative '../parser'
|
5
|
+
|
6
|
+
class I18nFlow::CLI
|
7
|
+
class CopyCommand < CommandBase
|
8
|
+
def invoke!
|
9
|
+
unless src_file && dst_file
|
10
|
+
exit_with_message(1, 'usage: i18n_flow copy [--locale=LOCALE] SRC_FILE DST_FILE')
|
11
|
+
end
|
12
|
+
|
13
|
+
parser.parse!
|
14
|
+
|
15
|
+
mark_as_todo(parser.root_proxy)
|
16
|
+
|
17
|
+
if locale && first_key_node
|
18
|
+
first_key_node.value = locale
|
19
|
+
end
|
20
|
+
|
21
|
+
File.write(dst_file, parser.root_proxy.to_yaml)
|
22
|
+
end
|
23
|
+
|
24
|
+
def src_file
|
25
|
+
args[0]
|
26
|
+
end
|
27
|
+
|
28
|
+
def dst_file
|
29
|
+
args[1]
|
30
|
+
end
|
31
|
+
|
32
|
+
def locale
|
33
|
+
options['locale']
|
34
|
+
end
|
35
|
+
|
36
|
+
def first_key_node
|
37
|
+
return @first_key_node if defined?(@first_key_node)
|
38
|
+
@first_key_node = parser.root_proxy
|
39
|
+
.send(:indexed_object)
|
40
|
+
.node
|
41
|
+
.tap { |n| break unless n.is_a?(Psych::Nodes::Mapping) }
|
42
|
+
&.tap { |n| break n.children.first }
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def parser
|
48
|
+
@parser ||= I18nFlow::Parser.new(File.read(src_file), file_path: src_file)
|
49
|
+
end
|
50
|
+
|
51
|
+
def mark_as_todo(ast)
|
52
|
+
if ast.alias?
|
53
|
+
return
|
54
|
+
end
|
55
|
+
if ast.scalar?
|
56
|
+
ast.node.tag = '!todo'
|
57
|
+
|
58
|
+
# https://github.com/ruby/psych/blob/f30b65befa4f0a5a8548d482424a84a2383b0284/ext/psych/yaml/emitter.c#L1187
|
59
|
+
ast.node.plain = ast.node.quoted = false
|
60
|
+
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
ast.each do |k, v|
|
65
|
+
mark_as_todo(v)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'command_base'
|
2
|
+
|
3
|
+
class I18nFlow::CLI
|
4
|
+
class HelpCommand < CommandBase
|
5
|
+
TEXT = <<-HELP
|
6
|
+
Manage translation status in yaml file
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
i18n_flow COMMAND [args...]
|
10
|
+
i18n_flow [options]
|
11
|
+
|
12
|
+
Options:
|
13
|
+
-v, --version Show version
|
14
|
+
-h Show help
|
15
|
+
|
16
|
+
Commands:
|
17
|
+
lint Validate files
|
18
|
+
search Search contents and keys
|
19
|
+
copy Copy translations and mark as todo
|
20
|
+
split Split a file into proper-sized files
|
21
|
+
version Show version
|
22
|
+
help Show help
|
23
|
+
HELP
|
24
|
+
|
25
|
+
def invoke!
|
26
|
+
puts TEXT
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|