lokalise_rails 0.0.2.1 → 1.0.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: e0590241845de9e22cbf22ac730c162d67294cd8a7e37c62c2afa4cf83508383
4
- data.tar.gz: 85adaa323f60647edb32cf9a246839dbf68ddafd5fc41b6fb3bdd4ae3c6c3bd8
3
+ metadata.gz: 87524123a10425d69c33950f4b2c16366146f5c1ab14c19dbc7185de61fb726a
4
+ data.tar.gz: 39ba0b0a91f443ea162d7804c89906f4523f7c13411fbd541624bafb9197a569
5
5
  SHA512:
6
- metadata.gz: 9827b20ed3fb6e44ede4cad6b72fba86ab0ed0224e8ce87266a24c9a99126af5183e484f9b3fec2f770c6c670b3063d633631ca5c279cd077273536831265a9f
7
- data.tar.gz: 4b04db96df8123247e8b7c6cd664dc0dcecbe574248c31df87bdb7f1c865e95b8ca15a13190af803d9338073257e25ff9ddd9664eb5cfe547aa0476807d7f809
6
+ metadata.gz: 4e36f385c123ab80402aaa428973c2c0706b2cbceabade8bcf12689fe0955bdc927a223c27a9114c102d83af6a709b061e1c10d2e189ca832b5b56a0a6b043f8
7
+ data.tar.gz: bbbe1857d99cdc7c3595f611d664c555981fbdf5f1d37c30a52cb179d641902f879b1492996dc7c1c1cb6dacdfbd7c2a3ca226f31a687879fddf59b1e8f9fe7a
@@ -1,10 +1,15 @@
1
1
  # Changelog
2
2
 
3
- ## 0.0.2 (26-Sep-20)
3
+ ## 1.0.0 (01-Oct-20)
4
4
 
5
- * Fix rake task
6
- * Fix config template
5
+ * Added export feature
6
+ * More convenient configuration and additional options
7
+ * Other major enhancements
7
8
 
8
- ## 0.0.1 (26-Sep-20)
9
+ ## 0.2.0 (26-Sep-20)
9
10
 
10
- * Initial release
11
+ * Allow to override options properly
12
+
13
+ ## 0.1.0 (26-Sep-20)
14
+
15
+ * Initial (proper) release
data/README.md CHANGED
@@ -1,6 +1,6 @@
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
 
@@ -10,34 +10,39 @@ This gem provides [Lokalise](http://lokalise.com) integration for Ruby on Rails
10
10
 
11
11
  ### Requirements
12
12
 
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.
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](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
14
 
15
15
  ### Installation
16
16
 
17
- Add the gem to your `Gemfile`
17
+ Add the gem to your `Gemfile`:
18
18
 
19
19
  ```ruby
20
20
  gem 'lokalise_rails'
21
21
  ```
22
22
 
23
- and run
23
+ and run:
24
24
 
25
25
  ```
26
26
  bundle install
27
27
  rails g lokalise_rails:install
28
28
  ```
29
29
 
30
- The latter command will generate a new initializer `lokalise_rails.rb` looking like this:
30
+ The latter command will generate a new config file `config/lokalise_rails.rb` looking like this:
31
31
 
32
32
  ```ruby
33
33
  require 'lokalise_rails'
34
34
 
35
- LokaliseRails.api_token = ENV['LOKALISE_API_TOKEN']
36
- LokaliseRails.project_id = ENV['LOKALISE_PROJECT_ID']
37
- # ...
35
+ LokaliseRails.config do |c|
36
+ c.api_token = ENV['LOKALISE_API_TOKEN']
37
+ c.project_id = ENV['LOKALISE_PROJECT_ID']
38
+
39
+ # ...other options
40
+ end
38
41
  ```
39
42
 
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.
43
+ You have to provide `api_token` and `project_id` to proceed. `project_id` can be found in your Lokalise project settings.
44
+
45
+ [Other options can be customized as well (see below)](https://github.com/bodrovis/lokalise_rails#import-settings) but they have sensible defaults.
41
46
 
42
47
  ## Importing translations from Lokalise
43
48
 
@@ -47,31 +52,30 @@ To import translations from the specified Lokalise project to your Rails app, ru
47
52
  rails lokalise_rails:import
48
53
  ```
49
54
 
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.
55
+ 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.
56
+
57
+ ## Exporting translations to Lokalise
58
+
59
+ To export translations from your Rails app to the specified Lokalise project, run the following command:
60
+
61
+ ```
62
+ rails lokalise_rails:export
63
+ ```
51
64
 
52
65
  ## Configuration
53
66
 
54
- Options are specified in the `config/initializers/lokalise_rails.rb` file.
67
+ Options are specified in the `config/lokalise_rails.rb` file.
55
68
 
56
69
  ### Global settings
57
70
 
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!):
61
-
62
- ```ruby
63
- class LokaliseRails
64
- class << self
65
- def locales_path
66
- "#{Rails.root}/config/locales_custom"
67
- end
68
- end
69
- end
70
- ```
71
+ * `api_token` (`string`, required) - Lokalise API token with read/write permissions.
72
+ * `project_id` (`string`, required) - Lokalise project ID. You must have import/export permissions in the specified project.
73
+ * `locales_path` (`string`) - path to the directory with your translation files. Defaults to `"#{Rails.root}/config/locales"`.
74
+ * `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).
71
75
 
72
76
  ### Import settings
73
77
 
74
- * `LokaliseRails.import_opts` (`hash`) - options that will be passed to Lokalise API when downloading translations to your app. Here are the default options:
78
+ * `import_opts` (`hash`) - options that will be passed to Lokalise API when downloading translations to your app. Here are the default options:
75
79
 
76
80
  ```ruby
77
81
  {
@@ -84,8 +88,28 @@ end
84
88
  }
85
89
  ```
86
90
 
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.
91
+ Full list of available import options [can be found in the official API documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post).
92
+ * `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.
93
+
94
+ ### Export settings
95
+
96
+ * `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:
97
+ + `data` (`string`, required) - base64-encoded contents of the translation file.
98
+ + `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.
99
+ + `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`:
100
+
101
+ ```yaml
102
+ en_US:
103
+ my_key: "my value"
104
+ ```
105
+
106
+ **Please note** that if your Lokalise project does not have a language with the specified `lang_iso` code, the export will fail.
107
+
108
+ * `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:
109
+
110
+ ```ruby
111
+ c.skip_file_export = ->(file) { f.split[1].to_s.include?('fr') }
112
+ ```
89
113
 
90
114
  ## License
91
115
 
@@ -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,33 @@
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
+ # Import options have the following defaults:
14
+ # c.import_opts = {
15
+ # format: 'yaml',
16
+ # placeholder_format: :icu,
17
+ # yaml_include_root: true,
18
+ # original_filenames: true,
19
+ # directory_prefix: '',
20
+ # indentation: '2sp'
21
+ # }
22
+
23
+ # Safe mode for imports is disabled by default:
24
+ # c.import_safe_mode = false
25
+
26
+ # Additional export options (only filename, contents, and lang_iso params are provided by default)
27
+ # c.export_opts = {}
28
+
29
+ # Provide additional file exclusion criteria for exports (by default, any file with the proper extension will be exported)
30
+ # c.skip_file_export = ->(file) { file.split[1].to_s.include?('fr') }
31
+
32
+ # Regular expression to use when choosing the files to extract from the downloaded archive and upload to Lokalise
33
+ # c.file_ext_regexp = /\.ya?ml\z/i
34
+ end
@@ -2,30 +2,56 @@
2
2
 
3
3
  require 'lokalise_rails/task_definition/base'
4
4
  require 'lokalise_rails/task_definition/importer'
5
- require 'lokalise_rails/railtie' if defined?(Rails)
6
-
7
- class LokaliseRails
8
- @project_id = nil
9
- @import_opts = {
10
- format: 'yaml',
11
- placeholder_format: :icu,
12
- yaml_include_root: true,
13
- original_filenames: true,
14
- directory_prefix: '',
15
- indentation: '2sp'
16
- }
17
- # @export_opts = {
18
- #
19
- # }
20
- @import_safe_mode = false
21
- @api_token = nil
5
+ require 'lokalise_rails/task_definition/exporter'
22
6
 
7
+ module LokaliseRails
23
8
  class << self
24
- attr_accessor :import_opts, :import_safe_mode, :api_token, :export_opts,
25
- :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
12
+
13
+ # Main interface to provide configuration options for rake tasks
14
+ def config
15
+ yield self
16
+ end
26
17
 
18
+ # Full path to directory with translation files
27
19
  def locales_path
28
- "#{Rails.root}/config/locales"
20
+ @locales_path || "#{Rails.root}/config/locales"
21
+ end
22
+
23
+ # Regular expression used to select translation files with proper extensions
24
+ def file_ext_regexp
25
+ @file_ext_regexp || /\.ya?ml\z/i
26
+ end
27
+
28
+ # Options for import rake task
29
+ def import_opts
30
+ @import_opts || {
31
+ format: 'yaml',
32
+ placeholder_format: :icu,
33
+ yaml_include_root: true,
34
+ original_filenames: true,
35
+ directory_prefix: '',
36
+ indentation: '2sp'
37
+ }
38
+ end
39
+
40
+ # Options for export rake task
41
+ def export_opts
42
+ @export_opts || {}
43
+ end
44
+
45
+ # Enables safe mode for import. When enabled, will check whether the target folder is empty or not
46
+ def import_safe_mode
47
+ @import_safe_mode.nil? ? false : @import_safe_mode
48
+ end
49
+
50
+ # Additional file skip criteria to apply when performing export
51
+ def skip_file_export
52
+ @skip_file_export || ->(_) { false }
29
53
  end
30
54
  end
31
55
  end
56
+
57
+ require 'lokalise_rails/railtie' if defined?(Rails)
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class LokaliseRails
3
+ require 'rake'
4
+
5
+ module LokaliseRails
4
6
  class Railtie < Rails::Railtie
5
7
  rake_tasks do
6
- puts Dir[File.join(File.dirname(__FILE__), '..', 'tasks', '**/*.rake')]
7
- Dir[
8
- File.join(File.dirname(__FILE__), '..', 'tasks', '**/*.rake')
9
- ].each { |rake| puts(File.file?(rake)) ; load(rake) }
8
+ load 'tasks/lokalise_rails_tasks.rake'
10
9
  end
11
10
  end
12
11
  end
@@ -1,17 +1,48 @@
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
17
+ end
18
+
19
+ # Checks task options
20
+ #
21
+ # @return Array
22
+ def opt_errors
23
+ errors = []
24
+ errors << 'Project ID is not set! Aborting...' if LokaliseRails.project_id.nil? || LokaliseRails.project_id.empty?
25
+ errors << 'Lokalise API token is not set! Aborting...' if LokaliseRails.api_token.nil? || LokaliseRails.api_token.empty?
26
+ errors
27
+ end
28
+
29
+ private
30
+
31
+ # Checks whether the provided file has a proper extension as dictated by the `file_ext_regexp` option
32
+ #
33
+ # @return Boolean
34
+ # @param raw_path [String, Pathname]
35
+ def proper_ext?(raw_path)
36
+ path = raw_path.is_a?(Pathname) ? raw_path : Pathname.new(raw_path)
37
+ LokaliseRails.file_ext_regexp.match? path.extname
38
+ end
39
+
40
+ # Returns directory and filename for the given entry
41
+ #
42
+ # @return Array
43
+ # @param entry [String]
44
+ def subdir_and_filename_for(entry)
45
+ Pathname.new(entry).split
15
46
  end
16
47
  end
17
48
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module LokaliseRails
6
+ module TaskDefinition
7
+ class Exporter < Base
8
+ class << self
9
+ # Performs translation file export from Rails to Lokalise and returns an array of queued processes
10
+ #
11
+ # @return [Array]
12
+ def export!
13
+ errors = opt_errors
14
+
15
+ if errors.any?
16
+ errors.each { |e| $stdout.puts e }
17
+ return false
18
+ end
19
+
20
+ queued_processes = []
21
+ each_file do |full_path, relative_path|
22
+ queued_processes << api_client.upload_file(
23
+ LokaliseRails.project_id, opts(full_path, relative_path)
24
+ )
25
+ rescue StandardError => e
26
+ $stdout.puts "Error while trying to upload #{full_path}: #{e.inspect}"
27
+ end
28
+
29
+ $stdout.print 'Task complete!'
30
+
31
+ queued_processes
32
+ end
33
+
34
+ # Processes each translation file in the specified directory
35
+ def each_file
36
+ return unless block_given?
37
+
38
+ loc_path = LokaliseRails.locales_path
39
+ Dir["#{loc_path}/**/*"].sort.each do |f|
40
+ full_path = Pathname.new f
41
+
42
+ next unless file_matches_criteria? full_path
43
+
44
+ relative_path = full_path.relative_path_from Pathname.new(loc_path)
45
+
46
+ yield full_path, relative_path
47
+ end
48
+ end
49
+
50
+ # Generates export options
51
+ #
52
+ # @return [Hash]
53
+ # @param full_p [Pathname]
54
+ # @param relative_p [Pathname]
55
+ def opts(full_p, relative_p)
56
+ content = File.read full_p
57
+
58
+ lang_iso = YAML.safe_load(content)&.keys&.first
59
+
60
+ initial_opts = {
61
+ data: Base64.strict_encode64(content.strip),
62
+ filename: relative_p,
63
+ lang_iso: lang_iso
64
+ }
65
+
66
+ initial_opts.merge LokaliseRails.export_opts
67
+ end
68
+
69
+ # Checks whether the specified file has to be processed or not
70
+ #
71
+ # @return [Boolean]
72
+ # @param full_path [Pathname]
73
+ def file_matches_criteria?(full_path)
74
+ full_path.file? && proper_ext?(full_path) &&
75
+ !LokaliseRails.skip_file_export.call(full_path)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end