lokalise_rails 0.1.0 → 1.2.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: ec64235246d319002907d0e605f89196248a50698bb3a7f50f0bebdd706cf7d5
4
- data.tar.gz: 8ae1100974fe1c4672a0ad264e83f70cdd424e77ae7a28249b921a26b086296b
3
+ metadata.gz: 02b78ecae0b5dbf76599249606858c5b24e31fc9826f8795feb34abac9d5ffb4
4
+ data.tar.gz: b7bc51d45b689181ae0d3d5366f507ae0e43c878c4ab55979ba54d7089eb49f7
5
5
  SHA512:
6
- metadata.gz: e77be0ceee5396a3343855f6fb917dfbf8d68568497f9afa0700c73a9fbbf1f7aa6ff1c07ff36c33c8ee55c83b2a77bb3cdd6fc012fe90e038c186b157eaac42
7
- data.tar.gz: 8655ee9cfd99362515d2acf669669b9ed8017590e3b0cd695ac6ac51826944d0945dba2f363ea7c269d284664237264be6e3ec9fc6989886799113549b4d9dfd
6
+ metadata.gz: 838ddae7af99842dbc4a7ce900c8b02a07571ff9c561e642e3bac6f92dbaabd9132f775b0ff1877ffd18fc20c1bf84ec3f7792139bad0c9fc97dec1d03389e64
7
+ data.tar.gz: 79c0314752c8e48b552eb78c564d24da0cd14fa41b1195909d8d06ca81913322fefa56a696f3c20d1c53c51aa16feb731c85f6fdd860242c98ad8b018b9c68ae
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 (11-Nov-20)
4
+
5
+ * New option `translations_loader`
6
+ * New option `translations_converter`
7
+ * New option `lang_iso_inferer`
8
+
9
+ ## 1.1.0 (23-Oct-20)
10
+
11
+ * New option `branch`
12
+ * New option `timeouts`
13
+ * New method `.reset_api_client!` for the task definitions
14
+
15
+ ## 1.0.1 (14-Oct-20)
16
+
17
+ * Minor bug fixes and spec updates
18
+
19
+ ## 1.0.0 (01-Oct-20)
20
+
21
+ * Added export feature
22
+ * More convenient configuration and additional options
23
+ * Other major enhancements
24
+
25
+ ## 0.2.0 (26-Sep-20)
26
+
27
+ * Allow to override options properly
28
+
3
29
  ## 0.1.0 (26-Sep-20)
4
30
 
5
31
  * Initial (proper) release
data/README.md CHANGED
@@ -1,43 +1,50 @@
1
1
  # LokaliseRails
2
2
 
3
- <!-- [![Gem Version](https://badge.fury.io/rb/ruby-lokalise-api.svg)](https://badge.fury.io/rb/ruby-lokalise-api) -->
3
+ [![Gem Version](https://badge.fury.io/rb/lokalise_rails.svg)](https://badge.fury.io/rb/lokalise_rails)
4
4
  [![Build Status](https://travis-ci.org/bodrovis/lokalise_rails.svg?branch=master)](https://travis-ci.org/bodrovis/lokalise_rails)
5
5
  [![Test Coverage](https://codecov.io/gh/bodrovis/lokalise_rails/graph/badge.svg)](https://codecov.io/gh/bodrovis/lokalise_rails)
6
6
 
7
7
  This gem provides [Lokalise](http://lokalise.com) integration for Ruby on Rails and allows to exchange translation files easily. It relies on [ruby-lokalise-api](https://lokalise.github.io/ruby-lokalise-api) to send APIv2 requests.
8
8
 
9
+ *If you would like to know how this gem was built, check out the ["How to create a Ruby gem" series at Lokalise blog](https://lokalise.com/blog/create-a-ruby-gem-basics/).*
10
+
9
11
  ## Getting started
10
12
 
11
13
  ### Requirements
12
14
 
13
- This gem requires Ruby 2.5+ and Rails 5.1+. It might work with older versions of Rails though. You will also need to setup a Lokalise account and a translation project. Finally, you will need to generate a read/write API token at your Lokalise profile.
15
+ This gem requires Ruby 2.5+ and Rails 5.1+. It might work with older versions of Rails though. You will also need to [setup a Lokalise account](https://app.lokalise.com/signup) and create a [translation project](https://docs.lokalise.com/en/articles/1400460-projects). Finally, you will need to generate a [read/write API token](https://docs.lokalise.com/en/articles/1929556-api-tokens) at your Lokalise profile.
14
16
 
15
17
  ### Installation
16
18
 
17
- Add the gem to your `Gemfile`
19
+ Add the gem to your `Gemfile`:
18
20
 
19
21
  ```ruby
20
22
  gem 'lokalise_rails'
21
23
  ```
22
24
 
23
- and run
25
+ and run:
24
26
 
25
27
  ```
26
28
  bundle install
27
29
  rails g lokalise_rails:install
28
30
  ```
29
31
 
30
- The latter command will generate a new initializer `lokalise_rails.rb` looking like this:
32
+ The latter command will generate a new config file `config/lokalise_rails.rb` looking like this:
31
33
 
32
34
  ```ruby
33
35
  require 'lokalise_rails'
34
36
 
35
- LokaliseRails.api_token = ENV['LOKALISE_API_TOKEN']
36
- LokaliseRails.project_id = ENV['LOKALISE_PROJECT_ID']
37
- # ...
37
+ LokaliseRails.config do |c|
38
+ c.api_token = ENV['LOKALISE_API_TOKEN']
39
+ c.project_id = ENV['LOKALISE_PROJECT_ID']
40
+
41
+ # ...other options
42
+ end
38
43
  ```
39
44
 
40
- You have to provide `api_token` and `project_id` to proceed. [Other options can be customized as well (see below)](https://github.com/bodrovis/lokalise_rails#import-settings) but they have sensible defaults.
45
+ You have to provide `api_token` and `project_id` to proceed. `project_id` can be found in your Lokalise project settings.
46
+
47
+ [Other options can be customized as well (see below)](https://github.com/bodrovis/lokalise_rails#import-settings) but they have sensible defaults.
41
48
 
42
49
  ## Importing translations from Lokalise
43
50
 
@@ -47,31 +54,50 @@ To import translations from the specified Lokalise project to your Rails app, ru
47
54
  rails lokalise_rails:import
48
55
  ```
49
56
 
50
- Please note that any existing files inside the `locales` directory will be overwritten! You may enable [safe mode](https://github.com/bodrovis/lokalise_rails#import-settings) to check whether the folder is empty or not.
57
+ Please note that any duplicating files inside the `locales` directory (or any other directory that you've specified in the options) will be overwritten! You may enable [safe mode](https://github.com/bodrovis/lokalise_rails#import-settings) to check whether the folder is empty or not.
51
58
 
52
- ## Configuration
59
+ ## Exporting translations to Lokalise
53
60
 
54
- Options are specified in the `config/initializers/lokalise_rails.rb` file.
61
+ To export translations from your Rails app to the specified Lokalise project, run the following command:
55
62
 
56
- ### Global settings
63
+ ```
64
+ rails lokalise_rails:export
65
+ ```
66
+
67
+ ## Running tasks programmatically
57
68
 
58
- * `LokaliseRails.api_token` (`string`, required) - Lokalise API token with read/write permissions.
59
- * `LokaliseRails.project_id` (`string`, required) - Lokalise project ID. You must have import/export permissions in the specified project.
60
- * `locales_path` - method returning a string with the path to your translation files. Defaults to `"#{Rails.root}/config/locales"`. To provide a custom path, override the method inside the initializer (make sure that the path exists!):
69
+ You can also run the import and export tasks from the Rails app:
61
70
 
62
71
  ```ruby
63
- class LokaliseRails
64
- class << self
65
- def locales_path
66
- "#{Rails.root}/config/locales_custom"
67
- end
68
- end
69
- end
72
+ require "#{Rails.root}/config/lokalise_rails.rb"
73
+
74
+ # Import the files:
75
+ result = LokaliseRails::TaskDefinition::Importer.import!
76
+ ```
77
+ `result` contains a boolean value with the result of the operation
78
+
79
+ ```ruby
80
+ # Export the files:
81
+ processes = LokaliseRails::TaskDefinition::Exporter.export!
70
82
  ```
71
83
 
84
+ `processes` contains a list of [queued background processes](https://lokalise.github.io/ruby-lokalise-api/api/queued-processes).
85
+
86
+ ## Configuration
87
+
88
+ Options are specified in the `config/lokalise_rails.rb` file.
89
+
90
+ ### Global settings
91
+
92
+ * `api_token` (`string`, required) - Lokalise API token with read/write permissions.
93
+ * `project_id` (`string`, required) - Lokalise project ID. You must have import/export permissions in the specified project.
94
+ * `locales_path` (`string`) - path to the directory with your translation files. Defaults to `"#{Rails.root}/config/locales"`.
95
+ * `branch` (`string`) - Lokalise project branch to use. Defaults to `"master"`.
96
+ * `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.
97
+
72
98
  ### Import settings
73
99
 
74
- * `LokaliseRails.import_opts` (`hash`) - options that will be passed to Lokalise API when downloading translations to your app. Here are the default options:
100
+ * `import_opts` (`hash`) - options that will be passed to Lokalise API when downloading translations to your app. Here are the default options:
75
101
 
76
102
  ```ruby
77
103
  {
@@ -84,9 +110,43 @@ end
84
110
  }
85
111
  ```
86
112
 
87
- Full list of available options [can be found at the official API documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post).
88
- * `LokaliseRails.import_safe_mode` (`boolean`) - default to `false`. When this option is enabled, the import task will check whether the `locales` directory is empty or not. If it is not empty, you will be prompted to continue.
113
+ Full list of available import options [can be found in the official API documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post).
114
+ * `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.
115
+
116
+ ### Export settings
117
+
118
+ * `export_opts` (`hash`) - options that will be passed to Lokalise API when uploading translations. Full list of available export options [can be found in the official documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post). By default, the following options are provided:
119
+ + `data` (`string`, required) - base64-encoded contents of the translation file.
120
+ + `filename` (`string`, required) - translation file name. If the file is stored under a subdirectory (for example, `nested/en.yml` inside the `locales/` directory), the whole path acts as a name. Later when importing files with such names, they will be placed into the proper subdirectories.
121
+ + `lang_iso` (`string`, required) - language ISO code which is determined using the root key inside your YAML file. For example, in this case the `lang_iso` is `en_US`:
122
+
123
+ ```yaml
124
+ en_US:
125
+ my_key: "my value"
126
+ ```
127
+
128
+ **Please note** that if your Lokalise project does not have a language with the specified `lang_iso` code, the export will fail.
129
+
130
+ * `skip_file_export` (`lambda` or `proc`) - specify additional exclusion criteria for the exported files. By default, the rake task will ignore all non-file entries and all files with improper extensions (the latter is controlled by the `file_ext_regexp`). Lambda passed to this option should accept a single argument which is full path to the file (instance of the [`Pathname` class](https://ruby-doc.org/stdlib-2.7.1/libdoc/pathname/rdoc/Pathname.html)). For example, to exclude all files that have `fr` part in their names, add the following config:
131
+
132
+ ```ruby
133
+ c.skip_file_export = ->(file) { f.split[1].to_s.include?('fr') }
134
+ ```
135
+
136
+ ### Settings to work with formats other than YAML
137
+
138
+ If your translation files are not in YAML format, you will need to adjust the following options:
139
+
140
+ * `file_ext_regexp` (`regexp`) - regular expression applied to file extensions to determine which files should be imported and exported. Defaults to `/\.ya?ml\z/i` (YAML files).
141
+ * `translations_loader` (`lambda` or `proc`) - loads translations data and makes sure they are valid before saving them to a translation file. Defaults to `->(raw_data) { YAML.safe_load raw_data }`. In the simplest case you may just return the data back, for example `-> (raw_data) { raw_data }`.
142
+ * `translations_converter` (`lambda` or `proc`) - converts translations data to a proper format before saving them to a translation file. Defaults to `->(raw_data) { raw_data.to_yaml }`. In the simplest case you may just return the data back, for example `-> (raw_data) { raw_data }`.
143
+ * `lang_iso_inferer` (`lambda` or `proc`) - infers language ISO code based on the translation file data before uploading it to Lokalise. Defaults to `->(data) { YAML.safe_load(data)&.keys&.first }`.
144
+
145
+ ## Running tests
146
+
147
+ 1. Copypaste `.env.example` file as `.env`. Put your Lokalise API token and project ID inside. The `.env` file is excluded from version control so your data is safe. All in all, we use pre-recorded VCR cassettes, so the actual API requests won’t be sent. However, providing at least some values is required.
148
+ 2. Run `rspec .`. Observe test results and code coverage.
89
149
 
90
150
  ## License
91
151
 
92
- Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Bodrov](http://bodrovis.tech)
152
+ Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Bodrov](http://bodrovis.tech). License type is [MIT](https://github.com/bodrovis/lokalise_rails/blob/master/LICENSE).
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rails/generators'
4
4
 
5
- class LokaliseRails
5
+ module LokaliseRails
6
6
  module Generators
7
7
  class InstallGenerator < Rails::Generators::Base
8
8
  source_root File.expand_path('../templates', __dir__)
@@ -10,7 +10,7 @@ class LokaliseRails
10
10
  desc 'Creates a LokaliseRails config file.'
11
11
 
12
12
  def copy_config
13
- template 'lokalise_rails_config.rb', "#{Rails.root}/config/initializers/lokalise_rails.rb"
13
+ template 'lokalise_rails_config.rb', "#{Rails.root}/config/lokalise_rails.rb"
14
14
  end
15
15
  end
16
16
  end
@@ -2,28 +2,49 @@
2
2
 
3
3
  require 'lokalise_rails'
4
4
 
5
- # These are mandatory options that you must set before running rake tasks:
6
- LokaliseRails.api_token = ENV['LOKALISE_API_TOKEN']
7
- LokaliseRails.project_id = ENV['LOKALISE_PROJECT_ID']
8
-
9
- # Import options have the following defaults:
10
- # LokaliseRails.import_opts = {
11
- # format: 'yaml',
12
- # placeholder_format: :icu,
13
- # yaml_include_root: true,
14
- # original_filenames: true,
15
- # directory_prefix: '',
16
- # indentation: '2sp'
17
- # }
18
-
19
- # Safe mode is disabled by default:
20
- # LokaliseRails.import_safe_mode = false
21
-
22
- # Provide a custom path to the directory with your translation files:
23
- # class LokaliseRails
24
- # class << self
25
- # def locales_path
26
- # "#{Rails.root}/config/locales"
27
- # end
28
- # end
29
- # end
5
+ LokaliseRails.config do |c|
6
+ # These are mandatory options that you must set before running rake tasks:
7
+ # c.api_token = ENV['LOKALISE_API_TOKEN']
8
+ # c.project_id = ENV['LOKALISE_PROJECT_ID']
9
+
10
+ # Provide a custom path to the directory with your translation files:
11
+ # c.locales_path = "#{Rails.root}/config/locales"
12
+
13
+ # Provide a Lokalise project branch to use:
14
+ # c.branch = 'master'
15
+
16
+ # Provide request timeouts for the Lokalise API client:
17
+ # c.timeouts = {open_timeout: nil, timeout: nil}
18
+
19
+ # Import options have the following defaults:
20
+ # c.import_opts = {
21
+ # format: 'yaml',
22
+ # placeholder_format: :icu,
23
+ # yaml_include_root: true,
24
+ # original_filenames: true,
25
+ # directory_prefix: '',
26
+ # indentation: '2sp'
27
+ # }
28
+
29
+ # Safe mode for imports is disabled by default:
30
+ # c.import_safe_mode = false
31
+
32
+ # Additional export options (only filename, contents, and lang_iso params are provided by default)
33
+ # c.export_opts = {}
34
+
35
+ # Provide additional file exclusion criteria for exports (by default, any file with the proper extension will be exported)
36
+ # c.skip_file_export = ->(file) { file.split[1].to_s.include?('fr') }
37
+
38
+ # Set the options below if you would like to work with format other than YAML
39
+ ## Regular expression to use when choosing the files to extract from the downloaded archive and upload to Lokalise
40
+ ## c.file_ext_regexp = /\.ya?ml\z/i
41
+
42
+ ## Load translations data and make sure they are valid:
43
+ ## c.translations_loader = ->(raw_data) { YAML.safe_load raw_data }
44
+
45
+ ## Convert translations data to a proper format:
46
+ ## c.translations_converter = ->(raw_data) { raw_data.to_yaml }
47
+
48
+ ## Infer language ISO code for the translation file:
49
+ ## c.lang_iso_inferer = ->(data) { YAML.safe_load(data)&.keys&.first }
50
+ end
@@ -2,29 +2,79 @@
2
2
 
3
3
  require 'lokalise_rails/task_definition/base'
4
4
  require 'lokalise_rails/task_definition/importer'
5
+ require 'lokalise_rails/task_definition/exporter'
5
6
 
6
- class LokaliseRails
7
- @project_id = nil
8
- @import_opts = {
9
- format: 'yaml',
10
- placeholder_format: :icu,
11
- yaml_include_root: true,
12
- original_filenames: true,
13
- directory_prefix: '',
14
- indentation: '2sp'
15
- }
16
- # @export_opts = {
17
- #
18
- # }
19
- @import_safe_mode = false
20
- @api_token = nil
21
-
7
+ module LokaliseRails
22
8
  class << self
23
- attr_accessor :import_opts, :import_safe_mode, :api_token, :export_opts,
24
- :project_id
9
+ attr_accessor :api_token, :project_id
10
+ attr_writer :import_opts, :import_safe_mode, :export_opts, :locales_path,
11
+ :file_ext_regexp, :skip_file_export, :branch, :timeouts,
12
+ :translations_loader, :translations_converter, :lang_iso_inferer
13
+
14
+ # Main interface to provide configuration options for rake tasks
15
+ def config
16
+ yield self
17
+ end
25
18
 
19
+ # Full path to directory with translation files
26
20
  def locales_path
27
- "#{Rails.root}/config/locales"
21
+ @locales_path || "#{Rails.root}/config/locales"
22
+ end
23
+
24
+ # Project branch to use
25
+ def branch
26
+ @branch || 'master'
27
+ end
28
+
29
+ # Set request timeouts for the Lokalise API client
30
+ def timeouts
31
+ @timeouts || {}
32
+ end
33
+
34
+ # Regular expression used to select translation files with proper extensions
35
+ def file_ext_regexp
36
+ @file_ext_regexp || /\.ya?ml\z/i
37
+ end
38
+
39
+ # Options for import rake task
40
+ def import_opts
41
+ @import_opts || {
42
+ format: 'yaml',
43
+ placeholder_format: :icu,
44
+ yaml_include_root: true,
45
+ original_filenames: true,
46
+ directory_prefix: '',
47
+ indentation: '2sp'
48
+ }
49
+ end
50
+
51
+ # Options for export rake task
52
+ def export_opts
53
+ @export_opts || {}
54
+ end
55
+
56
+ # Enables safe mode for import. When enabled, will check whether the target folder is empty or not
57
+ def import_safe_mode
58
+ @import_safe_mode.nil? ? false : @import_safe_mode
59
+ end
60
+
61
+ # Additional file skip criteria to apply when performing export
62
+ def skip_file_export
63
+ @skip_file_export || ->(_) { false }
64
+ end
65
+
66
+ def translations_loader
67
+ @translations_loader || ->(raw_data) { YAML.safe_load raw_data }
68
+ end
69
+
70
+ # Converts translations data to the proper format
71
+ def translations_converter
72
+ @translations_converter || ->(raw_data) { raw_data.to_yaml }
73
+ end
74
+
75
+ # Infers lang ISO for the given translation file
76
+ def lang_iso_inferer
77
+ @lang_iso_inferer || ->(data) { YAML.safe_load(data)&.keys&.first }
28
78
  end
29
79
  end
30
80
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rake'
4
-
5
- class LokaliseRails
3
+ module LokaliseRails
6
4
  class Railtie < Rails::Railtie
7
5
  rake_tasks do
8
6
  load 'tasks/lokalise_rails_tasks.rake'
@@ -1,17 +1,61 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ruby-lokalise-api'
4
- require 'open-uri'
4
+ require 'pathname'
5
5
 
6
- class LokaliseRails
6
+ module LokaliseRails
7
7
  module TaskDefinition
8
8
  class Base
9
9
  class << self
10
- def check_required_opts
11
- return [false, 'Project ID is not set! Aborting...'] unless LokaliseRails.project_id
12
- return [false, 'Lokalise API token is not set! Aborting...'] unless LokaliseRails.api_token
10
+ attr_writer :api_client
13
11
 
14
- [true, '']
12
+ # Creates a Lokalise API client
13
+ #
14
+ # @return [Lokalise::Client]
15
+ def api_client
16
+ @api_client ||= ::Lokalise.client LokaliseRails.api_token, LokaliseRails.timeouts
17
+ end
18
+
19
+ # Resets API client
20
+ def reset_api_client!
21
+ Lokalise.reset_client!
22
+ @api_client = nil
23
+ end
24
+
25
+ # Checks task options
26
+ #
27
+ # @return Array
28
+ def opt_errors
29
+ errors = []
30
+ errors << 'Project ID is not set! Aborting...' if LokaliseRails.project_id.nil? || LokaliseRails.project_id.empty?
31
+ errors << 'Lokalise API token is not set! Aborting...' if LokaliseRails.api_token.nil? || LokaliseRails.api_token.empty?
32
+ errors
33
+ end
34
+
35
+ private
36
+
37
+ # Checks whether the provided file has a proper extension as dictated by the `file_ext_regexp` option
38
+ #
39
+ # @return Boolean
40
+ # @param raw_path [String, Pathname]
41
+ def proper_ext?(raw_path)
42
+ path = raw_path.is_a?(Pathname) ? raw_path : Pathname.new(raw_path)
43
+ LokaliseRails.file_ext_regexp.match? path.extname
44
+ end
45
+
46
+ # Returns directory and filename for the given entry
47
+ #
48
+ # @return Array
49
+ # @param entry [String]
50
+ def subdir_and_filename_for(entry)
51
+ Pathname.new(entry).split
52
+ end
53
+
54
+ # Returns Lokalise project ID and branch, semicolumn separated
55
+ #
56
+ # @return [String]
57
+ def project_id_with_branch
58
+ "#{LokaliseRails.project_id}:#{LokaliseRails.branch}"
15
59
  end
16
60
  end
17
61
  end