translations_sync 0.4.5 → 0.4.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 568de929f677b238fe1cbe0064c74295bfcf55bf
4
- data.tar.gz: 905cdc5a32efc20b15af73b58e292e2c9eecfb6b
3
+ metadata.gz: 42096ed5df2d1d00a7071691ae3f9b61348b565b
4
+ data.tar.gz: b84217b76307b0ce2102ac99a906739f96d51e5b
5
5
  SHA512:
6
- metadata.gz: 26efd03cae3981f5a104140e3b05d77295f4cdd6dbb77a2f8d37ae5170f19a889181b9503c55477e404e87c9f59af89f348126badd09b8c1def44db5d4ecd279
7
- data.tar.gz: ecc6465b8d06fec02f5d45f8e5bb5aaeadc3539b0c500699e1f2daf9c7a9ed5de24cb9993b409975450e864991bcca65a20d77cee21d7cdfa26c2d215015bcfd
6
+ metadata.gz: 12153a22337d9e26444b2721904993537ce3451bc52f83b72effd6626a561f5804d1c198d85899a2b39f15568038dc22fcb06582633d6f5207c33ae294137fdd
7
+ data.tar.gz: 66f9a4a78afaf838b40498665ef4057483fade91cc2a07d020d5f056faa3fe090f83567280075993fe37529eaca0b5a7c0f2b91fa614dfef04476c468f5e7848
data/Changelog CHANGED
@@ -1,3 +1,16 @@
1
+ 2016-06-17 v.0.4.7
2
+ * Parameter IGNORE is added
3
+ * Documentation is refised
4
+
5
+ 2016-06-17 v.0.4.6
6
+ * The locale may be not only suffix, but also directory
7
+
8
+ 2014-12-19 v.0.4.5
9
+ * Ignore gem faker and use I18n.available_locales as default list of locales
10
+
11
+ 2014-12-19 v.0.4.4
12
+ * skipped
13
+
1
14
  2014-05-20 v.0.4.3
2
15
  * Dot can be used as separator between name and locale instead of underscore
3
16
 
data/README CHANGED
@@ -1,74 +1,99 @@
1
1
  TranslationsSync
2
2
  ================
3
3
 
4
- This plugin is intended to help the developer to synchronize the different locales for
5
- the project that uses yaml based locales, in particular, I18n.
4
+ This gem is intended to help the developer to synchronize the different
5
+ locales for the project that uses yaml based locales, in particular, I18n.
6
6
 
7
7
 
8
8
  Requirements
9
- ============
10
-
11
- gem 'ya2yaml'
9
+ ------------
12
10
 
11
+ gem 'ya2yaml'
12
+ gem 'active_support'
13
13
 
14
14
  Installation
15
- ============
15
+ ------------
16
+
17
+ 1. Add to your Gemfile
16
18
 
17
- 1. As plugin
18
- rails plugin install http://github.com/dima4p/translations_sync/
19
+ gem 'translations_sync'
19
20
 
20
- 2. As gem: add to your Gemfile
21
- gem 'translations_sync'
21
+ 2. If you are using the gem without bundle just install it
22
22
 
23
- 3. If you are using the gem outside rails, execute the following command to copy
24
- the rake file into your project's directory lib/tasks.
23
+ gem install translations_sync
25
24
 
26
- bundle exec translations_sync
25
+ Then execute the following command to copy the rake file into your
26
+ project's directory lib/tasks.
27
27
 
28
- Or, if you keep your rake tesks in other place, you can give the argument with the proper path
28
+ translations_sync
29
29
 
30
- bundle exec translations_sync path/to/directory
30
+ Or, if you keep your rake tasks in other place, you can give the argument
31
+ with the proper path
32
+
33
+ translations_sync path/to/directory
31
34
 
32
35
 
33
36
  Description
34
- ===========
35
-
36
- There are two rake tasks implemented in the plugin.
37
-
38
- 1. rake translations:sync
39
-
40
- This task generates the files with missing translations in the directory
41
- config/locales. One file per a locale is created with the name missing_#{locale}.yml
42
- Each file contains the text of one of the existing locales, namely the first one
43
- existing. The order to check is defined by the LIST parameter.
44
- This parameter can also be used to add a new locale. If it is not given I18n.available_locales will be used.
45
- The parameter EXCLUDE may be used to extract one or more locales from the participation
46
- in the process. If any locale is mentioned in both lists, it will not participate in the
47
- calculation of the missing translations but it's value may be used in the sample
48
- translation.
49
- The parameter NAME allows you to write the missing translations to the specified
50
- files instead of default 'missing'.
51
- The parameter SOURCE allows you to restrict the synchronization to be done within
52
- only one file name. Only the files for all the locales that meet the given name
53
- will be loaded for the synchronization.
54
- The parameter IN sets both NAME and SOURCE to its value.
55
-
56
- 2. rake translations:singles
37
+ -----------
38
+
39
+ This gem allows different organizations of translation files. They can be
40
+ grouped in the directories that correspond to locales, or the locale
41
+ may be defined in the suffix of a file name separated by a dot or underscore.
42
+ Let us call the file name without locale suffix and extension as
43
+ **base name**
44
+
45
+ When a file name is to be given as parameter in the description below
46
+ it should not include nor locale prefix, nor locale suffix and extension
47
+ whichever organization is used.
48
+
49
+ The main goal of the gem to assist in managing the translations for the
50
+ project. This can be done by using the `rake` tasks described below.
51
+
52
+ The following parameters can be given:
53
+
54
+ * `LIST=comma,separated,list` specifies the locales that should
55
+ participate in synchronization.
56
+ For example, `LIST=en,de,fr,zh-CN`
57
+ If omitted, I18n.available_locales will be used.
58
+ The order of the locales is important as the existing for the first
59
+ locale in the list will be provided for a missing translation(s).
60
+ The locale in LIST must not be present in I18n.available_locales.
61
+ This allows easily to add new locales to the project.
62
+ * `EXCLUDE=comma,separated,list` specifies the locales that should NOT participate.
63
+ * `NAME=name`. By default missing translations are written to the
64
+ **base name** "missing".
65
+ This parameter tells to use the given name as **base name**.
66
+ If any of the corresponding files exist, the missing translations will
67
+ be added to them.
68
+ * `SOURCE=name`. Only files with the given **base name** will be considered.
69
+ * `IN=name`. It is equivalent to `NAME=name SOURCE=name`
70
+ * `KEY=path.to.key`. Points to the key to be moved or removed.
71
+ Obviously, it should not include locale.
72
+ * `TO=path.to.key`.
73
+
74
+ Rake tasks
75
+ ----------
76
+
77
+ ### rake translations:sync
78
+
79
+ This task verifies that all the translation keys are present in all
80
+ files specifed by the given parameters and if any is missing creates/updates
81
+ corresponding file(s).
82
+
83
+ ### rake translations:singles
57
84
 
58
85
  This task generates a single file config/locales/singles.yml that contains the
59
- translations occuring only in one locale.
86
+ translations occurring only in one locale.
60
87
 
61
- 3. rake translations:move KEY=key.to.move TO=where.to.move
88
+ ### rake translations:move KEY=key.to.move TO=where.to.move
62
89
 
63
90
  This task moves the content of given KEY under the TO.
64
- You can use all the parameters available for the translations:sync task with the default
65
- value for the NAME equal to 'moved'.
66
-
67
- 4. rake translations:remove KEY=key.to.remove
91
+ You can use all the parameters available for the translations:sync task
92
+ with the default value for the NAME equal to 'moved'.
68
93
 
69
- This task removes the key from the translations. NAME defalts to 'removed' here.
94
+ ### rake translations:remove KEY=key.to.remove
70
95
 
71
- So far it works only for rails applications. Suggestions for others are welcome.
96
+ This task removes the key from the translations. NAME defaults to 'removed' here.
72
97
 
73
98
 
74
- Copyright (c) 2010-2011 Dmitri Koulikoff, released under the MIT license
99
+ Copyright (c) 2010-2016 Dmitri Koulikoff, released under the MIT license
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rubygems/specification'
6
6
  require 'date'
7
7
 
8
8
  GEM = "translations_sync"
9
- GEM_VERSION = "0.4.5"
9
+ GEM_VERSION = "0.4.7"
10
10
  AUTHOR = "Dmitri Koulikoff"
11
11
  EMAIL = "koulikoff@gmail.com"
12
12
  HOMEPAGE = "http://github.com/dima4p/translations_sync/"
@@ -5,13 +5,19 @@ namespace :translations do
5
5
 
6
6
  def get_ts(skip_source = false)
7
7
  source = skip_source ? nil : ENV['SOURCE'] || ENV['IN']
8
- TranslationsSync.new ENV['LIST'], ENV['EXCLUDE'], source
8
+ params = {}
9
+ params[:list] = ENV['LIST']
10
+ params[:exclude] = ENV['EXCLUDE']
11
+ params[:source] = ENV['SOURCE'] || ENV['IN'] unless skip_source
12
+ params[:ignore] = ENV['IGNORE']
13
+ TranslationsSync.new params
9
14
  end
10
15
 
11
- def save_files(translations, default_name, separator = '_')
16
+ def save_moved_files(ts, default_name)
17
+ translations = ts.moved
12
18
  name = ENV['NAME'] || ENV['IN'] || default_name
13
19
  translations.keys.sort.each do |lang|
14
- filename = File.join Rails.root, 'config', 'locales', "#{name}#{separator}#{lang}.yml"
20
+ filename = ts.filename_for name, lang
15
21
  print filename + ' ... '
16
22
  if File.exist? filename
17
23
  status = 'updated'
@@ -30,8 +36,7 @@ namespace :translations do
30
36
  ts = get_ts
31
37
  name = ENV['NAME'] || ENV['IN'] || 'missing'
32
38
  ts.missing.keys.sort.each do |lang|
33
- filename = File.join Rails.root, 'config', 'locales',
34
- "#{name}#{ts.separator}#{lang}.yml"
39
+ filename = ts.filename_for name, lang
35
40
  print filename + ' ... '
36
41
  if File.exist? filename
37
42
  hash = YAML::load(File.open(filename))
@@ -52,7 +57,7 @@ namespace :translations do
52
57
  desc "Detects the translations existing only in one locale" + PARAMS
53
58
  task :singles => :environment do
54
59
  ts = get_ts false
55
- filename = File.join Rails.root, 'config', 'locales', "singles.yml"
60
+ filename = ts.filename_for 'singles', nil
56
61
  if ts.singles.size > 0
57
62
  File.open(filename, "w") do |file|
58
63
  file.write(TranslationsSync.to_yaml ts.singles)
@@ -66,9 +71,10 @@ namespace :translations do
66
71
  desc "Moves the key in the translations" + PARAMS + " KEY=key.to.move TO=where.to.move IN=filespec"
67
72
  task :move => :environment do
68
73
  key = ENV['KEY'] or raise "Parameter KEY must be given"
74
+ to = ENV['TO'] or raise "Parameter TO must be given"
69
75
  ts = get_ts
70
- if ts.move key, ENV['TO']
71
- save_files ts.moved, 'moved', ts.separator
76
+ if ts.move key, to
77
+ save_moved_files ts, 'moved'
72
78
  else
73
79
  puts "The key \"#{key}\" was not found"
74
80
  end
@@ -79,7 +85,7 @@ namespace :translations do
79
85
  key = ENV['KEY'] or raise "Parameter KEY must be given"
80
86
  ts = get_ts
81
87
  if ts.remove key
82
- save_files ts.moved, 'removed', ts.separator
88
+ save_moved_files ts, 'removed'
83
89
  else
84
90
  puts "The key \"#{key}\" was not found"
85
91
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'ya2yaml'
3
3
  require 'i18n'
4
+ require 'active_support/hash_with_indifferent_access'
4
5
 
5
6
  class Hash
6
7
  def stringify_keys!
@@ -22,6 +23,7 @@ end
22
23
  class TranslationsSync
23
24
 
24
25
  attr_accessor :translations, :list
26
+ attr_reader :flat
25
27
  EXCLUDE_LIST = ''
26
28
  TAIL = '=TODO'
27
29
  PKORDER = {'zero' => 0, 'one' => 1, 'two' => 2, 'few' => 3, 'many' => 5, 'other' => 9}
@@ -53,9 +55,17 @@ class TranslationsSync
53
55
  end
54
56
  end # class << self
55
57
 
56
- def initialize(list = nil, exclude = nil, source = nil)
57
- I18n.backend.send(:init_translations) unless I18n.backend.initialized?
58
- translations = I18n.backend.send :translations
58
+ def initialize(*args)
59
+ params = args.pop if args.last.is_a? Hash
60
+ params = (params || {}).with_indifferent_access
61
+ unless args.size == 0
62
+ list, exclude, source = agrs
63
+ puts 'Deprecation warning: a Hash should be used to pass paramteters'
64
+ end
65
+ list ||= params[:list]
66
+ exclude ||= params[:exclude]
67
+ source ||= params[:source]
68
+ ignore = params[:ignore]
59
69
  @full_list = list ? list.split(',').map(&:to_sym) : I18n.available_locales
60
70
  @full_list = @full_list.uniq
61
71
  exclude = (exclude || EXCLUDE_LIST).split(',').map(&:to_sym)
@@ -79,20 +89,29 @@ class TranslationsSync
79
89
  acc
80
90
  end
81
91
 
92
+ translations_path_re = Regexp.new "#{translations_dir}(\\/[a-z]{2}(?:-[A-Z]{2})?)?\\/[-_/0-9a-zA-Z]+(?:(_|.)[a-z]{2}(?:-[A-Z]{2})?)?\\.(?:yml|rb)\\Z"
93
+ I18n.load_path.find do |path|
94
+ path.match translations_path_re
95
+ end
96
+ @prefix = $1 or @separator = $2
97
+
82
98
  if source
83
- re = Regexp.new "\\/#{Regexp.escape source}(_|.)[a-z]{2}(-[A-Z]{2})?\\.(yml|rb)\\Z"
99
+ translations_path_re = Regexp.new "#{translations_dir}(\\/[a-z]{2}(?:-[A-Z]{2})?)?\\/#{Regexp.escape source}(?:(_|.)[a-z]{2}(?:-[A-Z]{2})?)?\\.(?:yml|rb)\\Z"
84
100
  I18n.load_path.reject! do |path|
85
- path !~ re
101
+ path !~ translations_path_re
86
102
  end
87
- @separator = $1 == '.' ? '.' : '_'
88
- translations.each do |key, hash|
89
- hash.keys.each do |k|
90
- hash.delete(k) unless k == :pluralize
91
- end
103
+ end
104
+
105
+ if ignore
106
+ translations_path_re = Regexp.new "#{translations_dir}#{'\\/[^/]+' if @prefix}\\/#{Regexp.escape ignore}"
107
+ I18n.load_path.reject! do |path|
108
+ path =~ translations_path_re
92
109
  end
93
- I18n.backend.send(:init_translations)
94
110
  end
95
111
 
112
+ I18n.reload!
113
+ I18n.backend.send(:init_translations)
114
+ translations = I18n.backend.send :translations
96
115
  @flat = {}
97
116
  @list.each do |lang|
98
117
  flatten_keys(lang, translations[lang] || {}, @flat)
@@ -108,7 +127,7 @@ class TranslationsSync
108
127
  unless @locales_with_missing
109
128
  size = list.size
110
129
  @locales_with_missing = []
111
- @flat.each_pair do |key, val|
130
+ flat.each_pair do |key, val|
112
131
  if val.size < size
113
132
  (@locales_with_missing += list - val.keys).uniq!
114
133
  break if @locales_with_missing.size == size
@@ -124,7 +143,7 @@ class TranslationsSync
124
143
  locales_with_missing.each do |lang|
125
144
  @missing[lang] = {}
126
145
  end
127
- @flat.each_pair do |key, val|
146
+ flat.each_pair do |key, val|
128
147
  (locales_with_missing - val.keys).each do |lang|
129
148
  push_to_hash @missing[lang], lang, key, val, :missing
130
149
  end
@@ -138,7 +157,7 @@ class TranslationsSync
138
157
  unless @locales_with_singles
139
158
  size = list.size
140
159
  @locales_with_singles = []
141
- @flat.each_pair do |key, val|
160
+ flat.each_pair do |key, val|
142
161
  if val.size < size
143
162
  (@locales_with_singles += val.keys).uniq! if val.size == 1
144
163
  break if @locales_with_singles.size == size
@@ -154,7 +173,7 @@ class TranslationsSync
154
173
  locales_with_singles.each do |lang|
155
174
  @singles[lang] = {}
156
175
  end
157
- @flat.each_pair do |key, val|
176
+ flat.each_pair do |key, val|
158
177
  lang = val.keys.first
159
178
  push_to_hash @singles[lang], lang, key, val, :singles if val.size == 1
160
179
  end
@@ -170,14 +189,17 @@ class TranslationsSync
170
189
  destination ||= ''
171
190
  destination = destination.split('.').map(&:to_sym)
172
191
  destination << key.last if destination.size == 0
192
+ puts "key=#{key.inspect} destination=#{destination.inspect}"
173
193
  result = false
174
- @flat.each_pair do |array, val|
194
+ flat.each_pair do |array, val|
175
195
  if array[0, key_length] == key
176
196
  array[0, key_length] = destination
197
+ puts array.inspect
177
198
  result = true
178
199
  end
179
200
  end
180
201
  @moved = nil
202
+ puts result
181
203
  result
182
204
  end
183
205
 
@@ -187,7 +209,8 @@ class TranslationsSync
187
209
  @list.each do |lang|
188
210
  @moved[lang] = {}
189
211
  end
190
- @flat.each_pair do |key, val|
212
+ flat.each_pair do |key, val|
213
+ puts key.inspect
191
214
  val.keys.each do |lang|
192
215
  push_to_hash @moved[lang], lang, key, val, :moved
193
216
  end
@@ -204,7 +227,7 @@ class TranslationsSync
204
227
  key = key.split('.').map(&:to_sym)
205
228
  key_length = key.length
206
229
  result = false
207
- @flat.reject! do |array, val|
230
+ flat.reject! do |array, val|
208
231
  r = array[0, key_length] == key
209
232
  result ||= r
210
233
  r
@@ -213,8 +236,16 @@ class TranslationsSync
213
236
  result
214
237
  end
215
238
 
216
- def separator
217
- @separator || '_'
239
+ def filename_for(name, lang = nil)
240
+ if lang
241
+ if @prefix
242
+ "#{translations_dir}/#{lang}/#{name}.yml"
243
+ else
244
+ "#{translations_dir}/#{name}#{@separator}#{lang}.yml"
245
+ end
246
+ else
247
+ "#{translations_dir}/#{name}.yml"
248
+ end
218
249
  end
219
250
 
220
251
  private
@@ -277,11 +308,28 @@ class TranslationsSync
277
308
  value.stringify_keys! if value.is_a? Hash
278
309
  h[key.to_s] = value
279
310
  when :moved
280
- value = val[target] or raise 'The translations are not synchronized'
311
+ value = val[target]
312
+ raise "The translations are not synchronized for #{keys.inspect}" if value.nil?
281
313
  value.stringify_keys! if value.is_a? Hash
282
314
  h[key.to_s] = value
283
315
  end
284
316
  keys.push key
285
317
  end
286
318
 
319
+ def translations_dir
320
+ @translations_dir ||=
321
+ common_prefix(I18n.config.load_path.grep Regexp.new FileUtils.pwd)
322
+ end
323
+
324
+ def common_prefix(paths)
325
+ return '' if paths.empty?
326
+ return paths.first.split('/').slice(0...-1).join('/') if paths.length <= 1
327
+ arr = paths.sort
328
+ first = arr.first.split('/')
329
+ last = arr.last.split('/')
330
+ i = 0
331
+ i += 1 while first[i] == last[i] && i <= first.length
332
+ first.slice(0, i).join('/')
333
+ end
334
+
287
335
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: translations_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitri Koulikoff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-19 00:00:00.000000000 Z
11
+ date: 2016-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: ya2yaml
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -61,8 +75,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
75
  version: '0'
62
76
  requirements: []
63
77
  rubyforge_project:
64
- rubygems_version: 2.2.2
78
+ rubygems_version: 2.5.1
65
79
  signing_key:
66
80
  specification_version: 4
67
- summary: Synchronizes the different locales represeinted in yaml for I18n
81
+ summary: Synchronizes the different locales translations represeinted in yaml for
82
+ I18n
68
83
  test_files: []