lokalise_manager 6.0.0 → 6.1.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: f0df6efdcebd1ef7b1f3992a14c997d56859553cf0e1b089d43fe496f479bb1e
4
- data.tar.gz: 762127da9ea96e1b5ad532a5217d0f06556b3d9f61b65f722f79a50a406bba23
3
+ metadata.gz: b3c30a729a77e6a27fef710604138f0fed6f0f48c019bba7cc3017ba9a70f5a8
4
+ data.tar.gz: db85f6500fbbe0e5728c00abb2b51290353b5a6b47a18f160ec2dbaab39a37c5
5
5
  SHA512:
6
- metadata.gz: 42c3990642e4598cc746f1f991d57bceb1793b0de6f8a9ff8b7a33d42194c47a9d84243ee045658a4925dda13d2b6ee63bb0464bd48c8094951b60c2b83e8c9b
7
- data.tar.gz: 156793b3c527be7e88fa4790db675f98958ba80a2be717259f4e3fca937a1369b9660210d8778b727cce1249f9237873507c6800e88eec33d40aac3bf9b42c8a
6
+ metadata.gz: 19a205ecd21020dee1d506e0194be6ca964d0555cb7954d2eeb40ba14ab843870e056fc8e52a7ca306f791398d9e62589f272adc3419040d476e054d7435114d
7
+ data.tar.gz: f768da94e78938fabd30a6080e9b0cfa97510b6b07e35598951e5bd85cd831910f859f70abe5efa33473cd3d5f402349a1cadefe3147135a37a947a95edcdfaf
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.1.0 (19-Feb-2025)
4
+
5
+ * Added support for `import_async` option (default to `false`). When enabled, the [import process will happen in the background](https://developers.lokalise.com/reference/download-files-async) and the gem will use exponential backoff to wait for its completion according to the `max_retries_import` option.
6
+
3
7
  ## 6.0.0 (29-Nov-2024)
4
8
 
5
9
  * **Breaking change**: rename the `timeouts` config method to `additional_client_opts`. It has the same usage but now enables you to set both client timeouts and override the API host to send requests to.
data/README.md CHANGED
@@ -146,6 +146,7 @@ importer = LokaliseManager.importer api_token: '1234abc',
146
146
 
147
147
  * `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.
148
148
  * `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.
149
+ * `import_async` (`boolean`) — default to `false`. Runs the [import in the background](https://developers.lokalise.com/reference/download-files-async) on Lokalise. Uses exponential backoff to wait for completion, based on `max_retries_import`. Useful only for large projects.
149
150
 
150
151
  ### Export config
151
152
 
@@ -10,7 +10,7 @@ module LokaliseManager
10
10
  :file_ext_regexp, :skip_file_export, :branch, :additional_client_opts,
11
11
  :translations_loader, :translations_converter, :lang_iso_inferer,
12
12
  :max_retries_export, :max_retries_import, :use_oauth2_token, :silent_mode,
13
- :raise_on_export_fail
13
+ :raise_on_export_fail, :import_async
14
14
 
15
15
  # Yield self to block for configuration
16
16
  def config
@@ -84,6 +84,11 @@ module LokaliseManager
84
84
  @import_safe_mode.nil? ? false : @import_safe_mode
85
85
  end
86
86
 
87
+ # Return whether import should be performed asynchronously
88
+ def import_async
89
+ @import_async.nil? ? false : @import_async
90
+ end
91
+
87
92
  # Return whether to skip file export based on a lambda condition
88
93
  def skip_file_export
89
94
  @skip_file_export || ->(_) { false }
@@ -5,30 +5,43 @@ require 'pathname'
5
5
 
6
6
  module LokaliseManager
7
7
  module TaskDefinitions
8
- # Base class for LokaliseManager task definitions, providing common methods and logic
9
- # for importer and exporter classes. Handles API client interactions and configuration merging.
8
+ # Base class for LokaliseManager task definitions.
9
+ #
10
+ # Provides shared functionality for Importer and Exporter classes, including:
11
+ # - API client management.
12
+ # - Configuration merging.
13
+ # - File validation helpers.
14
+ # - Exponential backoff for retrying failed API requests.
10
15
  class Base
11
16
  using LokaliseManager::Utils::HashUtils
12
17
 
13
18
  attr_accessor :config
14
19
 
15
- # Initializes a new task object by merging custom and global configurations.
20
+ # Defines exceptions that should trigger a retry with exponential backoff.
16
21
  #
17
- # @param custom_opts [Hash] Custom configurations for specific tasks.
18
- # @param global_config [Object] Reference to the global configuration.
22
+ # - `JSON::ParserError`: Occurs when the API responds with non-JSON content (e.g., HTML due to rate limits).
23
+ # - `RubyLokaliseApi::Error::TooManyRequests`: Raised when too many requests are sent in a short period.
24
+ EXCEPTIONS = [JSON::ParserError, RubyLokaliseApi::Error::TooManyRequests].freeze
25
+
26
+ # Initializes a new task object with merged global and custom configurations.
27
+ #
28
+ # @param custom_opts [Hash] Custom configuration options specific to the task.
29
+ # @param global_config [Object] The global configuration object.
19
30
  def initialize(custom_opts = {}, global_config = LokaliseManager::GlobalConfig)
20
31
  merged_opts = merge_configs(global_config, custom_opts)
21
32
  @config = build_config_class(merged_opts)
22
33
  end
23
34
 
24
- # Retrieves or creates a Lokalise API client based on configuration.
35
+ # Retrieves or initializes the Lokalise API client based on the current configuration.
25
36
  #
26
- # @return [RubyLokaliseApi::Client] Lokalise API client.
37
+ # @return [RubyLokaliseApi::Client] An instance of the Lokalise API client.
27
38
  def api_client
28
39
  @api_client ||= create_api_client
29
40
  end
30
41
 
31
- # Resets API client
42
+ # Resets the API client, clearing cached instances.
43
+ #
44
+ # Useful when switching authentication tokens or handling connection issues.
32
45
  def reset_api_client!
33
46
  ::RubyLokaliseApi.reset_client!
34
47
  ::RubyLokaliseApi.reset_oauth2_client!
@@ -37,7 +50,9 @@ module LokaliseManager
37
50
 
38
51
  private
39
52
 
40
- # Creates a Lokalise API client based on configuration.
53
+ # Creates a new Lokalise API client instance based on the configuration.
54
+ #
55
+ # @return [RubyLokaliseApi::Client] The initialized API client.
41
56
  def create_api_client
42
57
  client_opts = [config.api_token, config.additional_client_opts]
43
58
  client_method = config.use_oauth2_token ? :oauth2_client : :client
@@ -46,6 +61,13 @@ module LokaliseManager
46
61
  end
47
62
 
48
63
  # Merges global and custom configurations.
64
+ #
65
+ # - Extracts all global config values.
66
+ # - Merges them with custom options using a deep merge strategy.
67
+ #
68
+ # @param global_config [Object] The global configuration object.
69
+ # @param custom_opts [Hash] The custom configuration options.
70
+ # @return [Hash] The merged configuration.
49
71
  def merge_configs(global_config, custom_opts)
50
72
  primary_opts = global_config
51
73
  .singleton_methods
@@ -58,13 +80,19 @@ module LokaliseManager
58
80
  primary_opts.deep_merge(custom_opts)
59
81
  end
60
82
 
61
- # Builds a config class with the given options.
83
+ # Constructs a configuration object from a hash of options.
84
+ #
85
+ # Uses a struct to provide attribute-style access to settings.
86
+ #
87
+ # @param all_opts [Hash] The merged configuration options.
88
+ # @return [Struct] A configuration object.
62
89
  def build_config_class(all_opts)
63
- config_klass = Struct.new(*all_opts.keys, keyword_init: true)
64
- config_klass.new(all_opts)
90
+ Struct.new(*all_opts.keys, keyword_init: true).new(all_opts)
65
91
  end
66
92
 
67
- # Checks and validates task options, raising errors if configurations are missing.
93
+ # Validates required configuration options.
94
+ #
95
+ # @raise [LokaliseManager::Error] If required configurations are missing.
68
96
  def check_options_errors!
69
97
  errors = []
70
98
  errors << 'Project ID is not set!' if config.project_id.nil? || config.project_id.empty?
@@ -72,36 +100,39 @@ module LokaliseManager
72
100
  raise LokaliseManager::Error, errors.join(' ') unless errors.empty?
73
101
  end
74
102
 
75
- # Checks if the file has the correct extension based on the configuration.
103
+ # Checks if a file has a valid extension based on the configuration.
76
104
  #
77
- # @param raw_path [String, Pathname] Path to check.
78
- # @return [Boolean] True if the extension matches, false otherwise.
105
+ # @param raw_path [String, Pathname] The file path to check.
106
+ # @return [Boolean] `true` if the file has a valid extension, `false` otherwise.
79
107
  def proper_ext?(raw_path)
80
108
  path = raw_path.is_a?(Pathname) ? raw_path : Pathname.new(raw_path)
81
109
  config.file_ext_regexp.match? path.extname
82
110
  end
83
111
 
84
- # Extracts the directory and filename from a given path.
112
+ # Extracts the subdirectory and filename from a given path.
85
113
  #
86
114
  # @param entry [String] The file path.
87
- # @return [Array] Contains [Pathname, Pathname] representing the directory and filename.
115
+ # @return [Array<Pathname, Pathname>] An array containing the subdirectory and filename.
88
116
  def subdir_and_filename_for(entry)
89
117
  Pathname.new(entry).split
90
118
  end
91
119
 
92
- # Constructs a project identifier string that may include a branch.
120
+ # Constructs a Lokalise project identifier that may include a branch.
93
121
  #
94
- # @return [String] Project identifier potentially including the branch.
122
+ # If a branch is specified, the project ID is formatted as `project_id:branch`.
123
+ #
124
+ # @return [String] The formatted project identifier.
95
125
  def project_id_with_branch
96
126
  config.branch.to_s.strip.empty? ? config.project_id.to_s : "#{config.project_id}:#{config.branch}"
97
127
  end
98
128
 
99
- # In rare cases the server might return HTML instead of JSON.
100
- # It happens when too many requests are being sent.
101
- # Until this is fixed, we revert to this quick'n'dirty solution.
102
- EXCEPTIONS = [JSON::ParserError, RubyLokaliseApi::Error::TooManyRequests].freeze
103
-
104
- # Handles retries with exponential backoff for specific exceptions.
129
+ # Executes a block with exponential backoff for handling API rate limits and temporary failures.
130
+ #
131
+ # Retries the operation for a defined number of attempts, doubling the wait time after each failure.
132
+ #
133
+ # @param max_retries [Integer] Maximum number of retries before giving up.
134
+ # @yield The operation to retry.
135
+ # @return [Object] The result of the block if successful.
105
136
  def with_exp_backoff(max_retries)
106
137
  return unless block_given?
107
138
 
@@ -4,14 +4,19 @@ require 'base64'
4
4
 
5
5
  module LokaliseManager
6
6
  module TaskDefinitions
7
- # Class to handle exporting translation files from a local project to Lokalise.
7
+ # Handles exporting translation files from a local project to Lokalise.
8
8
  class Exporter < Base
9
9
  # Maximum number of concurrent uploads to avoid exceeding Lokalise API rate limits.
10
10
  MAX_THREADS = 6
11
11
 
12
- # Exports translation files to Lokalise and handles any necessary concurrency and error checking.
12
+ # Exports translation files to Lokalise in batches to optimize performance.
13
13
  #
14
- # @return [Array] An array of process statuses for each file uploaded.
14
+ # - Validates configuration.
15
+ # - Gathers translation files from the project directory.
16
+ # - Uploads files to Lokalise in parallel, respecting API rate limits.
17
+ # - Handles errors and ensures failed uploads are reported.
18
+ #
19
+ # @return [Array] An array of process results for each uploaded file.
15
20
  def export!
16
21
  check_options_errors!
17
22
 
@@ -28,10 +33,10 @@ module LokaliseManager
28
33
 
29
34
  private
30
35
 
31
- # Handles parallel uploads of a group of files, utilizing threading.
36
+ # Uploads a group of files in parallel using threads.
32
37
  #
33
- # @param files_group [Array] Group of files to be uploaded.
34
- # @return [Array] Array of threads handling the file uploads.
38
+ # @param files_group [Array] List of file path pairs (full and relative).
39
+ # @return [Array] Array of results from the upload process.
35
40
  def parallel_upload(files_group)
36
41
  files_group.map do |file_data|
37
42
  Thread.new { do_upload(*file_data) }
@@ -47,11 +52,13 @@ module LokaliseManager
47
52
  raise thread.error.class, "Error while trying to upload #{thread.path}: #{thread.error.message}"
48
53
  end
49
54
 
50
- # Performs the actual upload of a file to Lokalise.
55
+ # Uploads a single file to Lokalise.
56
+ #
57
+ # Uses exponential backoff to retry failed uploads.
51
58
  #
52
- # @param f_path [Pathname] Full path to the file.
53
- # @param r_path [Pathname] Relative path of the file within the project.
54
- # @return [Struct] A struct with the success status, process details, and any error information.
59
+ # @param f_path [Pathname] Full file path.
60
+ # @param r_path [Pathname] Relative file path within the project.
61
+ # @return [Struct] Struct containing upload status, process details, and error (if any).
55
62
  def do_upload(f_path, r_path)
56
63
  proc_klass = Struct.new(:success, :process, :path, :error, keyword_init: true)
57
64
 
@@ -64,14 +71,14 @@ module LokaliseManager
64
71
  proc_klass.new(success: false, path: f_path, error: e)
65
72
  end
66
73
 
67
- # Prints a completion message to standard output.
74
+ # Prints a message indicating that the export process is complete.
68
75
  def print_completion_message
69
76
  $stdout.puts 'Task complete!'
70
77
  end
71
78
 
72
- # Retrieves all translation files from the specified directory.
79
+ # Collects all translation files that match export criteria.
73
80
  #
74
- # @return [Array] Array of [Pathname, Pathname] pairs representing full and relative paths.
81
+ # @return [Array] List of [Pathname, Pathname] pairs (full and relative paths).
75
82
  def all_files
76
83
  loc_path = Pathname.new(config.locales_path)
77
84
 
@@ -84,11 +91,13 @@ module LokaliseManager
84
91
  end
85
92
  end
86
93
 
87
- # Generates options for file upload to Lokalise.
94
+ # Constructs upload options for a file.
88
95
  #
89
- # @param full_p [Pathname] Full path to the file.
96
+ # Reads and encodes the file content in Base64 before sending it to Lokalise.
97
+ #
98
+ # @param full_p [Pathname] Full file path.
90
99
  # @param relative_p [Pathname] Relative path within the project.
91
- # @return [Hash] Options for the Lokalise API upload.
100
+ # @return [Hash] Upload options including encoded content, filename, and language.
92
101
  def opts(full_p, relative_p)
93
102
  content = File.read(full_p).strip
94
103
 
@@ -99,10 +108,14 @@ module LokaliseManager
99
108
  }.merge(config.export_opts)
100
109
  end
101
110
 
102
- # Checks whether the specified file meets the criteria for upload.
111
+ # Determines if a file meets the criteria for export.
112
+ #
113
+ # - Must be a valid file (not a directory).
114
+ # - Must match the allowed file extensions.
115
+ # - Must not be explicitly skipped by `skip_file_export`.
103
116
  #
104
- # @param full_path [Pathname] Full path to the file.
105
- # @return [Boolean] True if the file matches criteria, false otherwise.
117
+ # @param full_path [Pathname] Full file path.
118
+ # @return [Boolean] `true` if the file should be uploaded, `false` otherwise.
106
119
  def file_matches_criteria?(full_path)
107
120
  full_path.file? && proper_ext?(full_path) &&
108
121
  !config.skip_file_export.call(full_path)
@@ -6,13 +6,16 @@ require 'fileutils'
6
6
 
7
7
  module LokaliseManager
8
8
  module TaskDefinitions
9
- # The Importer class handles downloading translation files from Lokalise
10
- # and importing them into the specified project directory.
9
+ # Handles downloading translation files from Lokalise and importing them into the project directory.
11
10
  class Importer < Base
12
- # Initiates the import process by checking configuration, ensuring safe mode conditions,
13
- # downloading files, and processing them. Outputs task completion status.
11
+ # Initiates the translation import process.
14
12
  #
15
- # @return [Boolean] Returns true if the import completes successfully, false if cancelled.
13
+ # - Validates configuration.
14
+ # - Ensures safe mode conditions are met.
15
+ # - Downloads translation files.
16
+ # - Extracts and processes the downloaded files.
17
+ #
18
+ # @return [Boolean] Returns `true` if the import completes successfully, `false` if cancelled.
16
19
  def import!
17
20
  check_options_errors!
18
21
 
@@ -21,7 +24,7 @@ module LokaliseManager
21
24
  return false
22
25
  end
23
26
 
24
- open_and_process_zip download_files.bundle_url
27
+ open_and_process_zip(download_bundle)
25
28
 
26
29
  $stdout.print('Task complete!') unless config.silent_mode
27
30
  true
@@ -29,18 +32,67 @@ module LokaliseManager
29
32
 
30
33
  private
31
34
 
32
- # Downloads translation files from Lokalise, handling retries and errors using exponential backoff.
35
+ # Retrieves the download URL of the translation files.
36
+ #
37
+ # If `import_async` is enabled, initiates an asynchronous download process.
38
+ #
39
+ # @return [String] The URL of the downloaded translation bundle.
40
+ def download_bundle
41
+ return download_files.bundle_url unless config.import_async
42
+
43
+ process = download_files_async
44
+ process.details['download_url'] || process.details[:download_url]
45
+ end
46
+
47
+ # Downloads translation files from Lokalise using a synchronous request.
48
+ #
49
+ # Handles retries and errors using exponential backoff.
33
50
  #
34
- # @return [Hash] Returns the response from Lokalise API containing download details.
51
+ # @return [Hash] The response from Lokalise API containing download details.
35
52
  def download_files
36
- with_exp_backoff(config.max_retries_import) do
37
- api_client.download_files project_id_with_branch, config.import_opts
53
+ fetch_with_retry { api_client.download_files(project_id_with_branch, config.import_opts) }
54
+ end
55
+
56
+ # Initiates an asynchronous download request for translation files.
57
+ #
58
+ # Waits for the process to complete before proceeding.
59
+ #
60
+ # @return [QueuedProcess] The completed async download process object.
61
+ def download_files_async
62
+ process = fetch_with_retry { api_client.download_files_async(project_id_with_branch, config.import_opts) }
63
+ wait_for_async_download(process.process_id)
64
+ end
65
+
66
+ # Waits for an asynchronous translation file download process to finish.
67
+ #
68
+ # Uses exponential backoff for polling the process status.
69
+ #
70
+ # @param process_id [String] The ID of the asynchronous process.
71
+ # @return [QueuedProcess] The process object when completed successfully.
72
+ # @raise [LokaliseManager::Error] If the process fails or takes too long.
73
+ def wait_for_async_download(process_id)
74
+ (config.max_retries_import + 1).times do |i|
75
+ sleep 2**i
76
+ process = reload_process(process_id)
77
+
78
+ case process.status
79
+ when 'failed' then raise LokaliseManager::Error, 'Asynchronous download process failed'
80
+ when 'finished' then return process
81
+ end
38
82
  end
39
- rescue StandardError => e
40
- raise e.class, "There was an error when trying to download files: #{e.message}"
83
+
84
+ raise LokaliseManager::Error, "Asynchronous download process timed out after #{config.max_retries_import} tries"
85
+ end
86
+
87
+ # Retrieves the latest status of an asynchronous download process.
88
+ #
89
+ # @param process_id [String] The process ID to check.
90
+ # @return [QueuedProcess] The process object with updated status.
91
+ def reload_process(process_id)
92
+ api_client.queued_process project_id_with_branch, process_id
41
93
  end
42
94
 
43
- # Opens a ZIP archive from a given path and processes each entry if it matches the required file extension.
95
+ # Extracts and processes files from a ZIP archive.
44
96
  #
45
97
  # @param path [String] The URL or local path to the ZIP archive.
46
98
  def open_and_process_zip(path)
@@ -51,25 +103,29 @@ module LokaliseManager
51
103
  raise e.class, "Error processing ZIP file: #{e.message}"
52
104
  end
53
105
 
54
- # Processes a single ZIP entry by extracting data, determining the correct directory structure,
55
- # and writing the data to the appropriate file.
106
+ # Extracts data from a ZIP entry and writes it to the correct directory.
107
+ #
108
+ # - Extracts file content.
109
+ # - Determines the appropriate subdirectory and filename.
110
+ # - Writes the processed file.
56
111
  #
57
112
  # @param zip_entry [Zip::Entry] The ZIP entry to process.
58
113
  def process_entry(zip_entry)
59
114
  data = data_from(zip_entry)
60
- subdir, filename = subdir_and_filename_for(zip_entry.name)
61
- full_path = File.join(config.locales_path, subdir)
62
- FileUtils.mkdir_p full_path
115
+ full_path = File.join(config.locales_path, *subdir_and_filename_for(zip_entry.name))
116
+ FileUtils.mkdir_p File.dirname(full_path)
63
117
 
64
- File.write(File.join(full_path, filename), config.translations_converter.call(data), mode: 'w+:UTF-8')
118
+ File.write(full_path, config.translations_converter.call(data), mode: 'w+:UTF-8')
65
119
  rescue StandardError => e
66
120
  raise e.class, "Error processing entry #{zip_entry.name}: #{e.message}"
67
121
  end
68
122
 
69
- # Determines if the import should proceed based on the safe mode setting and the content of the target directory.
70
- # In safe mode, the directory must be empty, or the user must confirm continuation.
123
+ # Checks whether the import should proceed under safe mode constraints.
124
+ #
125
+ # If `import_safe_mode` is enabled, the target directory must be empty,
126
+ # or the user must explicitly confirm continuation.
71
127
  #
72
- # @return [Boolean] Returns true if the import should proceed, false otherwise.
128
+ # @return [Boolean] `true` if the import should proceed, `false` otherwise.
73
129
  def proceed_when_safe_mode?
74
130
  return true unless config.import_safe_mode && !Dir.empty?(config.locales_path.to_s)
75
131
 
@@ -78,21 +134,32 @@ module LokaliseManager
78
134
  $stdin.gets.strip.upcase == 'Y'
79
135
  end
80
136
 
81
- # Opens a local file or a remote URL using the provided path, safely handling different path schemes.
137
+ # Opens a local file or downloads a remote file.
82
138
  #
83
- # @param path [String] The path to the file, either a local path or a URL.
84
- # @return [IO] Returns an IO object for the file.
139
+ # @param path [String] The file path (local or URL).
140
+ # @return [IO] An IO object for reading the file.
85
141
  def open_file_or_remote(path)
86
142
  uri = URI.parse(path)
87
143
  uri.scheme&.start_with?('http') ? uri.open : File.open(path)
88
144
  end
89
145
 
90
- # Loads translations from the ZIP file.
146
+ # Reads and processes data from a ZIP file entry.
91
147
  #
92
- # @param zip_entry [Zip::Entry] The ZIP entry to process.
148
+ # @param zip_entry [Zip::Entry] The ZIP entry containing translation data.
149
+ # @return [String] The extracted file content.
93
150
  def data_from(zip_entry)
94
151
  config.translations_loader.call zip_entry.get_input_stream.read
95
152
  end
153
+
154
+ # Executes a block with exponential backoff for retrying failed operations.
155
+ #
156
+ # @yield The operation to retry.
157
+ # @return [Object] The result of the successful operation.
158
+ def fetch_with_retry(&block)
159
+ with_exp_backoff(config.max_retries_import, &block)
160
+ rescue StandardError => e
161
+ raise e.class, "Error during file download: #{e.message}"
162
+ end
96
163
  end
97
164
  end
98
165
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseManager
4
- VERSION = '6.0.0'
4
+ VERSION = '6.1.0'
5
5
  end
@@ -6,33 +6,52 @@ require 'yaml'
6
6
  loader = Zeitwerk::Loader.for_gem
7
7
  loader.setup
8
8
 
9
- # The LokaliseManager module provides functionalities to import and export translation
10
- # files to and from the Lokalise TMS. It simplifies interactions with the Lokalise API
11
- # by providing a straightforward interface to instantiate importers and exporters.
9
+ # The `LokaliseManager` module provides a high-level interface for importing and exporting
10
+ # translation files between a Ruby project and the Lokalise TMS.
12
11
  #
13
- # Example:
14
- # importer = LokaliseManager.importer(api_token: '1234abc', project_id: '123.abc')
15
- # exporter = LokaliseManager.exporter(api_token: '1234abc', project_id: '123.abc')
16
- # importer.import!
17
- # exporter.export!
12
+ # This module simplifies interactions with the Lokalise API by exposing two factory methods:
13
+ # - `importer` Instantiates an importer for fetching translations from Lokalise.
14
+ # - `exporter` Instantiates an exporter for uploading translations to Lokalise.
15
+ #
16
+ # ## Example Usage:
17
+ #
18
+ # ```ruby
19
+ # importer = LokaliseManager.importer(api_token: '1234abc', project_id: '123.abc')
20
+ # exporter = LokaliseManager.exporter(api_token: '1234abc', project_id: '123.abc')
21
+ #
22
+ # importer.import!
23
+ # exporter.export!
24
+ # ```
18
25
  #
19
26
  module LokaliseManager
20
27
  class << self
21
- # Creates an importer object for downloading translation files from Lokalise.
28
+ # Instantiates an importer for retrieving translation files from Lokalise.
22
29
  #
23
- # @param custom_opts [Hash] Custom options for the importer (e.g., API token and project ID).
24
- # @param global_config [Object] Global configuration settings, defaults to LokaliseManager::GlobalConfig.
25
- # @return [LokaliseManager::TaskDefinitions::Importer] An instance of the importer.
30
+ # @param custom_opts [Hash] Custom options for the importer (e.g., `api_token`, `project_id`).
31
+ # @param global_config [Object] The global configuration object (defaults to `LokaliseManager::GlobalConfig`).
32
+ # @return [LokaliseManager::TaskDefinitions::Importer] An `Importer` instance for downloading translations.
33
+ #
34
+ # ## Example:
35
+ # ```ruby
36
+ # importer = LokaliseManager.importer(api_token: 'xyz', project_id: '456.abc')
37
+ # importer.import!
38
+ # ```
26
39
  #
27
40
  def importer(custom_opts = {}, global_config = LokaliseManager::GlobalConfig)
28
41
  LokaliseManager::TaskDefinitions::Importer.new custom_opts, global_config
29
42
  end
30
43
 
31
- # Creates an exporter object for uploading translation files to Lokalise.
44
+ # Instantiates an exporter for uploading translation files to Lokalise.
45
+ #
46
+ # @param custom_opts [Hash] Custom options for the exporter (e.g., `api_token`, `project_id`).
47
+ # @param global_config [Object] The global configuration object (defaults to `LokaliseManager::GlobalConfig`).
48
+ # @return [LokaliseManager::TaskDefinitions::Exporter] An `Exporter` instance for uploading translations.
32
49
  #
33
- # @param custom_opts [Hash] Custom options for the exporter (e.g., API token and project ID).
34
- # @param global_config [Object] Global configuration settings, defaults to LokaliseManager::GlobalConfig.
35
- # @return [LokaliseManager::TaskDefinitions::Exporter] An instance of the exporter.
50
+ # ## Example:
51
+ # ```ruby
52
+ # exporter = LokaliseManager.exporter(api_token: 'xyz', project_id: '456.abc')
53
+ # exporter.export!
54
+ # ```
36
55
  #
37
56
  def exporter(custom_opts = {}, global_config = LokaliseManager::GlobalConfig)
38
57
  LokaliseManager::TaskDefinitions::Exporter.new custom_opts, global_config
@@ -23,6 +23,7 @@ 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 'base64', '~> 0.2.0'
26
27
  spec.add_dependency 'ruby-lokalise-api', '~> 9.3'
27
28
  spec.add_dependency 'rubyzip', '~> 2.3'
28
29
  spec.add_dependency 'zeitwerk', '~> 2.4'
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lokalise_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Krukowski
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-11-29 00:00:00.000000000 Z
10
+ date: 2025-02-19 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.2.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.2.0
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: ruby-lokalise-api
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -223,7 +236,6 @@ licenses:
223
236
  - MIT
224
237
  metadata:
225
238
  rubygems_mfa_required: 'true'
226
- post_install_message:
227
239
  rdoc_options: []
228
240
  require_paths:
229
241
  - lib
@@ -238,8 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
250
  - !ruby/object:Gem::Version
239
251
  version: '0'
240
252
  requirements: []
241
- rubygems_version: 3.5.23
242
- signing_key:
253
+ rubygems_version: 3.6.3
243
254
  specification_version: 4
244
255
  summary: Lokalise integration for Ruby
245
256
  test_files: []