lokalise_manager 2.2.1 → 3.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 +7 -0
- data/README.md +3 -3
- data/lib/lokalise_manager/error.rb +1 -0
- data/lib/lokalise_manager/global_config.rb +1 -0
- data/lib/lokalise_manager/task_definitions/base.rb +8 -7
- data/lib/lokalise_manager/task_definitions/exporter.rb +6 -3
- data/lib/lokalise_manager/task_definitions/importer.rb +1 -0
- data/lib/lokalise_manager/utils/hash_utils.rb +3 -2
- data/lib/lokalise_manager/version.rb +1 -1
- data/lib/lokalise_manager.rb +13 -8
- data/lokalise_manager.gemspec +3 -2
- data/spec/lib/lokalise_manager/task_definitions/base_spec.rb +11 -7
- data/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb +124 -90
- data/spec/lib/lokalise_manager/task_definitions/importer_spec.rb +8 -12
- data/spec/support/file_manager.rb +3 -1
- metadata +22 -8
- /data/spec/lib/{utils → lokalise_manager/utils}/hash_utils_spec.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f68d621f5413a53e386f1d1f1539e8f824f6f3e90e81c0fb93c71e9e1c271c9a
|
4
|
+
data.tar.gz: ecaf5166531cb24f7fa6162ea11d86f885ead2e911f40543cdd08e717e9731e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 659795e4573dab1751fa00b7d23ed43d6c9b276561fc763341b9a2d72dabadb9e8eeb638a7888d4f736b42e49efcb75a627d12c3b5bc63c9a46f369077dacb2c
|
7
|
+
data.tar.gz: f3681cca401d48512786731538697a2dcac4a7f47ab8d7037a6ce9444308dc4ab71ee34220218654dc71823c1d1a0b3945494015f6f822ac089ca87627a92d1d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.0.0 (11-Mar-22)
|
4
|
+
|
5
|
+
* **Breaking change**: Require Ruby 2.7 or above
|
6
|
+
* **Breaking change (potentially)**: Use ruby-lokalise-api v6. In general, this transition should not affect you if you employ `export!` and `import!` methods only. However, please be aware that ruby-lokalise-api has a few breaking changes [listed in its own changelog](https://lokalise.github.io/ruby-lokalise-api/additional_info/changelog)
|
7
|
+
* Use Zeitwerk loader
|
8
|
+
* Prettify and update source code
|
9
|
+
|
3
10
|
## 2.2.0 (23-Feb-22)
|
4
11
|
|
5
12
|
* Use ruby-lokalise-api v5
|
data/README.md
CHANGED
@@ -70,7 +70,7 @@ The uploading process is multi-threaded.
|
|
70
70
|
`processes` will contain an array of objects responding to the following methods:
|
71
71
|
|
72
72
|
* `#success` — usually returns `true` (to learn more, check documentation for the `:raise_on_export_fail` option below)
|
73
|
-
* `#process` — returns an object (an instance of the `
|
73
|
+
* `#process` — returns an object (an instance of the `RubyLokaliseApi::Resources::QueuedProcess`) representing a [queued background process](https://lokalise.github.io/ruby-lokalise-api/api/queued-processes) as uploading is done in the background on Lokalise.
|
74
74
|
* `#path` — returns an instance of the `Pathname` class which represent the file being uploaded.
|
75
75
|
|
76
76
|
You can perform periodic checks to read the status of the process. Here's a very simple example:
|
@@ -139,7 +139,7 @@ importer = LokaliseManager.importer api_token: '1234abc',
|
|
139
139
|
```
|
140
140
|
|
141
141
|
* `import_safe_mode` (`boolean`) — default to `false`. When this option is enabled, the import task will check whether the directory set with `locales_path` is empty or not. If it is not empty, you will be prompted to continue.
|
142
|
-
* `max_retries_import` (`integer`) — this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, this gem will apply an exponential backoff mechanism with a very simple formula: `2 ** retries`. If the maximum number of retries has been reached, a `
|
142
|
+
* `max_retries_import` (`integer`) — this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, this gem will apply an exponential backoff mechanism with a very simple formula: `2 ** retries`. If the maximum number of retries has been reached, a `RubyLokaliseApi::Error::TooManyRequests` exception will be raised and the operation will be halted.
|
143
143
|
|
144
144
|
### Export config
|
145
145
|
|
@@ -171,7 +171,7 @@ In this case the `export_opts` will have `detect_icu_plurals` set to `true` and
|
|
171
171
|
c.skip_file_export = ->(file) { f.split[1].to_s.include?('fr') }
|
172
172
|
```
|
173
173
|
|
174
|
-
* `max_retries_export` (`integer`) — this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, LokaliseManager will apply an exponential backoff mechanism with a very simple formula: `2 ** retries` (initially `retries` is `0`). If the maximum number of retries has been reached, a `
|
174
|
+
* `max_retries_export` (`integer`) — this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, LokaliseManager will apply an exponential backoff mechanism with a very simple formula: `2 ** retries` (initially `retries` is `0`). If the maximum number of retries has been reached, a `RubyLokaliseApi::Error::TooManyRequests` exception will be raised and the export operation will be halted. By default, LokaliseManager will make up to `5` retries which potentially means `1 + 2 + 4 + 8 + 16 + 32 = 63` seconds of waiting time. If the `max_retries_export` is less than `1`, LokaliseManager will not perform any retries and give up immediately after receiving error 429.
|
175
175
|
* `raise_on_export_fail` (`boolean`) — default is `true`. When this option is enabled, LokaliseManager will re-raise any exceptions that happened during the file uploading. In other words, if any uploading thread raised an exception, your exporting process will exit with an exception. Suppose, you are uploading 12 translation files; these files will be split in 2 groups with 6 files each, and each group will be uploaded in parallel (using threads). However, suppose some exception happens when uploading the first group. By default this exception will be re-raised for the whole process and the script will never try to upload the second group. If you would like to continue uploading even if an exception happened, set the `raise_on_export_fail` to `false`. In this case the `export!` method will return an array with scheduled processes and with information about processes that were not successfully scheduled. This information is represented as an object with three methods: `path` (contains an instance of the `Pathname` class which says which file could not be uploaded), `error` (the actual exception), and `success` (returns `false`). So, you can use the following snippet to check your processes:
|
176
176
|
|
177
177
|
```ruby
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'ruby_lokalise_api'
|
4
4
|
require 'pathname'
|
5
5
|
|
6
6
|
module LokaliseManager
|
7
7
|
module TaskDefinitions
|
8
|
+
# Base class for LokaliseManager task definitions that includes common methods and logic
|
8
9
|
class Base
|
9
10
|
using LokaliseManager::Utils::HashUtils
|
10
11
|
|
@@ -18,7 +19,7 @@ module LokaliseManager
|
|
18
19
|
def initialize(custom_opts = {}, global_config = LokaliseManager::GlobalConfig)
|
19
20
|
primary_opts = global_config.
|
20
21
|
singleton_methods.
|
21
|
-
|
22
|
+
filter { |m| m.to_s.end_with?('=') }.
|
22
23
|
each_with_object({}) do |method, opts|
|
23
24
|
reader = method.to_s.delete_suffix('=')
|
24
25
|
opts[reader.to_sym] = global_config.send(reader)
|
@@ -33,18 +34,18 @@ module LokaliseManager
|
|
33
34
|
|
34
35
|
# Creates a Lokalise API client
|
35
36
|
#
|
36
|
-
# @return [
|
37
|
+
# @return [RubyLokaliseApi::Client]
|
37
38
|
def api_client
|
38
39
|
client_opts = [config.api_token, config.timeouts]
|
39
40
|
client_method = config.use_oauth2_token ? :oauth2_client : :client
|
40
41
|
|
41
|
-
@api_client = ::
|
42
|
+
@api_client = ::RubyLokaliseApi.send(client_method, *client_opts)
|
42
43
|
end
|
43
44
|
|
44
45
|
# Resets API client
|
45
46
|
def reset_api_client!
|
46
|
-
::
|
47
|
-
::
|
47
|
+
::RubyLokaliseApi.reset_client!
|
48
|
+
::RubyLokaliseApi.reset_oauth2_client!
|
48
49
|
@api_client = nil
|
49
50
|
end
|
50
51
|
|
@@ -94,7 +95,7 @@ module LokaliseManager
|
|
94
95
|
retries = 0
|
95
96
|
begin
|
96
97
|
yield
|
97
|
-
rescue
|
98
|
+
rescue RubyLokaliseApi::Error::TooManyRequests => e
|
98
99
|
raise(e.class, "Gave up after #{retries} retries") if retries >= max_retries
|
99
100
|
|
100
101
|
sleep 2**retries
|
@@ -4,6 +4,7 @@ require 'base64'
|
|
4
4
|
|
5
5
|
module LokaliseManager
|
6
6
|
module TaskDefinitions
|
7
|
+
# Exporter class is used when you want to upload translation files from your project to Lokalise
|
7
8
|
class Exporter < Base
|
8
9
|
# Lokalise allows no more than 6 requests per second
|
9
10
|
MAX_THREADS = 6
|
@@ -38,7 +39,9 @@ module LokaliseManager
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def raise_on_fail(thread)
|
41
|
-
|
42
|
+
return if thread.success
|
43
|
+
|
44
|
+
raise(thread.error.class, "Error while trying to upload #{thread.path}: #{thread.error.message}")
|
42
45
|
end
|
43
46
|
|
44
47
|
# Performs the actual file uploading to Lokalise. If the API rate limit is exceeed,
|
@@ -59,7 +62,7 @@ module LokaliseManager
|
|
59
62
|
# Gets translation files from the specified directory
|
60
63
|
def all_files
|
61
64
|
loc_path = config.locales_path
|
62
|
-
Dir["#{loc_path}/**/*"].
|
65
|
+
Dir["#{loc_path}/**/*"].filter_map do |f|
|
63
66
|
full_path = Pathname.new f
|
64
67
|
|
65
68
|
next unless file_matches_criteria? full_path
|
@@ -67,7 +70,7 @@ module LokaliseManager
|
|
67
70
|
relative_path = full_path.relative_path_from Pathname.new(loc_path)
|
68
71
|
|
69
72
|
[full_path, relative_path]
|
70
|
-
end
|
73
|
+
end
|
71
74
|
end
|
72
75
|
|
73
76
|
# Generates export options
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Taken from https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
|
4
|
-
|
5
3
|
module LokaliseManager
|
6
4
|
module Utils
|
5
|
+
# Common helper methods for hashes
|
7
6
|
module HashUtils
|
8
7
|
refine Hash do
|
8
|
+
# Deeply merges two hashes
|
9
|
+
# Taken from https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
|
9
10
|
def deep_merge(other_hash, &block)
|
10
11
|
dup.deep_merge!(other_hash, &block)
|
11
12
|
end
|
data/lib/lokalise_manager.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'zeitwerk'
|
3
4
|
require 'yaml'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
require 'lokalise_manager/version'
|
8
|
-
require 'lokalise_manager/error'
|
9
|
-
require 'lokalise_manager/global_config'
|
10
|
-
require 'lokalise_manager/task_definitions/base'
|
11
|
-
require 'lokalise_manager/task_definitions/importer'
|
12
|
-
require 'lokalise_manager/task_definitions/exporter'
|
6
|
+
loader = Zeitwerk::Loader.for_gem
|
7
|
+
loader.setup
|
13
8
|
|
9
|
+
# LokaliseManager main module that exposes helper methods:
|
10
|
+
#
|
11
|
+
# importer = LokaliseManager.importer api_token: '1234abc', project_id: '123.abc'
|
12
|
+
# exporter = LokaliseManager.exporter api_token: '1234abc', project_id: '123.abc'
|
13
|
+
#
|
14
|
+
# Use the instantiated objects to import or export your translation files:
|
15
|
+
#
|
16
|
+
# importer.import!
|
17
|
+
# exporter.export!
|
18
|
+
#
|
14
19
|
module LokaliseManager
|
15
20
|
class << self
|
16
21
|
# Initializes a new importer client which is used to download
|
data/lokalise_manager.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'https://github.com/bodrovis/lokalise_manager'
|
13
13
|
spec.license = 'MIT'
|
14
14
|
spec.platform = Gem::Platform::RUBY
|
15
|
-
spec.required_ruby_version = '>= 2.
|
15
|
+
spec.required_ruby_version = '>= 2.7'
|
16
16
|
|
17
17
|
spec.files = Dir['README.md', 'LICENSE',
|
18
18
|
'CHANGELOG.md', 'lib/**/*.rb',
|
@@ -23,8 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.extra_rdoc_files = ['README.md']
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_dependency 'ruby-lokalise-api', '~>
|
26
|
+
spec.add_dependency 'ruby-lokalise-api', '~> 6.0'
|
27
27
|
spec.add_dependency 'rubyzip', '~> 2.3'
|
28
|
+
spec.add_dependency 'zeitwerk', '~> 2.4'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'codecov', '~> 0.2'
|
30
31
|
spec.add_development_dependency 'dotenv', '~> 2.5'
|
@@ -22,7 +22,7 @@ describe LokaliseManager::TaskDefinitions::Base do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
specify '.reset_client!' do
|
25
|
-
expect(described_object.api_client).to be_an_instance_of(
|
25
|
+
expect(described_object.api_client).to be_an_instance_of(RubyLokaliseApi::Client)
|
26
26
|
described_object.reset_api_client!
|
27
27
|
current_client = described_object.instance_variable_get :@api_client
|
28
28
|
expect(current_client).to be_nil
|
@@ -63,14 +63,18 @@ describe LokaliseManager::TaskDefinitions::Base do
|
|
63
63
|
it 'raises an error when the API key is not set' do
|
64
64
|
allow(LokaliseManager::GlobalConfig).to receive(:api_token).and_return(nil)
|
65
65
|
|
66
|
-
expect
|
66
|
+
expect do
|
67
|
+
described_object.send(:check_options_errors!)
|
68
|
+
end.to raise_error(LokaliseManager::Error, /API token is not set/i)
|
67
69
|
|
68
70
|
expect(LokaliseManager::GlobalConfig).to have_received(:api_token)
|
69
71
|
end
|
70
72
|
|
71
73
|
it 'returns an error when the project_id is not set' do
|
72
74
|
allow_project_id described_object, nil do
|
73
|
-
expect
|
75
|
+
expect do
|
76
|
+
described_object.send(:check_options_errors!)
|
77
|
+
end.to raise_error(LokaliseManager::Error, /ID is not set/i)
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
@@ -95,8 +99,8 @@ describe LokaliseManager::TaskDefinitions::Base do
|
|
95
99
|
})
|
96
100
|
|
97
101
|
client = described_object.api_client
|
98
|
-
expect(client).to be_an_instance_of(
|
99
|
-
expect(client).not_to be_an_instance_of(
|
102
|
+
expect(client).to be_an_instance_of(RubyLokaliseApi::Client)
|
103
|
+
expect(client).not_to be_an_instance_of(RubyLokaliseApi::OAuth2Client)
|
100
104
|
expect(client.open_timeout).to eq(100)
|
101
105
|
expect(client.timeout).to eq(500)
|
102
106
|
end
|
@@ -106,8 +110,8 @@ describe LokaliseManager::TaskDefinitions::Base do
|
|
106
110
|
|
107
111
|
client = described_object.api_client
|
108
112
|
|
109
|
-
expect(client).to be_an_instance_of(
|
110
|
-
expect(client).not_to be_an_instance_of(
|
113
|
+
expect(client).to be_an_instance_of(RubyLokaliseApi::OAuth2Client)
|
114
|
+
expect(client).not_to be_an_instance_of(RubyLokaliseApi::Client)
|
111
115
|
end
|
112
116
|
end
|
113
117
|
end
|
@@ -14,129 +14,155 @@ describe LokaliseManager::TaskDefinitions::Exporter do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'with many translation files' do
|
17
|
-
before :all do
|
18
|
-
add_translation_files! with_ru: true, additional: 5
|
19
|
-
end
|
20
|
-
|
21
|
-
after :all do
|
22
|
-
rm_translation_files
|
23
|
-
end
|
24
|
-
|
25
17
|
describe '.export!' do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
VCR.use_cassette('upload_files_multiple') do
|
30
|
-
expect { process = described_object.export!.first.process }.to output(/complete!/).to_stdout
|
18
|
+
context 'with no errors' do
|
19
|
+
before do
|
20
|
+
add_translation_files! with_ru: true, additional: 5
|
31
21
|
end
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
after do
|
24
|
+
rm_translation_files
|
25
|
+
end
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
allow(described_object).to receive(:sleep).and_return(0)
|
27
|
+
it 'sends a proper API request and handles rate limiting' do
|
28
|
+
process = nil
|
40
29
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
allow(described_object).to receive(:api_client).and_return(fake_client)
|
30
|
+
VCR.use_cassette('upload_files_multiple') do
|
31
|
+
expect { process = described_object.export!.first.process }.to output(/complete!/).to_stdout
|
32
|
+
end
|
45
33
|
|
46
|
-
|
34
|
+
expect(process.project_id).to eq(project_id)
|
35
|
+
expect(process.status).to eq('queued')
|
36
|
+
end
|
47
37
|
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
it 'handles too many requests but does not re-raise anything when raise_on_export_fail is false' do
|
39
|
+
allow(described_object.config).to receive(:max_retries_export).and_return(1)
|
40
|
+
allow(described_object.config).to receive(:raise_on_export_fail).and_return(false)
|
41
|
+
allow(described_object).to receive(:sleep).and_return(0)
|
42
|
+
|
43
|
+
fake_client = instance_double('RubyLokaliseApi::Client')
|
44
|
+
allow(fake_client).to receive(:token).with(any_args).and_return('fake_token')
|
45
|
+
allow(fake_client).to receive(:upload_file).with(any_args).and_raise(RubyLokaliseApi::Error::TooManyRequests)
|
46
|
+
allow(described_object).to receive(:api_client).and_return(fake_client)
|
47
|
+
processes = []
|
48
|
+
expect { processes = described_object.export! }.not_to raise_error
|
49
|
+
|
50
|
+
expect(processes[0].success).to be false
|
51
|
+
expect(processes[1].error.class).to eq(RubyLokaliseApi::Error::TooManyRequests)
|
52
|
+
expect(processes.count).to eq(7)
|
53
|
+
|
54
|
+
expect(described_object).to have_received(:sleep).exactly(7).times
|
55
|
+
expect(described_object).to have_received(:api_client).at_least(14).times
|
56
|
+
expect(fake_client).to have_received(:upload_file).exactly(14).times
|
57
|
+
end
|
51
58
|
end
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
60
|
+
context 'with errors' do
|
61
|
+
before do
|
62
|
+
add_translation_files! with_ru: true
|
63
|
+
end
|
64
|
+
|
65
|
+
after do
|
66
|
+
rm_translation_files
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'handles too many requests' do
|
70
|
+
allow(described_object.config).to receive(:max_retries_export).and_return(1)
|
71
|
+
allow(described_object).to receive(:sleep).and_return(0)
|
57
72
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
processes = []
|
63
|
-
expect { processes = described_object.export! }.not_to raise_error
|
73
|
+
fake_client = instance_double('RubyLokaliseApi::Client')
|
74
|
+
allow(fake_client).to receive(:token).with(any_args).and_return('fake_token')
|
75
|
+
allow(fake_client).to receive(:upload_file).with(any_args).and_raise(RubyLokaliseApi::Error::TooManyRequests)
|
76
|
+
allow(described_object).to receive(:api_client).and_return(fake_client)
|
64
77
|
|
65
|
-
|
66
|
-
|
67
|
-
|
78
|
+
expect do
|
79
|
+
described_object.export!
|
80
|
+
end.to raise_error(RubyLokaliseApi::Error::TooManyRequests, /Gave up after 1 retries/i)
|
68
81
|
|
69
|
-
|
70
|
-
|
71
|
-
|
82
|
+
expect(described_object).to have_received(:sleep).exactly(2).times
|
83
|
+
expect(described_object).to have_received(:api_client).at_least(4).times
|
84
|
+
expect(fake_client).to have_received(:upload_file).exactly(4).times
|
85
|
+
end
|
72
86
|
end
|
73
87
|
end
|
74
88
|
end
|
75
89
|
|
76
90
|
context 'with one translation file' do
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
after :all do
|
82
|
-
rm_translation_files
|
83
|
-
end
|
84
|
-
|
85
|
-
describe '.export!' do
|
86
|
-
it 'sends a proper API request but does not output anything when silent_mode is enabled' do
|
87
|
-
allow(described_object.config).to receive(:silent_mode).and_return(true)
|
91
|
+
context 'without files' do
|
92
|
+
it 'halts when the API key is not set' do
|
93
|
+
allow(described_object.config).to receive(:api_token).and_return(nil)
|
88
94
|
|
89
|
-
|
95
|
+
expect { described_object.export! }.to raise_error(LokaliseManager::Error, /API token is not set/i)
|
96
|
+
expect(described_object.config).to have_received(:api_token)
|
97
|
+
end
|
90
98
|
|
91
|
-
|
92
|
-
|
99
|
+
it 'halts when the project_id is not set' do
|
100
|
+
allow_project_id described_object, nil do
|
101
|
+
expect { described_object.export! }.to raise_error(LokaliseManager::Error, /ID is not set/i)
|
93
102
|
end
|
94
|
-
|
95
|
-
expect(process.status).to eq('queued')
|
96
|
-
expect(described_object.config).to have_received(:silent_mode).at_most(1).times
|
97
103
|
end
|
104
|
+
end
|
98
105
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
106
|
+
context 'with files' do
|
107
|
+
before do
|
108
|
+
add_translation_files!
|
109
|
+
end
|
103
110
|
|
104
|
-
|
105
|
-
|
111
|
+
after do
|
112
|
+
rm_translation_files
|
106
113
|
end
|
107
114
|
|
108
|
-
|
109
|
-
|
115
|
+
describe '.export!' do
|
116
|
+
it 'sends a proper API request but does not output anything when silent_mode is enabled' do
|
117
|
+
allow(described_object.config).to receive(:silent_mode).and_return(true)
|
110
118
|
|
111
|
-
|
112
|
-
described_object.export!
|
113
|
-
end.first
|
119
|
+
process = nil
|
114
120
|
|
115
|
-
|
116
|
-
|
117
|
-
|
121
|
+
VCR.use_cassette('upload_files') do
|
122
|
+
expect { process = described_object.export!.first.process }.not_to output(/complete!/).to_stdout
|
123
|
+
end
|
118
124
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
expect(process.status).to eq('queued')
|
123
|
-
end
|
125
|
+
expect(process.status).to eq('queued')
|
126
|
+
expect(described_object.config).to have_received(:silent_mode).at_most(1).times
|
127
|
+
end
|
124
128
|
|
125
|
-
|
126
|
-
|
129
|
+
it 'sends a proper API request' do
|
130
|
+
process = VCR.use_cassette('upload_files') do
|
131
|
+
described_object.export!
|
132
|
+
end.first.process
|
127
133
|
|
128
|
-
|
129
|
-
|
130
|
-
|
134
|
+
expect(process.project_id).to eq(project_id)
|
135
|
+
expect(process.status).to eq('queued')
|
136
|
+
end
|
131
137
|
|
132
|
-
|
133
|
-
|
134
|
-
|
138
|
+
it 'sends a proper API request when a different branch is provided' do
|
139
|
+
allow(described_object.config).to receive(:branch).and_return('develop')
|
140
|
+
|
141
|
+
process_data = VCR.use_cassette('upload_files_branch') do
|
142
|
+
described_object.export!
|
143
|
+
end.first
|
144
|
+
|
145
|
+
expect(described_object.config).to have_received(:branch).at_most(2).times
|
146
|
+
expect(process_data.success).to be true
|
147
|
+
expect(process_data.path.to_s).to include('en.yml')
|
148
|
+
|
149
|
+
process = process_data.process
|
150
|
+
expect(process).to be_an_instance_of(RubyLokaliseApi::Resources::QueuedProcess)
|
151
|
+
expect(process.project_id).to eq(project_id)
|
152
|
+
expect(process.status).to eq('queued')
|
135
153
|
end
|
136
154
|
end
|
137
155
|
end
|
138
156
|
|
139
157
|
describe '#all_files' do
|
158
|
+
before do
|
159
|
+
add_translation_files!
|
160
|
+
end
|
161
|
+
|
162
|
+
after do
|
163
|
+
rm_translation_files
|
164
|
+
end
|
165
|
+
|
140
166
|
it 'yield proper arguments' do
|
141
167
|
expect(described_object.send(:all_files).flatten).to include(
|
142
168
|
Pathname.new(path),
|
@@ -146,6 +172,14 @@ describe LokaliseManager::TaskDefinitions::Exporter do
|
|
146
172
|
end
|
147
173
|
|
148
174
|
describe '.opts' do
|
175
|
+
before do
|
176
|
+
add_translation_files!
|
177
|
+
end
|
178
|
+
|
179
|
+
after do
|
180
|
+
rm_translation_files
|
181
|
+
end
|
182
|
+
|
149
183
|
let(:base64content) { Base64.strict_encode64(File.read(path).strip) }
|
150
184
|
|
151
185
|
it 'generates proper options' do
|
@@ -178,11 +212,11 @@ describe LokaliseManager::TaskDefinitions::Exporter do
|
|
178
212
|
let(:filename_ru) { 'ru.yml' }
|
179
213
|
let(:path_ru) { "#{Dir.getwd}/locales/#{filename_ru}" }
|
180
214
|
|
181
|
-
before
|
215
|
+
before do
|
182
216
|
add_translation_files! with_ru: true
|
183
217
|
end
|
184
218
|
|
185
|
-
after
|
219
|
+
after do
|
186
220
|
rm_translation_files
|
187
221
|
end
|
188
222
|
|
@@ -191,7 +225,7 @@ describe LokaliseManager::TaskDefinitions::Exporter do
|
|
191
225
|
allow_project_id described_object, '542886116159f798720dc4.94769464'
|
192
226
|
|
193
227
|
VCR.use_cassette('upload_files_error') do
|
194
|
-
expect { described_object.export! }.to raise_error(
|
228
|
+
expect { described_object.export! }.to raise_error(RubyLokaliseApi::Error::BadRequest, /Unknown `lang_iso`/)
|
195
229
|
end
|
196
230
|
end
|
197
231
|
end
|
@@ -42,7 +42,7 @@ describe LokaliseManager::TaskDefinitions::Importer do
|
|
42
42
|
|
43
43
|
VCR.use_cassette('download_files_error') do
|
44
44
|
expect { described_object.send :download_files }.
|
45
|
-
to raise_error(
|
45
|
+
to raise_error(RubyLokaliseApi::Error::BadRequest, /Invalid `project_id` parameter/)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -52,11 +52,11 @@ describe LokaliseManager::TaskDefinitions::Importer do
|
|
52
52
|
it 'handles too many requests' do
|
53
53
|
allow(described_object).to receive(:sleep).and_return(0)
|
54
54
|
|
55
|
-
fake_client = instance_double('
|
56
|
-
allow(fake_client).to receive(:download_files).and_raise(
|
55
|
+
fake_client = instance_double('RubyLokaliseApi::Client')
|
56
|
+
allow(fake_client).to receive(:download_files).and_raise(RubyLokaliseApi::Error::TooManyRequests)
|
57
57
|
allow(described_object).to receive(:api_client).and_return(fake_client)
|
58
58
|
|
59
|
-
expect { described_object.import! }.to raise_error(
|
59
|
+
expect { described_object.import! }.to raise_error(RubyLokaliseApi::Error::TooManyRequests, /Gave up after 2 retries/i)
|
60
60
|
|
61
61
|
expect(described_object).to have_received(:sleep).exactly(2).times
|
62
62
|
expect(described_object).to have_received(:api_client).exactly(3).times
|
@@ -81,10 +81,9 @@ describe LokaliseManager::TaskDefinitions::Importer do
|
|
81
81
|
context 'when directory is empty' do
|
82
82
|
before do
|
83
83
|
mkdir_locales
|
84
|
-
rm_translation_files
|
85
84
|
end
|
86
85
|
|
87
|
-
after
|
86
|
+
after do
|
88
87
|
rm_translation_files
|
89
88
|
end
|
90
89
|
|
@@ -141,16 +140,13 @@ describe LokaliseManager::TaskDefinitions::Importer do
|
|
141
140
|
import_safe_mode: true
|
142
141
|
end
|
143
142
|
|
144
|
-
before :all do
|
145
|
-
mkdir_locales
|
146
|
-
end
|
147
|
-
|
148
143
|
before do
|
144
|
+
mkdir_locales
|
149
145
|
rm_translation_files
|
150
146
|
add_translation_files!
|
151
147
|
end
|
152
148
|
|
153
|
-
after
|
149
|
+
after do
|
154
150
|
rm_translation_files
|
155
151
|
end
|
156
152
|
|
@@ -183,7 +179,7 @@ describe LokaliseManager::TaskDefinitions::Importer do
|
|
183
179
|
expect(count_translations).to eq(1)
|
184
180
|
end
|
185
181
|
|
186
|
-
it 'import halts when a user chooses
|
182
|
+
it 'import halts when a user chooses to halt and debug info is not printed out when silent_mode is enabled' do
|
187
183
|
allow(safe_mode_obj.config).to receive(:silent_mode).and_return(true)
|
188
184
|
allow(safe_mode_obj).to receive(:download_files).at_most(0).times
|
189
185
|
allow($stdin).to receive(:gets).and_return('N')
|
@@ -4,7 +4,9 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
module FileManager
|
6
6
|
def mkdir_locales
|
7
|
-
|
7
|
+
return if File.directory?(LokaliseManager::GlobalConfig.locales_path)
|
8
|
+
|
9
|
+
FileUtils.mkdir_p(LokaliseManager::GlobalConfig.locales_path)
|
8
10
|
end
|
9
11
|
|
10
12
|
def rm_translation_files
|
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: 3.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: 2022-
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-lokalise-api
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '6.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: zeitwerk
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.4'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: codecov
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,8 +208,8 @@ files:
|
|
194
208
|
- spec/lib/lokalise_manager/task_definitions/base_spec.rb
|
195
209
|
- spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
|
196
210
|
- spec/lib/lokalise_manager/task_definitions/importer_spec.rb
|
211
|
+
- spec/lib/lokalise_manager/utils/hash_utils_spec.rb
|
197
212
|
- spec/lib/lokalise_manager_spec.rb
|
198
|
-
- spec/lib/utils/hash_utils_spec.rb
|
199
213
|
- spec/spec_helper.rb
|
200
214
|
- spec/support/file_manager.rb
|
201
215
|
- spec/support/spec_addons.rb
|
@@ -213,14 +227,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
213
227
|
requirements:
|
214
228
|
- - ">="
|
215
229
|
- !ruby/object:Gem::Version
|
216
|
-
version: 2.
|
230
|
+
version: '2.7'
|
217
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
232
|
requirements:
|
219
233
|
- - ">="
|
220
234
|
- !ruby/object:Gem::Version
|
221
235
|
version: '0'
|
222
236
|
requirements: []
|
223
|
-
rubygems_version: 3.3.
|
237
|
+
rubygems_version: 3.3.8
|
224
238
|
signing_key:
|
225
239
|
specification_version: 4
|
226
240
|
summary: Lokalise integration for Ruby
|
@@ -229,8 +243,8 @@ test_files:
|
|
229
243
|
- spec/lib/lokalise_manager/task_definitions/base_spec.rb
|
230
244
|
- spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
|
231
245
|
- spec/lib/lokalise_manager/task_definitions/importer_spec.rb
|
246
|
+
- spec/lib/lokalise_manager/utils/hash_utils_spec.rb
|
232
247
|
- spec/lib/lokalise_manager_spec.rb
|
233
|
-
- spec/lib/utils/hash_utils_spec.rb
|
234
248
|
- spec/spec_helper.rb
|
235
249
|
- spec/support/file_manager.rb
|
236
250
|
- spec/support/spec_addons.rb
|
File without changes
|