lokalise_manager 7.0.0 → 8.0.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
  SHA256:
3
- metadata.gz: 2f26d5ce781a9d86514c586bfed53b81bda6b5c9016f4277933b02fc74f6ccac
4
- data.tar.gz: 9f41116d698fc3c5bda485f414488d6e2ff89820d560204322e2e5349b69eb03
3
+ metadata.gz: 47771de487435a3744c042598ce442ecd0e7f1c52080cd2f089974efd6176350
4
+ data.tar.gz: f774cae469107a4816ec6267ec1f4a9201e40ec9f74b26396d8e09c0c4dcbd78
5
5
  SHA512:
6
- metadata.gz: 7366a212d37275abcb38970ddc20dcd913ba482acdcd07cb6b5e7aa1f40e4082f3ddbead4ec4cf9dbd663aa88e9f6daa78132dad00e4c2e7f35681091179439c
7
- data.tar.gz: 8e9e04bbe474d0407a41f07580f8405c1ead322c2bf948df2c6cd3db1661eb4e9875b8ca372e051134c32d944c749fb90f91bb93d66d2d19ae83f1197f4e90b0
6
+ metadata.gz: 6a27dd2250f829fc5accad0798504ed18900937bdfec79a1afe046582a381b0c703a6027fb548d98210ef2292096a31beba742e3db814607e9abf935baef31b8
7
+ data.tar.gz: 8f812892db1740c61486f2e16e2579394a51b3f804753aeffecdf6f13a80110de5d8d58a4c7e7730203f0ce02b9f0fd8096a566ceb7cda89344bba7743a8d6fb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 8.0.0 (26-Feb-2026)
4
+
5
+ * **Require Ruby 3.2+**
6
+ * Various code updates and enhancements
7
+
3
8
  ## 7.0.0 (26-Feb-2026)
4
9
 
5
10
  * Strengthen config options
data/README.md CHANGED
@@ -192,7 +192,7 @@ c.export_preprocessor = ->(raw_data, _path) { raw_data.upcase }
192
192
  c.export_filename_generator = ->(_full_path, relative_path) { relative_path.to_s.upcase }
193
193
  ```
194
194
 
195
- * `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.
195
+ * `max_retries_export` (`integer`) — controls how many times LokaliseManager retries an export when the Lokalise API returns HTTP status `429` (Too Many Requests) or when a temporary response parsing error occurs. Retries use exponential backoff based on `2 ** retries`, with a small random jitter added to each delay. If the maximum number of retries is reached, the original exception is raised and the export operation is halted. By default, LokaliseManager performs up to `5` retries, resulting in base delays of `1 + 2 + 4 + 8 + 16 = 31` seconds in total, plus up to approximately `5` seconds of additional jitter. If `max_retries_export` is less than `1`, LokaliseManager does not retry and gives up immediately after the first failure.
196
196
  * `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:
197
197
 
198
198
  ```ruby
@@ -5,9 +5,5 @@ module LokaliseManager
5
5
  # allowing the library to raise specific errors that can be easily identified
6
6
  # and handled separately from other StandardError exceptions in Ruby.
7
7
  class Error < StandardError
8
- # Initializes a new Error object
9
- def initialize(message = '')
10
- super
11
- end
12
8
  end
13
9
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'yaml'
4
+
3
5
  module LokaliseManager
4
6
  # GlobalConfig provides a central place to manage configuration settings for LokaliseManager.
5
7
  # It allows setting various operational parameters such as API tokens, paths, and behavior modifiers.
@@ -31,8 +31,8 @@ module LokaliseManager
31
31
  raise_on_export_fail import_async export_preprocessor export_filename_generator
32
32
  ].freeze
33
33
 
34
- BACKOFF_BASE_SECONDS = 1 # base multiplier (1,2,4,8...)
35
- BACKOFF_CAP_SECONDS = 32 # max sleep cap
34
+ BACKOFF_BASE_SECONDS = 1 # base multiplier (1,2,4,8...)
35
+ BACKOFF_CAP_SECONDS = 32 # max exponential backoff before jitter
36
36
  BACKOFF_JITTER_RANGE = 1.0 # adds rand * range
37
37
 
38
38
  # Initializes a new task object with merged global and custom configurations.
@@ -6,7 +6,7 @@ module LokaliseManager
6
6
  module TaskDefinitions
7
7
  # Handles exporting translation files from a local project to Lokalise.
8
8
  class Exporter < Base
9
- # Maximum number of concurrent uploads to avoid exceeding Lokalise API rate limits.
9
+ # Number of files uploaded concurrently in each batch.
10
10
  MAX_THREADS = 6
11
11
 
12
12
  ProcessResult = Struct.new(:success, :process, :path, :error, keyword_init: true)
@@ -15,7 +15,7 @@ module LokaliseManager
15
15
  #
16
16
  # - Validates configuration.
17
17
  # - Gathers translation files from the project directory.
18
- # - Uploads files to Lokalise in parallel, respecting API rate limits.
18
+ # - Uploads files to Lokalise in parallel and retries rate-limited requests.
19
19
  # - Handles errors and ensures failed uploads are reported.
20
20
  #
21
21
  # @return [Array] An array of process results for each uploaded file.
@@ -71,7 +71,9 @@ module LokaliseManager
71
71
  # @return [QueuedProcess] The process object when completed successfully.
72
72
  # @raise [LokaliseManager::Error] If the process fails or takes too long.
73
73
  def wait_for_async_download(process_id)
74
- (config.max_retries_import + 1).times do |i|
74
+ max_retries = [config.max_retries_import.to_i, 0].max
75
+
76
+ (max_retries + 1).times do |i|
75
77
  process = reload_process(process_id)
76
78
 
77
79
  case process.status
@@ -79,7 +81,7 @@ module LokaliseManager
79
81
  when 'finished' then return process
80
82
  end
81
83
 
82
- sleep_with_backoff(i)
84
+ sleep_with_backoff(i) if i < max_retries
83
85
  end
84
86
 
85
87
  raise LokaliseManager::Error, "Asynchronous download process timed out after #{config.max_retries_import} tries"
@@ -90,7 +92,9 @@ module LokaliseManager
90
92
  # @param process_id [String] The process ID to check.
91
93
  # @return [QueuedProcess] The process object with updated status.
92
94
  def reload_process(process_id)
93
- api_client.queued_process project_id_with_branch, process_id
95
+ fetch_with_retry do
96
+ api_client.queued_process(project_id_with_branch, process_id)
97
+ end
94
98
  end
95
99
 
96
100
  # Extracts and processes files from a ZIP archive.
@@ -146,7 +150,7 @@ module LokaliseManager
146
150
 
147
151
  $stdout.puts "The target directory #{path} is not empty!"
148
152
  $stdout.print 'Enter Y to continue: '
149
- $stdin.gets.strip.upcase == 'Y'
153
+ $stdin.gets&.strip&.upcase == 'Y'
150
154
  end
151
155
 
152
156
  # Opens a local file or downloads a remote file.
@@ -170,16 +174,8 @@ module LokaliseManager
170
174
  #
171
175
  # @yield The operation to retry.
172
176
  # @return [Object] The result of the successful operation.
173
- def fetch_with_retry(&block)
174
- with_exp_backoff(config.max_retries_import, &block)
175
- end
176
-
177
- # Extracts the subdirectory and filename from a given path.
178
- #
179
- # @param entry [String] The file path.
180
- # @return [Array<Pathname, Pathname>] An array containing the subdirectory and filename.
181
- def subdir_and_filename_for(entry)
182
- Pathname.new(entry).split
177
+ def fetch_with_retry(&)
178
+ with_exp_backoff(config.max_retries_import, &)
183
179
  end
184
180
  end
185
181
  end
@@ -6,7 +6,7 @@ module LokaliseManager
6
6
  module HashUtils
7
7
  refine Hash do
8
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
+ # Taken from https://api.rubyonrails.org/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html
10
10
  def deep_merge(other_hash, &block)
11
11
  dup.deep_merge!(other_hash, &block)
12
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseManager
4
- VERSION = '7.0.0'
4
+ VERSION = '8.0.0'
5
5
  end
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/bodrovis/lokalise_manager'
14
14
  spec.license = 'MIT'
15
15
  spec.platform = Gem::Platform::RUBY
16
- spec.required_ruby_version = '>= 3.0'
16
+ spec.required_ruby_version = '>= 3.2'
17
17
 
18
18
  spec.files = Dir['README.md', 'LICENSE',
19
19
  'CHANGELOG.md', 'lib/**/*.rb',
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ['lib']
23
23
 
24
24
  spec.add_dependency 'base64', '~> 0.3.0'
25
- spec.add_dependency 'ruby-lokalise-api', '~> 9.3'
25
+ spec.add_dependency 'ruby-lokalise-api', '~> 10.0'
26
26
  spec.add_dependency 'rubyzip', '>= 2.3', '< 4.0'
27
27
  spec.add_dependency 'zeitwerk', '~> 2.4'
28
28
 
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency 'rubocop-performance', '~> 1.5'
34
34
  spec.add_development_dependency 'rubocop-rake', '~> 0.7'
35
35
  spec.add_development_dependency 'rubocop-rspec', '~> 3.0'
36
- spec.add_development_dependency 'simplecov', '~> 0.22'
36
+ spec.add_development_dependency 'simplecov', '~> 1.0'
37
37
  spec.add_development_dependency 'webmock', '~> 3.18'
38
38
  spec.metadata = {
39
39
  'rubygems_mfa_required' => 'true',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lokalise_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Krukowski
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '9.3'
32
+ version: '10.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '9.3'
39
+ version: '10.0'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rubyzip
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -175,14 +175,14 @@ dependencies:
175
175
  requirements:
176
176
  - - "~>"
177
177
  - !ruby/object:Gem::Version
178
- version: '0.22'
178
+ version: '1.0'
179
179
  type: :development
180
180
  prerelease: false
181
181
  version_requirements: !ruby/object:Gem::Requirement
182
182
  requirements:
183
183
  - - "~>"
184
184
  - !ruby/object:Gem::Version
185
- version: '0.22'
185
+ version: '1.0'
186
186
  - !ruby/object:Gem::Dependency
187
187
  name: webmock
188
188
  requirement: !ruby/object:Gem::Requirement
@@ -234,14 +234,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
234
  requirements:
235
235
  - - ">="
236
236
  - !ruby/object:Gem::Version
237
- version: '3.0'
237
+ version: '3.2'
238
238
  required_rubygems_version: !ruby/object:Gem::Requirement
239
239
  requirements:
240
240
  - - ">="
241
241
  - !ruby/object:Gem::Version
242
242
  version: '0'
243
243
  requirements: []
244
- rubygems_version: 4.0.6
244
+ rubygems_version: 4.0.19
245
245
  specification_version: 4
246
246
  summary: Lokalise integration for Ruby
247
247
  test_files: []