i18n-tasks 0.9.34 → 0.9.35

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5477cbdf1fb14c575eaad7221cac570147acfcde877fa5960dcdfd958d76d270
4
- data.tar.gz: b40dbef296c01aa2c047b8ae2f6ef3567f8643b35895516a8fde281f225e6daa
3
+ metadata.gz: 8ac03642fdf45424834ce7e968e70af9d602c5d5721eda666dbd38635adcf542
4
+ data.tar.gz: 793b43903d97f1dccead925e5128142886708b279f55f04bcd62c6b349bddead
5
5
  SHA512:
6
- metadata.gz: f732fc9479ba13cd3acb1c7222401f873ace5a8db1ef248712c1ea4dbdb9d05a7fdc5da5bb3600c7c799c64b7f21b1586518b1feec508a0ad36d211110b07b3e
7
- data.tar.gz: f05241d9bd75bbecb1cb992882d84c4e9826c00c66b66263e7203603e19c9a188e96ea7f4e4131160e23216265df675f4519d190263cf14de59384bd2e62c88d
6
+ metadata.gz: 538b6490808142df807dcfa623e6907dd408dc9346e37b2ecbba2257350fa6dcf91b66f8b1f9338cc24fbd7f138ee5c20a7875633c26c9c06ac06dbb87e7e67a
7
+ data.tar.gz: f7570702d3599d229236ffd3841b33776b3bef50875b12c515b5bc3e63ace2ef2f86fd3058e957959e196c90ace5dc539a5b328a203f0e9f4460b26f3b751778
data/README.md CHANGED
@@ -22,7 +22,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
22
22
  Add i18n-tasks to the Gemfile:
23
23
 
24
24
  ```ruby
25
- gem 'i18n-tasks', '~> 0.9.34'
25
+ gem 'i18n-tasks', '~> 0.9.35'
26
26
  ```
27
27
 
28
28
  Copy the default [configuration file](#configuration):
@@ -212,7 +212,7 @@ $ i18n-tasks missing -f yaml fr | i18n-tasks tree-set-value 'TRME %{value}' | i1
212
212
  $ i18n-tasks unused -f yaml | i18n-tasks data-remove
213
213
  ```
214
214
 
215
- Remove all keys in `fr` but not `en` from `fr`:
215
+ Remove all keys from `fr` that do not exist in `en`. Do not change `en`:
216
216
  ```console
217
217
  $ i18n-tasks missing -t diff -f yaml en | i18n-tasks tree-mv en fr | i18n-tasks data-remove
218
218
  ```
@@ -405,7 +405,9 @@ translation:
405
405
  ```yaml
406
406
  # config/i18n-tasks.yml
407
407
  translation:
408
- deepl_api_key: <Deep Pro API key>
408
+ deepl_api_key: <DeepL Pro API key>
409
+ deepl_host: <optional>
410
+ deepl_version: <optional>
409
411
  ```
410
412
 
411
413
  <a name="yandex-translation-config"></a>
@@ -11,6 +11,7 @@ en:
11
11
  desc:
12
12
  all_locales: Do not expect key patterns to start with a locale, instead apply them to all
13
13
  locales implicitly.
14
+ config: Override config location
14
15
  confirm: Confirm automatically
15
16
  data_format: 'Data format: %{valid_text}.'
16
17
  keep_order: Keep the order of the keys
@@ -39,7 +39,8 @@ module I18n
39
39
  include Data
40
40
  include Stats
41
41
 
42
- def initialize(config = {})
42
+ def initialize(config = {}, config_file: nil)
43
+ @config_override = config_file
43
44
  self.config = config || {}
44
45
  end
45
46
 
@@ -34,7 +34,18 @@ class I18n::Tasks::CLI
34
34
  end
35
35
 
36
36
  def run(argv)
37
- I18n.with_locale(base_task.internal_locale) do
37
+ argv.each_with_index do |arg, i|
38
+ if ["--config", "-c"].include?(arg)
39
+ if File.exist?(argv[i+1])
40
+ @config_file = argv[i+1]
41
+ break
42
+ else
43
+ error "Config file doesn't exist: #{argv[i+1]}", 128
44
+ end
45
+ end
46
+ end
47
+
48
+ I18n.with_locale(base_task(config_file: @config_file).internal_locale) do
38
49
  name, *options = parse!(argv.dup)
39
50
  context.run(name, *options)
40
51
  end
@@ -52,8 +63,8 @@ class I18n::Tasks::CLI
52
63
 
53
64
  private
54
65
 
55
- def base_task
56
- @base_task ||= I18n::Tasks::BaseTask.new
66
+ def base_task(config_file: nil)
67
+ @base_task ||= I18n::Tasks::BaseTask.new(config_file: config_file)
57
68
  end
58
69
 
59
70
  def parse!(argv)
@@ -9,7 +9,7 @@ module I18n::Tasks
9
9
  cmd :health,
10
10
  pos: '[locale ...]',
11
11
  desc: t('i18n_tasks.cmd.desc.health'),
12
- args: %i[locales out_format]
12
+ args: %i[locales out_format config]
13
13
 
14
14
  def health(opt = {})
15
15
  forest = i18n.data_forest(opt[:locales])
@@ -28,6 +28,12 @@ module I18n::Tasks
28
28
  '--value VALUE',
29
29
  t('i18n_tasks.cmd.args.desc.value')
30
30
 
31
+ arg :config,
32
+ '-c',
33
+ '--config FILE',
34
+ t('i18n_tasks.cmd.args.desc.config')
35
+
36
+
31
37
  def arg_or_pos!(key, opts)
32
38
  opts[key] ||= opts[:arguments].try(:shift)
33
39
  end
@@ -20,7 +20,7 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
20
20
  ].freeze
21
21
 
22
22
  def file_config
23
- file = CONFIG_FILES.detect { |f| File.exist?(f) }
23
+ file = @config_override || CONFIG_FILES.detect { |f| File.exist?(f) }
24
24
  # rubocop:disable Security/Eval
25
25
  config = file && YAML.load(eval(Erubi::Engine.new(File.read(file, encoding: 'UTF-8')).src))
26
26
  # rubocop:enable Security/Eval
@@ -59,6 +59,8 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
59
59
  conf = (config[:translation] || {}).with_indifferent_access
60
60
  conf[:google_translate_api_key] = ENV['GOOGLE_TRANSLATE_API_KEY'] if ENV.key?('GOOGLE_TRANSLATE_API_KEY')
61
61
  conf[:deepl_api_key] = ENV['DEEPL_AUTH_KEY'] if ENV.key?('DEEPL_AUTH_KEY')
62
+ conf[:deepl_host] = ENV['DEEPL_HOST'] if ENV.key?('DEEPL_HOST')
63
+ conf[:deepl_version] = ENV['DEEPL_VERSION'] if ENV.key?('DEEPL_VERSION')
62
64
  conf[:yandex_api_key] = ENV['YANDEX_API_KEY'] if ENV.key?('YANDEX_API_KEY')
63
65
  conf
64
66
  end
@@ -65,6 +65,7 @@ module I18n::Tasks
65
65
  plural_nodes data[locale] do |node|
66
66
  children = node.children
67
67
  present_keys = Set.new(children.map { |c| c.key.to_sym })
68
+ next if ignore_key?(node.full_key(root: false), :missing)
68
69
  next if present_keys.superset?(required_keys)
69
70
 
70
71
  tree[node.full_key] = node.derive(
@@ -9,7 +9,9 @@ module I18n
9
9
  # @param roots [Array<String>] paths to relative roots
10
10
  # @param calling_method [#call, Symbol, String, false, nil]
11
11
  # @return [String] absolute version of the key
12
- def absolute_key(key, path, roots: config[:relative_roots], calling_method: nil)
12
+ def absolute_key(key, path, roots: config[:relative_roots],
13
+ exclude_method_name_paths: config[:exclude_method_name_paths],
14
+ calling_method: nil)
13
15
  return key unless key.start_with?(DOT)
14
16
  fail 'roots argument is required' unless roots.present?
15
17
 
@@ -18,7 +20,12 @@ module I18n
18
20
  fail(CommandError, "Cannot resolve relative key \"#{key}\".\n" \
19
21
  "Set search.relative_roots in config/i18n-tasks.yml (currently #{roots.inspect})")
20
22
  normalized_path.sub!(root, '')
21
- "#{prefix(normalized_path, calling_method: calling_method)}#{key}"
23
+
24
+ if (exclude_method_name_paths || []).map { |p| expand_path(p) }.include?(root)
25
+ "#{prefix(normalized_path)}#{key}"
26
+ else
27
+ "#{prefix(normalized_path, calling_method: calling_method)}#{key}"
28
+ end
22
29
  end
23
30
 
24
31
  private
@@ -31,12 +38,19 @@ module I18n
31
38
  # @return [String] the closest ancestor root for path, with a trailing {File::SEPARATOR}.
32
39
  def path_root(path, roots)
33
40
  roots.map do |p|
34
- File.expand_path(p) + File::SEPARATOR
41
+ expand_path(p)
35
42
  end.sort.reverse_each.detect do |root|
36
43
  path.start_with?(root)
37
44
  end
38
45
  end
39
46
 
47
+ # Expand a path and add a trailing {File::SEPARATOR}
48
+ # @param [String] path relative path
49
+ # @return [String] absolute path, with a trailing {File::SEPARATOR}.
50
+ def expand_path(path)
51
+ File.expand_path(path) + File::SEPARATOR
52
+ end
53
+
40
54
  # @param normalized_path [String] path/relative/to/a/root
41
55
  # @param calling_method [#call, Symbol, String, false, nil]
42
56
  def prefix(normalized_path, calling_method: nil)
@@ -94,7 +94,7 @@ module I18n::Tasks
94
94
  end
95
95
 
96
96
  INTERPOLATION_KEY_RE = /%\{[^}]+}/.freeze
97
- UNTRANSLATABLE_STRING = 'zxzxzx'
97
+ UNTRANSLATABLE_STRING = 'X__'
98
98
 
99
99
  # @param [String] value
100
100
  # @return [String] 'hello, %{name}' => 'hello, <round-trippable string>'
@@ -67,9 +67,15 @@ module I18n::Tasks::Translators
67
67
 
68
68
  def configure_api_key!
69
69
  api_key = @i18n_tasks.translation_config[:deepl_api_key]
70
+ host = @i18n_tasks.translation_config[:deepl_host]
71
+ version = @i18n_tasks.translation_config[:deepl_version]
70
72
  fail ::I18n::Tasks::CommandError, I18n.t('i18n_tasks.deepl_translate.errors.no_api_key') if api_key.blank?
71
73
 
72
- DeepL.configure { |config| config.auth_key = api_key }
74
+ DeepL.configure { |config|
75
+ config.auth_key = api_key
76
+ config.host = host unless host.blank?
77
+ config.version = version unless version.blank?
78
+ }
73
79
  end
74
80
  end
75
81
  end
@@ -16,6 +16,7 @@ module I18n::Tasks
16
16
  module UsedKeys # rubocop:disable Metrics/ModuleLength
17
17
  SEARCH_DEFAULTS = {
18
18
  paths: %w[app/].freeze,
19
+ relative_exclude_method_name_paths: [],
19
20
  relative_roots: %w[app/controllers app/helpers app/mailers app/presenters app/views].freeze,
20
21
  scanners: [
21
22
  ['::I18n::Tasks::Scanners::RubyAstScanner', { only: %w[*.rb] }],
@@ -24,7 +25,7 @@ module I18n::Tasks
24
25
  strict: true
25
26
  }.freeze
26
27
 
27
- ALWAYS_EXCLUDE = %w[*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less
28
+ ALWAYS_EXCLUDE = %w[*.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less
28
29
  *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus
29
30
  *.webp].freeze
30
31
 
@@ -105,7 +106,7 @@ module I18n::Tasks
105
106
 
106
107
  def merge_scanner_configs(a, b)
107
108
  a.deep_merge(b).tap do |c|
108
- %i[scanners paths relative_roots].each do |key|
109
+ %i[scanners paths relative_exclude_method_name_paths relative_roots].each do |key|
109
110
  c[key] = a[key] if b[key].blank?
110
111
  end
111
112
  %i[exclude].each do |key|
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
- VERSION = '0.9.34'
5
+ VERSION = '0.9.35'
6
6
  end
7
7
  end
@@ -64,6 +64,13 @@ search:
64
64
  # - app/presenters
65
65
  # - app/views
66
66
 
67
+ ## Directories where method names which should not be part of a relative key resolution.
68
+ # By default, if a relative translation is used inside a method, the name of the method will be considered part of the resolved key.
69
+ # Directories listed here will not consider the name of the method part of the resolved key
70
+ #
71
+ # relative_exclude_method_name_paths:
72
+ # -
73
+
67
74
  ## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
68
75
  ## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
69
76
  exclude:
@@ -90,6 +97,8 @@ search:
90
97
  # # DeepL Pro Translate
91
98
  # # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro
92
99
  # deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
100
+ # # deepl_host: "https://api.deepl.com"
101
+ # # deepl_version: "v2"
93
102
 
94
103
  ## Do not consider these keys missing:
95
104
  # ignore_missing:
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.9.34
4
+ version: 0.9.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-04 00:00:00.000000000 Z
11
+ date: 2021-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport