i18n-json 0.0.1 → 0.0.2

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: 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