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 +4 -4
- data/README.md +5 -3
- data/config/locales/en.yml +1 -0
- data/lib/i18n/tasks/base_task.rb +2 -1
- data/lib/i18n/tasks/cli.rb +14 -3
- data/lib/i18n/tasks/command/commands/health.rb +1 -1
- data/lib/i18n/tasks/command/options/common.rb +6 -0
- data/lib/i18n/tasks/configuration.rb +3 -1
- data/lib/i18n/tasks/missing_keys.rb +1 -0
- data/lib/i18n/tasks/scanners/relative_keys.rb +17 -3
- data/lib/i18n/tasks/translators/base_translator.rb +1 -1
- data/lib/i18n/tasks/translators/deepl_translator.rb +7 -1
- data/lib/i18n/tasks/used_keys.rb +3 -2
- data/lib/i18n/tasks/version.rb +1 -1
- data/templates/config/i18n-tasks.yml +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ac03642fdf45424834ce7e968e70af9d602c5d5721eda666dbd38635adcf542
|
4
|
+
data.tar.gz: 793b43903d97f1dccead925e5128142886708b279f55f04bcd62c6b349bddead
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
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: <
|
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>
|
data/config/locales/en.yml
CHANGED
@@ -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
|
data/lib/i18n/tasks/base_task.rb
CHANGED
data/lib/i18n/tasks/cli.rb
CHANGED
@@ -34,7 +34,18 @@ class I18n::Tasks::CLI
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def run(argv)
|
37
|
-
|
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)
|
@@ -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],
|
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
|
-
|
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
|
-
|
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)
|
@@ -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|
|
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
|
data/lib/i18n/tasks/used_keys.rb
CHANGED
@@ -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|
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2021-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|