From 77a8bae7e322d9f5913ddac26b3b16761086dbda Mon Sep 17 00:00:00 2001 From: bodrovis Date: Tue, 26 Oct 2021 17:14:18 +0300 Subject: [PATCH] Version 1.2.0 --- CHANGELOG.md | 5 +++ README.md | 1 + lib/ext/hash.rb | 22 ++++++++++++ lib/lokalise_manager.rb | 2 ++ lib/lokalise_manager/global_config.rb | 7 +++- lib/lokalise_manager/task_definitions/base.rb | 2 +- .../task_definitions/exporter.rb | 2 +- .../task_definitions/importer.rb | 4 +-- lib/lokalise_manager/version.rb | 2 +- spec/lib/ext/hash_spec.rb | 12 +++++++ .../lokalise_manager/global_config_spec.rb | 5 +++ .../task_definitions/base_spec.rb | 5 +++ .../task_definitions/exporter_spec.rb | 21 ++++++++++-- .../task_definitions/importer_spec.rb | 34 +++++++++++++++++-- 14 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 lib/ext/hash.rb create mode 100644 spec/lib/ext/hash_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5a100..8af2118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.2.0 (26-Oct-21) + +* Add a new option `:silent_mode` which is `false` by default. When silent mode is enabled, no debug info will be printed out to `$stdout`. The only exception are the "safe mode" messages — you'll still be prompted to continue if the target directory is not empty. +* Use `#deep_merge` instead of a simple merge when processing options. + ## 1.1.0 (25-Oct-21) * Add a new option `:use_oauth2_token` which is `false` by default. When enabled, you'll be able to provide a token obtained via [OAuth 2 flow](https://docs.lokalise.com/en/articles/5574713-oauth-2) rather than generated via Lokalise profile. The token should still be provided via the `:api_token` option: diff --git a/README.md b/README.md index 791e114..65d7666 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Please don't forget that Lokalise API has rate limiting and you cannot send more * `locales_path` (`string`) — path to the directory with your translation files. Defaults to `"#{Dir.getwd}/locales"`. * `branch` (`string`) — Lokalise project branch to use. Defaults to `""` (no branch is provided). * `timeouts` (`hash`) — set [request timeouts for the Lokalise API client](https://lokalise.github.io/ruby-lokalise-api/additional_info/customization#setting-timeouts). By default, requests have no timeouts: `{open_timeout: nil, timeout: nil}`. Both values are in seconds. +* `silent_mode` (`boolean`) — whether you would like to output debugging information to `$stdout`. By default, after a task is performed, a short notification message will be printed out to the terminal. When set to `false`, notifications won't be printed. Please note that currently `import_safe_mode` has higher priority. Even if you enable `silent_mode`, and the `import_safe_mode` is enabled as well, you will be prompted to confirm the import operation if the target directory is not empty. ### Import config diff --git a/lib/ext/hash.rb b/lib/ext/hash.rb new file mode 100644 index 0000000..424dcfa --- /dev/null +++ b/lib/ext/hash.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Taken from https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/activesupport/lib/active_support/core_ext/hash/deep_merge.rb + +class Hash + def deep_merge(other_hash, &block) + dup.deep_merge!(other_hash, &block) + end + + # Same as +deep_merge+, but modifies +self+. + def deep_merge!(other_hash, &block) + merge!(other_hash) do |key, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + this_val.deep_merge(other_val, &block) + elsif block + yield(key, this_val, other_val) + else + other_val + end + end + end +end diff --git a/lib/lokalise_manager.rb b/lib/lokalise_manager.rb index 35ce147..dc564e7 100644 --- a/lib/lokalise_manager.rb +++ b/lib/lokalise_manager.rb @@ -2,6 +2,8 @@ require 'yaml' +require 'ext/hash' + require 'lokalise_manager/version' require 'lokalise_manager/error' require 'lokalise_manager/global_config' diff --git a/lib/lokalise_manager/global_config.rb b/lib/lokalise_manager/global_config.rb index b0ebd99..c48d06f 100644 --- a/lib/lokalise_manager/global_config.rb +++ b/lib/lokalise_manager/global_config.rb @@ -7,13 +7,18 @@ class << self attr_writer :import_opts, :import_safe_mode, :export_opts, :locales_path, :file_ext_regexp, :skip_file_export, :branch, :timeouts, :translations_loader, :translations_converter, :lang_iso_inferer, - :max_retries_export, :max_retries_import, :use_oauth2_token + :max_retries_export, :max_retries_import, :use_oauth2_token, :silent_mode # Main interface to provide configuration options def config yield self end + # When enabled, won't print any debugging info to $stdout + def silent_mode + @silent_mode || false + end + # When enabled, will use OAuth 2 Lokalise client and will require to provide a token obtained via OAuth 2 flow # rather than via Lokalise profile def use_oauth2_token diff --git a/lib/lokalise_manager/task_definitions/base.rb b/lib/lokalise_manager/task_definitions/base.rb index d8a5de3..e159aea 100644 --- a/lib/lokalise_manager/task_definitions/base.rb +++ b/lib/lokalise_manager/task_definitions/base.rb @@ -23,7 +23,7 @@ def initialize(custom_opts = {}, global_config = LokaliseManager::GlobalConfig) opts[reader.to_sym] = global_config.send(reader) end - @config = OpenStruct.new primary_opts.merge(custom_opts) + @config = OpenStruct.new primary_opts.deep_merge(custom_opts) end # Creates a Lokalise API client diff --git a/lib/lokalise_manager/task_definitions/exporter.rb b/lib/lokalise_manager/task_definitions/exporter.rb index 621d846..10dd158 100644 --- a/lib/lokalise_manager/task_definitions/exporter.rb +++ b/lib/lokalise_manager/task_definitions/exporter.rb @@ -18,7 +18,7 @@ def export! raise e.class, "Error while trying to upload #{full_path}: #{e.message}" end - $stdout.print 'Task complete!' + $stdout.print('Task complete!') unless config.silent_mode queued_processes end diff --git a/lib/lokalise_manager/task_definitions/importer.rb b/lib/lokalise_manager/task_definitions/importer.rb index 9c73ba4..fcea418 100644 --- a/lib/lokalise_manager/task_definitions/importer.rb +++ b/lib/lokalise_manager/task_definitions/importer.rb @@ -14,13 +14,13 @@ def import! check_options_errors! unless proceed_when_safe_mode? - $stdout.print 'Task cancelled!' + $stdout.print('Task cancelled!') unless config.silent_mode return false end open_and_process_zip download_files['bundle_url'] - $stdout.print 'Task complete!' + $stdout.print('Task complete!') unless config.silent_mode true end diff --git a/lib/lokalise_manager/version.rb b/lib/lokalise_manager/version.rb index 5e5bdf8..ecc97c5 100644 --- a/lib/lokalise_manager/version.rb +++ b/lib/lokalise_manager/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module LokaliseManager - VERSION = '1.1.0' + VERSION = '1.2.0' end diff --git a/spec/lib/ext/hash_spec.rb b/spec/lib/ext/hash_spec.rb new file mode 100644 index 0000000..ff56889 --- /dev/null +++ b/spec/lib/ext/hash_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +describe Hash do + let(:h1) { {a: 100, b: 200, c: {c1: 100}} } + let(:h2) { {b: 250, c: {c1: 200}} } + + specify '#deep_merge' do + result = h1.deep_merge(h2) { |_key, this_val, other_val| this_val + other_val } + expect(result[:b]).to eq(450) + expect(result[:c][:c1]).to eq(300) + end +end diff --git a/spec/lib/lokalise_manager/global_config_spec.rb b/spec/lib/lokalise_manager/global_config_spec.rb index b62918f..cfa2e73 100644 --- a/spec/lib/lokalise_manager/global_config_spec.rb +++ b/spec/lib/lokalise_manager/global_config_spec.rb @@ -14,6 +14,11 @@ fake_class.project_id = '123.abc' end + it 'is possible to set silent_mode' do + allow(fake_class).to receive(:silent_mode=).with(true) + fake_class.silent_mode = true + end + it 'is possible to set use_oauth2_token' do allow(fake_class).to receive(:use_oauth2_token=).with(true) fake_class.use_oauth2_token = true diff --git a/spec/lib/lokalise_manager/task_definitions/base_spec.rb b/spec/lib/lokalise_manager/task_definitions/base_spec.rb index ab0d81a..178c591 100644 --- a/spec/lib/lokalise_manager/task_definitions/base_spec.rb +++ b/spec/lib/lokalise_manager/task_definitions/base_spec.rb @@ -19,6 +19,11 @@ expect(obj.config.project_id).to eq('345') expect(obj.config.token).to eq('fake') end + + it 'tes' do + obj = described_class.new import_opts: {filter_langs: ['fr']} + puts obj.config + end end specify '.reset_client!' do diff --git a/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb b/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb index 046aa6a..fad7617 100644 --- a/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb +++ b/spec/lib/lokalise_manager/task_definitions/exporter_spec.rb @@ -24,9 +24,11 @@ describe '.export!' do it 'sends a proper API request and handles rate limiting' do - process = VCR.use_cassette('upload_files_multiple') do - described_object.export! - end.first + process = nil + + VCR.use_cassette('upload_files_multiple') do + expect(-> { process = described_object.export!.first }).to output(/complete!/).to_stdout + end expect(process.project_id).to eq(project_id) expect(process.status).to eq('queued') @@ -58,6 +60,19 @@ end describe '.export!' do + it 'sends a proper API request but does not output anything when silent_mode is enabled' do + allow(described_object.config).to receive(:silent_mode).and_return(true) + + process = nil + + VCR.use_cassette('upload_files') do + expect(-> { process = described_object.export!.first }).not_to output(/complete!/).to_stdout + end + + expect(process.status).to eq('queued') + expect(described_object.config).to have_received(:silent_mode).at_most(1).times + end + it 'sends a proper API request' do process = VCR.use_cassette('upload_files') do described_object.export! diff --git a/spec/lib/lokalise_manager/task_definitions/importer_spec.rb b/spec/lib/lokalise_manager/task_definitions/importer_spec.rb index ce6130b..747d23f 100644 --- a/spec/lib/lokalise_manager/task_definitions/importer_spec.rb +++ b/spec/lib/lokalise_manager/task_definitions/importer_spec.rb @@ -103,8 +103,10 @@ end it 'runs import successfully' do - result = VCR.use_cassette('import') do - described_object.import! + result = nil + + VCR.use_cassette('import') do + expect(-> { result = described_object.import! }).to output(/complete!/).to_stdout end expect(result).to be true @@ -113,6 +115,20 @@ expect_file_exist loc_path, 'en.yml' expect_file_exist loc_path, 'ru.yml' end + + it 'runs import successfully but does not provide any output when silent_mode is enabled' do + allow(described_object.config).to receive(:silent_mode).and_return(true) + result = nil + + VCR.use_cassette('import') do + expect(-> { result = described_object.import! }).not_to output(/complete!/).to_stdout + end + + expect(result).to be true + expect_file_exist loc_path, 'en.yml' + expect_file_exist loc_path, 'ru.yml' + expect(described_object.config).to have_received(:silent_mode).at_most(1).times + end end context 'when directory is not empty and safe mode enabled' do @@ -157,9 +173,21 @@ it 'import halts when a user chooses not to proceed' do allow(safe_mode_obj).to receive(:download_files).at_most(0).times allow($stdin).to receive(:gets).and_return('N') - expect(-> { safe_mode_obj.import! }).to output(/is not empty/).to_stdout + expect(-> { safe_mode_obj.import! }).to output(/cancelled/).to_stdout + + expect(safe_mode_obj).not_to have_received(:download_files) + expect($stdin).to have_received(:gets) + expect(count_translations).to eq(1) + end + + it 'import halts when a user chooses not to proceed and debug info is not printed out when silent_mode is enabled' do + allow(safe_mode_obj.config).to receive(:silent_mode).and_return(true) + allow(safe_mode_obj).to receive(:download_files).at_most(0).times + allow($stdin).to receive(:gets).and_return('N') + expect(-> { safe_mode_obj.import! }).not_to output(/cancelled/).to_stdout expect(safe_mode_obj).not_to have_received(:download_files) + expect(safe_mode_obj.config).to have_received(:silent_mode) expect($stdin).to have_received(:gets) expect(count_translations).to eq(1) end