lokalise_rails 0.1.0 → 1.2.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: 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