i18n-migrations 0.1.4 → 0.2.0

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: 1f368a8f95872f236f752ebee22e0af6d30f8205
4
- data.tar.gz: c6cf48397cd39f07d65be2207da0f83f0924af73
3
+ metadata.gz: 682ef4a62f20bcdffffa20b2f0172e8c9a6f8542
4
+ data.tar.gz: 4b6c731797c9894f2a8fb92e0566b0147f10e44c
5
5
  SHA512:
6
- metadata.gz: 78d56421cb1c62ca4f89b9d16c52e9c0f35ecc82d23f58e631bbe21bd14753d8773dcd90456925197fcfa92514efef6811125393c69744237a14abcef091c751
7
- data.tar.gz: c86f46c588c42c87ed44f60dabd637d9f4424224f0cc674ab9174e898a26bbba82caee996b837d31d234c2ad869d32c7ad11850e952a95a105d00aecde111588
6
+ metadata.gz: 3857c51decac0553515d94152aa141133be04f323244e99468aaccbcde7ef21c224bf13d491df9f2b7e579c083657662842f92b3c04e75ee512e0ef6dbd51702
7
+ data.tar.gz: c038a06ef1bdb0fe5fc9491ffb2f8f807110c57a531592d3e607b40aee3a8e374388c2baf5763de358a67386443e67fe3eade32465fd487ddd8d8f55a1716244
@@ -3,7 +3,7 @@ require 'rest-client'
3
3
  module I18n
4
4
  module Migrations
5
5
  class GoogleTranslateDictionary
6
- def initialize(from_locale, to_locale, key, do_not_translate)
6
+ def initialize(from_locale:, to_locale:, key:, do_not_translate:)
7
7
  @from_locale, @to_locale, @key, @do_not_translate = from_locale, to_locale, key, do_not_translate
8
8
  end
9
9
 
@@ -0,0 +1,249 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+ require 'active_support/inflector'
4
+ require 'active_support/core_ext/object'
5
+ require 'colorize'
6
+
7
+ # this class does all the work, but doesn't hold config or do more than one locale
8
+ module I18n
9
+ module Migrations
10
+ class Locale
11
+ attr_reader :name
12
+ attr_reader :migrations
13
+
14
+ def initialize(name, locales_dir:, main_locale_name:, migrations:, dictionary:)
15
+ @name, @locales_dir, @main_locale_name, @migrations, @dictionary =
16
+ name, locales_dir, main_locale_name, migrations, dictionary
17
+ end
18
+
19
+ def validate(data, notes)
20
+ main_data = main_locale.read_data
21
+ main_data.each do |key, main_term|
22
+ old_term = data[key]
23
+ new_term, errors = @dictionary.fix(main_term, old_term)
24
+ if new_term != old_term
25
+ data[key] = new_term
26
+ puts "#{"Fix".green} #{key.green}:"
27
+ puts "#{@main_locale_name}: #{main_term}"
28
+ puts "#{@name} (old): #{old_term}"
29
+ puts "#{@name} (new): #{new_term}"
30
+ puts
31
+ end
32
+ replace_errors_in_notes(notes, key, errors)
33
+ if errors.length > 0
34
+ puts "Error #{errors.join(', ').red} #{key.yellow}"
35
+ puts "#{@main_locale_name.bold}: #{main_term}"
36
+ puts "#{@name.bold}: #{old_term}"
37
+ puts
38
+ end
39
+ end
40
+ end
41
+
42
+ def update_info
43
+ data, notes = read_data_and_notes
44
+ yield data, notes
45
+ write_data_and_notes(data, notes)
46
+ end
47
+
48
+ def migrate(data, notes)
49
+ missing_versions = (@migrations.all_versions - read_versions(data)).sort
50
+ if missing_versions.empty?
51
+ puts "#{@name}: up-to-date"
52
+ return
53
+ end
54
+ puts "#{@name}: Migrating #{missing_versions.join(', ')}"
55
+ missing_versions.each do |version|
56
+ migrate_to_version(data, notes, version, :up)
57
+ end
58
+ end
59
+
60
+ def rollback(data, notes)
61
+ last_version = read_versions(data).last
62
+ if last_version == nil
63
+ puts "#{@name}: no more migrations to roll back"
64
+ return
65
+ end
66
+ puts "#{@name}: Rolling back #{last_version}"
67
+ raise "Can't find #{last_version}.rb to rollback" unless @migrations.all_versions.include?(last_version)
68
+
69
+ migrate_to_version(data, notes, last_version, :down)
70
+ end
71
+
72
+ def pull(sheet)
73
+ puts "Pulling #{@name}"
74
+ data = {}
75
+ notes = {}
76
+ count = 0
77
+
78
+ (2..sheet.num_rows).each do |row|
79
+ key, value, note = sheet[row, 1], sheet[row, 3], sheet[row, 4]
80
+ if key.present?
81
+ assign_complex_key(data, key.split('.'), value.present? ? value : '')
82
+ if note.present?
83
+ assign_complex_key(notes, key.split('.'), note)
84
+ end
85
+ count += 1
86
+ print '.'
87
+ end
88
+ end
89
+
90
+ write_data_and_notes(data, notes)
91
+ write_remote_version(data)
92
+
93
+ puts "\n#{count} keys"
94
+ end
95
+
96
+ def push(sheet)
97
+ main_data = main_locale.read_data
98
+ data, notes = read_data_and_notes
99
+ row = 2
100
+
101
+ puts "Pushing #{@name}"
102
+
103
+ main_data.each do |key, value|
104
+ sheet[row, 1] = key
105
+ sheet[row, 2] = value
106
+ sheet[row, 3] = data[key]
107
+ sheet[row, 4] = notes[key]
108
+ row += 1
109
+ print '.'
110
+ end
111
+
112
+ sheet.synchronize
113
+ write_remote_version(data)
114
+
115
+ puts "\n#{main_data.keys.length} keys"
116
+ end
117
+
118
+ def create(limit = nil)
119
+ new_data, new_notes = {}, {}
120
+ count = 0
121
+ main_data = main_locale.read_data
122
+ main_data.each do |key, term|
123
+ new_data[key], new_notes[key] = @dictionary.lookup(term)
124
+ print '.'.green
125
+ break if limit && limit < (count += 1)
126
+ end
127
+ new_data['VERSION'] = main_data['VERSION']
128
+ puts
129
+ write_data_and_notes(new_data, new_notes)
130
+ end
131
+
132
+ def main_locale?
133
+ @name == @main_locale_name
134
+ end
135
+
136
+ def last_version
137
+ read_versions(read_data).last
138
+ end
139
+
140
+ private
141
+
142
+ def main_locale
143
+ Locale.new(@main_locale_name,
144
+ locales_dir: @locales_dir,
145
+ main_locale_name: @main_locale_name,
146
+ migrations: @migrations,
147
+ dictionary: null) # should not use dictionary on main locale
148
+ end
149
+
150
+ def replace_errors_in_notes(all_notes, key, errors)
151
+ return if all_notes[key].blank? && errors.empty?
152
+
153
+ notes = all_notes[key]
154
+ notes = notes.present? ? notes.split("\n") : []
155
+ notes = notes.reject { |n| n.start_with?("[error:") }
156
+ all_notes[key] = (errors.map { |e| "[error: #{e}]" } + notes).join("\n")
157
+ end
158
+
159
+ def read_data_and_notes
160
+ data = read_data
161
+ notes = main_locale? ? {} : read_from_file("../#{@name}_notes.yml")
162
+ [data, notes]
163
+ end
164
+
165
+ def read_data
166
+ read_from_file("#{@name}.yml")
167
+ end
168
+
169
+ def write_data_and_notes(data, notes)
170
+ write_to_file("#{@name}.yml", data)
171
+ write_to_file("../#{@name}_notes.yml", notes) unless main_locale?
172
+ end
173
+
174
+
175
+ def write_remote_version(data)
176
+ write_to_file("../#{@name}_remote_version.yml",
177
+ { 'VERSION' => read_versions(data) })
178
+ end
179
+
180
+
181
+ def migrate_to_version(data, notes, version, direction)
182
+ migrations.play_migration(version: version,
183
+ locale: @name,
184
+ data: data,
185
+ notes: notes,
186
+ dictionary: @dictionary,
187
+ direction: direction)
188
+
189
+ if direction == :up
190
+ data['VERSION'] = (read_versions(data) + [version]).join("\n")
191
+ else
192
+ data['VERSION'] = (read_versions(data) - [version]).join("\n")
193
+ end
194
+ end
195
+
196
+ def read_versions(data)
197
+ (data['VERSION'] && data['VERSION'].split("\n")) || []
198
+ end
199
+
200
+ def read_from_file(filename)
201
+ filename = File.join(@locales_dir, filename)
202
+ begin
203
+ hash = {}
204
+ add_to_hash(hash, YAML.load(File.read(filename))[@name.to_s])
205
+ hash
206
+ rescue
207
+ puts "Error loading #{filename}"
208
+ raise
209
+ end
210
+ end
211
+
212
+ def write_to_file(filename, hash)
213
+ # we have to go from flat keys -> values to a hash that contains other hashes
214
+ complex_hash = {}
215
+ hash.keys.sort.each do |key|
216
+ value = hash[key]
217
+ assign_complex_key(complex_hash, key.split('.'), value.present? ? value : '')
218
+ end
219
+ File.open(File.join(@locales_dir, filename), 'w') do |file|
220
+ file << { @name => complex_hash }.to_yaml
221
+ end
222
+ end
223
+
224
+ def assign_complex_key(hash, key, value)
225
+ if key.length == 0
226
+ # should never get here
227
+ elsif key.length == 1
228
+ hash[key[0]] = value
229
+ else
230
+ hash[key[0]] ||= {}
231
+ assign_complex_key(hash[key[0]], key[1..-1], value)
232
+ end
233
+ end
234
+
235
+ # flattens new_hash and adds it to hash
236
+ def add_to_hash(hash, new_hash, prefix = [])
237
+ return unless new_hash
238
+
239
+ new_hash.each do |key, value|
240
+ if value.is_a?(Hash)
241
+ add_to_hash(hash, value, prefix + [key])
242
+ else
243
+ hash[(prefix + [key]).join('.')] = value
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,29 @@
1
+ require 'active_support/inflector'
2
+
3
+ module I18n
4
+ module Migrations
5
+ class MigrationFactory
6
+ def initialize(migration_dir)
7
+ @migration_dir = migration_dir
8
+ end
9
+
10
+ def all_versions
11
+ Dir[@migration_dir + '/*.rb'].map { |name| File.basename(name).gsub('.rb', '') }
12
+ end
13
+
14
+ def play_migration(version:, locale:, data:, notes:, dictionary:, direction:)
15
+ filename = File.join(@migration_dir, "#{version}.rb")
16
+ require filename
17
+ migration_class_name = version.gsub(/^\d{12}_/, '').camelcase
18
+
19
+ migration = begin
20
+ migration_class_name.constantize.new(locale, data, notes, dictionary, direction)
21
+ rescue
22
+ raise "Couldn't load migration #{migration_class_name} in #{filename}"
23
+ end
24
+
25
+ migration.change
26
+ end
27
+ end
28
+ end
29
+ end
@@ -8,14 +8,31 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  require 'google_translate_dictionary'
9
9
  require 'google_spreadsheet'
10
10
  require 'config'
11
+ require 'locale'
12
+ require 'migration_factory'
11
13
 
14
+ # this class knows how to do all the things the cli needs done.
15
+ # it mostly delegates to locale to do it, often asking multiple locales to do the same thing
12
16
  module I18n
13
17
  module Migrations
14
18
  class Migrator
19
+ def locale_for(name)
20
+ Locale.new(name,
21
+ locales_dir: config.locales_dir,
22
+ main_locale_name: config.main_locale,
23
+ migrations: MigrationFactory.new(config.migration_dir),
24
+ dictionary: new_dictionary(name))
25
+ end
26
+
15
27
  def config
16
28
  @config ||= Config.new.read!
17
29
  end
18
30
 
31
+ # for testing
32
+ def config=(config)
33
+ @config = config
34
+ end
35
+
19
36
  def new_migration(name)
20
37
  name = name.parameterize(separator: '_')
21
38
  file_name = "#{Time.now.strftime('%Y%m%d%H%M')}_#{name.downcase.gsub(' ', '_')}.rb"
@@ -39,299 +56,84 @@ end
39
56
 
40
57
  def migrate(locale_or_all = 'all')
41
58
  each_locale(locale_or_all) do |locale|
42
- update_locale_info(locale) do |data, notes|
43
- migrate_locale(locale, data, notes)
59
+ locale.update_info do |data, notes|
60
+ locale.migrate(data, notes)
44
61
  end
45
62
  end
46
63
  end
47
64
 
48
65
  def rollback(locale_or_all)
49
66
  each_locale(locale_or_all) do |locale|
50
- update_locale_info(locale) do |data, notes|
51
- rollback_locale(locale, data, notes)
67
+ locale.update_info do |data, notes|
68
+ locale.rollback(data, notes)
52
69
  end
53
70
  end
54
71
  end
55
72
 
56
73
  def pull(locale_or_all)
57
74
  each_locale(locale_or_all) do |locale|
58
- next if locale == config.main_locale
59
- sheet = get_google_spreadsheet(locale)
60
- pull_locale(locale, sheet)
61
- migrate(locale)
75
+ next if locale.main_locale?
76
+ sheet = get_google_spreadsheet(locale.name)
77
+ locale.pull(sheet)
78
+ migrate(locale.name)
62
79
  end
63
80
  end
64
81
 
65
82
  def push(locale_or_all, force = false)
66
83
  each_locale(locale_or_all) do |locale|
67
- next if locale == config.main_locale
84
+ next if locale.main_locale?
68
85
  sheet = get_google_spreadsheet(locale)
69
86
  unless force
70
- pull_locale(locale, sheet)
71
- migrate(locale)
87
+ locale.pull(sheet)
88
+ migrate(locale.name)
72
89
  end
73
- push_locale(locale, sheet)
90
+ locale.push(sheet)
74
91
  end
75
92
  end
76
93
 
77
94
  def new_locale(new_locale, limit = nil)
78
- dictionary = new_dictionary(new_locale)
79
- new_data, new_notes = {}, {}
80
- count = 0
81
- main_data = read_locale_data(config.main_locale)
82
- main_data.each do |key, term|
83
- new_data[key], new_notes[key] = dictionary.lookup(term)
84
- print '.'.green
85
- break if limit && limit < count += 1
86
- end
87
- new_data['VERSION'] = main_data['VERSION']
88
- puts
89
- write_locale_data_and_notes(new_locale, new_data, new_notes)
95
+ locale_for(new_locale).create
90
96
  end
91
97
 
92
98
  def version
93
99
  each_locale do |locale|
94
- puts "#{locale}: #{locale_versions(read_locale_data(locale)).last}"
100
+ puts "#{locale.name}: #{locale.last_version}"
95
101
  end
96
102
  end
97
103
 
98
104
  def validate(locale_or_all)
99
105
  each_locale(locale_or_all) do |locale|
100
- next if locale == config.main_locale
101
- update_locale_info(locale) do |data, notes|
102
- validate_locale(locale, data, notes)
106
+ next if locale.main_locale?
107
+ locale.update_info do |data, notes|
108
+ locale.validate(data, notes)
103
109
  end
104
110
  end
105
111
  end
106
112
 
107
113
  private
108
114
 
109
- def validate_locale(locale, data, notes)
110
- main_data = read_locale_data(config.main_locale)
111
- dict = new_dictionary(locale)
112
- main_data.each do |key, main_term|
113
- old_term = data[key]
114
- new_term, errors = dict.fix(main_term, old_term)
115
- if new_term != old_term
116
- data[key] = new_term
117
- puts "#{"Fix".green} #{key.green}:"
118
- puts "#{config.main_locale}: #{main_term}"
119
- puts "#{locale} (old): #{old_term}"
120
- puts "#{locale} (new): #{new_term}"
121
- puts
122
- end
123
- replace_errors_in_notes(notes, key, errors)
124
- if errors.length > 0
125
- puts "Error #{errors.join(', ').red} #{key.yellow}"
126
- puts "#{config.main_locale.bold}: #{main_term}"
127
- puts "#{locale.bold}: #{old_term}"
128
- puts
129
- end
130
- end
131
- end
132
-
133
- def replace_errors_in_notes(all_notes, key, errors)
134
- return if all_notes[key].blank? && errors.empty?
135
-
136
- notes = all_notes[key]
137
- notes = notes.present? ? notes.split("\n") : []
138
- notes = notes.reject { |n| n.start_with?("[error:") }
139
- all_notes[key] = (errors.map{|e| "[error: #{e}]"} + notes).join("\n")
140
- end
141
-
142
- def update_locale_info(locale)
143
- data, notes = read_locale_data_and_notes(locale)
144
- yield data, notes
145
- write_locale_data_and_notes(locale, data, notes)
146
- end
147
-
148
- def read_locale_data_and_notes(locale)
149
- data = read_locale_data(locale)
150
- notes = locale == config.main_locale ? {} : read_locale_from_file(locale, "../#{locale}_notes.yml")
151
- [data, notes]
152
- end
153
-
154
- def read_locale_data(locale)
155
- read_locale_from_file(locale, "#{locale}.yml")
156
- end
157
-
158
- def write_locale_data_and_notes(locale, data, notes)
159
- write_locale_to_file(locale, "#{locale}.yml", data)
160
- write_locale_to_file(locale, "../#{locale}_notes.yml", notes) unless locale == config.main_locale
161
- end
162
-
163
- def pull_locale(locale, sheet)
164
- puts "Pulling #{locale}"
165
- data = {}
166
- notes = {}
167
- count = 0
168
-
169
- (2..sheet.num_rows).each do |row|
170
- key, value, note = sheet[row, 1], sheet[row, 3], sheet[row, 4]
171
- if key.present?
172
- assign_complex_key(data, key.split('.'), value.present? ? value : '')
173
- if note.present?
174
- assign_complex_key(notes, key.split('.'), note)
175
- end
176
- count += 1
177
- print '.'
178
- end
179
- end
180
-
181
- write_locale_data_and_notes(locale, data, notes)
182
- write_locale_remote_version(locale, data)
183
-
184
- puts "\n#{count} keys"
185
- end
186
-
187
- def write_locale_remote_version(locale, data)
188
- write_locale_to_file(locale,
189
- "../#{locale}_remote_version.yml",
190
- { 'VERSION' => locale_versions(data) })
191
- end
192
-
193
- def push_locale(locale, sheet)
194
- main_data = read_locale_data(config.main_locale)
195
- data, notes = read_locale_data_and_notes(locale)
196
- row = 2
197
-
198
- puts "Pushing #{locale}"
199
-
200
- main_data.each do |key, value|
201
- sheet[row, 1] = key
202
- sheet[row, 2] = value
203
- sheet[row, 3] = data[key]
204
- sheet[row, 4] = notes[key]
205
- row += 1
206
- print '.'
207
- end
208
-
209
- sheet.synchronize
210
- write_locale_remote_version(locale, data)
211
-
212
- puts "\n#{main_data.keys.length} keys"
213
- end
214
-
215
- def migrate_locale(locale, data, notes)
216
- missing_versions = (all_versions - locale_versions(data)).sort
217
- if missing_versions.empty?
218
- puts "#{locale}: up-to-date"
219
- return
220
- end
221
- puts "#{locale}: Migrating #{missing_versions.join(', ')}"
222
- missing_versions.each do |version|
223
- migrate_locale_to_version(locale, data, notes, version, :up)
224
- end
225
- end
226
-
227
- def rollback_locale(locale, data, notes)
228
- last_version = locale_versions(data).last
229
- if last_version == nil
230
- puts "#{locale}: no more migrations to roll back"
231
- return
232
- end
233
- puts "#{locale}: Rolling back #{last_version}"
234
- raise "Can't find #{last_version}.rb to rollback" unless all_versions.include?(last_version)
235
-
236
- migrate_locale_to_version(locale, data, notes, last_version, :down)
237
- end
238
-
239
- def migrate_locale_to_version(locale, data, notes, version, direction)
240
- filename = File.join(config.migration_dir, "#{version}.rb")
241
- require filename
242
- migration_class_name = version.gsub(/^\d{12}_/, '').camelcase
243
- dictionary = new_dictionary(locale)
244
-
245
- migration = begin
246
- migration_class_name.constantize.new(locale, data, notes, dictionary, direction)
247
- rescue
248
- raise "Couldn't load migration #{migration_class_name} in #{filename}"
249
- end
250
-
251
- migration.change
252
-
253
- if direction == :up
254
- data['VERSION'] = (locale_versions(data) + [version]).join("\n")
255
- else
256
- data['VERSION'] = (locale_versions(data) - [version]).join("\n")
257
- end
258
- end
259
-
260
- def locale_versions(data)
261
- (data['VERSION'] && data['VERSION'].split("\n")) || []
262
- end
263
-
264
- def read_locale_from_file(locale, filename)
265
- filename = File.join(config.locales_dir, filename)
266
- begin
267
- hash = {}
268
- add_to_hash(hash, YAML.load(File.read(filename))[locale.to_s])
269
- hash
270
- rescue
271
- puts "Error loading #{filename}"
272
- raise
273
- end
274
- end
275
-
276
- def write_locale_to_file(locale, filename, hash)
277
- # we have to go from flat keys -> values to a hash that contains other hashes
278
- complex_hash = {}
279
- hash.keys.sort.each do |key|
280
- value = hash[key]
281
- assign_complex_key(complex_hash, key.split('.'), value.present? ? value : '')
282
- end
283
- File.open(File.join(config.locales_dir, filename), 'w') do |file|
284
- file << { locale => complex_hash }.to_yaml
115
+ def each_locale(name = 'all')
116
+ (name == 'all' ? all_locale_names : [name]).each do |l|
117
+ yield locale_for(l)
285
118
  end
286
119
  end
287
120
 
288
- def assign_complex_key(hash, key, value)
289
- if key.length == 0
290
- # should never get here
291
- elsif key.length == 1
292
- hash[key[0]] = value
293
- else
294
- hash[key[0]] ||= {}
295
- assign_complex_key(hash[key[0]], key[1..-1], value)
296
- end
297
- end
298
-
299
- # flattens new_hash and adds it to hash
300
- def add_to_hash(hash, new_hash, prefix = [])
301
- return unless new_hash
302
-
303
- new_hash.each do |key, value|
304
- if value.is_a?(Hash)
305
- add_to_hash(hash, value, prefix + [key])
306
- else
307
- hash[(prefix + [key]).join('.')] = value
308
- end
309
- end
310
- end
311
-
312
- def each_locale(locale = 'all')
313
- (locale == 'all' ? all_locales : [locale]).each do |l|
314
- yield l
315
- end
316
- end
317
-
318
- def all_locales
121
+ def all_locale_names
319
122
  [config.main_locale] + config.other_locales
320
123
  end
321
124
 
322
- def all_versions
323
- Dir[config.migration_dir + '/*.rb'].map { |name| File.basename(name).gsub('.rb', '') }
324
- end
325
-
326
- def new_dictionary(locale)
327
- GoogleTranslateDictionary.new(config.main_locale, locale, config.google_translate_api_key, config.do_not_translate)
328
- end
329
-
330
125
  def get_google_spreadsheet(locale)
331
126
  GoogleSpreadsheet.new(locale,
332
127
  config.google_spreadsheets[locale],
333
128
  config.google_service_account_key_path).sheet
334
129
  end
130
+
131
+ def new_dictionary(locale)
132
+ GoogleTranslateDictionary.new(from_locale: config.main_locale,
133
+ to_locale: locale,
134
+ key: config.google_translate_api_key,
135
+ do_not_translate: config.do_not_translate)
136
+ end
335
137
  end
336
138
  end
337
139
  end
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module Migrations
3
- VERSION = "0.1.4"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Lightsmith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-03 00:00:00.000000000 Z
11
+ date: 2018-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,7 +122,9 @@ files:
122
122
  - lib/i18n/migrations/config.rb
123
123
  - lib/i18n/migrations/google_spreadsheet.rb
124
124
  - lib/i18n/migrations/google_translate_dictionary.rb
125
+ - lib/i18n/migrations/locale.rb
125
126
  - lib/i18n/migrations/migration.rb
127
+ - lib/i18n/migrations/migration_factory.rb
126
128
  - lib/i18n/migrations/migrator.rb
127
129
  - lib/i18n/migrations/version.rb
128
130
  homepage: https://github.com/transparentclassroom/i18n-migrations