i18n-tasks 0.3.10 → 0.3.11

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: 601f3e2a8ac21ec9d8f83aa71f5723623b109f69
4
- data.tar.gz: 5a9396e63a232357fd63d1d260a80ddfd274dea4
3
+ metadata.gz: 84ba1f92ba2da94773501e168515c76c3c6c21ab
4
+ data.tar.gz: 5d72ea2de6df682ab6f57b8f76d051f6d8b0f3e8
5
5
  SHA512:
6
- metadata.gz: 80187dee2d375fbe01e79313c6d7bd24927c91da51c52b102661f7b13378547c16743b571c0ebdb7fd3d29d35777db48900ce66f5d23108069d6f06f0510ac7b
7
- data.tar.gz: fe57c3b82c6d24c3d43c3203a184b21d99a04ec639d142aee38b1f336587d74308937ea9a7a33ac8a8a9b1d16296e83bf58e46749bbbbfb453a715cf0087924e
6
+ metadata.gz: 46efbb3c38b02738ee34069bc4d9384603485f5f0aeba4227139596ce7bd383cb5c9b9b2f98ddadacd9c1c28bec47170e137f02856d2b4de56a7d724ab853a76
7
+ data.tar.gz: a8b7a4968b32960205152674040c913e4032d999ee90f2b48e789593c1f81cfef3264c5f747d34608246548dd9fbbaafb94e7b01f8b825849515f7cf802956b7
data/CHANGES.md CHANGED
@@ -1,12 +1,16 @@
1
- ## 0.3.9
1
+ ## 0.3.11
2
2
 
3
- * Fix regression: Remove ActiveSupport::HashWithIndifferentAccess from locale data output
3
+ * Improve plural key handling
4
4
 
5
5
  ## 0.3.10
6
6
 
7
7
  * New (de)serialization options in config
8
8
  * `add-missing` placeholder argument can now use %{base_value}.
9
9
 
10
+ ## 0.3.9
11
+
12
+ * Fix regression: Remove ActiveSupport::HashWithIndifferentAccess from locale data output
13
+
10
14
  ## 0.3.8
11
15
 
12
16
  * Fix activesupport ~3.x compatibility issue (#45).
data/README.md CHANGED
@@ -49,6 +49,8 @@ Available commands:
49
49
  See `<command> --help` for more information on a specific command.
50
50
  ```
51
51
 
52
+ #### Add missing keys
53
+
52
54
  You can add missing values, generated from the key (for base locale) or copied from the base locale (for other locales).
53
55
  To add missing values to the base locale only:
54
56
 
@@ -59,6 +61,8 @@ i18n-tasks add-missing base
59
61
  i18n-tasks add-missing -p 'PLEASE-TRANSLATE %{base_value}' fr
60
62
  ```
61
63
 
64
+ #### Google Translate missing keys
65
+
62
66
  Translate missing values with Google Translate ([more below on the API key](#translation-config)).
63
67
 
64
68
  ```bash
@@ -67,37 +71,38 @@ i18n-tasks translate-missing
67
71
  i18n-tasks translate-missing --from base es fr
68
72
  ```
69
73
 
70
- Sort the keys and write them to their respective files with `normalize`.
71
- This always happens on `add-missing` and `translate-missing`.
74
+ Sort the keys and write them to their respective files with `i18n-tasks normalize`.
75
+ This always happens on `i18n-tasks add-missing` and `i18n-tasks translate-missing`.
72
76
 
73
77
  ```bash
74
78
  i18n-tasks normalize
75
79
  ```
76
80
 
77
- See exactly where the keys are used with `find`:
81
+ #### Find usages
82
+
83
+ See where the keys are used with `i18n-tasks find`:
78
84
 
79
85
  ```bash
80
- # Show all usages of all keys
81
- i18n-tasks find
82
- # Filter by a key pattern
86
+ i18n-tasks find common.help
83
87
  i18n-tasks find 'auth.*'
84
88
  i18n-tasks find '{number,currency}.format.*'
85
89
  ```
86
90
 
87
91
  ![i18n-screenshot][screenshot-find]
88
92
 
89
- Relative keys (`t '.title'`) and plural keys (key.one/many/other/etc) are fully supported.
93
+ #### Features
90
94
 
91
- Scope argument is supported, but only when it is the first keyword argument ([this](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb) can be improved):
95
+ Relative keys (`t '.title'`) and plural keys (`key.{one,many,other,...}`) are fully supported.
96
+ Scope argument is supported, but only when it is the first keyword argument ([improvements welcome](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb)):
92
97
 
93
- ```ruby
94
- # this is supported
95
- t :invalid, scope: [:auth, :password], attempts: 5
96
- # but not this
97
- t :invalid, attempts: 5, scope: [:auth, :password]
98
- ```
98
+ ```ruby
99
+ # this is supported
100
+ t :invalid, scope: [:auth, :password], attempts: 5
101
+ # but not this
102
+ t :invalid, attempts: 5, scope: [:auth, :password]
103
+ ```
99
104
 
100
- Unused report will detect pattern translations and not report them, e.g.:
105
+ Unused report will detect certain dynamic key forms and not report them, e.g.:
101
106
 
102
107
  ```ruby
103
108
  t 'category.' + category.key # all 'category.*' keys are considered used
@@ -128,27 +133,38 @@ The default data adapter supports YAML and JSON files.
128
133
 
129
134
  ```yaml
130
135
  # config/i18n-tasks.yml
131
- # i18n data storage
132
136
  data:
133
- # file_system is the default adapter, you can provide a custom class name here:
134
- adapter: file_system
137
+ # configure YAML / JSON serializer options
138
+ # passed directly to load / dump / parse / serialize.
139
+ yaml:
140
+ write:
141
+ # do not wrap lines at 80 characters (override default)
142
+ line_width: -1
143
+ ```
144
+
145
+ #### Multiple locale files
146
+
147
+ Use `data.read` and `data.write` options to work with locale data spread over multiple files.
148
+
149
+ ```
150
+ # config/i18n-tasks.yml
151
+ data:
135
152
  # a list of file globs to read from per-locale
136
- read:
137
- # default:
138
- - 'config/locales/%{locale}.yml'
139
- # to also read from namespaced files, e.g. simple_form.en.yml:
153
+ read:
154
+ # read from namespaced files, e.g. simple_form.en.yml
140
155
  - 'config/locales/*.%{locale}.yml'
156
+ # read from a gem (config is parsed with ERB first, then YAML)
157
+ - "<%= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
158
+ # default
159
+ - 'config/locales/%{locale}.yml'
141
160
  # a list of {key pattern => file} routes, matched top to bottom
142
161
  write:
143
- # save all devise keys in it's own file (per locale):
144
- - ['devise.*', 'config/locales/devise.%{locale}.yml']
145
- # default catch-all:
146
- - 'config/locales/%{locale}.yml' # path is short for ['*', path]
147
- # configure YAML / JSON serializer options (when using the default adapter)
148
- yaml:
149
- write:
150
- # do not wrap lines at 80 characters (default)
151
- line_width: -1
162
+ # write models.* and views.* keys to the respective files
163
+ - ['{models,views}.*', 'config/locales/\1.%{locale}.yml']
164
+ # or, write every top-level key namespace to its own file
165
+ - ['{:}.*', 'config/locales/\1.%{locale}.yml']
166
+ # default, sugar for ['*', path]
167
+ - 'config/locales/%{locale}.yml'
152
168
  ```
153
169
 
154
170
  #### Key pattern syntax
@@ -159,16 +175,16 @@ data:
159
175
  | `:` | matches a single key |
160
176
  | `{a, b.c}` | match any in set, can use `:` and `*`, match is captured |
161
177
 
162
- Example:
178
+ #### Custom adapters
179
+
180
+ If you store data somewhere but in the filesystem, e.g. in the database or mongodb, you can implement a custom adapter.
181
+ Implement [a handful of methods][adapter-example], then set `data.adapter` to the class name; the rest of the `data` config is passed to the initializer.
163
182
 
164
183
  ```yaml
165
184
  # config/i18n-tasks.yml
166
185
  data:
167
- write:
168
- # store sorcery and simple_form keys in the respective files:
169
- - ['{sorcery,simple_form}.*', 'config/locales/\1.%{locale}.yml']
170
- # write every key namespace to its own file:
171
- - ['{:}.*', 'config/locales/\1.%{locale}.yml']
186
+ # file_system is the default adapter, you can provide a custom class name here:
187
+ adapter: file_system
172
188
  ```
173
189
 
174
190
  ### Usage search
@@ -308,3 +324,4 @@ This was originally developed for [Zuigo](http://zuigo.com/), a platform to orga
308
324
  [badge-code-climate]: http://img.shields.io/codeclimate/github/glebm/i18n-tasks.svg
309
325
  [i18n-gem]: https://github.com/svenfuchs/i18n "svenfuchs/i18n on Github"
310
326
  [screenshot-find]: https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-usages.png "i18n-tasks find output screenshot"
327
+ [adapter-example]: https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/data/file_system_base.rb
@@ -69,7 +69,7 @@ module I18n::Tasks
69
69
  end
70
70
 
71
71
  def list_to_tree_data(list)
72
- key_values = list.sort
72
+ key_values = list.sort_by(&:first)
73
73
  tree_data = {}
74
74
  key_values.each do |key, value|
75
75
  key_segments = key.to_s.split('.')
@@ -42,8 +42,10 @@ module I18n::Tasks
42
42
  @keys_missing_from_locale ||= {}
43
43
  @keys_missing_from_locale[locale] ||= begin
44
44
  keys = data[base_locale].traverse_map_if { |key, base_value|
45
- key if !ignore_key?(key, :missing) && !key_value?(key, locale) && !key_value?(depluralize_key(key), locale)
46
- }
45
+ next if ignore_key?(key, :missing)
46
+ key = depluralize_key(key, locale)
47
+ key if !key_value?(key, locale)
48
+ }.uniq
47
49
  KeyGroup.new keys, type: :missing_from_locale, locale: locale
48
50
  end
49
51
  end
@@ -4,11 +4,11 @@ module I18n::Tasks::PluralKeys
4
4
  # @param [String] key i18n key
5
5
  # @param [String] locale to pull key data from
6
6
  # @return the base form if the key is a specific plural form (e.g. apple for apple.many), and the key as passed otherwise
7
- def depluralize_key(locale = base_locale, key)
7
+ def depluralize_key(key, locale = base_locale)
8
8
  return key if key !~ PLURAL_KEY_RE || t(key, locale).is_a?(Hash)
9
9
  parent_key = key.split('.')[0..-2] * '.'
10
- plural_versions = t(parent_key, locale)
11
- if plural_versions.is_a?(Hash) && plural_versions.all? { |k, v| ".#{k}" =~ PLURAL_KEY_RE && !v.is_a?(Hash) }
10
+ plural_versions = t(parent_key, locale) || (locale != base_locale && t(parent_key, base_locale))
11
+ if plural_versions.is_a?(Hash) && plural_versions.all? { |k, v| !v.is_a?(Hash) && ".#{k}" =~ PLURAL_KEY_RE }
12
12
  parent_key
13
13
  else
14
14
  key
@@ -10,7 +10,7 @@ module I18n
10
10
  @unused_keys[locale] ||= begin
11
11
  keys = data[locale].traverse_map_if { |key, value|
12
12
  next if used_in_expr?(key) || ignore_key?(key, :unused)
13
- key = depluralize_key(locale, key)
13
+ key = depluralize_key(key, locale)
14
14
  [key, value] unless used_key?(key)
15
15
  }.uniq
16
16
  KeyGroup.new keys, locale: locale, type: :unused
@@ -22,7 +22,7 @@ module I18n
22
22
  unused = unused_keys
23
23
  locales.each do |locale|
24
24
  used_key_values = data[locale].traverse_map_if { |key, value|
25
- [key, value] unless unused.include?(depluralize_key(locale, key))
25
+ [key, value] unless unused.include?(depluralize_key(key, locale))
26
26
  }
27
27
  data[locale] = used_key_values
28
28
  end
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module Tasks
3
- VERSION = '0.3.10'
3
+ VERSION = '0.3.11'
4
4
  end
5
5
  end
@@ -12,6 +12,8 @@ p = t 'ignore_eq_base_all.a'
12
12
  p = t 'ignore_eq_base_es.a'
13
13
  p = t 'numeric.a'
14
14
  p = t 'plural.a', count: 2
15
+ p = t 'missing_in_es_plural_1.a', count: 2
16
+ p = t 'missing_in_es_plural_2.a', count: 2
15
17
  p = t 'devise.a'
16
18
  p = t :missing_symbol_key
17
19
  p #{t :"missing_symbol.key_two"} #{t :'missing_symbol.key_three'}
@@ -11,7 +11,8 @@ describe 'i18n-tasks' do
11
11
  %w( en.used_but_missing.key en.relative.index.missing
12
12
  es.missing_in_es.a es.blank_in_es.a es.same_in_es.a
13
13
  en.hash.pattern_missing.a en.hash.pattern_missing.b
14
- en.missing_symbol_key en.missing_symbol.key_two en.missing_symbol.key_three )
14
+ en.missing_symbol_key en.missing_symbol.key_two en.missing_symbol.key_three
15
+ es.missing_in_es_plural_1.a es.missing_in_es_plural_2.a)
15
16
  }
16
17
  it 'detects missing or identical' do
17
18
  capture_stderr do
@@ -93,6 +94,7 @@ describe 'i18n-tasks' do
93
94
  run_cmd :add_missing, locales: 'es'
94
95
  in_test_app_dir {
95
96
  expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a']).to eq 'EN_TEXT'
97
+ expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es_plural_1']['a']['one']).to eq 'EN_TEXT'
96
98
  }
97
99
  end
98
100
 
@@ -155,6 +157,8 @@ TXT
155
157
  'unused' => {'a' => v, 'numeric' => v_num, 'plural' => {'one' => v, 'other' => v}},
156
158
  'ignore_unused' => {'a' => v},
157
159
  'missing_in_es' => {'a' => v},
160
+ 'missing_in_es_plural_1' => { 'a' => {'one' => v, 'other' => v}},
161
+ 'missing_in_es_plural_2' => { 'a' => {'one' => v, 'other' => v}},
158
162
  'same_in_es' => {'a' => v},
159
163
  'ignore_eq_base_all' => {'a' => v},
160
164
  'ignore_eq_base_es' => {'a' => v},
@@ -179,7 +183,8 @@ TXT
179
183
  }
180
184
 
181
185
  en_data = gen_data.('EN_TEXT')
182
- es_data = gen_data.('ES_TEXT').except('missing_in_es')
186
+ es_data = gen_data.('ES_TEXT').except(
187
+ 'missing_in_es', 'missing_in_es_plural_1', 'missing_in_es_plural_2')
183
188
  es_data['same_in_es']['a'] = 'EN_TEXT'
184
189
  es_data['blank_in_es']['a'] = ''
185
190
  es_data['ignore_eq_base_all']['a'] = 'EN_TEXT'
@@ -33,7 +33,7 @@ describe 'Plural keys' do
33
33
  end
34
34
 
35
35
  def depluralize(key)
36
- task.depluralize_key('en', key)
36
+ task.depluralize_key(key, 'en')
37
37
  end
38
38
  end
39
39
 
@@ -26,7 +26,7 @@ RSpec::Matchers.define :be_i18n_keys do |expected|
26
26
  end
27
27
 
28
28
  match do |actual|
29
- extract_keys(actual).should =~ expected
29
+ extract_keys(actual).sort.should == expected.sort
30
30
  end
31
31
 
32
32
  failure_message_for_should do |actual|
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.3.10
4
+ version: 0.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-13 00:00:00.000000000 Z
11
+ date: 2014-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubis