i18n-json 0.0.1 → 0.0.2

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: d34f8bbee444530bf71f4d3b7760e1d08de77a44b41896cf58385c8aa03a688d
4
- data.tar.gz: 3017e38551fa0c1978b8374589c365561dcea14107f7f6adb6c82179cba3bbae
3
+ metadata.gz: b81e3b3409e00ed7ddcc14ca89fb4a3d156e994fc3726e0b7497b830b79d7283
4
+ data.tar.gz: d70e1fde67b202d8615f7664f24badd060b15be60193202813ef9234ab6655d2
5
5
  SHA512:
6
- metadata.gz: ea8b93e7caf242b46a4486ae53d81b5cd9534329f6a998e17bce88570a5935dbcfb343f47ff669891b6655d9bb010939bd3bad9157a1a75290c63a2628b3dab0
7
- data.tar.gz: e719b49e2ac49c152fc07e8aa4f73c0194d665688b6be12b832399b331ef1d1822f3debf3bec4b005e0e4f975cb8cc53c31eb8570f9781175e8328b4947f63dd
6
+ metadata.gz: 38b833a5607098230ebb72afcfd26350d3fca1eaf48efa3b011a1266b32f461344c93cefea6de1a7f30973366de61992f4adb7091b3f9d792108d2cc8b74acd5
7
+ data.tar.gz: 4ea046aa5a7611a68698f863fa140223ed0853b02b4d3c6324980b2b50e8bdfc3a0d528cb7f0c200054332ddd83775ddebe5bfcb8fe1898d94ef72df13ba9745
data/.github/FUNDING.yml CHANGED
@@ -1,2 +1,3 @@
1
1
  ---
2
+ github: [fnando]
2
3
  custom: ["https://www.paypal.me/nandovieira/🍕"]
@@ -1,47 +1,63 @@
1
1
  ---
2
2
  name: tests
3
3
 
4
- on: [push]
4
+ on:
5
+ pull_request:
6
+ branches:
7
+ - main
8
+ push:
9
+ branches:
10
+ - main
11
+
12
+ schedule:
13
+ - cron: "0 10 * * *"
14
+
15
+ workflow_dispatch:
16
+ inputs: {}
5
17
 
6
18
  jobs:
7
19
  build:
8
- runs-on: ubuntu-latest
20
+ name: Tests with Ruby ${{ matrix.ruby }} and ${{ matrix.gemfile }}
21
+ runs-on: "ubuntu-latest"
22
+ strategy:
23
+ fail-fast: false
24
+ matrix:
25
+ ruby: [3.0.x, 2.7.x, 2.6.x]
26
+ gemfile:
27
+ - Gemfile
9
28
 
10
29
  steps:
11
- - name: Clone repo
12
- uses: actions/checkout@v1
30
+ - uses: actions/checkout@v2.3.4
13
31
 
14
- - name: Ruby cache
15
- uses: actions/cache@v1
16
- id: cache
17
- with:
18
- path: ~/local/rubies
19
- key: ruby-2.6.5
20
-
21
- - name: Rubygems cache
22
- uses: actions/cache@v1
32
+ - uses: actions/cache@v2
23
33
  with:
24
34
  path: vendor/bundle
25
- key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
26
- restore-keys: ${{ runner.os }}-gem-
27
-
28
- - name: Install ruby
29
- uses: clupprich/ruby-build-action@master
30
- id: ruby
35
+ key: >
36
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-${{
37
+ hashFiles(matrix.gemfile) }}
38
+ restore-keys: >
39
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-${{
40
+ hashFiles(matrix.gemfile) }}
41
+
42
+ - name: Set up Ruby
43
+ uses: actions/setup-ruby@v1
31
44
  with:
32
- ruby-version: 2.6.5
33
- cache-available: ${{ steps.cache.outputs.cache-hit == 'true' }}
45
+ ruby-version: ${{ matrix.ruby }}
34
46
 
35
- - name: Bundle install
47
+ - name: Install dependencies
48
+ run: |
49
+ sudo apt-get install -y libevent-dev libseccomp-dev git libsasl2-dev
50
+
51
+ - name: Install gem dependencies
52
+ env:
53
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
36
54
  run: |
37
55
  gem install bundler
38
56
  bundle config path vendor/bundle
39
- bundle install --jobs 4 --retry 3
57
+ bundle update --jobs 4 --retry 3
40
58
 
41
- - name: Run ruby tests
59
+ - name: Run Tests
60
+ env:
61
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
42
62
  run: |
43
63
  bundle exec rake
44
-
45
- - name: Run lint
46
- run: |
47
- bundle exec rubocop
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ *.lock
data/.rubocop.yml CHANGED
@@ -4,6 +4,7 @@ inherit_gem:
4
4
 
5
5
  AllCops:
6
6
  TargetRubyVersion: 2.6
7
+ NewCops: enable
7
8
 
8
9
  Naming/FileName:
9
10
  Exclude:
data/README.md CHANGED
@@ -46,12 +46,13 @@ translations:
46
46
  - "*"
47
47
  ```
48
48
 
49
- The code API:
49
+ The Ruby API:
50
50
 
51
51
  ```ruby
52
52
  require "i18n-json"
53
53
 
54
- I18n::JSON.call(config_file: "config/i18n.yml")
54
+ I18nJSON.call(config_file: "config/i18n.yml")
55
+ I18nJSON.call(config: config)
55
56
  ```
56
57
 
57
58
  The CLI API:
@@ -61,20 +62,76 @@ $ i18n-json init --config config/i18n.yml
61
62
  $ i18n-json export --config config/i18n.yml --require config/boot.rb
62
63
  ```
63
64
 
65
+ ## Automatically export translations
66
+
67
+ ### Using guard
68
+
69
+ You can also automatically export translations when file changes using
70
+ [guard-i18n-json](https://github.com/fnando/guard-i18n-json).
71
+
72
+ First, add the template to your `Guardfile` with the following command:
73
+
74
+ ```console
75
+ $ bundle exec guard init i18n_json
76
+ ```
77
+
78
+ Something like this will be added:
79
+
80
+ ```ruby
81
+ guard(:i18n_json,
82
+ run_on_start: true,
83
+ config_file: "./config/i18n.yml",
84
+ require_file: "./config/boot.rb") do
85
+ watch(%r{^(app|config)/locales/.+\.(yml|po)$})
86
+ watch(%r{^config/i18n.yml$})
87
+ watch("Gemfile")
88
+ end
89
+ ```
90
+
91
+ Configure file paths accordingly.
92
+
93
+ ### Using listen
94
+
95
+ Create a file under `config/initializers/i18n.rb` with the following content:
96
+
97
+ ```ruby
98
+ # frozen_string_literal: true
99
+
100
+ require "i18n-json/listen"
101
+
102
+ I18nJSON.listen
103
+ ```
104
+
105
+ The code above will watch for changes based on `config/i18n.yml` and
106
+ `config/locales`. You can customize these options with
107
+ `I18nJSON.listen(config_file: "config/i18n.yml", locales_dir: "config/locales")`.
108
+
64
109
  ## Development
65
110
 
66
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
111
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
112
+ `rake test` to run the tests. You can also run `bin/console` for an interactive
113
+ prompt that will allow you to experiment.
67
114
 
68
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
115
+ To install this gem onto your local machine, run `bundle exec rake install`. To
116
+ release a new version, update the version number in `version.rb`, and then run
117
+ `bundle exec rake release`, which will create a git tag for the version, push
118
+ git commits and tags, and push the `.gem` file to
119
+ [rubygems.org](https://rubygems.org).
69
120
 
70
121
  ## Contributing
71
122
 
72
- Bug reports and pull requests are welcome on GitHub at https://github.com/fnando/i18n-json. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
123
+ Bug reports and pull requests are welcome on GitHub at
124
+ https://github.com/fnando/i18n-json. This project is intended to be a safe,
125
+ welcoming space for collaboration, and contributors are expected to adhere to
126
+ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
73
127
 
74
128
  ## License
75
129
 
76
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
130
+ The gem is available as open source under the terms of the
131
+ [MIT License](https://opensource.org/licenses/MIT).
77
132
 
78
133
  ## Code of Conduct
79
134
 
80
- Everyone interacting in the I18n::Json project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/fnando/i18n-json/blob/master/CODE_OF_CONDUCT.md).
135
+ Everyone interacting in the I18n::Json project’s codebases, issue trackers, chat
136
+ rooms and mailing lists is expected to follow the
137
+ [code of conduct](https://github.com/fnando/i18n-json/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
+ require "rubocop/rake_task"
5
6
 
6
7
  Rake::TestTask.new(:test) do |t|
7
8
  t.libs << "test"
@@ -9,4 +10,6 @@ Rake::TestTask.new(:test) do |t|
9
10
  t.test_files = FileList["test/**/*_test.rb"]
10
11
  end
11
12
 
12
- task default: :test
13
+ RuboCop::RakeTask.new
14
+
15
+ task default: %i[test rubocop]
data/i18n-json.gemspec CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.version = I18nJSON::VERSION
8
8
  spec.authors = ["Nando Vieira"]
9
9
  spec.email = ["me@fnando.com"]
10
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
10
11
 
11
12
  spec.summary = "Export I18n translations to JSON."
12
13
  spec.description = spec.summary
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "guard"
4
+ gem "guard-compat"
5
+ require "guard/compat/plugin"
6
+
7
+ require "i18n-json"
8
+ require_relative "i18n_json/version"
9
+
10
+ module Guard
11
+ class I18nJson < Plugin
12
+ attr_reader :config_file, :require_file, :current_thread
13
+
14
+ def initialize(options = {})
15
+ @config_file = options.delete(:config_file)
16
+ @require_file = options.delete(:require_file)
17
+ super
18
+ end
19
+
20
+ def start
21
+ export_files
22
+ end
23
+
24
+ def stop
25
+ current_thread&.exit
26
+ end
27
+
28
+ def reload
29
+ export_files
30
+ end
31
+
32
+ def run_all
33
+ export_files
34
+ end
35
+
36
+ def run_on_additions(paths)
37
+ export_files(paths)
38
+ end
39
+
40
+ def run_on_modifications(paths)
41
+ export_files(paths)
42
+ end
43
+
44
+ def run_on_removals(paths)
45
+ export_files(paths)
46
+ end
47
+
48
+ def export_files(changes = nil)
49
+ return unless validate_file(:config_file, config_file)
50
+ return unless validate_file(:require_file, require_file)
51
+
52
+ current_thread&.exit
53
+
54
+ info("Changes detected: #{changes.join(', ')}") if changes
55
+
56
+ @current_thread = Thread.new do
57
+ require @require_file
58
+ ::I18nJSON.call(config_file: @config_file)
59
+ end
60
+
61
+ current_thread.join
62
+ end
63
+
64
+ def validate_file(key, file)
65
+ return true if file && File.file?(file)
66
+
67
+ error("#{key.inspect} must be a file")
68
+ false
69
+ end
70
+
71
+ def error(message)
72
+ ::Guard::UI.error "[guard-i18n-json] #{message}"
73
+ end
74
+
75
+ def info(message)
76
+ ::Guard::UI.info "[guard-i18n-json] #{message}"
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard(:i18n_json,
4
+ run_on_start: true,
5
+ config_file: "./config/i18n_json.yml",
6
+ require_file: "./config/boot.rb") do
7
+ watch(%r{^(app|config)/locales/.+\.(yml|po)$})
8
+ watch(%r{^config/i18n_json.yml$})
9
+ watch("Gemfile")
10
+ end
data/lib/i18n-json.rb CHANGED
@@ -16,8 +16,14 @@ require_relative "./i18n-json/schema"
16
16
  require_relative "./i18n-json/version"
17
17
 
18
18
  module I18nJSON
19
- def self.call(config_file:)
20
- config = Glob::SymbolizeKeys.call(YAML.load_file(config_file))
19
+ MissingConfigError = Class.new(StandardError)
20
+
21
+ def self.call(config_file: nil, config: nil)
22
+ if !config_file && !config
23
+ raise MissingConfigError, "you must set either `config_file` or `config`"
24
+ end
25
+
26
+ config = Glob::SymbolizeKeys.call(config || YAML.load_file(config_file))
21
27
  Schema.validate!(config)
22
28
 
23
29
  config[:translations].each do |group|
@@ -30,7 +36,7 @@ module I18nJSON
30
36
  output_file_path = File.expand_path(group[:file])
31
37
 
32
38
  if output_file_path.include?(":locale")
33
- filtered_translations.keys.each do |locale|
39
+ filtered_translations.each_key do |locale|
34
40
  locale_file_path = output_file_path.gsub(/:locale/, locale.to_s)
35
41
  write_file(locale_file_path, locale => filtered_translations[locale])
36
42
  end
@@ -45,9 +45,18 @@ module I18nJSON
45
45
  ui.fail_with("ERROR: require file doesn't exist at #{require_file}")
46
46
  end
47
47
 
48
- require require_file if require_file
48
+ require_without_warnings(require_file) if require_file
49
49
  I18nJSON.call(config_file: config_file)
50
50
  end
51
+
52
+ private def require_without_warnings(path)
53
+ old_verbose = $VERBOSE
54
+ $VERBOSE = nil
55
+
56
+ require path
57
+ ensure
58
+ $VERBOSE = old_verbose
59
+ end
51
60
  end
52
61
  end
53
62
  end
@@ -35,10 +35,12 @@ module I18nJSON
35
35
  file << <<~YAML
36
36
  ---
37
37
  translations:
38
- - file: some/dir/locale.json
38
+ - file: app/javascript/locales.json
39
39
  patterns:
40
40
  - "*"
41
41
  - "!*.activerecord"
42
+ - "!*.errors"
43
+ - "!*.number.nth"
42
44
 
43
45
  YAML
44
46
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "listen"
4
+ require "listen"
5
+ require "i18n-json"
6
+
7
+ module I18nJSON
8
+ class << self
9
+ attr_accessor :started
10
+ end
11
+
12
+ def self.listen(
13
+ config_file: Rails.root.join("config/i18n.yml"),
14
+ locales_dir: Rails.root.join("config/locales")
15
+ )
16
+ return unless Rails.env.development?
17
+ return if started
18
+
19
+ self.started = true
20
+
21
+ relative_paths =
22
+ [config_file, locales_dir].map {|path| relative_path(path) }
23
+
24
+ debug("Watching #{relative_paths.inspect}")
25
+
26
+ listener(config_file, locales_dir.to_s).start
27
+ I18nJSON.call(config_file: config_file)
28
+ end
29
+
30
+ def self.relative_path(path)
31
+ Pathname.new(path).relative_path_from(Rails.root).to_s
32
+ end
33
+
34
+ def self.relative_path_list(paths)
35
+ paths.map {|path| relative_path(path) }
36
+ end
37
+
38
+ def self.debug(message)
39
+ logger.tagged("i18n-json") { logger.debug(message) }
40
+ end
41
+
42
+ def self.logger
43
+ @logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
44
+ end
45
+
46
+ def self.listener(config_file, locales_dir) # rubocop:disable Metrics/MethodLength
47
+ paths = [File.dirname(config_file), locales_dir]
48
+
49
+ Listen.to(*paths) do |changed, added, removed|
50
+ changes = compute_changes(
51
+ [config_file, locales_dir],
52
+ changed,
53
+ added,
54
+ removed
55
+ )
56
+
57
+ next unless changes.any?
58
+
59
+ debug(changes.map {|key, value| "#{key}=#{value.inspect}" }.join(", "))
60
+
61
+ I18nJSON.call(config_file: config_file)
62
+ end
63
+ end
64
+
65
+ def self.compute_changes(paths, changed, added, removed)
66
+ paths = paths.map {|path| relative_path(path) }
67
+
68
+ {
69
+ changed: included_on_watched_paths(paths, changed),
70
+ added: included_on_watched_paths(paths, added),
71
+ removed: included_on_watched_paths(paths, removed)
72
+ }.select {|_k, v| v.any? }
73
+ end
74
+
75
+ def self.included_on_watched_paths(paths, changes)
76
+ changes.map {|change| relative_path(change) }.select do |change|
77
+ paths.any? {|path| change.start_with?(path) }
78
+ end
79
+ end
80
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18nJSON
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-16 00:00:00.000000000 Z
11
+ date: 2021-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glob
@@ -193,7 +193,6 @@ files:
193
193
  - CHANGELOG.md
194
194
  - CODE_OF_CONDUCT.md
195
195
  - Gemfile
196
- - Gemfile.lock
197
196
  - LICENSE.txt
198
197
  - README.md
199
198
  - Rakefile
@@ -201,12 +200,15 @@ files:
201
200
  - bin/setup
202
201
  - exe/i18n-json
203
202
  - i18n-json.gemspec
203
+ - lib/guard/i18n_json.rb
204
+ - lib/guard/i18n_json/templates/Guardfile
204
205
  - lib/i18n-json.rb
205
206
  - lib/i18n-json/cli.rb
206
207
  - lib/i18n-json/cli/command.rb
207
208
  - lib/i18n-json/cli/export_command.rb
208
209
  - lib/i18n-json/cli/init_command.rb
209
210
  - lib/i18n-json/cli/ui.rb
211
+ - lib/i18n-json/listen.rb
210
212
  - lib/i18n-json/schema.rb
211
213
  - lib/i18n-json/version.rb
212
214
  homepage: https://github.com/fnando/i18n-json
@@ -215,7 +217,7 @@ licenses:
215
217
  metadata:
216
218
  homepage_uri: https://github.com/fnando/i18n-json
217
219
  source_code_uri: https://github.com/fnando/i18n-json
218
- post_install_message:
220
+ post_install_message:
219
221
  rdoc_options: []
220
222
  require_paths:
221
223
  - lib
@@ -223,15 +225,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
225
  requirements:
224
226
  - - ">="
225
227
  - !ruby/object:Gem::Version
226
- version: '0'
228
+ version: 2.6.0
227
229
  required_rubygems_version: !ruby/object:Gem::Requirement
228
230
  requirements:
229
231
  - - ">="
230
232
  - !ruby/object:Gem::Version
231
233
  version: '0'
232
234
  requirements: []
233
- rubygems_version: 3.0.3
234
- signing_key:
235
+ rubygems_version: 3.2.3
236
+ signing_key:
235
237
  specification_version: 4
236
238
  summary: Export I18n translations to JSON.
237
239
  test_files: []
data/Gemfile.lock DELETED
@@ -1,90 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- i18n-json (0.0.1)
5
- glob
6
- i18n
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activesupport (6.0.2)
12
- concurrent-ruby (~> 1.0, >= 1.0.2)
13
- i18n (>= 0.7, < 2)
14
- minitest (~> 5.1)
15
- tzinfo (~> 1.1)
16
- zeitwerk (~> 2.2)
17
- ast (2.4.0)
18
- awesome_print (1.8.0)
19
- byebug (11.0.1)
20
- coderay (1.1.2)
21
- concurrent-ruby (1.1.5)
22
- docile (1.3.2)
23
- glob (0.2.0)
24
- i18n (1.7.0)
25
- concurrent-ruby (~> 1.0)
26
- jaro_winkler (1.5.4)
27
- json (2.3.0)
28
- method_source (0.9.2)
29
- minitest (5.13.0)
30
- minitest-utils (0.4.6)
31
- minitest
32
- parallel (1.19.1)
33
- parser (2.6.5.0)
34
- ast (~> 2.4.0)
35
- pry (0.12.2)
36
- coderay (~> 1.1.0)
37
- method_source (~> 0.9.0)
38
- pry-byebug (3.7.0)
39
- byebug (~> 11.0)
40
- pry (~> 0.10)
41
- pry-meta (0.0.10)
42
- awesome_print
43
- pry
44
- pry-byebug
45
- pry-remote
46
- pry-remote (0.1.8)
47
- pry (~> 0.9)
48
- slop (~> 3.0)
49
- rainbow (3.0.0)
50
- rake (13.0.1)
51
- redis (4.1.3)
52
- rubocop (0.77.0)
53
- jaro_winkler (~> 1.5.1)
54
- parallel (~> 1.10)
55
- parser (>= 2.6)
56
- rainbow (>= 2.2.2, < 4.0)
57
- ruby-progressbar (~> 1.7)
58
- unicode-display_width (>= 1.4.0, < 1.7)
59
- rubocop-fnando (0.0.3)
60
- ruby-progressbar (1.10.1)
61
- simplecov (0.17.1)
62
- docile (~> 1.1)
63
- json (>= 1.8, < 3)
64
- simplecov-html (~> 0.10.0)
65
- simplecov-html (0.10.2)
66
- slop (3.6.0)
67
- thread_safe (0.3.6)
68
- tzinfo (1.2.5)
69
- thread_safe (~> 0.1)
70
- unicode-display_width (1.6.0)
71
- zeitwerk (2.2.2)
72
-
73
- PLATFORMS
74
- ruby
75
-
76
- DEPENDENCIES
77
- activesupport
78
- bundler
79
- i18n-json!
80
- minitest
81
- minitest-utils
82
- pry-meta
83
- rake
84
- redis
85
- rubocop
86
- rubocop-fnando
87
- simplecov
88
-
89
- BUNDLED WITH
90
- 2.0.2