i18n-tasks 0.9.18 → 0.9.19

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
  SHA1:
3
- metadata.gz: 6c8f584095c296651d391ff4d7bda8f7976ed897
4
- data.tar.gz: '0886ab5028387f20c2b6a5a246fb9435a7285ce1'
3
+ metadata.gz: a645618f76025d6f6c0e9c1e82d19cf049aa5f7a
4
+ data.tar.gz: b5d360c72ce14d141757a177c3f4a906ad84588d
5
5
  SHA512:
6
- metadata.gz: 84624f8fda11ae08790761f4e6f2490abe6cd3f04d8783b2e3bfd0e809b40eecaae7dfa6643b6db45e3c92152fedf9ca8e131808295b9ff08469e8c8bfe82c53
7
- data.tar.gz: 660b804e12dec65e30ccd96f0441fd8eea8fcc0b20a8eb3a64b8fb7e5f5bce18927f45c5fddb8844a058d3d98faaa17a0ae785599b026215a317db3088140e70
6
+ metadata.gz: 2ec7dd16adc0fe0aba80ea32f4ba7f60d665646be16f0c58fd7f5b34a6b8e5412a55678068f1e1daf5be5c660e4a2baf9216e80be6a8bef6e8dcc000fd425d6c
7
+ data.tar.gz: b4f7c9a678a51534a5fdc15c3efc09e8e3ccec18de6b08246b4ae456a412c4190db148a621e6b933b6228db6193146aa9b3bbfd809500e0219c0d81280c26ed2
data/README.md CHANGED
@@ -24,7 +24,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
24
24
  Add i18n-tasks to the Gemfile:
25
25
 
26
26
  ```ruby
27
- gem 'i18n-tasks', '~> 0.9.18'
27
+ gem 'i18n-tasks', '~> 0.9.19'
28
28
  ```
29
29
 
30
30
  Copy the default [configuration file](#configuration):
@@ -37,9 +37,8 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
37
37
  end
38
38
 
39
39
  def config=(conf)
40
- @config = file_config.deep_merge(conf)
40
+ @config = file_config.deep_merge(conf)
41
41
  @config_sections = {}
42
- @config
43
42
  end
44
43
 
45
44
  # data config
@@ -110,7 +109,7 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
110
109
 
111
110
  def config_for_inspect
112
111
  to_hash_from_indifferent(config_sections.reject { |_k, v| v.blank? }).tap do |sections|
113
- sections.each do |_k, section|
112
+ sections.each_value do |section|
114
113
  section.merge! section.delete('config') if section.is_a?(Hash) && section.key?('config')
115
114
  end
116
115
  end
@@ -59,12 +59,16 @@ module I18n::Tasks
59
59
  !t(key, locale).nil?
60
60
  end
61
61
 
62
+ def external_key?(key, locale = base_locale)
63
+ data.external(locale)[locale.to_s][key]
64
+ end
65
+
62
66
  # Normalize all the locale data in the store (by writing to the store).
63
67
  #
64
68
  # @param [Array<String>] locales locales to normalize. Default: all.
65
69
  # @param [Boolean] force_pattern_router Whether to use pattern router regardless of the config.
66
70
  def normalize_store!(locales: nil, force_pattern_router: false)
67
- locales = self.locales unless locales
71
+ locales ||= self.locales
68
72
  router = force_pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
69
73
  data.with_router(router) do
70
74
  Array(locales).each do |target_locale|
@@ -32,27 +32,45 @@ module I18n::Tasks
32
32
  end
33
33
  end
34
34
 
35
- # get locale tree
35
+ # @param [String, Symbol] locale
36
+ # @return [::I18n::Tasks::Data::Siblings]
36
37
  def get(locale)
37
38
  locale = locale.to_s
38
- @trees ||= {}
39
- @trees[locale] ||= Tree::Siblings[locale => {}].merge!(
40
- read_locale(locale)
41
- )
39
+ @trees ||= {}
40
+ @trees[locale] ||= read_locale(locale)
42
41
  end
43
42
 
44
43
  alias [] get
45
44
 
45
+ # @param [String, Symbol] locale
46
+ # @return [::I18n::Tasks::Data::Siblings]
47
+ def external(locale)
48
+ locale = locale.to_s
49
+ @external ||= {}
50
+ @external[locale] ||= read_locale(locale, paths: config[:external])
51
+ end
52
+
46
53
  # set locale tree
54
+ # @param [String, Symbol] locale
55
+ # @param [::I18n::Tasks::Data::Siblings] tree
47
56
  def set(locale, tree)
48
57
  locale = locale.to_s
58
+ @trees.delete(locale) if @trees
59
+ paths_before = Set.new(get(locale)[locale].leaves.map { |node| node.data[:path] })
60
+ paths_after = Set.new([])
49
61
  router.route locale, tree do |path, tree_slice|
62
+ paths_after << path
50
63
  write_tree path, tree_slice
51
64
  end
65
+ (paths_before - paths_after).each do |path|
66
+ FileUtils.remove_file(path) if File.exist?(path)
67
+ end
52
68
  @trees.delete(locale) if @trees
53
69
  @available_locales = nil
54
70
  end
55
71
 
72
+ alias []= set
73
+
56
74
  # @param [String] locale
57
75
  # @return [Array<String>] paths to files that are not normalized
58
76
  def non_normalized_paths(locale)
@@ -62,7 +80,7 @@ module I18n::Tasks
62
80
  end
63
81
 
64
82
  def write(forest)
65
- forest.each { |root| set(root.key, root) }
83
+ forest.each { |root| set(root.key, root.to_siblings) }
66
84
  end
67
85
 
68
86
  def merge!(forest)
@@ -76,15 +94,14 @@ module I18n::Tasks
76
94
 
77
95
  def remove_by_key!(forest)
78
96
  forest.inject(Tree::Siblings.new) do |removed, root|
79
- locale_data = get(root.key)
97
+ locale = root.key
98
+ locale_data = get(locale)
80
99
  subtracted = locale_data.subtract_by_key(forest)
81
- set root.key, subtracted
100
+ set locale, subtracted
82
101
  removed.merge! locale_data.subtract_by_key(subtracted)
83
102
  end
84
103
  end
85
104
 
86
- alias []= set
87
-
88
105
  # @return self
89
106
  def reload
90
107
  @trees = nil
@@ -145,17 +162,17 @@ module I18n::Tasks
145
162
 
146
163
  protected
147
164
 
148
- def read_locale(locale)
149
- Array(config[:read]).map do |path|
165
+ def read_locale(locale, paths: config[:read])
166
+ Array(paths).flat_map do |path|
150
167
  Dir.glob format(path, locale: locale)
151
- end.reduce(:+).map do |path|
168
+ end.map do |path|
152
169
  [path.freeze, load_file(path) || {}]
153
170
  end.map do |path, data|
154
171
  filter_nil_keys! path, data
155
172
  Data::Tree::Siblings.from_nested_hash(data).tap do |s|
156
173
  s.leaves { |x| x.data.update(path: path, locale: locale) }
157
174
  end
158
- end.reduce(:merge!) || Tree::Siblings.null
175
+ end.reduce(Tree::Siblings[locale => {}], :merge!)
159
176
  end
160
177
 
161
178
  def filter_nil_keys!(path, data, suffix = [])
@@ -23,7 +23,9 @@ module I18n::Tasks
23
23
  end
24
24
 
25
25
  # Route keys to destinations
26
- # @param forest [I18n::Tasks::LocaleTree::Siblings] forest roots are locales.
26
+ # @param forest [I18n::Tasks::Data::Tree::Siblings] forest roots are locales.
27
+ # @yieldparam [String] dest_path
28
+ # @yieldparam [I18n::Tasks::Data::Tree::Siblings] tree_slice
27
29
  # @return [Hash] mapping of destination => [ [key, value], ... ]
28
30
  def route(locale, forest, &block)
29
31
  return to_enum(:route, locale, forest) unless block
@@ -181,7 +181,7 @@ module I18n::Tasks
181
181
  if key_pattern.present?
182
182
  pattern_re = I18n::Tasks::KeyPatternMatching.compile_key_pattern(key_pattern)
183
183
  end
184
- keys.each do |key, node|
184
+ keys.each do |key, node| # rubocop:disable Performance/HashEachMethods
185
185
  next if pattern_re && key !~ pattern_re
186
186
  node.value = value_proc.call(node)
187
187
  end
@@ -85,7 +85,7 @@ module I18n::Tasks
85
85
  end
86
86
 
87
87
  def locale_key_missing?(locale, key)
88
- !key_value?(key, locale) && !ignore_key?(key, :missing)
88
+ !key_value?(key, locale) && !external_key?(key) && !ignore_key?(key, :missing)
89
89
  end
90
90
 
91
91
  # @param [::I18n::Tasks::Data::Tree::Siblings] forest
@@ -65,7 +65,7 @@ module I18n::Tasks::Scanners
65
65
  re && re =~ line
66
66
  end
67
67
 
68
- VALID_KEY_RE_DYNAMIC = /^(#{VALID_KEY_CHARS}|[:\#{@}\[\]])+$/
68
+ VALID_KEY_RE_DYNAMIC = /^(#{VALID_KEY_CHARS}|[:\#{@}\[\]])+$/ # rubocop:disable Lint/InterpolationCheck
69
69
 
70
70
  def valid_key?(key)
71
71
  if @config[:strict]
@@ -34,12 +34,12 @@ module I18n::Tasks::Scanners
34
34
 
35
35
  # parse expressions with literals and variable
36
36
  def first_argument_re
37
- /(?: (?: #{literal_re} ) | #{variable_re} )/x
37
+ /(?: (?: #{literal_re} ) | #{expr_re} )/x
38
38
  end
39
39
 
40
40
  # strip literals, convert expressions to #{interpolations}
41
41
  def strip_literal(val)
42
- if val =~ /\A\w/
42
+ if val =~ /\A[\w@]/
43
43
  "\#{#{val}}"
44
44
  else
45
45
  super(val)
@@ -54,17 +54,9 @@ module I18n::Tasks::Scanners
54
54
  ) (\[[^\n)%#]*\]|[^\n)%#,]*)/x
55
55
  end
56
56
 
57
- # match code expression
58
- # matches characters until , as a heuristic to parse scopes like [:categories, cat.key]
59
- # can be massively improved by matching parenthesis
57
+ # match a limited subset of code expressions (no parenthesis, commas, etc)
60
58
  def expr_re
61
- /[\w():"'.\s]+/x
62
- end
63
-
64
- # match variable key
65
- # e.g: t(key, scope: 'scope') => t('scope.#{key}')
66
- def variable_re
67
- /\w+/
59
+ /[\w@.&|\s?!]+/
68
60
  end
69
61
 
70
62
  # extract literal or array of literals
@@ -115,7 +115,7 @@ module I18n::Tasks::Scanners
115
115
  def extract_string(node, array_join_with: nil, array_flatten: false, array_reject_blank: false)
116
116
  if %i[sym str int].include?(node.type)
117
117
  node.children[0].to_s
118
- elsif %i[true false].include?(node.type)
118
+ elsif %i[true false].include?(node.type) # rubocop:disable Lint/BooleanSymbol
119
119
  node.type.to_s
120
120
  elsif node.type == :nil
121
121
  ''
@@ -149,7 +149,7 @@ module I18n::Tasks::Scanners
149
149
  # @return [String, nil] `nil` is returned only when a dynamic value is encountered in strict mode.
150
150
  def extract_array_as_string(node, array_join_with:, array_flatten: false, array_reject_blank: false)
151
151
  children_strings = node.children.map do |child|
152
- if %i[sym str int true false].include?(child.type)
152
+ if %i[sym str int true false].include?(child.type) # rubocop:disable Lint/BooleanSymbol
153
153
  extract_string child
154
154
  else
155
155
  # ignore dynamic argument in strict mode
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
- VERSION = '0.9.18'
5
+ VERSION = '0.9.19'
6
6
  end
7
7
  end
@@ -19,8 +19,6 @@ data:
19
19
  # - config/locales/%{locale}.yml
20
20
  ## More files:
21
21
  # - config/locales/**/*.%{locale}.yml
22
- ## Another gem (replace %#= with %=):
23
- # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
24
22
 
25
23
  # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
26
24
  # `i18n-tasks normalize -p` will force move the keys according to these rules
@@ -30,6 +28,12 @@ data:
30
28
  ## Catch-all default:
31
29
  # - config/locales/%{locale}.yml
32
30
 
31
+ # External locale data (e.g. gems).
32
+ # This data is not considered unused and is never written to.
33
+ external:
34
+ ## Example (replace %#= with %=):
35
+ # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
36
+
33
37
  ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
34
38
  # router: conservative_router
35
39
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.18
4
+ version: 0.9.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-13 00:00:00.000000000 Z
11
+ date: 2017-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport