i18n-tasks 0.5.0 → 0.5.1

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
  SHA1:
3
- metadata.gz: f4ae19f0f97a5f8ae9221b45ef316b08a5efbe62
4
- data.tar.gz: 2b957a1c692318da437ca4235aeb2a1b9e47f2b6
3
+ metadata.gz: f8f89d95e642baf84d0f2db83a184cdbfaca5fdb
4
+ data.tar.gz: a2051af98f8ea1c9eac7ee7b201ac1680e30b82c
5
5
  SHA512:
6
- metadata.gz: d00e68fb5727c9d95df84b5de56bd57d53a6adc6e9e00e1ce05c16e6f99055b30b0bc9c478dfabba238962a5d75cc75dc75b97ae4724bde1b07e4f07150b396d
7
- data.tar.gz: 5bc8932e731220f37abce28f4b637c60ab41ed02b8e3c8ab5f0c273385ae269fae4a996e408a006d9ba59bd95bab1e1599d2cc48670ff828421fe96d4d1380d4
6
+ metadata.gz: 6856046b53147ee028f7491f975694769ec069bd3740f288fd44b069764562ca818a253b333520f3bc670091d0fa4dfba4bed25b9e36c48bbbdfa726c10431a7
7
+ data.tar.gz: 258eae7c4f1909161f8fb494e3bc3d40afa7998058f4e0fbd836838340eec38680d0bc61b88a8234adc4166875a6f5003c864038db75204ca5f79f13b844c707
data/CHANGES.md CHANGED
@@ -1,8 +1,14 @@
1
+ ## 0.5.1
2
+
3
+ * Fix [conservative router](https://github.com/glebm/i18n-tasks#conservative-router).
4
+ * Default router is now the default.
5
+
1
6
  ## 0.5.0
2
7
 
3
8
  * internals refactored to use trees everywhere
4
9
  * type `guide` in `i18n-tasks irb` to learn more about the commands
5
10
  * (remove-)unused tasks now work per locale
11
+ * `ignore` settings are shown on `i18n-tasks config`
6
12
  * Rubinius 2.2.7 compatibility
7
13
 
8
14
  ## 0.4.5
data/README.md CHANGED
@@ -18,7 +18,7 @@ i18n-tasks can be used with any project using [i18n][i18n-gem] (default in Rails
18
18
  Add to Gemfile:
19
19
 
20
20
  ```ruby
21
- gem 'i18n-tasks', '~> 0.5.0'
21
+ gem 'i18n-tasks', '~> 0.5.1'
22
22
  ```
23
23
 
24
24
 
@@ -173,6 +173,14 @@ data:
173
173
  - 'config/locales/%{locale}.yml'
174
174
  ```
175
175
 
176
+ #### Key pattern syntax
177
+
178
+ | syntax | description |
179
+ |:------------:|:----------------------------------------------------------|
180
+ | `*` | matches everything |
181
+ | `:` | matches a single key |
182
+ | `{a, b.c}` | match any in set, can use `:` and `*`, match is captured |
183
+
176
184
  For writing to locale files i18n-tasks provides 2 options.
177
185
 
178
186
  ##### Pattern router
@@ -181,7 +189,6 @@ Pattern router organizes keys based on a list of key patterns, as in the example
181
189
 
182
190
  ```
183
191
  data:
184
- # pattern_router is default
185
192
  router: pattern_router
186
193
  # a list of {key pattern => file} routes, matched top to bottom
187
194
  write:
@@ -197,6 +204,7 @@ data:
197
204
 
198
205
  Conservative router keeps the keys where they are found, or infers the path from base locale.
199
206
  If the key is completely new, conservative router will fall back to the pattern router behaviour.
207
+ Conservative router is the default router.
200
208
 
201
209
  ```
202
210
  data:
@@ -205,14 +213,6 @@ data:
205
213
  - 'config/locales/%{locale}.yml'
206
214
  ```
207
215
 
208
- #### Key pattern syntax
209
-
210
- | syntax | description |
211
- |:------------:|:----------------------------------------------------------|
212
- | `*` | matches everything |
213
- | `:` | matches a single key |
214
- | `{a, b.c}` | match any in set, can use `:` and `*`, match is captured |
215
-
216
216
  #### Custom adapters
217
217
 
218
218
  If you store data somewhere but in the filesystem, e.g. in the database or mongodb, you can implement a custom adapter.
@@ -9,6 +9,7 @@ require 'i18n/tasks/missing_keys'
9
9
  require 'i18n/tasks/unused_keys'
10
10
  require 'i18n/tasks/google_translation'
11
11
  require 'i18n/tasks/fill_tasks'
12
+ require 'i18n/tasks/locale_pathname'
12
13
  require 'i18n/tasks/data'
13
14
  require 'i18n/tasks/configuration'
14
15
 
@@ -74,10 +74,11 @@ module I18n::Tasks
74
74
  desc 'normalize translation data: sort and move to the right files'
75
75
  opts do
76
76
  on '-l', :locales=, 'Locales to normalize (default: all)', on_locale_opt
77
+ on '-p', :pattern_router, 'Use pattern router, regardless of config.', argument: false, optional: true
77
78
  end
78
79
  cmd :normalize do |opt = {}|
79
80
  parse_locales! opt
80
- i18n_task.normalize_store! opt[:locales]
81
+ i18n_task.normalize_store! opt[:locales], opt[:pattern_router]
81
82
  end
82
83
 
83
84
  desc 'remove unused keys'
@@ -31,11 +31,11 @@ module I18n::Tasks
31
31
  def guide
32
32
  green(bold "i18n-tasks IRB Quick Start guide") + "\n" + <<-TEXT
33
33
  #{yellow 'Data as trees'}
34
- data[base_locale]
34
+ tree(locale)
35
35
  missing_tree(locale, compared_to = base_locale)
36
36
  used_tree(source_locations: false, key_filter: nil)
37
37
  unused_tree(locale)
38
- Tree::Siblings['es' => {'hello' => 'Hola'}]
38
+ build_tree('es' => {'hello' => 'Hola'})
39
39
 
40
40
  #{yellow 'Traversal'}
41
41
  tree = missing_tree(base_locale)
@@ -55,7 +55,7 @@ module I18n::Tasks
55
55
  # Pass {root: true} to include root node in full_key (usually locale)
56
56
 
57
57
  #{yellow 'Nodes'}
58
- node = missing_tree(base_locale).leaves.first
58
+ node = node(key, locale)
59
59
  node.key # only the part after the last dot
60
60
  node.full_key # full key. Includes root key, pass {root: false} to override.
61
61
  # also: value, value_or_children_hash, data, walk_to_root, walk_from_root
@@ -82,6 +82,25 @@ module I18n::Tasks
82
82
  reload
83
83
  end
84
84
 
85
+ def with_router(router)
86
+ router_was = self.router
87
+ self.router = router
88
+ yield
89
+ ensure
90
+ self.router = router_was
91
+ end
92
+
93
+ def router
94
+ @router ||= begin
95
+ name = @config[:router].presence || 'conservative_router'
96
+ if name[0] != name[0].upcase
97
+ name = "I18n::Tasks::Data::Router::#{name.classify}"
98
+ end
99
+ name.constantize.new(self, @config)
100
+ end
101
+ end
102
+ attr_writer :router
103
+
85
104
  protected
86
105
 
87
106
  def read_locale(locale)
@@ -99,16 +118,6 @@ module I18n::Tasks
99
118
  def base_locale
100
119
  config[:base_locale]
101
120
  end
102
-
103
- def router
104
- @router ||= begin
105
- name = @config[:router].presence || 'pattern_router'
106
- if name[0] != name[0].upcase
107
- name = "I18n::Tasks::Data::Router::#{name.classify}"
108
- end
109
- name.constantize.new(self, @config)
110
- end
111
- end
112
121
  end
113
122
  end
114
123
  end
@@ -13,30 +13,34 @@ module I18n::Tasks
13
13
 
14
14
  def route(locale, forest, &block)
15
15
  return to_enum(:route, locale, forest) unless block
16
- out = {}
16
+ out = Hash.new { |hash, key| hash[key] = Set.new }
17
17
  not_found = Set.new
18
18
  forest.keys do |key, node|
19
19
  locale_key = "#{locale}.#{key}"
20
20
  path = adapter[locale][locale_key].try(:data).try(:[], :path)
21
-
22
21
  # infer from base
23
22
  unless path
24
23
  path = base_tree["#{base_locale}.#{key}"].try(:data).try(:[], :path)
25
- path = path.try :sub, /(^|[\/.])#{base_locale}(?=\.)/, "\\1#{locale}"
24
+ path = LocalePathname.replace_locale(path, base_locale, locale)
26
25
  end
27
-
28
26
  if path
29
- (out[path] ||= Set.new) << locale_key
27
+ out[path] << locale_key
30
28
  else
31
29
  not_found << locale_key
32
30
  end
33
31
  end
32
+
33
+ if not_found.present?
34
+ # fall back to pattern router
35
+ not_found_tree = forest.select_keys(root: true) { |key, _| not_found.include?(key) }
36
+ super(locale, not_found_tree) { |path, tree|
37
+ out[path] += tree.key_names(root: true)
38
+ }
39
+ end
40
+
34
41
  out.each do |dest, keys|
35
42
  block.yield dest, forest.select_keys(root: true) { |key, _| keys.include?(key) }
36
43
  end
37
- if not_found.present?
38
- super(locale, forest.select_keys(root: true) { |key, _| not_found.include?(key) }, &block)
39
- end
40
44
  end
41
45
 
42
46
  protected
@@ -30,7 +30,7 @@ module I18n::Tasks
30
30
  end
31
31
 
32
32
  def build_tree(hash)
33
- I18n::Tasks::Data::Tree::Siblings.from_nested_hash(hash)
33
+ I18n::Tasks::Data::Tree::Siblings.from_nested_hash(hash.deep_stringify_keys)
34
34
  end
35
35
 
36
36
  def t_proc(locale = base_locale)
@@ -44,11 +44,14 @@ module I18n::Tasks
44
44
  end
45
45
 
46
46
  # write to store, normalizing all data
47
- def normalize_store!(from = nil)
47
+ def normalize_store!(from = nil, pattern_router = false)
48
48
  from = self.locales unless from
49
- Array(from).each do |target_locale|
50
- # the store itself handles normalization
51
- data[target_locale] = data[target_locale]
49
+ router = pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
50
+ data.with_router(router) do
51
+ Array(from).each do |target_locale|
52
+ # store handles normalization
53
+ data[target_locale] = data[target_locale]
54
+ end
52
55
  end
53
56
  end
54
57
  end
@@ -3,10 +3,13 @@ module I18n::Tasks
3
3
  module FillTasks
4
4
  def fill_missing_value(opts = {})
5
5
  value = opts[:value] || ''
6
+ base = opts[:base_locale] || base_locale
6
7
  locales_for_update(opts).each do |locale|
7
- data[locale] = data[locale].merge! missing_tree(locale).keys { |key, node|
8
+ m = missing_tree(locale, base).keys { |key, node|
8
9
  node.value = value.respond_to?(:call) ? value.call(key, locale, node) : value
10
+ node.data[:path] = LocalePathname.replace_locale(node.data[:path], base, locale) if node.data.key?(:path)
9
11
  }
12
+ data[locale] = data[locale].merge! m
10
13
  end
11
14
  end
12
15
 
@@ -0,0 +1,9 @@
1
+ module I18n::Tasks
2
+ module LocalePathname
3
+ extend self
4
+
5
+ def replace_locale(path, from, to)
6
+ path.try :sub, /(^|[\/.])#{from}(?=\.)/, "\\1#{to}"
7
+ end
8
+ end
9
+ end
@@ -51,7 +51,7 @@ module I18n
51
51
  line.strip!
52
52
  line.sub!(/(.*?)(#{key})(.*)$/) { dark($1) + underline($2) + dark($3) }
53
53
  }
54
- puts " #{green "#{u[:path]}:#{u[:line_num]}"} #{line}"
54
+ puts " #{green "#{u[:src_path]}:#{u[:line_num]}"} #{line}"
55
55
  end
56
56
  end
57
57
  else
@@ -102,7 +102,7 @@ module I18n::Tasks::Scanners
102
102
  end
103
103
 
104
104
  def src_location(path, text, src_pos)
105
- src = {path: path}
105
+ src = {src_path: path}
106
106
  if @record_src_loc
107
107
  src.merge!(src_text_location(text, src_pos))
108
108
  end
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
  module I18n
3
3
  module Tasks
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.1'
5
5
  end
6
6
  end
@@ -5,6 +5,7 @@ locales: [es]
5
5
  data:
6
6
  # The default file adapter supports YAML and JSON files. You can provide a class name here.
7
7
  adapter: file_system
8
+ #router: pattern_router
8
9
  # adapter options
9
10
  read:
10
11
  - 'config/locales/%{locale}.yml'
@@ -62,7 +62,7 @@ describe 'i18n-tasks' do
62
62
  it 'moves keys to the corresponding files as per data.write' do
63
63
  in_test_app_dir {
64
64
  expect(File).to_not exist 'config/locales/devise.en.yml'
65
- run_cmd :normalize
65
+ run_cmd :normalize, pattern_router: true
66
66
  expect(YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a']).to eq 'EN_TEXT'
67
67
  }
68
68
  end
@@ -105,10 +105,10 @@ describe 'i18n-tasks' do
105
105
  in_test_app_dir {
106
106
  expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']).to be_nil
107
107
  }
108
+ run_cmd :normalize, pattern_router: true
108
109
  run_cmd :add_missing, locales: 'all', placeholder: 'TRME'
109
110
  in_test_app_dir {
110
111
  expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a']).to eq 'TRME'
111
- # does not touch existing, but moves to the right file:
112
112
  expect(YAML.load_file('config/locales/devise.es.yml')['es']['devise']['a']).to eq 'ES_TEXT'
113
113
  }
114
114
  end
@@ -23,15 +23,15 @@ h1 = t 'b'
23
23
  leaves[0],
24
24
  'a',
25
25
  source_locations:
26
- [{pos: 6, line_num: 1, line_pos: 7, line: "div = t 'a'", path: 'a.html.slim'},
27
- {pos: 18, line_num: 2, line_pos: 7, line: " p = t 'a'", path: 'a.html.slim'}]
26
+ [{pos: 6, line_num: 1, line_pos: 7, line: "div = t 'a'", src_path: 'a.html.slim'},
27
+ {pos: 18, line_num: 2, line_pos: 7, line: " p = t 'a'", src_path: 'a.html.slim'}]
28
28
  )
29
29
 
30
30
  expect_node_key_data(
31
31
  leaves[1],
32
32
  'b',
33
33
  source_locations:
34
- [{pos: 29, line_num: 3, line_pos: 6, line: "h1 = t 'b'", path: 'a.html.slim'}]
34
+ [{pos: 29, line_num: 3, line_pos: 6, line: "h1 = t 'b'", src_path: 'a.html.slim'}]
35
35
  )
36
36
  end
37
37
 
@@ -42,7 +42,7 @@ h1 = t 'b'
42
42
  used_keys.leaves.first,
43
43
  'b',
44
44
  source_locations:
45
- [{pos: 29, line_num: 3, line_pos: 6, line: "h1 = t 'b'", path: 'a.html.slim'}]
45
+ [{pos: 29, line_num: 3, line_pos: 6, line: "h1 = t 'b'", src_path: 'a.html.slim'}]
46
46
  )
47
47
  end
48
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
@@ -227,6 +227,7 @@ files:
227
227
  - lib/i18n/tasks/google_translation.rb
228
228
  - lib/i18n/tasks/ignore_keys.rb
229
229
  - lib/i18n/tasks/key_pattern_matching.rb
230
+ - lib/i18n/tasks/locale_pathname.rb
230
231
  - lib/i18n/tasks/logging.rb
231
232
  - lib/i18n/tasks/missing_keys.rb
232
233
  - lib/i18n/tasks/plural_keys.rb