i18n-tasks 1.0.14 → 1.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 +4 -4
- data/README.md +138 -39
- data/Rakefile +4 -4
- data/bin/i18n-tasks +3 -3
- data/config/locales/en.yml +17 -1
- data/config/locales/ru.yml +18 -1
- data/i18n-tasks.gemspec +28 -38
- data/lib/i18n/tasks/base_task.rb +19 -19
- data/lib/i18n/tasks/cli.rb +37 -30
- data/lib/i18n/tasks/command/collection.rb +4 -4
- data/lib/i18n/tasks/command/commander.rb +5 -5
- data/lib/i18n/tasks/command/commands/check_prism.rb +126 -0
- data/lib/i18n/tasks/command/commands/data.rb +33 -33
- data/lib/i18n/tasks/command/commands/eq_base.rb +3 -3
- data/lib/i18n/tasks/command/commands/health.rb +6 -5
- data/lib/i18n/tasks/command/commands/interpolations.rb +14 -3
- data/lib/i18n/tasks/command/commands/meta.rb +6 -6
- data/lib/i18n/tasks/command/commands/missing.rb +28 -26
- data/lib/i18n/tasks/command/commands/tree.rb +33 -33
- data/lib/i18n/tasks/command/commands/usages.rb +24 -24
- data/lib/i18n/tasks/command/dsl.rb +1 -1
- data/lib/i18n/tasks/command/option_parsers/enum.rb +8 -7
- data/lib/i18n/tasks/command/option_parsers/locale.rb +4 -4
- data/lib/i18n/tasks/command/options/common.rb +16 -16
- data/lib/i18n/tasks/command/options/data.rb +18 -18
- data/lib/i18n/tasks/command/options/locales.rb +33 -24
- data/lib/i18n/tasks/commands.rb +14 -12
- data/lib/i18n/tasks/concurrent/cache.rb +1 -1
- data/lib/i18n/tasks/concurrent/cached_value.rb +1 -1
- data/lib/i18n/tasks/configuration.rb +26 -20
- data/lib/i18n/tasks/console_context.rb +11 -11
- data/lib/i18n/tasks/data/adapter/json_adapter.rb +1 -1
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +5 -5
- data/lib/i18n/tasks/data/file_formats.rb +3 -3
- data/lib/i18n/tasks/data/file_system.rb +5 -5
- data/lib/i18n/tasks/data/file_system_base.rb +26 -26
- data/lib/i18n/tasks/data/language_names.rb +202 -0
- data/lib/i18n/tasks/data/router/conservative_router.rb +3 -3
- data/lib/i18n/tasks/data/router/isolating_router.rb +19 -19
- data/lib/i18n/tasks/data/router/pattern_router.rb +5 -5
- data/lib/i18n/tasks/data/tree/node.rb +27 -27
- data/lib/i18n/tasks/data/tree/nodes.rb +10 -10
- data/lib/i18n/tasks/data/tree/siblings.rb +20 -20
- data/lib/i18n/tasks/data/tree/traversal.rb +5 -5
- data/lib/i18n/tasks/data.rb +4 -4
- data/lib/i18n/tasks/html_keys.rb +2 -2
- data/lib/i18n/tasks/ignore_keys.rb +9 -9
- data/lib/i18n/tasks/interpolations.rb +21 -1
- data/lib/i18n/tasks/key_pattern_matching.rb +8 -8
- data/lib/i18n/tasks/logging.rb +2 -1
- data/lib/i18n/tasks/missing_keys.rb +24 -8
- data/lib/i18n/tasks/plural_keys.rb +6 -4
- data/lib/i18n/tasks/references.rb +4 -4
- data/lib/i18n/tasks/reports/base.rb +18 -14
- data/lib/i18n/tasks/reports/terminal.rb +64 -47
- data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/default_i18n_subject_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +10 -10
- data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +2 -2
- data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +69 -10
- data/lib/i18n/tasks/scanners/file_scanner.rb +5 -5
- data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +2 -2
- data/lib/i18n/tasks/scanners/files/file_finder.rb +8 -8
- data/lib/i18n/tasks/scanners/files/file_reader.rb +1 -1
- data/lib/i18n/tasks/scanners/local_ruby_parser.rb +9 -9
- data/lib/i18n/tasks/scanners/occurrence_from_position.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +7 -7
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +20 -20
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +8 -8
- data/lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb +48 -0
- data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +374 -0
- data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +337 -0
- data/lib/i18n/tasks/scanners/relative_keys.rb +8 -8
- data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -3
- data/lib/i18n/tasks/scanners/results/occurrence.rb +14 -10
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +1 -1
- data/lib/i18n/tasks/scanners/ruby_key_literals.rb +6 -6
- data/lib/i18n/tasks/scanners/ruby_parser_factory.rb +27 -0
- data/lib/i18n/tasks/scanners/ruby_scanner.rb +225 -0
- data/lib/i18n/tasks/scanners/scanner.rb +2 -2
- data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +1 -1
- data/lib/i18n/tasks/split_key.rb +4 -4
- data/lib/i18n/tasks/stats.rb +3 -3
- data/lib/i18n/tasks/translation.rb +8 -5
- data/lib/i18n/tasks/translators/base_translator.rb +43 -13
- data/lib/i18n/tasks/translators/deepl_translator.rb +22 -14
- data/lib/i18n/tasks/translators/google_translator.rb +178 -26
- data/lib/i18n/tasks/translators/openai_translator.rb +56 -31
- data/lib/i18n/tasks/translators/watsonx_translator.rb +155 -0
- data/lib/i18n/tasks/translators/yandex_translator.rb +13 -9
- data/lib/i18n/tasks/unused_keys.rb +1 -1
- data/lib/i18n/tasks/used_keys.rb +32 -32
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/i18n/tasks.rb +17 -16
- data/templates/config/i18n-tasks.yml +14 -2
- data/templates/minitest/i18n_test.rb +3 -3
- data/templates/rspec/i18n_spec.rb +7 -7
- metadata +38 -172
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/command/collection"
|
|
4
4
|
|
|
5
5
|
module I18n::Tasks
|
|
6
6
|
module Command
|
|
@@ -10,22 +10,22 @@ module I18n::Tasks
|
|
|
10
10
|
|
|
11
11
|
missing_types = I18n::Tasks::MissingKeys.missing_keys_types
|
|
12
12
|
arg :missing_types,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
"-t",
|
|
14
|
+
"--types #{missing_types * ","}",
|
|
15
|
+
Array,
|
|
16
|
+
t("i18n_tasks.cmd.args.desc.missing_types", valid: missing_types * ", "),
|
|
17
|
+
parser: OptionParsers::Enum::ListParser.new(
|
|
18
|
+
missing_types,
|
|
19
|
+
proc do |invalid, valid|
|
|
20
|
+
I18n.t("i18n_tasks.cmd.errors.invalid_missing_type",
|
|
21
|
+
invalid: invalid * ", ", valid: valid * ", ", count: invalid.length)
|
|
22
|
+
end
|
|
23
|
+
)
|
|
24
24
|
|
|
25
25
|
cmd :missing,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
pos: "[locale ...]",
|
|
27
|
+
desc: t("i18n_tasks.cmd.desc.missing"),
|
|
28
|
+
args: %i[locales out_format missing_types pattern]
|
|
29
29
|
|
|
30
30
|
def missing(opt = {})
|
|
31
31
|
forest = i18n.missing_keys(**opt.slice(:locales, :base_locale, :types))
|
|
@@ -38,9 +38,9 @@ module I18n::Tasks
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
cmd :translate_missing,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
pos: "[locale ...]",
|
|
42
|
+
desc: t("i18n_tasks.cmd.desc.translate_missing"),
|
|
43
|
+
args: [:locales, :locale_to_translate_from, arg(:out_format).from(1), :translation_backend, :pattern]
|
|
44
44
|
|
|
45
45
|
def translate_missing(opt = {})
|
|
46
46
|
missing = i18n.missing_diff_forest opt[:locales], opt[:from]
|
|
@@ -48,17 +48,19 @@ module I18n::Tasks
|
|
|
48
48
|
pattern_re = i18n.compile_key_pattern(opt[:pattern])
|
|
49
49
|
missing.select_keys! { |full_key, _node| full_key =~ pattern_re }
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
backend = opt[:backend].presence || i18n.translation_config[:backend]
|
|
53
|
+
translated = i18n.translate_forest missing, from: opt[:from], backend: backend.to_sym
|
|
52
54
|
i18n.data.merge! translated
|
|
53
|
-
log_stderr t(
|
|
55
|
+
log_stderr t("i18n_tasks.translate_missing.translated", count: translated.leaves.count)
|
|
54
56
|
print_forest translated, opt
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
cmd :add_missing,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
pos: "[locale ...]",
|
|
61
|
+
desc: t("i18n_tasks.cmd.desc.add_missing"),
|
|
62
|
+
args: [:locales, :out_format, :pattern, arg(:value) + [{default: "%{value_or_default_or_human_key}"}],
|
|
63
|
+
["--nil-value", "Set value to nil. Takes precedence over the value argument."]]
|
|
62
64
|
|
|
63
65
|
# Merge base locale first, as this may affect the value for the other locales
|
|
64
66
|
def add_missing(opt = {}) # rubocop:disable Metrics/AbcSize
|
|
@@ -67,7 +69,7 @@ module I18n::Tasks
|
|
|
67
69
|
opt[:locales] - [i18n.base_locale]
|
|
68
70
|
].reject(&:empty?).each_with_object(i18n.empty_forest) do |locales, added|
|
|
69
71
|
forest = i18n.missing_keys(locales: locales, **opt.slice(:types, :base_locale))
|
|
70
|
-
|
|
72
|
+
.set_each_value!(opt[:"nil-value"] ? nil : opt[:value])
|
|
71
73
|
if opt[:pattern]
|
|
72
74
|
pattern_re = i18n.compile_key_pattern(opt[:pattern])
|
|
73
75
|
forest.select_keys! { |full_key, _node| full_key =~ pattern_re }
|
|
@@ -75,7 +77,7 @@ module I18n::Tasks
|
|
|
75
77
|
i18n.data.merge! forest
|
|
76
78
|
added.merge! forest
|
|
77
79
|
end.tap do |added|
|
|
78
|
-
log_stderr t(
|
|
80
|
+
log_stderr t("i18n_tasks.add_missing.added", count: added.leaves.count)
|
|
79
81
|
print_forest added, opt
|
|
80
82
|
end
|
|
81
83
|
end
|
|
@@ -8,9 +8,9 @@ module I18n::Tasks
|
|
|
8
8
|
include I18n::Tasks::KeyPatternMatching
|
|
9
9
|
|
|
10
10
|
cmd :tree_translate,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
pos: "[tree (or stdin)]",
|
|
12
|
+
desc: t("i18n_tasks.cmd.desc.tree_translate"),
|
|
13
|
+
args: [:locale_to_translate_from, arg(:data_format).from(1), :translation_backend]
|
|
14
14
|
|
|
15
15
|
def tree_translate(opts = {})
|
|
16
16
|
forest = forest_pos_or_stdin!(opts)
|
|
@@ -18,79 +18,79 @@ module I18n::Tasks
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
cmd :tree_merge,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
pos: "[[tree] [tree] ... (or stdin)]",
|
|
22
|
+
desc: t("i18n_tasks.cmd.desc.tree_merge"),
|
|
23
|
+
args: %i[data_format nostdin]
|
|
24
24
|
|
|
25
25
|
def tree_merge(opts = {})
|
|
26
26
|
print_forest merge_forests_stdin_and_pos!(opts), opts
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
cmd :tree_filter,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
pos: "[pattern] [tree (or stdin)]",
|
|
31
|
+
desc: t("i18n_tasks.cmd.desc.tree_filter"),
|
|
32
|
+
args: %i[data_format pattern]
|
|
33
33
|
|
|
34
34
|
def tree_filter(opts = {})
|
|
35
35
|
pattern = arg_or_pos! :pattern, opts
|
|
36
|
-
forest
|
|
36
|
+
forest = forest_pos_or_stdin! opts
|
|
37
37
|
unless pattern.blank?
|
|
38
38
|
pattern_re = i18n.compile_key_pattern(pattern)
|
|
39
|
-
forest
|
|
39
|
+
forest = forest.select_keys { |full_key, _node| full_key =~ pattern_re }
|
|
40
40
|
end
|
|
41
41
|
print_forest forest, opts
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
arg :all_locales,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
"-a",
|
|
46
|
+
"--all-locales",
|
|
47
|
+
t("i18n_tasks.cmd.args.desc.all_locales")
|
|
48
48
|
|
|
49
49
|
cmd :tree_mv,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
pos: "FROM_KEY_PATTERN TO_KEY_PATTERN [tree (or stdin)]",
|
|
51
|
+
desc: t("i18n_tasks.cmd.desc.tree_mv_key"),
|
|
52
|
+
args: %i[data_format all_locales]
|
|
53
53
|
def tree_mv(opt = {})
|
|
54
|
-
fail CommandError,
|
|
54
|
+
fail CommandError, "requires FROM_KEY_PATTERN and TO_KEY_PATTERN" if opt[:arguments].size < 2
|
|
55
55
|
|
|
56
56
|
from_pattern = opt[:arguments].shift
|
|
57
57
|
to_pattern = opt[:arguments].shift
|
|
58
58
|
forest = forest_pos_or_stdin!(opt)
|
|
59
|
-
forest.mv_key!(compile_key_pattern(from_pattern), to_pattern, root: !opt[:
|
|
59
|
+
forest.mv_key!(compile_key_pattern(from_pattern), to_pattern, root: !opt[:"all-locales"])
|
|
60
60
|
print_forest forest, opt
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
cmd :tree_subtract,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
pos: "[[tree] [tree] ... (or stdin)]",
|
|
65
|
+
desc: t("i18n_tasks.cmd.desc.tree_subtract"),
|
|
66
|
+
args: %i[data_format nostdin]
|
|
67
67
|
|
|
68
68
|
def tree_subtract(opt = {})
|
|
69
69
|
forests = forests_stdin_and_pos! opt, 2
|
|
70
|
-
forest
|
|
70
|
+
forest = forests.reduce(:subtract_by_key) || empty_forest
|
|
71
71
|
print_forest forest, opt
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
cmd :tree_set_value,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
pos: "[VALUE] [tree (or stdin)]",
|
|
76
|
+
desc: t("i18n_tasks.cmd.desc.tree_set_value"),
|
|
77
|
+
args: %i[value data_format nostdin pattern]
|
|
78
78
|
|
|
79
79
|
def tree_set_value(opt = {})
|
|
80
|
-
value
|
|
81
|
-
forest
|
|
80
|
+
value = arg_or_pos! :value, opt
|
|
81
|
+
forest = forest_pos_or_stdin!(opt)
|
|
82
82
|
key_pattern = opt[:pattern]
|
|
83
|
-
fail CommandError,
|
|
83
|
+
fail CommandError, "pass value (-v, --value)" if value.blank?
|
|
84
84
|
|
|
85
85
|
forest.set_each_value!(value, key_pattern)
|
|
86
86
|
print_forest forest, opt
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
cmd :tree_convert,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
pos: "[tree (or stdin)]",
|
|
91
|
+
desc: t("i18n_tasks.cmd.desc.tree_convert"),
|
|
92
|
+
args: [arg(:data_format).dup.tap { |a| a[0..1] = ["-f", "--from FORMAT"] },
|
|
93
|
+
arg(:out_format).dup.tap { |a| a[0..1] = ["-t", "--to FORMAT"] }]
|
|
94
94
|
|
|
95
95
|
def tree_convert(opt = {})
|
|
96
96
|
forest = forest_pos_or_stdin! opt.merge(format: opt[:from])
|
|
@@ -7,18 +7,18 @@ module I18n::Tasks
|
|
|
7
7
|
include Command::Collection
|
|
8
8
|
|
|
9
9
|
arg :strict,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
"--[no-]strict",
|
|
11
|
+
t("i18n_tasks.cmd.args.desc.strict")
|
|
12
12
|
|
|
13
13
|
arg :keep_order,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
"-k",
|
|
15
|
+
"--keep-order",
|
|
16
|
+
t("i18n_tasks.cmd.args.desc.keep_order")
|
|
17
17
|
|
|
18
18
|
cmd :find,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
pos: "[pattern]",
|
|
20
|
+
desc: t("i18n_tasks.cmd.desc.find"),
|
|
21
|
+
args: %i[out_format pattern strict]
|
|
22
22
|
|
|
23
23
|
def find(opt = {})
|
|
24
24
|
opt[:filter] ||= opt.delete(:pattern) || opt[:arguments].try(:first)
|
|
@@ -27,9 +27,9 @@ module I18n::Tasks
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
cmd :unused,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
pos: "[locale ...]",
|
|
31
|
+
desc: t("i18n_tasks.cmd.desc.unused"),
|
|
32
|
+
args: %i[locales out_format strict]
|
|
33
33
|
|
|
34
34
|
def unused(opt = {})
|
|
35
35
|
forest = i18n.unused_keys(**opt.slice(:locales, :strict))
|
|
@@ -38,9 +38,9 @@ module I18n::Tasks
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
cmd :remove_unused,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
pos: "[locale ...]",
|
|
42
|
+
desc: t("i18n_tasks.cmd.desc.remove_unused"),
|
|
43
|
+
args: %i[locales out_format strict keep_order confirm pattern]
|
|
44
44
|
|
|
45
45
|
def remove_unused(opt = {}) # rubocop:disable Metrics/AbcSize
|
|
46
46
|
unused_keys = i18n.unused_keys(**opt.slice(:locales, :strict))
|
|
@@ -53,26 +53,26 @@ module I18n::Tasks
|
|
|
53
53
|
if unused_keys.present?
|
|
54
54
|
terminal_report.unused_keys(unused_keys)
|
|
55
55
|
confirm_remove_unused!(unused_keys, opt)
|
|
56
|
-
i18n.data.config = i18n.data.config.merge(sort: false) if opt[:
|
|
56
|
+
i18n.data.config = i18n.data.config.merge(sort: false) if opt[:"keep-order"]
|
|
57
57
|
removed = i18n.data.remove_by_key!(unused_keys)
|
|
58
|
-
log_stderr t(
|
|
58
|
+
log_stderr t("i18n_tasks.remove_unused.removed", count: unused_keys.leaves.count)
|
|
59
59
|
print_forest removed, opt
|
|
60
60
|
else
|
|
61
|
-
log_stderr Rainbow(t(
|
|
61
|
+
log_stderr Rainbow(t("i18n_tasks.remove_unused.noop")).green.bright
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
private
|
|
66
66
|
|
|
67
67
|
def confirm_remove_unused!(unused_keys, opt)
|
|
68
|
-
return if ENV[
|
|
68
|
+
return if ENV["CONFIRM"] || opt[:confirm]
|
|
69
69
|
|
|
70
|
-
locales = Rainbow(unused_keys.flat_map { |root| root.key.split(
|
|
71
|
-
msg
|
|
72
|
-
Rainbow(t(
|
|
73
|
-
Rainbow(t(
|
|
74
|
-
Rainbow(
|
|
75
|
-
].join(
|
|
70
|
+
locales = Rainbow(unused_keys.flat_map { |root| root.key.split("+") }.sort.uniq * ", ").bright
|
|
71
|
+
msg = [
|
|
72
|
+
Rainbow(t("i18n_tasks.remove_unused.confirm", count: unused_keys.leaves.count, locales: locales)).red,
|
|
73
|
+
Rainbow(t("i18n_tasks.common.continue_q")).yellow,
|
|
74
|
+
Rainbow("(yes/no)").yellow
|
|
75
|
+
].join(" ")
|
|
76
76
|
exit 1 unless agree msg
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -6,20 +6,21 @@ module I18n::Tasks
|
|
|
6
6
|
module Enum
|
|
7
7
|
class Parser
|
|
8
8
|
DEFAULT_ERROR = proc do |invalid, valid|
|
|
9
|
-
I18n.t(
|
|
9
|
+
I18n.t("i18n_tasks.cmd.enum_opt.invalid", invalid: invalid, valid: valid * ", ")
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def initialize(valid, error_message = DEFAULT_ERROR)
|
|
13
|
-
@valid
|
|
12
|
+
def initialize(valid, error_message = DEFAULT_ERROR, allow_blank: false)
|
|
13
|
+
@valid = valid.map(&:to_s)
|
|
14
14
|
@error_message = error_message
|
|
15
|
+
@allow_blank = allow_blank
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def call(value, *)
|
|
18
|
-
return @valid.first
|
|
19
|
+
return @valid.first if value.blank? && !@allow_blank
|
|
19
20
|
|
|
20
21
|
if @valid.include?(value)
|
|
21
22
|
value
|
|
22
|
-
|
|
23
|
+
elsif value.present? || !@allow_blank
|
|
23
24
|
fail CommandError, @error_message.call(value, @valid)
|
|
24
25
|
end
|
|
25
26
|
end
|
|
@@ -27,11 +28,11 @@ module I18n::Tasks
|
|
|
27
28
|
|
|
28
29
|
class ListParser
|
|
29
30
|
DEFAULT_ERROR = proc do |invalid, valid|
|
|
30
|
-
I18n.t(
|
|
31
|
+
I18n.t("i18n_tasks.cmd.enum_list_opt.invalid", invalid: invalid * ", ", valid: valid * ", ")
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def initialize(valid, error_message = DEFAULT_ERROR)
|
|
34
|
-
@valid
|
|
35
|
+
@valid = valid.map(&:to_s)
|
|
35
36
|
@error_message = error_message
|
|
36
37
|
end
|
|
37
38
|
|
|
@@ -5,11 +5,11 @@ module I18n::Tasks
|
|
|
5
5
|
module OptionParsers
|
|
6
6
|
module Locale
|
|
7
7
|
module Validator
|
|
8
|
-
VALID_LOCALE_RE = /\A\w[\w\-.]*\z/i
|
|
8
|
+
VALID_LOCALE_RE = /\A\w[\w\-.]*\z/i
|
|
9
9
|
|
|
10
10
|
def validate!(locale)
|
|
11
11
|
if VALID_LOCALE_RE !~ locale
|
|
12
|
-
fail CommandError, I18n.t(
|
|
12
|
+
fail CommandError, I18n.t("i18n_tasks.cmd.errors.invalid_locale", invalid: locale)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
locale
|
|
@@ -23,7 +23,7 @@ module I18n::Tasks
|
|
|
23
23
|
|
|
24
24
|
# @param [#base_locale, #locales] context
|
|
25
25
|
def call(val, context)
|
|
26
|
-
if val.blank? || val ==
|
|
26
|
+
if val.blank? || val == "base"
|
|
27
27
|
context.base_locale
|
|
28
28
|
else
|
|
29
29
|
validate! val
|
|
@@ -41,7 +41,7 @@ module I18n::Tasks
|
|
|
41
41
|
if vals == %w[all] || vals.blank?
|
|
42
42
|
context.locales
|
|
43
43
|
else
|
|
44
|
-
move_base_locale_to_front!(vals.map { |v| v ==
|
|
44
|
+
move_base_locale_to_front!(vals.map { |v| (v == "base") ? context.base_locale : v }, context.base_locale)
|
|
45
45
|
end.tap do |locales|
|
|
46
46
|
locales.each { |locale| validate! locale }
|
|
47
47
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/command/dsl"
|
|
4
4
|
|
|
5
5
|
module I18n::Tasks
|
|
6
6
|
module Command
|
|
@@ -9,29 +9,29 @@ module I18n::Tasks
|
|
|
9
9
|
include Command::DSL
|
|
10
10
|
|
|
11
11
|
arg :nostdin,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
"-S",
|
|
13
|
+
"--nostdin",
|
|
14
|
+
t("i18n_tasks.cmd.args.desc.nostdin")
|
|
15
15
|
|
|
16
16
|
arg :confirm,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
"-y",
|
|
18
|
+
"--confirm",
|
|
19
|
+
desc: t("i18n_tasks.cmd.args.desc.confirm")
|
|
20
20
|
|
|
21
21
|
arg :pattern,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
"-p",
|
|
23
|
+
"--pattern PATTERN",
|
|
24
|
+
t("i18n_tasks.cmd.args.desc.key_pattern")
|
|
25
25
|
|
|
26
26
|
arg :value,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
"-v",
|
|
28
|
+
"--value VALUE",
|
|
29
|
+
t("i18n_tasks.cmd.args.desc.value", dummy: "value") # Dummy value is workaround for https://github.com/ruby-i18n/i18n/issues/689
|
|
30
30
|
|
|
31
31
|
arg :config,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
"-c",
|
|
33
|
+
"--config FILE",
|
|
34
|
+
t("i18n_tasks.cmd.args.desc.config")
|
|
35
35
|
|
|
36
36
|
def arg_or_pos!(key, opts)
|
|
37
37
|
opts[key] ||= opts[:arguments].try(:shift)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/command/option_parsers/enum"
|
|
4
4
|
|
|
5
5
|
module I18n::Tasks
|
|
6
6
|
module Command
|
|
@@ -9,21 +9,21 @@ module I18n::Tasks
|
|
|
9
9
|
include Command::DSL
|
|
10
10
|
|
|
11
11
|
DATA_FORMATS = %w[yaml json keys].freeze
|
|
12
|
-
OUT_FORMATS
|
|
12
|
+
OUT_FORMATS = ["terminal-table", *DATA_FORMATS, "inspect", "key-values"].freeze
|
|
13
13
|
|
|
14
14
|
format_arg = proc do |type, values|
|
|
15
15
|
default = values.first
|
|
16
16
|
arg type,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
"-f",
|
|
18
|
+
"--format FORMAT",
|
|
19
|
+
values,
|
|
20
|
+
{"yml" => "yaml"},
|
|
21
|
+
t("i18n_tasks.cmd.args.desc.#{type}", valid_text: values * ", ", default_text: default),
|
|
22
|
+
parser: OptionParsers::Enum::Parser.new(values,
|
|
23
|
+
proc do |value, valid|
|
|
24
|
+
I18n.t("i18n_tasks.cmd.errors.invalid_format",
|
|
25
|
+
invalid: value, valid: valid * ", ")
|
|
26
|
+
end)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# i18n-tasks-use t('i18n_tasks.cmd.args.desc.data_format')
|
|
@@ -63,9 +63,9 @@ module I18n::Tasks
|
|
|
63
63
|
|
|
64
64
|
# @return [I18n::Tasks::Data::Tree::Siblings]
|
|
65
65
|
def parse_forest(src, format)
|
|
66
|
-
fail CommandError, I18n.t(
|
|
66
|
+
fail CommandError, I18n.t("i18n_tasks.cmd.errors.pass_forest") unless src
|
|
67
67
|
|
|
68
|
-
if format ==
|
|
68
|
+
if format == "keys"
|
|
69
69
|
::I18n::Tasks::Data::Tree::Siblings.from_key_names parse_keys(src)
|
|
70
70
|
else
|
|
71
71
|
::I18n::Tasks::Data::Tree::Siblings.from_nested_hash i18n.data.adapter_parse(src, format)
|
|
@@ -79,13 +79,13 @@ module I18n::Tasks
|
|
|
79
79
|
def print_forest(forest, opts, version = :show_tree)
|
|
80
80
|
format = opts[:format].to_s
|
|
81
81
|
case format
|
|
82
|
-
when
|
|
82
|
+
when "terminal-table"
|
|
83
83
|
terminal_report.send(version, forest)
|
|
84
|
-
when
|
|
84
|
+
when "inspect"
|
|
85
85
|
puts forest.inspect
|
|
86
|
-
when
|
|
86
|
+
when "keys"
|
|
87
87
|
puts forest.key_names(root: true)
|
|
88
|
-
when
|
|
88
|
+
when "key-values"
|
|
89
89
|
puts(forest.key_values(root: true).map { |kv| kv.join("\t") })
|
|
90
90
|
when *DATA_FORMATS
|
|
91
91
|
puts i18n.data.adapter_dump forest.to_hash(true), format
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/command/option_parsers/locale"
|
|
4
|
+
require "i18n/tasks/command/option_parsers/enum"
|
|
4
5
|
|
|
5
6
|
module I18n::Tasks
|
|
6
7
|
module Command
|
|
@@ -9,35 +10,43 @@ module I18n::Tasks
|
|
|
9
10
|
include Command::DSL
|
|
10
11
|
|
|
11
12
|
arg :locales,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
"-l",
|
|
14
|
+
"--locales en,es,ru",
|
|
15
|
+
Array,
|
|
16
|
+
t("i18n_tasks.cmd.args.desc.locales_filter"),
|
|
17
|
+
parser: OptionParsers::Locale::ListParser,
|
|
18
|
+
default: "all",
|
|
19
|
+
consume_positional: true
|
|
19
20
|
|
|
20
21
|
arg :locale,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
"-l",
|
|
23
|
+
"--locale en",
|
|
24
|
+
t("i18n_tasks.cmd.args.desc.locale"),
|
|
25
|
+
parser: OptionParsers::Locale::Parser,
|
|
26
|
+
default: "base"
|
|
26
27
|
|
|
27
28
|
arg :locale_to_translate_from,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
"-f",
|
|
30
|
+
"--from en",
|
|
31
|
+
t("i18n_tasks.cmd.args.desc.locale_to_translate_from"),
|
|
32
|
+
parser: OptionParsers::Locale::Parser,
|
|
33
|
+
default: "base"
|
|
33
34
|
|
|
34
|
-
TRANSLATION_BACKENDS = %w[google deepl].freeze
|
|
35
|
+
TRANSLATION_BACKENDS = %w[google deepl yandex openai watsonx].freeze
|
|
35
36
|
arg :translation_backend,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
"-b",
|
|
38
|
+
"--backend BACKEND",
|
|
39
|
+
t("i18n_tasks.cmd.args.desc.translation_backend"),
|
|
40
|
+
parser:
|
|
41
|
+
OptionParsers::Enum::Parser.new(
|
|
42
|
+
TRANSLATION_BACKENDS,
|
|
43
|
+
proc do |value, valid|
|
|
44
|
+
if value.present?
|
|
45
|
+
I18n.t("i18n_tasks.cmd.errors.invalid_backend", invalid: value&.strip, valid: valid * ", ")
|
|
46
|
+
end
|
|
47
|
+
end,
|
|
48
|
+
allow_blank: true
|
|
49
|
+
)
|
|
41
50
|
end
|
|
42
51
|
end
|
|
43
52
|
end
|
data/lib/i18n/tasks/commands.rb
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require
|
|
13
|
-
require
|
|
3
|
+
require "i18n/tasks/command/dsl"
|
|
4
|
+
require "i18n/tasks/command/collection"
|
|
5
|
+
require "i18n/tasks/command/commands/health"
|
|
6
|
+
require "i18n/tasks/command/commands/missing"
|
|
7
|
+
require "i18n/tasks/command/commands/usages"
|
|
8
|
+
require "i18n/tasks/command/commands/interpolations"
|
|
9
|
+
require "i18n/tasks/command/commands/eq_base"
|
|
10
|
+
require "i18n/tasks/command/commands/data"
|
|
11
|
+
require "i18n/tasks/command/commands/tree"
|
|
12
|
+
require "i18n/tasks/command/commands/meta"
|
|
13
|
+
require "i18n/tasks/command/commands/check_prism"
|
|
14
|
+
require "i18n/tasks/command/commander"
|
|
14
15
|
|
|
15
16
|
module I18n::Tasks
|
|
16
17
|
class Commands < Command::Commander
|
|
@@ -23,7 +24,8 @@ module I18n::Tasks
|
|
|
23
24
|
include Command::Commands::Data
|
|
24
25
|
include Command::Commands::Tree
|
|
25
26
|
include Command::Commands::Meta
|
|
27
|
+
include Command::Commands::CheckPrism
|
|
26
28
|
|
|
27
|
-
require
|
|
29
|
+
require "highline/import"
|
|
28
30
|
end
|
|
29
31
|
end
|