lokalise_manager 1.2.1 → 2.0.0

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
  SHA256:
3
- metadata.gz: 33815f129df22f7a27f91689cad944193aca9b992f14e7115a2737088785d3b3
4
- data.tar.gz: 1fc5a893bb917bac5afd39f2b35dbbb54286b878dce42f0805135105490520b5
3
+ metadata.gz: 0f9ca0fe8caf151e84dcc09f29368bc61b5bc3cdb4341ef5c1b21040b764a17a
4
+ data.tar.gz: 8c9194a836a1261638f2b22d8d2d7553bfbe605325911cb0c0ecef9332e9084c
5
5
  SHA512:
6
- metadata.gz: 7fecf43ac4f105be85fe2e4548643849b78a239ec523a79b37fec4b6acbeddf319dd4ac594e5caf28e4b174fed76e05b18d3bf6d6343d055daa2115d661b41c4
7
- data.tar.gz: 85f6c703a1ee2107cfe165b7c652cc81d2c2f0a0ae2a02af44cfb0e0cf31a185e5cbe3cbe27c8c53d411a8dd4f3046a98b02dadde3d983855e02cead3347cfb4
6
+ metadata.gz: 7c4b7131ea9d6b60ff4094d0e34c92484818eb3c608a016932426c83bbcab4a06f4c820399f2fa70cc2a78d9a60a73dcf442ec9ba082bdc095ab539b467e1677
7
+ data.tar.gz: b98c062b4ecc030c37fa1f1ad95126209749c99ec7aba72b616fad380819d55552dc6d4b2a611b94471f79b3748855eefbaab3c9397ab49e9f8e19a6a6afb1ab
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.0 (27-Jan-22)
4
+
5
+ * `export!` method is now taking advantage of multi-threading (as Lokalise API allows to send requests in parallel since January 2022)
6
+ * Test with Ruby 3.1.0
7
+ * Other minor fixes
8
+
3
9
  ## 1.2.1 (26-Nov-21)
4
10
 
5
11
  * Use refinements instead of monkey patching to add hash methods
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # LokaliseManager
2
2
 
3
3
  ![Gem](https://img.shields.io/gem/v/lokalise_manager)
4
- [![Build Status](https://travis-ci.com/bodrovis/lokalise_manager.svg?branch=master)](https://travis-ci.com/github/bodrovis/lokalise_manager)
4
+ ![CI](https://github.com/bodrovis/lokalise_manager/actions/workflows/ci.yml/badge.svg)
5
5
  [![Test Coverage](https://codecov.io/gh/bodrovis/lokalise_manager/graph/badge.svg)](https://codecov.io/gh/bodrovis/lokalise_manager)
6
6
  ![Downloads total](https://img.shields.io/gem/dt/lokalise_manager)
7
7
 
@@ -271,4 +271,4 @@ importer.import!
271
271
 
272
272
  ## License
273
273
 
274
- Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Bodrov](http://bodrovis.tech). License type is [MIT](https://github.com/bodrovis/lokalise_manager/blob/master/LICENSE).
274
+ Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Bodrov](http://bodrovis.tech). License type is [MIT](https://github.com/bodrovis/lokalise_manager/blob/master/LICENSE).
@@ -38,12 +38,13 @@ module LokaliseManager
38
38
  client_opts = [config.api_token, {enable_compression: true}.merge(config.timeouts)]
39
39
  client_method = config.use_oauth2_token ? :oauth_client : :client
40
40
 
41
- @api_client ||= ::Lokalise.send(client_method, *client_opts)
41
+ @api_client = ::Lokalise.send(client_method, *client_opts)
42
42
  end
43
43
 
44
44
  # Resets API client
45
45
  def reset_api_client!
46
- Lokalise.reset_client!
46
+ ::Lokalise.reset_client!
47
+ ::Lokalise.reset_oauth_client!
47
48
  @api_client = nil
48
49
  end
49
50
 
@@ -5,6 +5,7 @@ require 'base64'
5
5
  module LokaliseManager
6
6
  module TaskDefinitions
7
7
  class Exporter < Base
8
+ using LokaliseManager::Utils::ArrayUtils
8
9
  # Performs translation file export to Lokalise and returns an array of queued processes
9
10
  #
10
11
  # @return [Array]
@@ -12,10 +13,13 @@ module LokaliseManager
12
13
  check_options_errors!
13
14
 
14
15
  queued_processes = []
15
- each_file do |full_path, relative_path|
16
- queued_processes << do_upload(full_path, relative_path)
17
- rescue StandardError => e
18
- raise e.class, "Error while trying to upload #{full_path}: #{e.message}"
16
+
17
+ all_files.in_groups_of(6) do |files_group|
18
+ parallel_upload(files_group).each do |thr|
19
+ raise_on_fail thr
20
+
21
+ queued_processes.push thr[:process]
22
+ end
19
23
  end
20
24
 
21
25
  $stdout.print('Task complete!') unless config.silent_mode
@@ -25,18 +29,32 @@ module LokaliseManager
25
29
 
26
30
  private
27
31
 
32
+ def parallel_upload(files_group)
33
+ files_group.compact.map do |file_data|
34
+ do_upload(*file_data)
35
+ end.map(&:value)
36
+ end
37
+
38
+ def raise_on_fail(thread)
39
+ raise thread[:error].class, "Error while trying to upload #{thread[:path]}: #{thread[:error].message}" if thread[:status] == :fail
40
+ end
41
+
28
42
  # Performs the actual file uploading to Lokalise. If the API rate limit is exceeed,
29
43
  # applies exponential backoff
30
44
  def do_upload(f_path, r_path)
31
- with_exp_backoff(config.max_retries_export) do
32
- api_client.upload_file project_id_with_branch, opts(f_path, r_path)
45
+ Thread.new do
46
+ process = with_exp_backoff(config.max_retries_export) do
47
+ api_client.upload_file project_id_with_branch, opts(f_path, r_path)
48
+ end
49
+ {status: :ok, process: process}
50
+ rescue StandardError => e
51
+ {status: :fail, path: f_path, error: e}
33
52
  end
34
53
  end
35
54
 
36
- # Processes each translation file in the specified directory
37
- def each_file
38
- return unless block_given?
39
-
55
+ # Gets translation files from the specified directory
56
+ def all_files
57
+ files = []
40
58
  loc_path = config.locales_path
41
59
  Dir["#{loc_path}/**/*"].sort.each do |f|
42
60
  full_path = Pathname.new f
@@ -45,8 +63,9 @@ module LokaliseManager
45
63
 
46
64
  relative_path = full_path.relative_path_from Pathname.new(loc_path)
47
65
 
48
- yield full_path, relative_path
66
+ files << [full_path, relative_path]
49
67
  end
68
+ files
50
69
  end
51
70
 
52
71
  # Generates export options
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Taken from https://github.com/rails/rails/blob/6bfc637659248df5d6719a86d2981b52662d9b50/activesupport/lib/active_support/core_ext/array/grouping.rb
4
+
5
+ module LokaliseManager
6
+ module Utils
7
+ module ArrayUtils
8
+ refine Array do
9
+ def in_groups_of(number, fill_with = nil, &block)
10
+ if number.to_i <= 0
11
+ raise ArgumentError,
12
+ "Group size must be a positive integer, was #{number.inspect}"
13
+ end
14
+
15
+ if fill_with == false
16
+ collection = self
17
+ else
18
+ padding = (number - (size % number)) % number
19
+ collection = dup.concat(Array.new(padding, fill_with))
20
+ end
21
+
22
+ collection.each_slice(number, &block)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseManager
4
- VERSION = '1.2.1'
4
+ VERSION = '2.0.0'
5
5
  end
@@ -3,6 +3,7 @@
3
3
  require 'yaml'
4
4
 
5
5
  require 'lokalise_manager/utils/hash_utils'
6
+ require 'lokalise_manager/utils/array_utils'
6
7
 
7
8
  require 'lokalise_manager/version'
8
9
  require 'lokalise_manager/error'
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'rspec', '~> 3.6'
33
33
  spec.add_development_dependency 'rubocop', '~> 1.0'
34
34
  spec.add_development_dependency 'rubocop-performance', '~> 1.5'
35
- spec.add_development_dependency 'rubocop-rspec', '~> 2.6.0'
35
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.6'
36
36
  spec.add_development_dependency 'simplecov', '~> 0.16'
37
37
  spec.add_development_dependency 'vcr', '~> 6.0'
38
38
  spec.metadata = {
@@ -24,7 +24,7 @@ describe LokaliseManager::TaskDefinitions::Base do
24
24
  specify '.reset_client!' do
25
25
  expect(described_object.api_client).to be_an_instance_of(Lokalise::Client)
26
26
  described_object.reset_api_client!
27
- current_client = described_object.instance_variable_get '@api_client'
27
+ current_client = described_object.instance_variable_get :@api_client
28
28
  expect(current_client).to be_nil
29
29
  end
30
30
 
@@ -35,17 +35,19 @@ describe LokaliseManager::TaskDefinitions::Exporter do
35
35
  end
36
36
 
37
37
  it 'handles too many requests' do
38
+ allow(described_object.config).to receive(:max_retries_export).and_return(1)
38
39
  allow(described_object).to receive(:sleep).and_return(0)
39
40
 
40
41
  fake_client = instance_double('Lokalise::Client')
42
+ allow(fake_client).to receive(:token).with(any_args).and_return('fake_token')
41
43
  allow(fake_client).to receive(:upload_file).with(any_args).and_raise(Lokalise::Error::TooManyRequests)
42
44
  allow(described_object).to receive(:api_client).and_return(fake_client)
43
45
 
44
- expect(-> { described_object.export! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 2 retries/i)
46
+ expect(-> { described_object.export! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 1 retries/i)
45
47
 
46
- expect(described_object).to have_received(:sleep).exactly(2).times
47
- expect(described_object).to have_received(:api_client).exactly(3).times
48
- expect(fake_client).to have_received(:upload_file).exactly(3).times
48
+ expect(described_object).to have_received(:sleep).exactly(6).times
49
+ expect(described_object).to have_received(:api_client).at_least(12).times
50
+ expect(fake_client).to have_received(:upload_file).exactly(12).times
49
51
  end
50
52
  end
51
53
  end
@@ -108,9 +110,9 @@ describe LokaliseManager::TaskDefinitions::Exporter do
108
110
  end
109
111
  end
110
112
 
111
- describe '.each_file' do
113
+ describe '#all_files' do
112
114
  it 'yield proper arguments' do
113
- expect { |b| described_object.send(:each_file, &b) }.to yield_with_args(
115
+ expect(described_object.send(:all_files).first).to include(
114
116
  Pathname.new(path),
115
117
  Pathname.new(relative_name)
116
118
  )
@@ -180,30 +182,29 @@ describe LokaliseManager::TaskDefinitions::Exporter do
180
182
  end
181
183
  end
182
184
 
183
- describe '.each_file' do
184
- it 'yields every translation file' do
185
- expect { |b| described_object.send(:each_file, &b) }.to yield_successive_args(
186
- [
187
- Pathname.new(path),
188
- Pathname.new(relative_name)
189
- ],
190
- [
191
- Pathname.new(path_ru),
192
- Pathname.new(filename_ru)
193
- ]
185
+ describe '#each_file' do
186
+ it 'returns all files' do
187
+ files = described_object.send(:all_files)
188
+ expect(files[0]).to include(
189
+ Pathname.new(path),
190
+ Pathname.new(relative_name)
191
+ )
192
+ expect(files[1]).to include(
193
+ Pathname.new(path_ru),
194
+ Pathname.new(filename_ru)
194
195
  )
195
196
  end
196
197
 
197
- it 'does not yield files that have to be skipped' do
198
+ it 'does not return files that have to be skipped' do
198
199
  allow(described_object.config).to receive(:skip_file_export).twice.and_return(
199
200
  ->(f) { f.split[1].to_s.include?('ru') }
200
201
  )
201
- expect { |b| described_object.send(:each_file, &b) }.to yield_successive_args(
202
- [
203
- Pathname.new(path),
204
- Pathname.new(relative_name)
205
- ]
202
+ files = described_object.send(:all_files)
203
+ expect(files[0]).to include(
204
+ Pathname.new(path),
205
+ Pathname.new(relative_name)
206
206
  )
207
+ expect(files.count).to eq(1)
207
208
 
208
209
  expect(described_object.config).to have_received(:skip_file_export).twice
209
210
  end
@@ -9,12 +9,16 @@ describe LokaliseManager::TaskDefinitions::Importer do
9
9
  let(:loc_path) { described_object.config.locales_path }
10
10
  let(:project_id) { ENV['LOKALISE_PROJECT_ID'] }
11
11
  let(:local_trans) { "#{Dir.getwd}/spec/fixtures/trans.zip" }
12
- let(:faulty_trans) { "#{Dir.getwd}/spec/fixtures/faulty_trans.zip" }
13
12
 
14
- describe '.open_and_process_zip' do
13
+ describe '#open_and_process_zip' do
15
14
  it 're-raises errors during file processing' do
16
- expect(-> { described_object.send(:open_and_process_zip, faulty_trans) }).
17
- to raise_error(Psych::DisallowedClass, /Error when trying to process fail\.yml/)
15
+ entry = double
16
+ allow(entry).to receive(:name).and_return('fail.yml')
17
+ allow(described_object).to receive(:data_from).with(entry).and_raise(EncodingError)
18
+ expect(-> { described_object.send(:process!, entry) }).
19
+ to raise_error(EncodingError, /Error when trying to process fail\.yml/)
20
+
21
+ expect(described_object).to have_received(:data_from)
18
22
  end
19
23
 
20
24
  it 're-raises errors during file opening' do
@@ -23,7 +27,7 @@ describe LokaliseManager::TaskDefinitions::Importer do
23
27
  end
24
28
  end
25
29
 
26
- describe '.download_files' do
30
+ describe '#download_files' do
27
31
  it 'returns a proper download URL' do
28
32
  response = VCR.use_cassette('download_files') do
29
33
  described_object.send :download_files
@@ -111,9 +115,9 @@ describe LokaliseManager::TaskDefinitions::Importer do
111
115
 
112
116
  expect(result).to be true
113
117
 
114
- expect(count_translations).to eq(8)
115
- expect_file_exist loc_path, 'en.yml'
116
- expect_file_exist loc_path, 'ru.yml'
118
+ expect(count_translations).to eq(24)
119
+ expect_file_exist loc_path, 'en_1.yml'
120
+ expect_file_exist loc_path, 'ru_2.yml'
117
121
  end
118
122
 
119
123
  it 'runs import successfully but does not provide any output when silent_mode is enabled' do
@@ -125,8 +129,8 @@ describe LokaliseManager::TaskDefinitions::Importer do
125
129
  end
126
130
 
127
131
  expect(result).to be true
128
- expect_file_exist loc_path, 'en.yml'
129
- expect_file_exist loc_path, 'ru.yml'
132
+ expect_file_exist loc_path, 'en_1.yml'
133
+ expect_file_exist loc_path, 'ru_2.yml'
130
134
  expect(described_object.config).to have_received(:silent_mode).at_most(1).times
131
135
  end
132
136
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe LokaliseManager::Utils::ArrayUtils do
4
+ using described_class
5
+ let(:arr) { (1..8).to_a }
6
+
7
+ describe '#in_groups_of' do
8
+ it 'raises an exception when the number is less than 1' do
9
+ expect(-> { arr.in_groups_of(-1) }).to raise_error(ArgumentError)
10
+ end
11
+
12
+ it 'uses collection itself if fill_with is false' do
13
+ enum = arr.in_groups_of(5, false)
14
+ enum.next
15
+ expect(enum.next.count).to eq(3)
16
+ end
17
+ end
18
+ end
data/spec/support/vcr.rb CHANGED
@@ -6,6 +6,8 @@ VCR.configure do |c|
6
6
  c.ignore_hosts 'codeclimate.com'
7
7
  c.hook_into :faraday
8
8
  c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
9
- c.filter_sensitive_data('<LOKALISE_TOKEN>') { ENV.fetch('LOKALISE_API_TOKEN') }
9
+ c.filter_sensitive_data('<LOKALISE_TOKEN>') do |_i|
10
+ ENV.fetch('LOKALISE_API_TOKEN')
11
+ end
10
12
  c.configure_rspec_metadata!
11
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lokalise_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Bodrov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-26 00:00:00.000000000 Z
11
+ date: 2022-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-lokalise-api
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 2.6.0
131
+ version: '2.6'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 2.6.0
138
+ version: '2.6'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: simplecov
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -187,6 +187,7 @@ files:
187
187
  - lib/lokalise_manager/task_definitions/base.rb
188
188
  - lib/lokalise_manager/task_definitions/exporter.rb
189
189
  - lib/lokalise_manager/task_definitions/importer.rb
190
+ - lib/lokalise_manager/utils/array_utils.rb
190
191
  - lib/lokalise_manager/utils/hash_utils.rb
191
192
  - lib/lokalise_manager/version.rb
192
193
  - lokalise_manager.gemspec
@@ -195,6 +196,7 @@ files:
195
196
  - spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
196
197
  - spec/lib/lokalise_manager/task_definitions/importer_spec.rb
197
198
  - spec/lib/lokalise_manager_spec.rb
199
+ - spec/lib/utils/array_utils_spec.rb
198
200
  - spec/lib/utils/hash_utils_spec.rb
199
201
  - spec/spec_helper.rb
200
202
  - spec/support/file_manager.rb
@@ -220,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
222
  - !ruby/object:Gem::Version
221
223
  version: '0'
222
224
  requirements: []
223
- rubygems_version: 3.2.31
225
+ rubygems_version: 3.3.5
224
226
  signing_key:
225
227
  specification_version: 4
226
228
  summary: Lokalise integration for Ruby
@@ -230,6 +232,7 @@ test_files:
230
232
  - spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
231
233
  - spec/lib/lokalise_manager/task_definitions/importer_spec.rb
232
234
  - spec/lib/lokalise_manager_spec.rb
235
+ - spec/lib/utils/array_utils_spec.rb
233
236
  - spec/lib/utils/hash_utils_spec.rb
234
237
  - spec/spec_helper.rb
235
238
  - spec/support/file_manager.rb