i18n-tasks 1.0.15 → 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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -13
  3. data/Rakefile +4 -4
  4. data/bin/i18n-tasks +3 -3
  5. data/config/locales/en.yml +6 -0
  6. data/config/locales/ru.yml +7 -0
  7. data/i18n-tasks.gemspec +28 -41
  8. data/lib/i18n/tasks/base_task.rb +19 -19
  9. data/lib/i18n/tasks/cli.rb +37 -30
  10. data/lib/i18n/tasks/command/collection.rb +4 -4
  11. data/lib/i18n/tasks/command/commander.rb +5 -5
  12. data/lib/i18n/tasks/command/commands/check_prism.rb +126 -0
  13. data/lib/i18n/tasks/command/commands/data.rb +33 -33
  14. data/lib/i18n/tasks/command/commands/eq_base.rb +3 -3
  15. data/lib/i18n/tasks/command/commands/health.rb +6 -5
  16. data/lib/i18n/tasks/command/commands/interpolations.rb +14 -3
  17. data/lib/i18n/tasks/command/commands/meta.rb +6 -6
  18. data/lib/i18n/tasks/command/commands/missing.rb +25 -25
  19. data/lib/i18n/tasks/command/commands/tree.rb +33 -33
  20. data/lib/i18n/tasks/command/commands/usages.rb +24 -24
  21. data/lib/i18n/tasks/command/dsl.rb +1 -1
  22. data/lib/i18n/tasks/command/option_parsers/enum.rb +5 -5
  23. data/lib/i18n/tasks/command/option_parsers/locale.rb +4 -4
  24. data/lib/i18n/tasks/command/options/common.rb +16 -16
  25. data/lib/i18n/tasks/command/options/data.rb +18 -18
  26. data/lib/i18n/tasks/command/options/locales.rb +32 -32
  27. data/lib/i18n/tasks/commands.rb +14 -12
  28. data/lib/i18n/tasks/concurrent/cache.rb +1 -1
  29. data/lib/i18n/tasks/concurrent/cached_value.rb +1 -1
  30. data/lib/i18n/tasks/configuration.rb +22 -21
  31. data/lib/i18n/tasks/console_context.rb +11 -11
  32. data/lib/i18n/tasks/data/adapter/json_adapter.rb +1 -1
  33. data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +5 -5
  34. data/lib/i18n/tasks/data/file_formats.rb +3 -3
  35. data/lib/i18n/tasks/data/file_system.rb +5 -5
  36. data/lib/i18n/tasks/data/file_system_base.rb +26 -26
  37. data/lib/i18n/tasks/data/language_names.rb +202 -0
  38. data/lib/i18n/tasks/data/router/conservative_router.rb +3 -3
  39. data/lib/i18n/tasks/data/router/isolating_router.rb +19 -19
  40. data/lib/i18n/tasks/data/router/pattern_router.rb +5 -5
  41. data/lib/i18n/tasks/data/tree/node.rb +27 -27
  42. data/lib/i18n/tasks/data/tree/nodes.rb +10 -10
  43. data/lib/i18n/tasks/data/tree/siblings.rb +20 -20
  44. data/lib/i18n/tasks/data/tree/traversal.rb +5 -5
  45. data/lib/i18n/tasks/data.rb +4 -4
  46. data/lib/i18n/tasks/html_keys.rb +2 -2
  47. data/lib/i18n/tasks/ignore_keys.rb +9 -9
  48. data/lib/i18n/tasks/interpolations.rb +21 -1
  49. data/lib/i18n/tasks/key_pattern_matching.rb +8 -8
  50. data/lib/i18n/tasks/logging.rb +2 -1
  51. data/lib/i18n/tasks/missing_keys.rb +24 -8
  52. data/lib/i18n/tasks/plural_keys.rb +6 -4
  53. data/lib/i18n/tasks/references.rb +4 -4
  54. data/lib/i18n/tasks/reports/base.rb +18 -14
  55. data/lib/i18n/tasks/reports/terminal.rb +64 -47
  56. data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +3 -3
  57. data/lib/i18n/tasks/scanners/ast_matchers/default_i18n_subject_matcher.rb +3 -3
  58. data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +10 -10
  59. data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +1 -1
  60. data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +69 -10
  61. data/lib/i18n/tasks/scanners/file_scanner.rb +5 -5
  62. data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +3 -3
  63. data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +3 -3
  64. data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +2 -2
  65. data/lib/i18n/tasks/scanners/files/file_finder.rb +8 -8
  66. data/lib/i18n/tasks/scanners/files/file_reader.rb +1 -1
  67. data/lib/i18n/tasks/scanners/local_ruby_parser.rb +8 -8
  68. data/lib/i18n/tasks/scanners/occurrence_from_position.rb +1 -1
  69. data/lib/i18n/tasks/scanners/pattern_mapper.rb +7 -7
  70. data/lib/i18n/tasks/scanners/pattern_scanner.rb +20 -20
  71. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +8 -8
  72. data/lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb +8 -1
  73. data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +101 -61
  74. data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +169 -105
  75. data/lib/i18n/tasks/scanners/relative_keys.rb +8 -8
  76. data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -3
  77. data/lib/i18n/tasks/scanners/results/occurrence.rb +14 -10
  78. data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +1 -1
  79. data/lib/i18n/tasks/scanners/ruby_key_literals.rb +6 -6
  80. data/lib/i18n/tasks/scanners/ruby_parser_factory.rb +1 -1
  81. data/lib/i18n/tasks/scanners/ruby_scanner.rb +225 -0
  82. data/lib/i18n/tasks/scanners/scanner.rb +2 -2
  83. data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +1 -1
  84. data/lib/i18n/tasks/split_key.rb +4 -4
  85. data/lib/i18n/tasks/stats.rb +3 -3
  86. data/lib/i18n/tasks/translation.rb +5 -5
  87. data/lib/i18n/tasks/translators/base_translator.rb +40 -14
  88. data/lib/i18n/tasks/translators/deepl_translator.rb +17 -14
  89. data/lib/i18n/tasks/translators/google_translator.rb +169 -25
  90. data/lib/i18n/tasks/translators/openai_translator.rb +34 -23
  91. data/lib/i18n/tasks/translators/watsonx_translator.rb +16 -16
  92. data/lib/i18n/tasks/translators/yandex_translator.rb +8 -8
  93. data/lib/i18n/tasks/unused_keys.rb +1 -1
  94. data/lib/i18n/tasks/used_keys.rb +32 -33
  95. data/lib/i18n/tasks/version.rb +1 -1
  96. data/lib/i18n/tasks.rb +17 -17
  97. data/templates/config/i18n-tasks.yml +12 -0
  98. data/templates/minitest/i18n_test.rb +3 -3
  99. data/templates/rspec/i18n_spec.rb +7 -7
  100. metadata +25 -185
  101. data/lib/i18n/tasks/scanners/prism_scanner.rb +0 -83
  102. data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
@@ -7,18 +7,18 @@ module I18n::Tasks
7
7
  include Command::Collection
8
8
 
9
9
  arg :strict,
10
- '--[no-]strict',
11
- t('i18n_tasks.cmd.args.desc.strict')
10
+ "--[no-]strict",
11
+ t("i18n_tasks.cmd.args.desc.strict")
12
12
 
13
13
  arg :keep_order,
14
- '-k',
15
- '--keep-order',
16
- t('i18n_tasks.cmd.args.desc.keep_order')
14
+ "-k",
15
+ "--keep-order",
16
+ t("i18n_tasks.cmd.args.desc.keep_order")
17
17
 
18
18
  cmd :find,
19
- pos: '[pattern]',
20
- desc: t('i18n_tasks.cmd.desc.find'),
21
- args: %i[out_format pattern strict]
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
- pos: '[locale ...]',
31
- desc: t('i18n_tasks.cmd.desc.unused'),
32
- args: %i[locales out_format strict]
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
- pos: '[locale ...]',
42
- desc: t('i18n_tasks.cmd.desc.remove_unused'),
43
- args: %i[locales out_format strict keep_order confirm pattern]
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[:'keep-order']
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('i18n_tasks.remove_unused.removed', count: unused_keys.leaves.count)
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('i18n_tasks.remove_unused.noop')).green.bright
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['CONFIRM'] || opt[:confirm]
68
+ return if ENV["CONFIRM"] || opt[:confirm]
69
69
 
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(' ')
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
@@ -17,7 +17,7 @@ module I18n::Tasks
17
17
  module ClassMethods
18
18
  def cmd(name, conf = nil)
19
19
  if conf
20
- conf = conf.dup
20
+ conf = conf.dup
21
21
  conf[:args] = (conf[:args] || []).map { |arg| arg.is_a?(Symbol) ? arg(arg) : arg }
22
22
  dsl(:cmds)[name] = conf
23
23
  else
@@ -6,13 +6,13 @@ module I18n::Tasks
6
6
  module Enum
7
7
  class Parser
8
8
  DEFAULT_ERROR = proc do |invalid, valid|
9
- I18n.t('i18n_tasks.cmd.enum_opt.invalid', invalid: invalid, valid: valid * ', ')
9
+ I18n.t("i18n_tasks.cmd.enum_opt.invalid", invalid: invalid, valid: valid * ", ")
10
10
  end
11
11
 
12
12
  def initialize(valid, error_message = DEFAULT_ERROR, allow_blank: false)
13
- @valid = valid.map(&:to_s)
13
+ @valid = valid.map(&:to_s)
14
14
  @error_message = error_message
15
- @allow_blank = allow_blank
15
+ @allow_blank = allow_blank
16
16
  end
17
17
 
18
18
  def call(value, *)
@@ -28,11 +28,11 @@ module I18n::Tasks
28
28
 
29
29
  class ListParser
30
30
  DEFAULT_ERROR = proc do |invalid, valid|
31
- I18n.t('i18n_tasks.cmd.enum_list_opt.invalid', invalid: invalid * ', ', valid: valid * ', ')
31
+ I18n.t("i18n_tasks.cmd.enum_list_opt.invalid", invalid: invalid * ", ", valid: valid * ", ")
32
32
  end
33
33
 
34
34
  def initialize(valid, error_message = DEFAULT_ERROR)
35
- @valid = valid.map(&:to_s)
35
+ @valid = valid.map(&:to_s)
36
36
  @error_message = error_message
37
37
  end
38
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.freeze
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('i18n_tasks.cmd.errors.invalid_locale', invalid: locale)
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 == 'base'
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 == 'base' ? context.base_locale : v }, context.base_locale)
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 'i18n/tasks/command/dsl'
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
- '-S',
13
- '--nostdin',
14
- t('i18n_tasks.cmd.args.desc.nostdin')
12
+ "-S",
13
+ "--nostdin",
14
+ t("i18n_tasks.cmd.args.desc.nostdin")
15
15
 
16
16
  arg :confirm,
17
- '-y',
18
- '--confirm',
19
- desc: t('i18n_tasks.cmd.args.desc.confirm')
17
+ "-y",
18
+ "--confirm",
19
+ desc: t("i18n_tasks.cmd.args.desc.confirm")
20
20
 
21
21
  arg :pattern,
22
- '-p',
23
- '--pattern PATTERN',
24
- t('i18n_tasks.cmd.args.desc.key_pattern')
22
+ "-p",
23
+ "--pattern PATTERN",
24
+ t("i18n_tasks.cmd.args.desc.key_pattern")
25
25
 
26
26
  arg :value,
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
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
- '-c',
33
- '--config FILE',
34
- t('i18n_tasks.cmd.args.desc.config')
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 'i18n/tasks/command/option_parsers/enum'
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 = ['terminal-table', *DATA_FORMATS, 'inspect', 'key-values'].freeze
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
- '-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)
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('i18n_tasks.cmd.errors.pass_forest') unless src
66
+ fail CommandError, I18n.t("i18n_tasks.cmd.errors.pass_forest") unless src
67
67
 
68
- if format == 'keys'
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 'terminal-table'
82
+ when "terminal-table"
83
83
  terminal_report.send(version, forest)
84
- when 'inspect'
84
+ when "inspect"
85
85
  puts forest.inspect
86
- when 'keys'
86
+ when "keys"
87
87
  puts forest.key_names(root: true)
88
- when 'key-values'
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,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'i18n/tasks/command/option_parsers/locale'
4
- require 'i18n/tasks/command/option_parsers/enum'
3
+ require "i18n/tasks/command/option_parsers/locale"
4
+ require "i18n/tasks/command/option_parsers/enum"
5
5
 
6
6
  module I18n::Tasks
7
7
  module Command
@@ -10,43 +10,43 @@ module I18n::Tasks
10
10
  include Command::DSL
11
11
 
12
12
  arg :locales,
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
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
20
20
 
21
21
  arg :locale,
22
- '-l',
23
- '--locale en',
24
- t('i18n_tasks.cmd.args.desc.locale'),
25
- parser: OptionParsers::Locale::Parser,
26
- default: 'base'
22
+ "-l",
23
+ "--locale en",
24
+ t("i18n_tasks.cmd.args.desc.locale"),
25
+ parser: OptionParsers::Locale::Parser,
26
+ default: "base"
27
27
 
28
28
  arg :locale_to_translate_from,
29
- '-f',
30
- '--from en',
31
- t('i18n_tasks.cmd.args.desc.locale_to_translate_from'),
32
- parser: OptionParsers::Locale::Parser,
33
- default: 'base'
29
+ "-f",
30
+ "--from en",
31
+ t("i18n_tasks.cmd.args.desc.locale_to_translate_from"),
32
+ parser: OptionParsers::Locale::Parser,
33
+ default: "base"
34
34
 
35
35
  TRANSLATION_BACKENDS = %w[google deepl yandex openai watsonx].freeze
36
36
  arg :translation_backend,
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
- )
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
+ )
50
50
  end
51
51
  end
52
52
  end
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
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/commander'
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 'highline/import'
29
+ require "highline/import"
28
30
  end
29
31
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'i18n/tasks/concurrent/cached_value'
3
+ require "i18n/tasks/concurrent/cached_value"
4
4
 
5
5
  module I18n::Tasks::Concurrent
6
6
  # A thread-safe cache.
@@ -35,7 +35,7 @@ module I18n::Tasks::Concurrent
35
35
  # Below are the implementations for major ruby engines, based on concurrent-ruby.
36
36
  # rubocop:disable Lint/DuplicateMethods,Naming/AccessorMethodName
37
37
  case RUBY_ENGINE
38
- when 'rbx'
38
+ when "rbx"
39
39
  def get_result_volatile
40
40
  Rubinius.memory_barrier
41
41
  @result
@@ -2,8 +2,8 @@
2
2
 
3
3
  module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
4
4
  DEFAULTS = {
5
- base_locale: 'en',
6
- internal_locale: 'en',
5
+ base_locale: "en",
6
+ internal_locale: "en",
7
7
  search: ::I18n::Tasks::UsedKeys::SEARCH_DEFAULTS,
8
8
  data: ::I18n::Tasks::Data::DATA_DEFAULTS,
9
9
  translation_backend: :google
@@ -21,20 +21,20 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
21
21
  ].freeze
22
22
 
23
23
  def file_config
24
- file = @config_override || CONFIG_FILES.detect { |f| File.exist?(f) }
24
+ file = @config_override || CONFIG_FILES.detect { |f| File.exist?(f) }
25
25
  # rubocop:disable Security/Eval
26
- config = file && YAML.load(eval(Erubi::Engine.new(File.read(file, encoding: 'UTF-8')).src))
26
+ config = file && YAML.load(eval(Erubi::Engine.new(File.read(file, encoding: "UTF-8")).src))
27
27
  # rubocop:enable Security/Eval
28
28
  if config.present?
29
29
  config.with_indifferent_access.tap do |c|
30
30
  if c[:relative_roots]
31
- warn_deprecated 'Please move relative_roots under search in config/i18n-tasks.yml.'
31
+ warn_deprecated "Please move relative_roots under search in config/i18n-tasks.yml."
32
32
  c[:search][:relative_roots] = c.delete(:relative_roots)
33
33
  end
34
34
 
35
35
  if c.dig(:search, :exclude_method_name_paths)
36
36
  warn_deprecated(
37
- 'Please rename exclude_method_name_paths to relative_exclude_method_name_paths in config/i18n-tasks.yml.'
37
+ "Please rename exclude_method_name_paths to relative_exclude_method_name_paths in config/i18n-tasks.yml."
38
38
  )
39
39
  c[:search][:relative_exclude_method_name_paths] = c[:search].delete(:exclude_method_name_paths)
40
40
  end
@@ -64,16 +64,17 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
64
64
  @config_sections[:translation] ||= begin
65
65
  conf = (config[:translation] || {}).with_indifferent_access
66
66
  conf[:backend] ||= DEFAULTS[:translation_backend]
67
- conf[:google_translate_api_key] = ENV['GOOGLE_TRANSLATE_API_KEY'] if ENV.key?('GOOGLE_TRANSLATE_API_KEY')
68
- conf[:deepl_api_key] = ENV['DEEPL_AUTH_KEY'] if ENV.key?('DEEPL_AUTH_KEY')
69
- conf[:deepl_host] = ENV['DEEPL_HOST'] if ENV.key?('DEEPL_HOST')
70
- conf[:deepl_version] = ENV['DEEPL_VERSION'] if ENV.key?('DEEPL_VERSION')
71
- conf[:openai_api_key] = ENV['OPENAI_API_KEY'] if ENV.key?('OPENAI_API_KEY')
72
- conf[:openai_model] = ENV['OPENAI_MODEL'] if ENV.key?('OPENAI_MODEL')
73
- conf[:watsonx_api_key] = ENV['WATSONX_API_KEY'] if ENV.key?('WATSONX_API_KEY')
74
- conf[:watsonx_project_id] = ENV['WATSONX_PROJECT_ID'] if ENV.key?('WATSONX_PROJECT_ID')
75
- conf[:watsonx_model] = ENV['WATSONX_MODEL'] if ENV.key?('WATSONX_MODEL')
76
- conf[:yandex_api_key] = ENV['YANDEX_API_KEY'] if ENV.key?('YANDEX_API_KEY')
67
+ conf[:google_translate_api_key] = ENV["GOOGLE_TRANSLATE_API_KEY"] if ENV.key?("GOOGLE_TRANSLATE_API_KEY")
68
+ conf[:deepl_api_key] = ENV["DEEPL_AUTH_KEY"] if ENV.key?("DEEPL_AUTH_KEY")
69
+ conf[:deepl_host] = ENV["DEEPL_HOST"] if ENV.key?("DEEPL_HOST")
70
+ conf[:deepl_version] = ENV["DEEPL_VERSION"] if ENV.key?("DEEPL_VERSION")
71
+ conf[:openai_api_key] = ENV["OPENAI_API_KEY"] if ENV.key?("OPENAI_API_KEY")
72
+ conf[:openai_model] = ENV["OPENAI_MODEL"] if ENV.key?("OPENAI_MODEL")
73
+ conf[:openai_locale_prompts] ||= {}
74
+ conf[:watsonx_api_key] = ENV["WATSONX_API_KEY"] if ENV.key?("WATSONX_API_KEY")
75
+ conf[:watsonx_project_id] = ENV["WATSONX_PROJECT_ID"] if ENV.key?("WATSONX_PROJECT_ID")
76
+ conf[:watsonx_model] = ENV["WATSONX_MODEL"] if ENV.key?("WATSONX_MODEL")
77
+ conf[:yandex_api_key] = ENV["YANDEX_API_KEY"] if ENV.key?("YANDEX_API_KEY")
77
78
  conf
78
79
  end
79
80
  end
@@ -91,11 +92,11 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
91
92
  def internal_locale
92
93
  @config_sections[:internal_locale] ||= begin
93
94
  internal_locale = (config[:internal_locale] || DEFAULTS[:internal_locale]).to_s
94
- valid_locales = Dir[File.join(I18n::Tasks.gem_path, 'config', 'locales', '*.yml')]
95
- .map { |f| File.basename(f, '.yml') }
95
+ valid_locales = Dir[File.join(I18n::Tasks.gem_path, "config", "locales", "*.yml")]
96
+ .map { |f| File.basename(f, ".yml") }
96
97
  unless valid_locales.include?(internal_locale)
97
98
  log_warn "invalid internal_locale #{internal_locale.inspect}. " \
98
- "Available internal locales: #{valid_locales * ', '}."
99
+ "Available internal locales: #{valid_locales * ", "}."
99
100
  internal_locale = DEFAULTS[:internal_locale].to_s
100
101
  end
101
102
  internal_locale
@@ -103,7 +104,7 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
103
104
  end
104
105
 
105
106
  def ignore_config(type = nil)
106
- key = type ? "ignore_#{type}" : 'ignore'
107
+ key = type ? "ignore_#{type}" : "ignore"
107
108
  @config_sections[key] ||= config[key]
108
109
  end
109
110
 
@@ -126,7 +127,7 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
126
127
  def config_for_inspect
127
128
  to_hash_from_indifferent(config_sections.reject { |_k, v| v.blank? }).tap do |sections|
128
129
  sections.each_value do |section|
129
- section.merge! section.delete('config') if section.is_a?(Hash) && section.key?('config')
130
+ section.merge! section.delete("config") if section.is_a?(Hash) && section.key?("config")
130
131
  end
131
132
  end
132
133
  end
@@ -16,12 +16,12 @@ module I18n::Tasks
16
16
 
17
17
  class << self
18
18
  def start
19
- require 'irb'
19
+ require "irb"
20
20
  IRB.setup nil
21
21
  ctx = IRB::Irb.new.context
22
22
  IRB.conf[:MAIN_CONTEXT] = ctx
23
- $stderr.puts Messages.banner
24
- require 'irb/ext/multi-irb'
23
+ warn Messages.banner
24
+ require "irb/ext/multi-irb"
25
25
  IRB.irb nil, new
26
26
  end
27
27
  end
@@ -30,18 +30,18 @@ module I18n::Tasks
30
30
  module_function
31
31
 
32
32
  def banner
33
- Rainbow("i18n-tasks v#{I18n::Tasks::VERSION} IRB").bright + "\nType #{Rainbow('guide').green} to learn more"
33
+ Rainbow("i18n-tasks v#{I18n::Tasks::VERSION} IRB").bright + "\nType #{Rainbow("guide").green} to learn more"
34
34
  end
35
35
 
36
36
  def guide
37
- "#{Rainbow('i18n-tasks IRB Quick Start guide').green.bright}\n#{<<~TEXT}"
38
- #{Rainbow('Data as trees').yellow}
37
+ "#{Rainbow("i18n-tasks IRB Quick Start guide").green.bright}\n#{<<~TEXT}"
38
+ #{Rainbow("Data as trees").yellow}
39
39
  tree(locale)
40
40
  used_tree(key_filter: nil, strict: nil)
41
41
  unused_tree(locale: base_locale, strict: nil)
42
42
  build_tree('es' => {'hello' => 'Hola'})
43
43
 
44
- #{Rainbow('Traversal').yellow}
44
+ #{Rainbow("Traversal").yellow}
45
45
  tree = missing_diff_tree('es')
46
46
  tree.nodes { |node| }
47
47
  tree.nodes.to_a
@@ -49,23 +49,23 @@ module I18n::Tasks
49
49
  tree.each { |root_node| }
50
50
  # also levels, depth_first, and breadth_first
51
51
 
52
- #{Rainbow('Select nodes').yellow}
52
+ #{Rainbow("Select nodes").yellow}
53
53
  tree.select_nodes { |node| } # new tree with only selected nodes
54
54
 
55
- #{Rainbow('Match by full key').yellow}
55
+ #{Rainbow("Match by full key").yellow}
56
56
  tree.select_keys { |key, leaf| } # new tree with only selected keys
57
57
  tree.grep_keys(/hello/) # grep, using ===
58
58
  tree.keys { |key, leaf| } # enumerate over [full_key, leaf_node]
59
59
  # Pass {root: true} to include root node in full_key (usually locale)
60
60
 
61
- #{Rainbow('Nodes').yellow}
61
+ #{Rainbow("Nodes").yellow}
62
62
  node = node(key, locale)
63
63
  node.key # only the part after the last dot
64
64
  node.full_key # full key. Includes root key, pass {root: false} to override.
65
65
  # also: value, value_or_children_hash, data, walk_to_root, walk_from_root
66
66
  Tree::Node.new(key: 'en')
67
67
 
68
- #{Rainbow('Keys').yellow}
68
+ #{Rainbow("Keys").yellow}
69
69
  t(key, locale)
70
70
  key_value?(key, locale)
71
71
  depluralize_key(key, locale) # convert 'hat.one' to 'hat'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
3
+ require "json"
4
4
 
5
5
  module I18n::Tasks
6
6
  module Data
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
3
+ require "yaml"
4
4
  module I18n::Tasks
5
5
  module Data
6
6
  module Adapter
7
7
  module YamlAdapter
8
- EMOJI_REGEX = /\\u[\da-f]{8}/i.freeze
9
- TRAILING_SPACE_REGEX = / $/.freeze
8
+ EMOJI_REGEX = /\\u[\da-f]{8}/i
9
+ TRAILING_SPACE_REGEX = / $/
10
10
 
11
11
  class << self
12
12
  # @return [Hash] locale tree
@@ -26,12 +26,12 @@ module I18n::Tasks
26
26
 
27
27
  # @return [String]
28
28
  def restore_emojis(yaml)
29
- yaml.gsub(EMOJI_REGEX) { |m| [m[-8..].to_i(16)].pack('U') }
29
+ yaml.gsub(EMOJI_REGEX) { |m| [m[-8..].to_i(16)].pack("U") }
30
30
  end
31
31
 
32
32
  # @return [String]
33
33
  def strip_trailing_spaces(yaml)
34
- yaml.gsub(TRAILING_SPACE_REGEX, '')
34
+ yaml.gsub(TRAILING_SPACE_REGEX, "")
35
35
  end
36
36
  end
37
37
  end