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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -2
- data/lib/lokalise_manager/task_definitions/base.rb +3 -2
- data/lib/lokalise_manager/task_definitions/exporter.rb +30 -11
- data/lib/lokalise_manager/utils/array_utils.rb +27 -0
- data/lib/lokalise_manager/version.rb +1 -1
- data/lib/lokalise_manager.rb +1 -0
- data/lokalise_manager.gemspec +1 -1
- data/spec/lib/lokalise_manager/task_definitions/base_spec.rb +1 -1
- data/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb +24 -23
- data/spec/lib/lokalise_manager/task_definitions/importer_spec.rb +14 -10
- data/spec/lib/utils/array_utils_spec.rb +18 -0
- data/spec/support/vcr.rb +3 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f9ca0fe8caf151e84dcc09f29368bc61b5bc3cdb4341ef5c1b21040b764a17a
|
4
|
+
data.tar.gz: 8c9194a836a1261638f2b22d8d2d7553bfbe605325911cb0c0ecef9332e9084c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
32
|
-
|
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
|
-
#
|
37
|
-
def
|
38
|
-
|
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
|
-
|
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
|
data/lib/lokalise_manager.rb
CHANGED
data/lokalise_manager.gemspec
CHANGED
@@ -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
|
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
|
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
|
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(
|
47
|
-
expect(described_object).to have_received(:api_client).
|
48
|
-
expect(fake_client).to have_received(:upload_file).exactly(
|
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 '
|
113
|
+
describe '#all_files' do
|
112
114
|
it 'yield proper arguments' do
|
113
|
-
expect
|
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 '
|
184
|
-
it '
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
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
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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 '
|
13
|
+
describe '#open_and_process_zip' do
|
15
14
|
it 're-raises errors during file processing' do
|
16
|
-
|
17
|
-
|
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 '
|
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(
|
115
|
-
expect_file_exist loc_path, '
|
116
|
-
expect_file_exist loc_path, '
|
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, '
|
129
|
-
expect_file_exist loc_path, '
|
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>')
|
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:
|
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:
|
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
|
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
|
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.
|
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
|