i18n-tasks 0.9.18 → 0.9.19
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 +1 -1
- data/lib/i18n/tasks/configuration.rb +2 -3
- data/lib/i18n/tasks/data.rb +5 -1
- data/lib/i18n/tasks/data/file_system_base.rb +31 -14
- data/lib/i18n/tasks/data/router/pattern_router.rb +3 -1
- data/lib/i18n/tasks/data/tree/traversal.rb +1 -1
- data/lib/i18n/tasks/missing_keys.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +4 -12
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +2 -2
- data/lib/i18n/tasks/version.rb +1 -1
- data/templates/config/i18n-tasks.yml +6 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a645618f76025d6f6c0e9c1e82d19cf049aa5f7a
|
4
|
+
data.tar.gz: b5d360c72ce14d141757a177c3f4a906ad84588d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ec7dd16adc0fe0aba80ea32f4ba7f60d665646be16f0c58fd7f5b34a6b8e5412a55678068f1e1daf5be5c660e4a2baf9216e80be6a8bef6e8dcc000fd425d6c
|
7
|
+
data.tar.gz: b4f7c9a678a51534a5fdc15c3efc09e8e3ccec18de6b08246b4ae456a412c4190db148a621e6b933b6228db6193146aa9b3bbfd809500e0219c0d81280c26ed2
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
|
|
24
24
|
Add i18n-tasks to the Gemfile:
|
25
25
|
|
26
26
|
```ruby
|
27
|
-
gem 'i18n-tasks', '~> 0.9.
|
27
|
+
gem 'i18n-tasks', '~> 0.9.19'
|
28
28
|
```
|
29
29
|
|
30
30
|
Copy the default [configuration file](#configuration):
|
@@ -37,9 +37,8 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def config=(conf)
|
40
|
-
@config
|
40
|
+
@config = file_config.deep_merge(conf)
|
41
41
|
@config_sections = {}
|
42
|
-
@config
|
43
42
|
end
|
44
43
|
|
45
44
|
# data config
|
@@ -110,7 +109,7 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
|
|
110
109
|
|
111
110
|
def config_for_inspect
|
112
111
|
to_hash_from_indifferent(config_sections.reject { |_k, v| v.blank? }).tap do |sections|
|
113
|
-
sections.
|
112
|
+
sections.each_value do |section|
|
114
113
|
section.merge! section.delete('config') if section.is_a?(Hash) && section.key?('config')
|
115
114
|
end
|
116
115
|
end
|
data/lib/i18n/tasks/data.rb
CHANGED
@@ -59,12 +59,16 @@ module I18n::Tasks
|
|
59
59
|
!t(key, locale).nil?
|
60
60
|
end
|
61
61
|
|
62
|
+
def external_key?(key, locale = base_locale)
|
63
|
+
data.external(locale)[locale.to_s][key]
|
64
|
+
end
|
65
|
+
|
62
66
|
# Normalize all the locale data in the store (by writing to the store).
|
63
67
|
#
|
64
68
|
# @param [Array<String>] locales locales to normalize. Default: all.
|
65
69
|
# @param [Boolean] force_pattern_router Whether to use pattern router regardless of the config.
|
66
70
|
def normalize_store!(locales: nil, force_pattern_router: false)
|
67
|
-
locales
|
71
|
+
locales ||= self.locales
|
68
72
|
router = force_pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
|
69
73
|
data.with_router(router) do
|
70
74
|
Array(locales).each do |target_locale|
|
@@ -32,27 +32,45 @@ module I18n::Tasks
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
#
|
35
|
+
# @param [String, Symbol] locale
|
36
|
+
# @return [::I18n::Tasks::Data::Siblings]
|
36
37
|
def get(locale)
|
37
38
|
locale = locale.to_s
|
38
|
-
@trees
|
39
|
-
@trees[locale] ||=
|
40
|
-
read_locale(locale)
|
41
|
-
)
|
39
|
+
@trees ||= {}
|
40
|
+
@trees[locale] ||= read_locale(locale)
|
42
41
|
end
|
43
42
|
|
44
43
|
alias [] get
|
45
44
|
|
45
|
+
# @param [String, Symbol] locale
|
46
|
+
# @return [::I18n::Tasks::Data::Siblings]
|
47
|
+
def external(locale)
|
48
|
+
locale = locale.to_s
|
49
|
+
@external ||= {}
|
50
|
+
@external[locale] ||= read_locale(locale, paths: config[:external])
|
51
|
+
end
|
52
|
+
|
46
53
|
# set locale tree
|
54
|
+
# @param [String, Symbol] locale
|
55
|
+
# @param [::I18n::Tasks::Data::Siblings] tree
|
47
56
|
def set(locale, tree)
|
48
57
|
locale = locale.to_s
|
58
|
+
@trees.delete(locale) if @trees
|
59
|
+
paths_before = Set.new(get(locale)[locale].leaves.map { |node| node.data[:path] })
|
60
|
+
paths_after = Set.new([])
|
49
61
|
router.route locale, tree do |path, tree_slice|
|
62
|
+
paths_after << path
|
50
63
|
write_tree path, tree_slice
|
51
64
|
end
|
65
|
+
(paths_before - paths_after).each do |path|
|
66
|
+
FileUtils.remove_file(path) if File.exist?(path)
|
67
|
+
end
|
52
68
|
@trees.delete(locale) if @trees
|
53
69
|
@available_locales = nil
|
54
70
|
end
|
55
71
|
|
72
|
+
alias []= set
|
73
|
+
|
56
74
|
# @param [String] locale
|
57
75
|
# @return [Array<String>] paths to files that are not normalized
|
58
76
|
def non_normalized_paths(locale)
|
@@ -62,7 +80,7 @@ module I18n::Tasks
|
|
62
80
|
end
|
63
81
|
|
64
82
|
def write(forest)
|
65
|
-
forest.each { |root| set(root.key, root) }
|
83
|
+
forest.each { |root| set(root.key, root.to_siblings) }
|
66
84
|
end
|
67
85
|
|
68
86
|
def merge!(forest)
|
@@ -76,15 +94,14 @@ module I18n::Tasks
|
|
76
94
|
|
77
95
|
def remove_by_key!(forest)
|
78
96
|
forest.inject(Tree::Siblings.new) do |removed, root|
|
79
|
-
|
97
|
+
locale = root.key
|
98
|
+
locale_data = get(locale)
|
80
99
|
subtracted = locale_data.subtract_by_key(forest)
|
81
|
-
set
|
100
|
+
set locale, subtracted
|
82
101
|
removed.merge! locale_data.subtract_by_key(subtracted)
|
83
102
|
end
|
84
103
|
end
|
85
104
|
|
86
|
-
alias []= set
|
87
|
-
|
88
105
|
# @return self
|
89
106
|
def reload
|
90
107
|
@trees = nil
|
@@ -145,17 +162,17 @@ module I18n::Tasks
|
|
145
162
|
|
146
163
|
protected
|
147
164
|
|
148
|
-
def read_locale(locale)
|
149
|
-
Array(
|
165
|
+
def read_locale(locale, paths: config[:read])
|
166
|
+
Array(paths).flat_map do |path|
|
150
167
|
Dir.glob format(path, locale: locale)
|
151
|
-
end.
|
168
|
+
end.map do |path|
|
152
169
|
[path.freeze, load_file(path) || {}]
|
153
170
|
end.map do |path, data|
|
154
171
|
filter_nil_keys! path, data
|
155
172
|
Data::Tree::Siblings.from_nested_hash(data).tap do |s|
|
156
173
|
s.leaves { |x| x.data.update(path: path, locale: locale) }
|
157
174
|
end
|
158
|
-
end.reduce(:merge!)
|
175
|
+
end.reduce(Tree::Siblings[locale => {}], :merge!)
|
159
176
|
end
|
160
177
|
|
161
178
|
def filter_nil_keys!(path, data, suffix = [])
|
@@ -23,7 +23,9 @@ module I18n::Tasks
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# Route keys to destinations
|
26
|
-
# @param forest [I18n::Tasks::
|
26
|
+
# @param forest [I18n::Tasks::Data::Tree::Siblings] forest roots are locales.
|
27
|
+
# @yieldparam [String] dest_path
|
28
|
+
# @yieldparam [I18n::Tasks::Data::Tree::Siblings] tree_slice
|
27
29
|
# @return [Hash] mapping of destination => [ [key, value], ... ]
|
28
30
|
def route(locale, forest, &block)
|
29
31
|
return to_enum(:route, locale, forest) unless block
|
@@ -181,7 +181,7 @@ module I18n::Tasks
|
|
181
181
|
if key_pattern.present?
|
182
182
|
pattern_re = I18n::Tasks::KeyPatternMatching.compile_key_pattern(key_pattern)
|
183
183
|
end
|
184
|
-
keys.each do |key, node|
|
184
|
+
keys.each do |key, node| # rubocop:disable Performance/HashEachMethods
|
185
185
|
next if pattern_re && key !~ pattern_re
|
186
186
|
node.value = value_proc.call(node)
|
187
187
|
end
|
@@ -85,7 +85,7 @@ module I18n::Tasks
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def locale_key_missing?(locale, key)
|
88
|
-
!key_value?(key, locale) && !ignore_key?(key, :missing)
|
88
|
+
!key_value?(key, locale) && !external_key?(key) && !ignore_key?(key, :missing)
|
89
89
|
end
|
90
90
|
|
91
91
|
# @param [::I18n::Tasks::Data::Tree::Siblings] forest
|
@@ -65,7 +65,7 @@ module I18n::Tasks::Scanners
|
|
65
65
|
re && re =~ line
|
66
66
|
end
|
67
67
|
|
68
|
-
VALID_KEY_RE_DYNAMIC = /^(#{VALID_KEY_CHARS}|[:\#{@}\[\]])+$/
|
68
|
+
VALID_KEY_RE_DYNAMIC = /^(#{VALID_KEY_CHARS}|[:\#{@}\[\]])+$/ # rubocop:disable Lint/InterpolationCheck
|
69
69
|
|
70
70
|
def valid_key?(key)
|
71
71
|
if @config[:strict]
|
@@ -34,12 +34,12 @@ module I18n::Tasks::Scanners
|
|
34
34
|
|
35
35
|
# parse expressions with literals and variable
|
36
36
|
def first_argument_re
|
37
|
-
/(?: (?: #{literal_re} ) | #{
|
37
|
+
/(?: (?: #{literal_re} ) | #{expr_re} )/x
|
38
38
|
end
|
39
39
|
|
40
40
|
# strip literals, convert expressions to #{interpolations}
|
41
41
|
def strip_literal(val)
|
42
|
-
if val =~ /\A\w/
|
42
|
+
if val =~ /\A[\w@]/
|
43
43
|
"\#{#{val}}"
|
44
44
|
else
|
45
45
|
super(val)
|
@@ -54,17 +54,9 @@ module I18n::Tasks::Scanners
|
|
54
54
|
) (\[[^\n)%#]*\]|[^\n)%#,]*)/x
|
55
55
|
end
|
56
56
|
|
57
|
-
# match code
|
58
|
-
# matches characters until , as a heuristic to parse scopes like [:categories, cat.key]
|
59
|
-
# can be massively improved by matching parenthesis
|
57
|
+
# match a limited subset of code expressions (no parenthesis, commas, etc)
|
60
58
|
def expr_re
|
61
|
-
/[\w
|
62
|
-
end
|
63
|
-
|
64
|
-
# match variable key
|
65
|
-
# e.g: t(key, scope: 'scope') => t('scope.#{key}')
|
66
|
-
def variable_re
|
67
|
-
/\w+/
|
59
|
+
/[\w@.&|\s?!]+/
|
68
60
|
end
|
69
61
|
|
70
62
|
# extract literal or array of literals
|
@@ -115,7 +115,7 @@ module I18n::Tasks::Scanners
|
|
115
115
|
def extract_string(node, array_join_with: nil, array_flatten: false, array_reject_blank: false)
|
116
116
|
if %i[sym str int].include?(node.type)
|
117
117
|
node.children[0].to_s
|
118
|
-
elsif %i[true false].include?(node.type)
|
118
|
+
elsif %i[true false].include?(node.type) # rubocop:disable Lint/BooleanSymbol
|
119
119
|
node.type.to_s
|
120
120
|
elsif node.type == :nil
|
121
121
|
''
|
@@ -149,7 +149,7 @@ module I18n::Tasks::Scanners
|
|
149
149
|
# @return [String, nil] `nil` is returned only when a dynamic value is encountered in strict mode.
|
150
150
|
def extract_array_as_string(node, array_join_with:, array_flatten: false, array_reject_blank: false)
|
151
151
|
children_strings = node.children.map do |child|
|
152
|
-
if %i[sym str int true false].include?(child.type)
|
152
|
+
if %i[sym str int true false].include?(child.type) # rubocop:disable Lint/BooleanSymbol
|
153
153
|
extract_string child
|
154
154
|
else
|
155
155
|
# ignore dynamic argument in strict mode
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -19,8 +19,6 @@ data:
|
|
19
19
|
# - config/locales/%{locale}.yml
|
20
20
|
## More files:
|
21
21
|
# - config/locales/**/*.%{locale}.yml
|
22
|
-
## Another gem (replace %#= with %=):
|
23
|
-
# - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
|
24
22
|
|
25
23
|
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
|
26
24
|
# `i18n-tasks normalize -p` will force move the keys according to these rules
|
@@ -30,6 +28,12 @@ data:
|
|
30
28
|
## Catch-all default:
|
31
29
|
# - config/locales/%{locale}.yml
|
32
30
|
|
31
|
+
# External locale data (e.g. gems).
|
32
|
+
# This data is not considered unused and is never written to.
|
33
|
+
external:
|
34
|
+
## Example (replace %#= with %=):
|
35
|
+
# - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
|
36
|
+
|
33
37
|
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
|
34
38
|
# router: conservative_router
|
35
39
|
|
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.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|