i18n 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/lib/i18n/backend.rb +1 -0
  4. data/lib/i18n/backend/base.rb +12 -1
  5. data/lib/i18n/backend/cache_file.rb +36 -0
  6. data/lib/i18n/backend/chain.rb +22 -0
  7. data/lib/i18n/backend/key_value.rb +24 -0
  8. data/lib/i18n/backend/simple.rb +1 -1
  9. data/lib/i18n/config.rb +16 -0
  10. data/lib/i18n/core_ext/hash.rb +8 -0
  11. data/lib/i18n/interpolate/ruby.rb +5 -3
  12. data/lib/i18n/version.rb +1 -1
  13. metadata +16 -52
  14. data/gemfiles/Gemfile.rails-3.2.x +0 -10
  15. data/gemfiles/Gemfile.rails-4.0.x +0 -10
  16. data/gemfiles/Gemfile.rails-4.1.x +0 -10
  17. data/gemfiles/Gemfile.rails-4.2.x +0 -10
  18. data/gemfiles/Gemfile.rails-5.0.x +0 -10
  19. data/gemfiles/Gemfile.rails-5.1.x +0 -10
  20. data/gemfiles/Gemfile.rails-master +0 -10
  21. data/test/api/all_features_test.rb +0 -58
  22. data/test/api/cascade_test.rb +0 -28
  23. data/test/api/chain_test.rb +0 -24
  24. data/test/api/fallbacks_test.rb +0 -30
  25. data/test/api/key_value_test.rb +0 -24
  26. data/test/api/memoize_test.rb +0 -56
  27. data/test/api/override_test.rb +0 -42
  28. data/test/api/pluralization_test.rb +0 -30
  29. data/test/api/simple_test.rb +0 -28
  30. data/test/backend/cache_test.rb +0 -109
  31. data/test/backend/cascade_test.rb +0 -86
  32. data/test/backend/chain_test.rb +0 -122
  33. data/test/backend/exceptions_test.rb +0 -36
  34. data/test/backend/fallbacks_test.rb +0 -211
  35. data/test/backend/interpolation_compiler_test.rb +0 -118
  36. data/test/backend/key_value_test.rb +0 -85
  37. data/test/backend/memoize_test.rb +0 -79
  38. data/test/backend/metadata_test.rb +0 -48
  39. data/test/backend/pluralization_test.rb +0 -45
  40. data/test/backend/simple_test.rb +0 -111
  41. data/test/backend/transliterator_test.rb +0 -84
  42. data/test/core_ext/hash_test.rb +0 -36
  43. data/test/gettext/api_test.rb +0 -214
  44. data/test/gettext/backend_test.rb +0 -92
  45. data/test/i18n/exceptions_test.rb +0 -117
  46. data/test/i18n/gettext_plural_keys_test.rb +0 -20
  47. data/test/i18n/interpolate_test.rb +0 -91
  48. data/test/i18n/load_path_test.rb +0 -34
  49. data/test/i18n/middleware_test.rb +0 -24
  50. data/test/i18n_test.rb +0 -462
  51. data/test/locale/fallbacks_test.rb +0 -133
  52. data/test/locale/tag/rfc4646_test.rb +0 -143
  53. data/test/locale/tag/simple_test.rb +0 -32
  54. data/test/run_all.rb +0 -20
  55. data/test/test_data/locales/de.po +0 -82
  56. data/test/test_data/locales/en.rb +0 -3
  57. data/test/test_data/locales/en.yaml +0 -3
  58. data/test/test_data/locales/en.yml +0 -3
  59. data/test/test_data/locales/invalid/empty.yml +0 -0
  60. data/test/test_data/locales/invalid/syntax.yml +0 -4
  61. data/test/test_data/locales/plurals.rb +0 -113
  62. data/test/test_helper.rb +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e56b50c83ab6291a1321b462814b80ad73d74d01cb77c25ab6a1d948c8737afc
4
- data.tar.gz: 23d1ac1b19a36a2543e063f612170f45be6d404d2ff258c611c75be159dde98c
3
+ metadata.gz: 8f090f4664c260c453c6287eda93ccabd1681c8ca2cef077794fcc8ec32dab4f
4
+ data.tar.gz: 639643c1611bd9800407a84b1fc4c0dcf57e85e9cab85c9a4a82e56418a15a48
5
5
  SHA512:
6
- metadata.gz: b555490dcb1c101f72f04f6ce9f257070da32021906355f7ccf96ee8ef62d33fda682e75bfb634d91c13afc72fa2d6f74135721a0df40c473edb083cf0a04360
7
- data.tar.gz: 810d9280d42cf03d60d4251371bad79f602799b786660413e00b8f4d351a81c70b0ad7f4223ac276d0600721139e367b2b39a656f6d60335993bcc46d30abafb
6
+ metadata.gz: 8b9747cc4ba7e203400ed38c21a2c6e5c35b45c4283bd56e4cb608b72c3904e6117d80b11a91b97753344ac0185fae0f340e3687b26eb40a95669d0039fad6ee
7
+ data.tar.gz: 48aa51116fe7450ce06036dbd537e7711d66d755a4001bc148936573c08b74744428cf5877f757fe53fb6326d8b99f891639a31844396d9c24e1ff2477cebd1d
data/README.md CHANGED
@@ -104,6 +104,10 @@ the API definition test methods in test/api/tests.
104
104
  All other test cases (e.g. as defined in test/backend, test/core_ext) etc.
105
105
  follow the usual test setup and should be easy to grok.
106
106
 
107
+ ## More Documentation
108
+
109
+ Additional documentation can be found here: https://github.com/svenfuchs/i18n/wiki
110
+
107
111
  ## Authors
108
112
 
109
113
  * [Sven Fuchs](http://www.artweb-design.de)
@@ -5,6 +5,7 @@ module I18n
5
5
  autoload :Base, 'i18n/backend/base'
6
6
  autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
7
7
  autoload :Cache, 'i18n/backend/cache'
8
+ autoload :CacheFile, 'i18n/backend/cache_file'
8
9
  autoload :Cascade, 'i18n/backend/cascade'
9
10
  autoload :Chain, 'i18n/backend/chain'
10
11
  autoload :Fallbacks, 'i18n/backend/fallbacks'
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require 'json'
4
5
  require 'i18n/core_ext/hash'
5
6
 
6
7
  module I18n
@@ -9,7 +10,7 @@ module I18n
9
10
  include I18n::Backend::Transliterator
10
11
 
11
12
  # Accepts a list of paths to translation files. Loads translations from
12
- # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
13
+ # plain Ruby (*.rb), YAML files (*.yml), or JSON files (*.json). See #load_rb, #load_yml, and #load_json
13
14
  # for details.
14
15
  def load_translations(*filenames)
15
16
  filenames = I18n.load_path if filenames.empty?
@@ -235,6 +236,16 @@ module I18n
235
236
  end
236
237
  alias_method :load_yaml, :load_yml
237
238
 
239
+ # Loads a JSON translations file. The data must have locales as
240
+ # toplevel keys.
241
+ def load_json(filename)
242
+ begin
243
+ ::JSON.parse(File.read(filename))
244
+ rescue TypeError, StandardError => e
245
+ raise InvalidLocaleData.new(filename, e.inspect)
246
+ end
247
+ end
248
+
238
249
  def translate_localization_format(locale, object, format, options)
239
250
  format.to_s.gsub(/%[aAbBpP]/) do |match|
240
251
  case match
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/sha2'
4
+
5
+ module I18n
6
+ module Backend
7
+ # Overwrites the Base load_file method to cache loaded file contents.
8
+ module CacheFile
9
+ # Optionally provide path_roots array to normalize filename paths,
10
+ # to make the cached i18n data portable across environments.
11
+ attr_accessor :path_roots
12
+
13
+ protected
14
+
15
+ # Track loaded translation files in the `i18n.load_file` scope,
16
+ # and skip loading the file if its contents are still up-to-date.
17
+ def load_file(filename)
18
+ initialized = !respond_to?(:initialized?) || initialized?
19
+ key = I18n::Backend::Flatten.escape_default_separator(normalized_path(filename))
20
+ old_mtime, old_digest = initialized && lookup(:i18n, key, :load_file)
21
+ return if (mtime = File.mtime(filename).to_i) == old_mtime ||
22
+ (digest = Digest::SHA2.file(filename).hexdigest) == old_digest
23
+ super
24
+ store_translations(:i18n, load_file: { key => [mtime, digest] })
25
+ end
26
+
27
+ # Translate absolute filename to relative path for i18n key.
28
+ def normalized_path(file)
29
+ return file unless path_roots
30
+ path = path_roots.find(&file.method(:start_with?)) ||
31
+ raise(InvalidLocaleData.new(file, 'outside expected path roots'))
32
+ file.sub(path, path_roots.index(path).to_s)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -26,6 +26,15 @@ module I18n
26
26
  self.backends = backends
27
27
  end
28
28
 
29
+ def initialized?
30
+ backends.all? do |backend|
31
+ backend.instance_eval do
32
+ return false unless initialized?
33
+ end
34
+ end
35
+ true
36
+ end
37
+
29
38
  def reload!
30
39
  backends.each { |backend| backend.reload! }
31
40
  end
@@ -74,6 +83,19 @@ module I18n
74
83
  end
75
84
 
76
85
  protected
86
+ def init_translations
87
+ backends.each do |backend|
88
+ backend.send(:init_translations)
89
+ end
90
+ end
91
+
92
+ def translations
93
+ backends.first.instance_eval do
94
+ init_translations unless initialized?
95
+ translations
96
+ end
97
+ end
98
+
77
99
  def namespace_lookup?(result, options)
78
100
  result.is_a?(Hash) && !options.has_key?(:count)
79
101
  end
@@ -76,6 +76,10 @@ module I18n
76
76
  @store, @subtrees = store, subtrees
77
77
  end
78
78
 
79
+ def initialized?
80
+ !@store.nil?
81
+ end
82
+
79
83
  def store_translations(locale, data, options = EMPTY_HASH)
80
84
  escape = options.fetch(:escape, true)
81
85
  flatten_translations(locale, data, escape, @subtrees).each do |key, value|
@@ -105,6 +109,26 @@ module I18n
105
109
 
106
110
  protected
107
111
 
112
+ # Queries the translations from the key-value store and converts
113
+ # them into a hash such as the one returned from loading the
114
+ # haml files
115
+ def translations
116
+ @translations = @store.keys.clone.map do |main_key|
117
+ main_value = JSON.decode(@store[main_key])
118
+ main_key.to_s.split(".").reverse.inject(main_value) do |value, key|
119
+ {key.to_sym => value}
120
+ end
121
+ end.inject{|hash, elem| hash.deep_merge!(elem)}.deep_symbolize_keys
122
+ end
123
+
124
+ def init_translations
125
+ # NO OP
126
+ # This call made also inside Simple Backend and accessed by
127
+ # other plugins like I18n-js and babilu and
128
+ # to use it along with the Chain backend we need to
129
+ # provide a uniform API even for protected methods :S
130
+ end
131
+
108
132
  def subtrees?
109
133
  @subtrees
110
134
  end
@@ -39,7 +39,7 @@ module I18n
39
39
  end
40
40
  locale = locale.to_sym
41
41
  translations[locale] ||= {}
42
- data = data.deep_symbolize_keys
42
+ data = data.deep_stringify_keys.deep_symbolize_keys
43
43
  translations[locale].deep_merge!(data)
44
44
  end
45
45
 
@@ -145,5 +145,21 @@ module I18n
145
145
  def enforce_available_locales=(enforce_available_locales)
146
146
  @@enforce_available_locales = enforce_available_locales
147
147
  end
148
+
149
+ # Returns the current interpolation patterns. Defaults to
150
+ # I18n::DEFAULT_INTERPOLATION_PATTERNS.
151
+ def interpolation_patterns
152
+ @@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup
153
+ end
154
+
155
+ # Sets the current interpolation patterns. Used to set a interpolation
156
+ # patterns.
157
+ #
158
+ # E.g. using {{}} as a placeholder like "{{hello}}, world!":
159
+ #
160
+ # I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/
161
+ def interpolation_patterns=(interpolation_patterns)
162
+ @@interpolation_patterns = interpolation_patterns
163
+ end
148
164
  end
149
165
  end
@@ -17,6 +17,14 @@ class Hash
17
17
  }
18
18
  end unless Hash.method_defined?(:deep_symbolize_keys)
19
19
 
20
+ def deep_stringify_keys
21
+ inject({}) { |result, (key, value)|
22
+ value = value.deep_stringify_keys if value.is_a?(Hash)
23
+ result[key.to_s] = value
24
+ result
25
+ }
26
+ end unless Hash.method_defined?(:deep_stringify_keys)
27
+
20
28
  # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
21
29
  MERGER = proc do |key, v1, v2|
22
30
  Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
@@ -2,11 +2,13 @@
2
2
  # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
3
3
 
4
4
  module I18n
5
- INTERPOLATION_PATTERN = Regexp.union(
5
+ DEFAULT_INTERPOLATION_PATTERNS = [
6
6
  /%%/,
7
7
  /%\{(\w+)\}/, # matches placeholders like "%{foo}"
8
8
  /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
9
- )
9
+ ].freeze
10
+ INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
11
+ deprecate_constant :INTERPOLATION_PATTERN if method_defined? :INTERPOLATION_PATTERN
10
12
 
11
13
  class << self
12
14
  # Return String or raises MissingInterpolationArgument exception.
@@ -18,7 +20,7 @@ module I18n
18
20
  end
19
21
 
20
22
  def interpolate_hash(string, values)
21
- string.gsub(INTERPOLATION_PATTERN) do |match|
23
+ string.gsub(Regexp.union(config.interpolation_patterns)) do |match|
22
24
  if match == '%%'
23
25
  '%'
24
26
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.1.1"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2018-10-14 00:00:00.000000000 Z
16
+ date: 2018-12-11 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -37,17 +37,11 @@ extra_rdoc_files: []
37
37
  files:
38
38
  - MIT-LICENSE
39
39
  - README.md
40
- - gemfiles/Gemfile.rails-3.2.x
41
- - gemfiles/Gemfile.rails-4.0.x
42
- - gemfiles/Gemfile.rails-4.1.x
43
- - gemfiles/Gemfile.rails-4.2.x
44
- - gemfiles/Gemfile.rails-5.0.x
45
- - gemfiles/Gemfile.rails-5.1.x
46
- - gemfiles/Gemfile.rails-master
47
40
  - lib/i18n.rb
48
41
  - lib/i18n/backend.rb
49
42
  - lib/i18n/backend/base.rb
50
43
  - lib/i18n/backend/cache.rb
44
+ - lib/i18n/backend/cache_file.rb
51
45
  - lib/i18n/backend/cascade.rb
52
46
  - lib/i18n/backend/chain.rb
53
47
  - lib/i18n/backend/fallbacks.rb
@@ -89,48 +83,6 @@ files:
89
83
  - lib/i18n/tests/pluralization.rb
90
84
  - lib/i18n/tests/procs.rb
91
85
  - lib/i18n/version.rb
92
- - test/api/all_features_test.rb
93
- - test/api/cascade_test.rb
94
- - test/api/chain_test.rb
95
- - test/api/fallbacks_test.rb
96
- - test/api/key_value_test.rb
97
- - test/api/memoize_test.rb
98
- - test/api/override_test.rb
99
- - test/api/pluralization_test.rb
100
- - test/api/simple_test.rb
101
- - test/backend/cache_test.rb
102
- - test/backend/cascade_test.rb
103
- - test/backend/chain_test.rb
104
- - test/backend/exceptions_test.rb
105
- - test/backend/fallbacks_test.rb
106
- - test/backend/interpolation_compiler_test.rb
107
- - test/backend/key_value_test.rb
108
- - test/backend/memoize_test.rb
109
- - test/backend/metadata_test.rb
110
- - test/backend/pluralization_test.rb
111
- - test/backend/simple_test.rb
112
- - test/backend/transliterator_test.rb
113
- - test/core_ext/hash_test.rb
114
- - test/gettext/api_test.rb
115
- - test/gettext/backend_test.rb
116
- - test/i18n/exceptions_test.rb
117
- - test/i18n/gettext_plural_keys_test.rb
118
- - test/i18n/interpolate_test.rb
119
- - test/i18n/load_path_test.rb
120
- - test/i18n/middleware_test.rb
121
- - test/i18n_test.rb
122
- - test/locale/fallbacks_test.rb
123
- - test/locale/tag/rfc4646_test.rb
124
- - test/locale/tag/simple_test.rb
125
- - test/run_all.rb
126
- - test/test_data/locales/de.po
127
- - test/test_data/locales/en.rb
128
- - test/test_data/locales/en.yaml
129
- - test/test_data/locales/en.yml
130
- - test/test_data/locales/invalid/empty.yml
131
- - test/test_data/locales/invalid/syntax.yml
132
- - test/test_data/locales/plurals.rb
133
- - test/test_helper.rb
134
86
  homepage: http://github.com/svenfuchs/i18n
135
87
  licenses:
136
88
  - MIT
@@ -139,7 +91,19 @@ metadata:
139
91
  changelog_uri: https://github.com/svenfuchs/i18n/releases
140
92
  documentation_uri: https://guides.rubyonrails.org/i18n.html
141
93
  source_code_uri: https://github.com/svenfuchs/i18n
142
- post_install_message:
94
+ post_install_message: |2+
95
+
96
+ HEADS UP! i18n 1.1 changed fallbacks to exclude default locale.
97
+ But that may break your application.
98
+
99
+ Please check your Rails app for 'config.i18n.fallbacks = true'.
100
+ If you're using I18n 1.1.x and Rails (< 6.0), this should be
101
+ 'config.i18n.fallbacks = [I18n.default_locale]'.
102
+ If not, fallbacks will be broken in your app by I18n 1.1.x.
103
+
104
+ For more info see:
105
+ https://github.com/svenfuchs/i18n/releases/tag/v1.1.0
106
+
143
107
  rdoc_options: []
144
108
  require_paths:
145
109
  - lib
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 3.2.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 4.0.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 4.1.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 4.2.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 5.0.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 5.1.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', github: 'rails/rails', branch: 'master'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'