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 +4 -4
- data/Changelog +13 -0
- data/README +72 -47
- data/Rakefile +1 -1
- data/lib/tasks/translations_sync.rake +15 -9
- data/lib/translations_sync.rb +69 -21
- metadata +19 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 42096ed5df2d1d00a7071691ae3f9b61348b565b
|
|
4
|
+
data.tar.gz: b84217b76307b0ce2102ac99a906739f96d51e5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
-
|
|
18
|
-
rails plugin install http://github.com/dima4p/translations_sync/
|
|
19
|
+
gem 'translations_sync'
|
|
19
20
|
|
|
20
|
-
2.
|
|
21
|
-
gem 'translations_sync'
|
|
21
|
+
2. If you are using the gem without bundle just install it
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
the rake file into your project's directory lib/tasks.
|
|
23
|
+
gem install translations_sync
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Then execute the following command to copy the rake file into your
|
|
26
|
+
project's directory lib/tasks.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
translations_sync
|
|
29
29
|
|
|
30
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
The
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
86
|
+
translations occurring only in one locale.
|
|
60
87
|
|
|
61
|
-
|
|
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
|
|
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
|
-
|
|
94
|
+
### rake translations:remove KEY=key.to.remove
|
|
70
95
|
|
|
71
|
-
|
|
96
|
+
This task removes the key from the translations. NAME defaults to 'removed' here.
|
|
72
97
|
|
|
73
98
|
|
|
74
|
-
Copyright (c) 2010-
|
|
99
|
+
Copyright (c) 2010-2016 Dmitri Koulikoff, released under the MIT license
|
data/Rakefile
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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,
|
|
71
|
-
|
|
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
|
-
|
|
88
|
+
save_moved_files ts, 'removed'
|
|
83
89
|
else
|
|
84
90
|
puts "The key \"#{key}\" was not found"
|
|
85
91
|
end
|
data/lib/translations_sync.rb
CHANGED
|
@@ -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(
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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 !~
|
|
101
|
+
path !~ translations_path_re
|
|
86
102
|
end
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
217
|
-
|
|
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]
|
|
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.
|
|
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:
|
|
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.
|
|
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
|
|
81
|
+
summary: Synchronizes the different locales translations represeinted in yaml for
|
|
82
|
+
I18n
|
|
68
83
|
test_files: []
|