i18n-tasks 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/README.md +13 -7
- data/bin/i18n-tasks +7 -5
- data/config/i18n-tasks.yml +3 -0
- data/config/locales/en.yml +11 -5
- data/config/locales/ru.yml +102 -0
- data/lib/i18n/tasks/command/commander.rb +10 -15
- data/lib/i18n/tasks/command/commands/data.rb +6 -12
- data/lib/i18n/tasks/command/commands/eq_base.rb +1 -3
- data/lib/i18n/tasks/command/commands/health.rb +1 -2
- data/lib/i18n/tasks/command/commands/meta.rb +2 -2
- data/lib/i18n/tasks/command/commands/missing.rb +13 -29
- data/lib/i18n/tasks/command/commands/tree.rb +13 -16
- data/lib/i18n/tasks/command/commands/usages.rb +4 -9
- data/lib/i18n/tasks/command/commands/xlsx.rb +1 -2
- data/lib/i18n/tasks/command/dsl/enum_opt.rb +24 -5
- data/lib/i18n/tasks/command/options/common.rb +4 -4
- data/lib/i18n/tasks/command/options/enum_opt.rb +7 -3
- data/lib/i18n/tasks/command/options/locales.rb +9 -7
- data/lib/i18n/tasks/command/options/trees.rb +17 -37
- data/lib/i18n/tasks/configuration.rb +4 -0
- data/lib/i18n/tasks/slop_command.rb +23 -10
- data/lib/i18n/tasks/version.rb +1 -1
- data/spec/google_translate_spec.rb +1 -1
- data/spec/support/test_codebase.rb +1 -1
- data/templates/config/i18n-tasks.yml +3 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1da0127b4f5d5823790e0b3e95609d72bc5d89ce
|
4
|
+
data.tar.gz: 4b3444adf44532e8c4cfa4906658f23f95f385c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d914cabb6ace1ccf7f1eebf8dd68cd885a8929713edc095aebb7073e771cf06bb0ddcce78e1ff6df51562bc68ee11d8e6b1110f3120ad6d3093f985ae44fcb2
|
7
|
+
data.tar.gz: 2b8add28adae0c70a297e253dd104bc5877f95a68c4b5d16038f99d313b088b6268da15ca6e052e099be69308cfd2b758428ba276e64d94fdfb6e8cad6fbe2af
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,7 @@ i18n-tasks can be used with any project using [i18n][i18n-gem] (default in Rails
|
|
25
25
|
Add to Gemfile:
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
gem 'i18n-tasks', '~> 0.7.
|
28
|
+
gem 'i18n-tasks', '~> 0.7.2'
|
29
29
|
```
|
30
30
|
|
31
31
|
Copy default [configuration file](#configuration) (optional):
|
@@ -137,12 +137,12 @@ $ i18n-tasks normalize -p
|
|
137
137
|
Relative keys (`t '.title'`) and plural keys (`key.{one,many,other,...}`) are fully supported.
|
138
138
|
Scope argument is supported, but only when it is the first keyword argument ([improvements welcome](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb)):
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
140
|
+
```ruby
|
141
|
+
# this is supported
|
142
|
+
t :invalid, scope: [:auth, :password], attempts: 5
|
143
|
+
# but not this
|
144
|
+
t :invalid, attempts: 5, scope: [:auth, :password]
|
145
|
+
```
|
146
146
|
|
147
147
|
Unused report will detect certain dynamic key forms and not report them, e.g.:
|
148
148
|
|
@@ -175,6 +175,12 @@ base_locale: en
|
|
175
175
|
locales: [es, fr] # This includes base_locale by default
|
176
176
|
```
|
177
177
|
|
178
|
+
`internal_locale` controls the language i18n-tasks reports in. Locales available are `en` and `ru` (pull request to add more!).
|
179
|
+
|
180
|
+
```yaml
|
181
|
+
internal_locale: en
|
182
|
+
```
|
183
|
+
|
178
184
|
### Storage
|
179
185
|
|
180
186
|
The default data adapter supports YAML and JSON files.
|
data/bin/i18n-tasks
CHANGED
@@ -22,21 +22,23 @@ err = proc { |message, exit_code|
|
|
22
22
|
}
|
23
23
|
|
24
24
|
begin
|
25
|
-
ran
|
25
|
+
ran = false
|
26
26
|
commander = ::I18n::Tasks::Commands
|
27
|
+
instance = commander.new
|
28
|
+
instance.set_internal_locale!
|
27
29
|
slop_adapter = ::I18n::Tasks::SlopCommand
|
28
|
-
args
|
29
|
-
args
|
30
|
+
args = ARGV.dup
|
31
|
+
args = ['--help'] if args.empty?
|
30
32
|
Slop.parse(args, help: true) do
|
31
33
|
on('-v', '--version', 'Print the version') {
|
32
34
|
puts I18n::Tasks::VERSION
|
33
35
|
exit
|
34
36
|
}
|
35
37
|
commander.cmds.each do |name, attr|
|
36
|
-
slop_dsl = slop_adapter.slop_command(name, attr) { |name, opts
|
38
|
+
slop_dsl = slop_adapter.slop_command(name, attr) { |name, opts|
|
37
39
|
begin
|
38
40
|
ran = true
|
39
|
-
|
41
|
+
instance.safe_run name, opts
|
40
42
|
rescue Errno::EPIPE
|
41
43
|
# ignore Errno::EPIPE which is throw when pipe breaks, e.g.:
|
42
44
|
# i18n-tasks missing | head
|
data/config/i18n-tasks.yml
CHANGED
@@ -5,6 +5,9 @@ base_locale: en
|
|
5
5
|
## uncomment to set locales explicitly
|
6
6
|
# locales: [en, es, fr]
|
7
7
|
|
8
|
+
## i18n-tasks report locale, default: en, available: en, ru
|
9
|
+
internal_locale: ru
|
10
|
+
|
8
11
|
# Read and write locale data
|
9
12
|
data:
|
10
13
|
## by default, translation data are read from the file system, or you can provide a custom data adapter
|
data/config/locales/en.yml
CHANGED
@@ -66,26 +66,32 @@ en:
|
|
66
66
|
config: display i18n-tasks configuration
|
67
67
|
gem_path: show path to the gem
|
68
68
|
irb: start REPL session within i18n-tasks context
|
69
|
+
xlsx_report: save missing and unused translations to an Excel file
|
69
70
|
args:
|
70
71
|
default_text: 'Default: %{value}'
|
72
|
+
default_all: 'Default: all'
|
71
73
|
desc:
|
72
74
|
out_format: 'Output format: %{valid_text}. %{default_text}.'
|
73
75
|
data_format: 'Data format: %{valid_text}. %{default_text}.'
|
74
76
|
keys: List of keys separated by commas (,), spaces, or newlines.
|
75
77
|
locales_filter: 'Comma-separated list of locale(s) to process. Default: all. Special: base.'
|
78
|
+
locales_to_translate_from: 'Locale to translate from (default: base)'
|
76
79
|
locale: 'Locale. Default: base'
|
77
80
|
confirm: Confirm automatically
|
78
81
|
nostdin: Do not read from stdin
|
79
82
|
strict: Do not infer dynamic key usage such as `t("category.\#{category.name}")`
|
80
|
-
missing_types: 'Filter by types: %{valid}.'
|
83
|
+
missing_types: 'Filter by types: %{valid}. Default: all'
|
81
84
|
key_pattern: Filter by key pattern (e.g. 'common.*')
|
85
|
+
key_pattern_to_rename: Full key (pattern) to rename. Required
|
86
|
+
new_key_name: New name, interpolates original name as %{key}. Required
|
82
87
|
value: 'Value. Interpolates: %{value}, %{human_key}, %{value_or_human_key}'
|
83
88
|
pattern_router: 'Use pattern router: keys moved per config data.write'
|
84
89
|
enum_opt:
|
85
|
-
desc:
|
86
|
-
|
87
|
-
|
88
|
-
|
90
|
+
desc: "%{valid_text}. %{default_text}"
|
91
|
+
invalid: "%{invalid} is not one of: %{valid}."
|
92
|
+
enum_list_opt:
|
93
|
+
desc: 'Comma-separated list of: %{valid_text}. %{default_text}'
|
94
|
+
invalid: "%{invalid} is not in: %{valid}."
|
89
95
|
errors:
|
90
96
|
pass_forest: Pass locale forest
|
91
97
|
invalid_locale: Invalid locale %{invalid}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
---
|
2
|
+
ru:
|
3
|
+
i18n_tasks:
|
4
|
+
common:
|
5
|
+
locale: "Язык"
|
6
|
+
type: "Тип"
|
7
|
+
key: "Ключ"
|
8
|
+
value: "Значение"
|
9
|
+
base_value: "Исходное значение"
|
10
|
+
details: "Детали"
|
11
|
+
continue_q: "Продолжить?"
|
12
|
+
n_more: "ещё %{count}"
|
13
|
+
google_translate:
|
14
|
+
errors:
|
15
|
+
no_results: Google Translate не дал результатов. Убедитесь в том, что платежная информация
|
16
|
+
добавлена в в https://code.google.com/apis/console.
|
17
|
+
remove_unused:
|
18
|
+
confirm:
|
19
|
+
one: "Один перевод будут удалён из %{locales}."
|
20
|
+
other: "Переводы (%{count}) будут удалены из %{locales}."
|
21
|
+
removed: "Удалены ключи (%{count})"
|
22
|
+
noop: "Нет неиспользуемых ключей"
|
23
|
+
translate_missing:
|
24
|
+
translated: "Переведены ключи (%{count})"
|
25
|
+
add_missing:
|
26
|
+
added: "Добавлены ключи (%{count})"
|
27
|
+
unused:
|
28
|
+
none: "Все переводы используются."
|
29
|
+
missing:
|
30
|
+
none: "Всё переведено."
|
31
|
+
usages:
|
32
|
+
none: "Не найдено использований."
|
33
|
+
health:
|
34
|
+
no_keys_detected: "Ключи не обнаружены. Проверьте data.read в config/i18n-tasks.yml."
|
35
|
+
data_stats:
|
36
|
+
title: "Данные (%{locales}):"
|
37
|
+
text: "%{key_count} ключей в %{locale_count} языках. В среднем, длина строки: %{value_chars_avg},
|
38
|
+
сегменты ключей: %{key_segments_avg}, ключей в языке %{per_locale_avg}."
|
39
|
+
text_single_locale: "%{key_count} ключей. В среднем, длина строки: %{value_chars_avg}, сегменты
|
40
|
+
ключей: %{key_segments_avg}."
|
41
|
+
cmd:
|
42
|
+
encourage:
|
43
|
+
- "Хорошая работа!"
|
44
|
+
- "Отлично!"
|
45
|
+
- "Прекрасно!"
|
46
|
+
desc:
|
47
|
+
normalize: "нормализовать файлы переводов (сортировка и распределение)"
|
48
|
+
data: "показать данные переводов"
|
49
|
+
data_merge: "добавить дерево к переводам"
|
50
|
+
data_write: "заменить переводы деревом"
|
51
|
+
data_remove: "удалить ключи, которые есть в дереве, из данных"
|
52
|
+
health: "Всё ОК?"
|
53
|
+
find: "показать, где ключи используются в коде"
|
54
|
+
unused: "показать неиспользуемые переводы"
|
55
|
+
missing: "показать недостающие переводы"
|
56
|
+
translate_missing: "перевести недостающие переводы с Google Translate"
|
57
|
+
add_missing: "добавить недостающие ключи к переводам"
|
58
|
+
remove_unused: "удалить неиспользуемые ключи"
|
59
|
+
eq_base: "показать переводы, равные значениям в основном языке"
|
60
|
+
tree_merge: "объединенить деревья"
|
61
|
+
tree_filter: "фильтровать дерево по ключу"
|
62
|
+
tree_rename_key: "переименовать узел дерева"
|
63
|
+
tree_subtract: "дерево A минус ключи в дереве B"
|
64
|
+
tree_set_value: "заменить значения ключей"
|
65
|
+
tree_convert: "преобразовать дерево между форматами"
|
66
|
+
config: "показать конфигурацию"
|
67
|
+
gem_path: "показать путь к ruby gem"
|
68
|
+
irb: "начать REPL сессию в контексте i18n-tasks"
|
69
|
+
xlsx_report: "сохранить недостающие и неиспользуемые переводы в Excel-файл"
|
70
|
+
args:
|
71
|
+
default_text: "По умолчанию: %{value}"
|
72
|
+
default_all: "По умолчанию: все"
|
73
|
+
desc:
|
74
|
+
out_format: "Формат вывода: %{valid_text}. %{default_text}."
|
75
|
+
data_format: "Формат данных: %{valid_text}. %{default_text}."
|
76
|
+
keys: "Список ключей, разделенных запятыми (,), пробелами или символами новой строки."
|
77
|
+
locales_filter: "Список языков для обработки, разделенный запятыми (,). По умолчанию: все.
|
78
|
+
Специальное значение: base."
|
79
|
+
locales_to_translate_from: "Язык с которого переводить (по умолчанию: base)"
|
80
|
+
locale: "Язык. По умолчанию: base"
|
81
|
+
confirm: "Подтвердить автоматом"
|
82
|
+
nostdin: "Не читать дерево из стандартного ввода"
|
83
|
+
strict: Не угадывать динамические использования ключей, например `t("category.#{category.key}")`
|
84
|
+
missing_types: "Типы недостающих переводов: %{valid}. По умолчанию: все"
|
85
|
+
key_pattern: "Маска ключа (например, common.*)"
|
86
|
+
key_pattern_to_rename: "Полный ключ (шаблон) для переименования. Необходимый параметр."
|
87
|
+
new_key_name: "Новое имя, интерполирует оригинальное название как %{key}. Необходимый параметр."
|
88
|
+
value: "Значение, интерполируется с %{value}, %{human_key}, %{value_or_human_key}"
|
89
|
+
pattern_router: "Использовать pattern_router: ключи распределятся по файлам согласно data.write"
|
90
|
+
enum_opt:
|
91
|
+
desc: "%{valid_text}. %{default_text}"
|
92
|
+
invalid: "%{invalid} не является одним из: %{valid}."
|
93
|
+
enum_list_opt:
|
94
|
+
desc: "Разделенных запятыми список: %{valid_text}. %{default_text}"
|
95
|
+
invalid: "%{invalid} не в: %{valid}."
|
96
|
+
errors:
|
97
|
+
pass_forest: "Передайте дерево"
|
98
|
+
invalid_locale: "Неверный язык %{invalid}"
|
99
|
+
invalid_format: "Неизвестный формат %{invalid}. Форматы: %{valid}."
|
100
|
+
invalid_missing_type:
|
101
|
+
one: "Неизвестный тип %{invalid}. Типы: %{valid}."
|
102
|
+
other: "Неизвестные типы: %{invalid}. Типы: %{valid}."
|
@@ -12,12 +12,6 @@ module I18n::Tasks
|
|
12
12
|
@i18n = i18n
|
13
13
|
end
|
14
14
|
|
15
|
-
def args_with_stdin(opt)
|
16
|
-
sources = opt[:arguments] || []
|
17
|
-
sources.unshift $stdin.read unless opt[:nostdin]
|
18
|
-
sources
|
19
|
-
end
|
20
|
-
|
21
15
|
def safe_run(name, opts)
|
22
16
|
begin
|
23
17
|
coloring_was = Term::ANSIColor.coloring?
|
@@ -32,16 +26,23 @@ module I18n::Tasks
|
|
32
26
|
end
|
33
27
|
end
|
34
28
|
|
35
|
-
def run(name, opts)
|
29
|
+
def run(name, opts = {})
|
30
|
+
name = name.to_sym
|
31
|
+
public_name = name.to_s.tr '_', '-'
|
32
|
+
SlopCommand.parse_opts! opts, self.class.cmds[name][:opt], self
|
36
33
|
if opts.empty?
|
37
|
-
log_verbose "run #{
|
34
|
+
log_verbose "run #{public_name} without arguments"
|
38
35
|
send name
|
39
36
|
else
|
40
|
-
log_verbose "run #{
|
37
|
+
log_verbose "run #{public_name} with #{opts.map { |k, v| "#{k}=#{v}" } * ' '}"
|
41
38
|
send name, opts
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
42
|
+
def set_internal_locale!
|
43
|
+
I18n.locale = i18n.internal_locale
|
44
|
+
end
|
45
|
+
|
45
46
|
protected
|
46
47
|
|
47
48
|
def terminal_report
|
@@ -52,12 +53,6 @@ module I18n::Tasks
|
|
52
53
|
@spreadsheet_report ||= I18n::Tasks::Reports::Spreadsheet.new(i18n)
|
53
54
|
end
|
54
55
|
|
55
|
-
class << self
|
56
|
-
def run_command(name, opts)
|
57
|
-
::I18n::Tasks::Commands.new.safe_run(name, opts)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
56
|
def desc(name)
|
62
57
|
self.class.cmds.try(:[], name).try(:desc)
|
63
58
|
end
|
@@ -7,38 +7,34 @@ module I18n::Tasks
|
|
7
7
|
cmd_opt :pattern_router, {
|
8
8
|
short: :p,
|
9
9
|
long: :pattern_router,
|
10
|
-
desc:
|
10
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.pattern_router') },
|
11
11
|
conf: {argument: false, optional: true}
|
12
12
|
}
|
13
13
|
|
14
14
|
cmd :normalize,
|
15
15
|
args: '[locale ...]',
|
16
|
-
desc: I18n.t('i18n_tasks.cmd.desc.normalize'),
|
16
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.normalize') },
|
17
17
|
opt: cmd_opts(:locales, :pattern_router)
|
18
18
|
|
19
19
|
def normalize(opt = {})
|
20
|
-
opt_locales! opt
|
21
20
|
i18n.normalize_store! opt[:locales], opt[:pattern_router]
|
22
21
|
end
|
23
22
|
|
24
23
|
cmd :data,
|
25
24
|
args: '[locale ...]',
|
26
|
-
desc: I18n.t('i18n_tasks.cmd.desc.data'),
|
25
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.data') },
|
27
26
|
opt: cmd_opts(:locales, :out_format)
|
28
27
|
|
29
28
|
def data(opt = {})
|
30
|
-
opt_locales! opt
|
31
|
-
opt_output_format! opt
|
32
29
|
print_forest i18n.data_forest(opt[:locales]), opt
|
33
30
|
end
|
34
31
|
|
35
32
|
cmd :data_merge,
|
36
33
|
args: '[tree ...]',
|
37
|
-
desc: I18n.t('i18n_tasks.cmd.desc.data_merge'),
|
34
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.data_merge') },
|
38
35
|
opt: cmd_opts(:data_format, :nostdin)
|
39
36
|
|
40
37
|
def data_merge(opt = {})
|
41
|
-
opt_data_format! opt
|
42
38
|
forest = opt_forests_merged_stdin_args!(opt)
|
43
39
|
merged = i18n.data.merge!(forest)
|
44
40
|
print_forest merged, opt
|
@@ -46,11 +42,10 @@ module I18n::Tasks
|
|
46
42
|
|
47
43
|
cmd :data_write,
|
48
44
|
args: '[tree]',
|
49
|
-
desc: I18n.t('i18n_tasks.cmd.desc.data_write'),
|
45
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.data_write') },
|
50
46
|
opt: cmd_opts(:data_format, :nostdin)
|
51
47
|
|
52
48
|
def data_write(opt = {})
|
53
|
-
opt_data_format! opt
|
54
49
|
forest = opt_forest_arg_or_stdin!(opt)
|
55
50
|
i18n.data.write forest
|
56
51
|
print_forest forest, opt
|
@@ -58,11 +53,10 @@ module I18n::Tasks
|
|
58
53
|
|
59
54
|
cmd :data_remove,
|
60
55
|
args: '[tree]',
|
61
|
-
desc: I18n.t('i18n_tasks.cmd.desc.data_remove'),
|
56
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.data_remove') },
|
62
57
|
opt: cmd_opts(:data_format, :nostdin)
|
63
58
|
|
64
59
|
def data_remove(opt = {})
|
65
|
-
opt_data_format! opt
|
66
60
|
removed = i18n.data.remove_by_key!(opt_forest_arg_or_stdin!(opt))
|
67
61
|
log_stderr 'Removed:'
|
68
62
|
print_forest removed, opt
|
@@ -6,12 +6,10 @@ module I18n::Tasks
|
|
6
6
|
|
7
7
|
cmd :eq_base,
|
8
8
|
args: '[locale ...]',
|
9
|
-
desc: I18n.t('i18n_tasks.cmd.desc.eq_base'),
|
9
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.eq_base') },
|
10
10
|
opt: cmd_opts(:locales, :out_format)
|
11
11
|
|
12
12
|
def eq_base(opt = {})
|
13
|
-
opt_locales! opt
|
14
|
-
opt_output_format! opt
|
15
13
|
print_forest i18n.eq_base_keys(opt), opt, :eq_base_keys
|
16
14
|
end
|
17
15
|
end
|
@@ -6,11 +6,10 @@ module I18n::Tasks
|
|
6
6
|
|
7
7
|
cmd :health,
|
8
8
|
args: '[locale ...]',
|
9
|
-
desc: I18n.t('i18n_tasks.cmd.desc.health'),
|
9
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.health') },
|
10
10
|
opt: cmd_opts(:locales, :out_format)
|
11
11
|
|
12
12
|
def health(opt = {})
|
13
|
-
opt_locales! opt
|
14
13
|
forest = i18n.data_forest(opt[:locales])
|
15
14
|
stats = i18n.forest_stats(forest)
|
16
15
|
if stats[:key_count].zero?
|
@@ -6,7 +6,7 @@ module I18n::Tasks
|
|
6
6
|
|
7
7
|
cmd :config,
|
8
8
|
args: '[section ...]',
|
9
|
-
desc: I18n.t('i18n_tasks.cmd.desc.config')
|
9
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.config') }
|
10
10
|
|
11
11
|
def config(opts = {})
|
12
12
|
cfg = i18n.config_for_inspect
|
@@ -17,7 +17,7 @@ module I18n::Tasks
|
|
17
17
|
puts cfg
|
18
18
|
end
|
19
19
|
|
20
|
-
cmd :gem_path, desc: I18n.t('i18n_tasks.cmd.desc.gem_path')
|
20
|
+
cmd :gem_path, desc: proc { I18n.t('i18n_tasks.cmd.desc.gem_path') }
|
21
21
|
|
22
22
|
def gem_path
|
23
23
|
puts I18n::Tasks.gem_path
|
@@ -4,38 +4,31 @@ module I18n::Tasks
|
|
4
4
|
module Missing
|
5
5
|
include Command::Collection
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
}
|
13
|
-
|
14
|
-
DEFAULT_ADD_MISSING_VALUE = '%{value_or_human_key}'
|
7
|
+
enum_opt :missing_types, I18n::Tasks::MissingKeys.missing_keys_types
|
8
|
+
cmd_opt :missing_types, enum_list_opt_attr(
|
9
|
+
:t, :types=, enum_opt(:missing_types),
|
10
|
+
proc { |valid, default| I18n.t('i18n_tasks.cmd.args.desc.missing_types', valid: valid, default: default) },
|
11
|
+
proc { |invalid, valid| I18n.t('i18n_tasks.cmd.errors.invalid_missing_type', invalid: invalid * ', ', valid: valid * ', ', count: invalid.length) })
|
15
12
|
|
16
13
|
cmd :missing,
|
17
14
|
args: '[locale ...]',
|
18
|
-
desc: I18n.t('i18n_tasks.cmd.desc.missing'),
|
15
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.missing') },
|
19
16
|
opt: cmd_opts(:locales, :out_format, :missing_types)
|
20
17
|
|
21
18
|
def missing(opt = {})
|
22
|
-
opt_locales!(opt)
|
23
|
-
opt_output_format!(opt)
|
24
|
-
opt_missing_types!(opt)
|
25
19
|
print_forest i18n.missing_keys(opt), opt, :missing_keys
|
26
20
|
end
|
27
21
|
|
28
22
|
cmd :translate_missing,
|
29
23
|
args: '[locale ...]',
|
30
|
-
desc: I18n.t('i18n_tasks.cmd.desc.translate_missing'),
|
24
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.translate_missing') },
|
31
25
|
opt: [cmd_opt(:locales),
|
32
|
-
cmd_opt(:locale).merge(short: :f, long: :from=, desc:
|
26
|
+
cmd_opt(:locale).merge(short: :f, long: :from=, desc: proc {
|
27
|
+
I18n.t('i18n_tasks.cmd.args.desc.locales_to_translate_from') }),
|
33
28
|
cmd_opt(:out_format).except(:short)]
|
34
29
|
|
35
30
|
def translate_missing(opt = {})
|
36
|
-
|
37
|
-
opt_output_format! opt
|
38
|
-
from = opt_locale! opt, :from
|
31
|
+
from = opt[:from]
|
39
32
|
translated = (opt[:locales] - [from]).inject i18n.empty_forest do |result, locale|
|
40
33
|
result.merge! i18n.google_translate_forest i18n.missing_tree(locale, from), from, locale
|
41
34
|
end
|
@@ -44,29 +37,20 @@ module I18n::Tasks
|
|
44
37
|
print_forest translated, opt
|
45
38
|
end
|
46
39
|
|
40
|
+
DEFAULT_ADD_MISSING_VALUE = '%{value_or_human_key}'
|
41
|
+
|
47
42
|
cmd :add_missing,
|
48
43
|
args: '[locale ...]',
|
49
|
-
desc: I18n.t('i18n_tasks.cmd.desc.add_missing'),
|
44
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.add_missing') },
|
50
45
|
opt: cmd_opts(:locales, :out_format) <<
|
51
46
|
cmd_opt(:value).merge(desc: "#{cmd_opt(:value)[:desc]}. #{I18n.t('i18n_tasks.cmd.args.default_text', value: DEFAULT_ADD_MISSING_VALUE)}")
|
52
47
|
|
53
48
|
def add_missing(opt = {})
|
54
|
-
opt_locales! opt
|
55
|
-
opt_output_format! opt
|
56
49
|
forest = i18n.missing_keys(opt).set_each_value!(opt[:value] || DEFAULT_ADD_MISSING_VALUE)
|
57
50
|
i18n.data.merge! forest
|
58
51
|
log_stderr I18n.t('i18n_tasks.add_missing.added', count: forest.leaves.count)
|
59
52
|
print_forest forest, opt
|
60
53
|
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def opt_missing_types!(opt)
|
65
|
-
parse_enum_list_opt(opt[:types], I18n::Tasks::MissingKeys.missing_keys_types) do |invalid, valid|
|
66
|
-
I18n.t('i18n_tasks.cmd.errors.invalid_missing_type',
|
67
|
-
invalid: invalid * ', ', valid: valid * ', ', count: invalid.length)
|
68
|
-
end
|
69
|
-
end
|
70
54
|
end
|
71
55
|
end
|
72
56
|
end
|
@@ -6,7 +6,7 @@ module I18n::Tasks
|
|
6
6
|
|
7
7
|
cmd :tree_merge,
|
8
8
|
args: '[tree ...]',
|
9
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_merge'),
|
9
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_merge') },
|
10
10
|
opt: cmd_opts(:data_format, :nostdin)
|
11
11
|
|
12
12
|
def tree_merge(opts = {})
|
@@ -15,12 +15,11 @@ module I18n::Tasks
|
|
15
15
|
|
16
16
|
cmd :tree_filter,
|
17
17
|
args: '[pattern] [tree]',
|
18
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_filter'),
|
18
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_filter') },
|
19
19
|
opt: cmd_opts(:data_format, :pattern)
|
20
20
|
|
21
21
|
def tree_filter(opt = {})
|
22
|
-
|
23
|
-
pattern = opt_or_arg!(:pattern, opt)
|
22
|
+
pattern = opt_or_arg! :pattern, opt
|
24
23
|
forest = opt_forest_arg_or_stdin!(opt)
|
25
24
|
unless pattern.blank?
|
26
25
|
pattern_re = i18n.compile_key_pattern(pattern)
|
@@ -31,15 +30,17 @@ module I18n::Tasks
|
|
31
30
|
|
32
31
|
cmd :tree_rename_key,
|
33
32
|
args: '<key> <name> [tree]',
|
34
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_rename_key'),
|
35
|
-
opt:
|
36
|
-
|
37
|
-
|
33
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_rename_key') },
|
34
|
+
opt: [
|
35
|
+
cmd_opt(:pattern).merge(short: :k, long: :key=, desc: proc {
|
36
|
+
I18n.t('i18n_tasks.cmd.args.desc.key_pattern_to_rename') }),
|
37
|
+
cmd_opt(:pattern).merge(short: :n, long: :name=, desc: proc {
|
38
|
+
I18n.t('i18n_tasks.cmd.args.desc.new_key_name') })
|
39
|
+
] + cmd_opts(:data_format)
|
38
40
|
|
39
41
|
def tree_rename_key(opt = {})
|
40
42
|
key = opt_or_arg! :key, opt
|
41
43
|
name = opt_or_arg! :name, opt
|
42
|
-
opt_data_format! opt
|
43
44
|
forest = opt_forest_arg_or_stdin! opt
|
44
45
|
raise CommandError.new('pass full key to rename (-k, --key)') if key.blank?
|
45
46
|
raise CommandError.new('pass new name (-n, --name)') if name.blank?
|
@@ -49,11 +50,10 @@ module I18n::Tasks
|
|
49
50
|
|
50
51
|
cmd :tree_subtract,
|
51
52
|
args: '[tree A] [tree B ...]',
|
52
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_subtract'),
|
53
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_subtract') },
|
53
54
|
opt: cmd_opts(:data_format, :nostdin)
|
54
55
|
|
55
56
|
def tree_subtract(opt = {})
|
56
|
-
opt_data_format! opt
|
57
57
|
forests = opt_forests_stdin_args! opt, 2
|
58
58
|
forest = forests.reduce(:subtract_by_key) || empty_forest
|
59
59
|
print_forest forest, opt
|
@@ -61,11 +61,10 @@ module I18n::Tasks
|
|
61
61
|
|
62
62
|
cmd :tree_set_value,
|
63
63
|
args: '[value] [tree]',
|
64
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_set_value'),
|
64
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_set_value') },
|
65
65
|
opt: cmd_opts(:value, :data_format, :nostdin, :pattern)
|
66
66
|
|
67
67
|
def tree_set_value(opt = {})
|
68
|
-
opt_data_format! opt
|
69
68
|
value = opt_or_arg! :value, opt
|
70
69
|
forest = opt_forest_arg_or_stdin!(opt)
|
71
70
|
key_pattern = opt[:pattern]
|
@@ -76,13 +75,11 @@ module I18n::Tasks
|
|
76
75
|
|
77
76
|
cmd :tree_convert,
|
78
77
|
args: '<tree>',
|
79
|
-
desc: I18n.t('i18n_tasks.cmd.desc.tree_convert'),
|
78
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.tree_convert') },
|
80
79
|
opt: [cmd_opt(:data_format).merge(short: :f, long: :from=),
|
81
80
|
cmd_opt(:out_format).merge(short: :t, long: :to=)]
|
82
81
|
|
83
82
|
def tree_convert(opt = {})
|
84
|
-
opt_data_format! opt, :from
|
85
|
-
opt_output_format! opt, :to
|
86
83
|
forest = opt_forest_arg_or_stdin! opt.merge(format: opt[:from])
|
87
84
|
print_forest forest, opt.merge(format: opt[:to])
|
88
85
|
end
|
@@ -7,39 +7,34 @@ module I18n::Tasks
|
|
7
7
|
cmd_opt :strict, {
|
8
8
|
short: :s,
|
9
9
|
long: :strict,
|
10
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.strict')
|
10
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.strict') }
|
11
11
|
}
|
12
12
|
|
13
13
|
cmd :find,
|
14
14
|
args: '[pattern]',
|
15
|
-
desc: I18n.t('i18n_tasks.cmd.desc.find'),
|
15
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.find') },
|
16
16
|
opt: cmd_opts(:out_format, :pattern)
|
17
17
|
|
18
18
|
def find(opt = {})
|
19
|
-
opt_output_format! opt
|
20
19
|
opt[:filter] ||= opt.delete(:pattern) || opt[:arguments].try(:first)
|
21
20
|
print_forest i18n.used_tree(key_filter: opt[:filter].presence, source_occurrences: true), opt, :used_keys
|
22
21
|
end
|
23
22
|
|
24
23
|
cmd :unused,
|
25
24
|
args: '[locale ...]',
|
26
|
-
desc: I18n.t('i18n_tasks.cmd.desc.unused'),
|
25
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.unused') },
|
27
26
|
opt: cmd_opts(:locales, :out_format, :strict)
|
28
27
|
|
29
28
|
def unused(opt = {})
|
30
|
-
opt_locales! opt
|
31
|
-
opt_output_format! opt
|
32
29
|
print_forest i18n.unused_keys(opt), opt, :unused_keys
|
33
30
|
end
|
34
31
|
|
35
32
|
cmd :remove_unused,
|
36
33
|
args: '[locale ...]',
|
37
|
-
desc: I18n.t('i18n_tasks.cmd.desc.remove_unused'),
|
34
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.remove_unused') },
|
38
35
|
opt: cmd_opts(:locales, :out_format, :strict, :confirm)
|
39
36
|
|
40
37
|
def remove_unused(opt = {})
|
41
|
-
opt_locales! opt
|
42
|
-
opt_output_format! opt
|
43
38
|
unused_keys = i18n.unused_keys(opt)
|
44
39
|
if unused_keys.present?
|
45
40
|
terminal_report.unused_keys(unused_keys)
|
@@ -6,7 +6,7 @@ module I18n::Tasks
|
|
6
6
|
|
7
7
|
cmd :xlsx_report,
|
8
8
|
args: '[locale...]',
|
9
|
-
desc:
|
9
|
+
desc: proc { I18n.t('i18n_tasks.cmd.desc.xlsx_report') },
|
10
10
|
opt: [cmd_opt(:locales),
|
11
11
|
{short: :p, long: :path=, desc: 'Destination path', conf: {default: 'tmp/i18n-report.xlsx'}}]
|
12
12
|
|
@@ -18,7 +18,6 @@ module I18n::Tasks
|
|
18
18
|
log_stderr Term::ANSIColor.red Term::ANSIColor.bold message
|
19
19
|
exit 1
|
20
20
|
end
|
21
|
-
opt_locales! opt
|
22
21
|
spreadsheet_report.save_report opt[:path], opt.except(:path)
|
23
22
|
end
|
24
23
|
end
|
@@ -11,14 +11,33 @@ module I18n::Tasks
|
|
11
11
|
end
|
12
12
|
|
13
13
|
DEFAULT_ENUM_OPT_DESC = proc { |valid, default|
|
14
|
-
I18n.t('i18n_tasks.cmd.enum_opt.desc
|
14
|
+
I18n.t('i18n_tasks.cmd.enum_opt.desc', valid_text: valid, default_text: default)
|
15
15
|
}
|
16
16
|
|
17
|
-
def enum_opt_attr(short, long, valid,
|
17
|
+
def enum_opt_attr(short, long, valid, desc, error_msg)
|
18
18
|
desc ||= DEFAULT_ENUM_OPT_DESC
|
19
|
-
{
|
20
|
-
|
21
|
-
conf: {default: valid.first, argument: true, optional: false}
|
19
|
+
desc_proc = proc { desc.call(valid * ', ', I18n.t('i18n_tasks.cmd.args.default_text', value: valid.first)) }
|
20
|
+
{short: short, long: long, desc: desc_proc,
|
21
|
+
conf: {default: valid.first, argument: true, optional: false},
|
22
|
+
parse: enum_parse_proc(:parse_enum_opt, valid, &error_msg)}
|
23
|
+
end
|
24
|
+
|
25
|
+
DEFAULT_LIST_OPT_DESC = proc { |valid, default|
|
26
|
+
I18n.t('i18n_tasks.cmd.enum_list_opt.desc', valid_text: valid, default_text: default)
|
27
|
+
}
|
28
|
+
|
29
|
+
def enum_list_opt_attr(short, long, valid, desc, error_msg)
|
30
|
+
desc ||= DEFAULT_LIST_OPT_DESC
|
31
|
+
desc_proc = proc { desc.call(valid * ', ', I18n.t('i18n_tasks.cmd.args.default_all')) }
|
32
|
+
{short: short, long: long, desc: desc_proc,
|
33
|
+
conf: {as: Array, delimiter: /\s*[+:,]\s*/},
|
34
|
+
parse: enum_parse_proc(:parse_enum_list_opt, valid, &error_msg)}
|
35
|
+
end
|
36
|
+
|
37
|
+
def enum_parse_proc(method, valid, &error)
|
38
|
+
proc { |opt, key|
|
39
|
+
opt[key] = send(method, opt[key], valid, &error)
|
40
|
+
}
|
22
41
|
end
|
23
42
|
end
|
24
43
|
end
|
@@ -14,28 +14,28 @@ module I18n::Tasks
|
|
14
14
|
cmd_opt :nostdin, {
|
15
15
|
short: :S,
|
16
16
|
long: :nostdin,
|
17
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.nostdin'),
|
17
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.nostdin') },
|
18
18
|
conf: {default: false}
|
19
19
|
}
|
20
20
|
|
21
21
|
cmd_opt :confirm, {
|
22
22
|
short: :y,
|
23
23
|
long: :confirm,
|
24
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.confirm'),
|
24
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.confirm') },
|
25
25
|
conf: {default: false}
|
26
26
|
}
|
27
27
|
|
28
28
|
cmd_opt :pattern, {
|
29
29
|
short: :p,
|
30
30
|
long: :pattern=,
|
31
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.key_pattern'),
|
31
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.key_pattern') },
|
32
32
|
conf: {argument: true, optional: false}
|
33
33
|
}
|
34
34
|
|
35
35
|
cmd_opt :value, {
|
36
36
|
short: :v,
|
37
37
|
long: :value=,
|
38
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.value'),
|
38
|
+
desc: proc { I18n.t('i18n_tasks.cmd.args.desc.value') },
|
39
39
|
conf: {argument: true, optional: false}
|
40
40
|
}
|
41
41
|
|
@@ -3,7 +3,7 @@ module I18n::Tasks
|
|
3
3
|
module Options
|
4
4
|
module EnumOpt
|
5
5
|
DEFAULT_ENUM_OPT_ERROR = proc { |bad, good|
|
6
|
-
I18n.t('i18n_tasks.cmd.enum_opt.
|
6
|
+
I18n.t('i18n_tasks.cmd.enum_opt.invalid', invalid: bad, valid: good * ', ')
|
7
7
|
}
|
8
8
|
|
9
9
|
def parse_enum_opt(value, valid, &error_msg)
|
@@ -23,14 +23,18 @@ module I18n::Tasks
|
|
23
23
|
end
|
24
24
|
|
25
25
|
DEFAULT_ENUM_LIST_ERROR = proc { |bad, good|
|
26
|
-
I18n.t('i18n_tasks.cmd.
|
26
|
+
I18n.t('i18n_tasks.cmd.enum_list_opt.invalid', invalid: bad * ', ', valid: good * ', ')
|
27
27
|
}
|
28
28
|
|
29
29
|
def parse_enum_list_opt(values, valid, &error_msg)
|
30
30
|
values = explode_list_opt(values)
|
31
31
|
invalid = values - valid.map(&:to_s)
|
32
32
|
if invalid.empty?
|
33
|
-
values
|
33
|
+
if values.empty?
|
34
|
+
valid
|
35
|
+
else
|
36
|
+
values
|
37
|
+
end
|
34
38
|
else
|
35
39
|
error_msg ||= DEFAULT_ENUM_LIST_ERROR
|
36
40
|
raise CommandError.new error_msg.call(invalid, valid)
|
@@ -8,17 +8,20 @@ module I18n::Tasks
|
|
8
8
|
short: :l,
|
9
9
|
long: :locales=,
|
10
10
|
desc: I18n.t('i18n_tasks.cmd.args.desc.locales_filter'),
|
11
|
-
conf: {as: Array, delimiter: /\s*[+:,]\s*/, default: 'all', argument: true, optional: false}
|
11
|
+
conf: {as: Array, delimiter: /\s*[+:,]\s*/, default: 'all', argument: true, optional: false},
|
12
|
+
parse: :parse_locales
|
12
13
|
}
|
14
|
+
|
13
15
|
cmd_opt :locale, {
|
14
16
|
short: :l,
|
15
17
|
long: :locale=,
|
16
18
|
desc: I18n.t('i18n_tasks.cmd.args.desc.locale'),
|
17
|
-
conf: {default: 'base', argument: true, optional: false}
|
19
|
+
conf: {default: 'base', argument: true, optional: false},
|
20
|
+
parse: :parse_locale
|
18
21
|
}
|
19
22
|
|
20
|
-
def
|
21
|
-
argv = Array(opt[:arguments]) + Array(opt[
|
23
|
+
def parse_locales(opt, key = :locales)
|
24
|
+
argv = Array(opt[:arguments]) + Array(opt[key])
|
22
25
|
locales = if argv == ['all'] || argv == 'all' || argv.blank?
|
23
26
|
i18n.locales
|
24
27
|
else
|
@@ -26,16 +29,15 @@ module I18n::Tasks
|
|
26
29
|
end
|
27
30
|
locales.each { |locale| validate_locale!(locale) }
|
28
31
|
log_verbose "locales for the command are #{locales.inspect}"
|
29
|
-
opt[
|
32
|
+
opt[key] = locales
|
30
33
|
end
|
31
34
|
|
32
|
-
def
|
35
|
+
def parse_locale(opt, key = :locale)
|
33
36
|
val = opt[key]
|
34
37
|
opt[key] = base_locale if val.blank? || val == 'base'
|
35
38
|
opt[key]
|
36
39
|
end
|
37
40
|
|
38
|
-
|
39
41
|
VALID_LOCALE_RE = /\A\w[\w\-_\.]*\z/i
|
40
42
|
|
41
43
|
def validate_locale!(locale)
|
@@ -3,27 +3,24 @@ module I18n::Tasks
|
|
3
3
|
module Options
|
4
4
|
module Trees
|
5
5
|
extend Command::DSL
|
6
|
+
format_opt = proc { |type|
|
7
|
+
enum_opt_attr :f, :format=, enum_opt(type),
|
8
|
+
proc { |valid, default|
|
9
|
+
I18n.t("i18n_tasks.cmd.args.desc.#{type}", valid_text: valid, default_text: default) },
|
10
|
+
proc { |value, valid|
|
11
|
+
I18n.t('i18n_tasks.cmd.errors.invalid_format', invalid: value, valid: valid * ', ') }
|
12
|
+
}
|
6
13
|
|
7
14
|
enum_opt :data_format, %w(yaml json keys)
|
8
|
-
|
9
|
-
|
10
|
-
}
|
15
|
+
# i18n-tasks-use t('i18n_tasks.cmd.args.desc.data_format')
|
16
|
+
cmd_opt :data_format, format_opt.call(:data_format)
|
11
17
|
|
12
18
|
enum_opt :out_format, ['terminal-table', *enum_opt(:data_format), 'inspect']
|
13
|
-
|
14
|
-
|
15
|
-
}
|
16
|
-
|
17
|
-
cmd_opt :keys, {
|
18
|
-
short: :k,
|
19
|
-
long: :keys=,
|
20
|
-
desc: I18n.t('i18n_tasks.cmd.args.desc.keys'),
|
21
|
-
conf: {as: Array, delimiter: /[+:,]/, argument: true, optional: false}
|
22
|
-
}
|
19
|
+
# i18n-tasks-use t('i18n_tasks.cmd.args.desc.out_format')
|
20
|
+
cmd_opt :out_format, format_opt.call(:out_format)
|
23
21
|
|
24
22
|
def print_forest(forest, opt, version = :show_tree)
|
25
23
|
format = opt[:format].to_s
|
26
|
-
|
27
24
|
case format
|
28
25
|
when 'terminal-table'
|
29
26
|
terminal_report.send(version, forest)
|
@@ -36,34 +33,18 @@ module I18n::Tasks
|
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
39
|
-
|
40
|
-
I18n.t('i18n_tasks.cmd.errors.invalid_format', invalid: value, valid: valid * ', ')
|
41
|
-
end
|
42
|
-
|
43
|
-
def opt_output_format!(opt = {}, key = :format)
|
44
|
-
opt[key] = parse_enum_opt opt[key], :out_format, &INVALID_FORMAT_MSG
|
45
|
-
end
|
46
|
-
|
47
|
-
def opt_data_format!(opt = {}, key = :format)
|
48
|
-
opt[key] = parse_enum_opt opt[key], :data_format, &INVALID_FORMAT_MSG
|
49
|
-
end
|
50
|
-
|
51
|
-
def opt_args_keys!(opt = {})
|
52
|
-
opt[:keys] = explode_list_opt(opt[:keys]) + Array(opt[:arguments])
|
53
|
-
end
|
54
|
-
|
55
|
-
def opt_forest_arg_or_stdin!(opt)
|
36
|
+
def opt_forest_arg_or_stdin!(opt, format = opt[:format])
|
56
37
|
src = opt[:arguments].try(:shift) || $stdin.read
|
57
|
-
parse_forest(src,
|
38
|
+
parse_forest(src, format)
|
58
39
|
end
|
59
40
|
|
60
|
-
def opt_forests_stdin_args!(opt, num = false)
|
41
|
+
def opt_forests_stdin_args!(opt, num = false, format = opt[:format])
|
61
42
|
args = opt[:arguments] || []
|
62
43
|
if opt[:nostdin]
|
63
44
|
sources = []
|
64
45
|
else
|
65
46
|
sources = [$stdin.read]
|
66
|
-
num
|
47
|
+
num -= 1 if num
|
67
48
|
end
|
68
49
|
if num
|
69
50
|
num.times { sources << args.shift }
|
@@ -71,7 +52,7 @@ module I18n::Tasks
|
|
71
52
|
sources += args
|
72
53
|
args.clear
|
73
54
|
end
|
74
|
-
sources.map { |src| parse_forest(src,
|
55
|
+
sources.map { |src| parse_forest(src, format) }
|
75
56
|
end
|
76
57
|
|
77
58
|
def opt_forests_merged_stdin_args!(opt)
|
@@ -80,11 +61,10 @@ module I18n::Tasks
|
|
80
61
|
}
|
81
62
|
end
|
82
63
|
|
83
|
-
def parse_forest(src,
|
64
|
+
def parse_forest(src, format)
|
84
65
|
if !src
|
85
66
|
raise CommandError.new(I18n.t('i18n_tasks.cmd.errors.pass_forest'))
|
86
67
|
end
|
87
|
-
format = opt_data_format!(opt)
|
88
68
|
if format == 'keys'
|
89
69
|
Data::Tree::Siblings.from_key_names parse_keys(src)
|
90
70
|
else
|
@@ -70,6 +70,9 @@ module I18n::Tasks::Configuration
|
|
70
70
|
@config_sections[:base_locale] ||= (config[:base_locale] || 'en').to_s
|
71
71
|
end
|
72
72
|
|
73
|
+
def internal_locale
|
74
|
+
@config_sections[:internal_locale] ||= (config[:internal_locale] || 'en').to_s
|
75
|
+
end
|
73
76
|
|
74
77
|
def ignore_config(type = nil)
|
75
78
|
key = type ? "ignore_#{type}" : 'ignore'
|
@@ -81,6 +84,7 @@ module I18n::Tasks::Configuration
|
|
81
84
|
def config_sections
|
82
85
|
# init all sections
|
83
86
|
base_locale
|
87
|
+
internal_locale
|
84
88
|
locales
|
85
89
|
data_config
|
86
90
|
search_config
|
@@ -4,24 +4,37 @@ module I18n::Tasks::SlopCommand
|
|
4
4
|
def slop_command(name, attr, &block)
|
5
5
|
proc {
|
6
6
|
command name.tr('_', '-') do
|
7
|
-
opts = attr[:opt]
|
8
7
|
args = attr[:args]
|
9
8
|
banner "Usage: i18n-tasks #{name} [options] #{args}" if args.present?
|
10
9
|
desc = attr[:desc]
|
10
|
+
desc = desc.call if desc.respond_to?(:call)
|
11
11
|
description desc if desc
|
12
|
-
|
13
|
-
|
14
|
-
on *[:short, :long, :desc, :conf].map { |k| opt[k] }.compact
|
15
|
-
end
|
12
|
+
attr[:opt].try :each do |opt|
|
13
|
+
on *opt.values_at(:short, :long, :desc, :conf).compact.map { |v| v.respond_to?(:call) ? v.call : v }
|
16
14
|
end
|
17
|
-
run { |
|
15
|
+
run { |slop_opts, slop_args|
|
16
|
+
slop_opts = slop_opts.to_hash(true).reject { |k, v| v.nil? }
|
17
|
+
slop_opts.merge!(arguments: slop_args) unless slop_args.empty?
|
18
|
+
block.call name, slop_opts
|
19
|
+
}
|
18
20
|
end
|
19
21
|
}
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def parse_opts!(opts, opts_conf, context)
|
25
|
+
return if !opts_conf
|
26
|
+
opts_conf.each do |opt_conf|
|
27
|
+
parse = opt_conf[:parse]
|
28
|
+
if parse
|
29
|
+
key = opt_conf[:long].to_s.sub(/=\z/, '').to_sym
|
30
|
+
if parse.respond_to?(:call)
|
31
|
+
context.instance_exec opts, key, &parse
|
32
|
+
elsif Symbol === parse
|
33
|
+
context.instance_exec do
|
34
|
+
send parse, opts, key
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -53,7 +53,7 @@ describe 'Google Translation' do
|
|
53
53
|
}
|
54
54
|
})
|
55
55
|
|
56
|
-
cmd.translate_missing
|
56
|
+
cmd.run :translate_missing
|
57
57
|
expect(task.t('common.hello', 'es')).to eq(text_test[2])
|
58
58
|
expect(task.t('common.hello_html', 'es')).to eq(html_test[2])
|
59
59
|
expect(task.t('common.array_key', 'es')).to eq(array_test[2])
|
@@ -5,6 +5,9 @@ base_locale: en
|
|
5
5
|
## uncomment to set locales explicitly
|
6
6
|
# locales: [en, es, fr]
|
7
7
|
|
8
|
+
## i18n-tasks report locale, default: en, available: en, ru
|
9
|
+
# internal_locale: ru
|
10
|
+
|
8
11
|
# Read and write locale data
|
9
12
|
data:
|
10
13
|
## by default, translation data are read from the file system, or you can provide a custom data adapter
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubis
|
@@ -217,6 +217,7 @@ files:
|
|
217
217
|
- bin/i18n-tasks
|
218
218
|
- config/i18n-tasks.yml
|
219
219
|
- config/locales/en.yml
|
220
|
+
- config/locales/ru.yml
|
220
221
|
- i18n-tasks.gemspec
|
221
222
|
- lib/i18n/tasks.rb
|
222
223
|
- lib/i18n/tasks/base_task.rb
|