i18n-tasks 0.1.6 → 0.1.7

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: b5394593809b1be9eabef55d84ee0cf8ce692884
4
- data.tar.gz: 5629b833e0ef043538a387a3eff45a1e16fdbc6f
3
+ metadata.gz: fba31809b28d7db5c2f2febad005236e8e4b7e1b
4
+ data.tar.gz: 0b3f032893745205af5368c017fe092fea521b26
5
5
  SHA512:
6
- metadata.gz: 80141dbe9b294f9e83b3d1a812aa5f3381e2909ddf8175cec2df66dae8da310e6aedda8d36bb7a11c511d04e41a59972469eabe6475b88f0cfa0065034efa9b7
7
- data.tar.gz: a0c620f7af53c0aa9f820afc057eb658f8c84d43caad4a9affdb1854d1b5ecacf76ceef4288b7265eaecca2382e0f3a8e6de226e7c21205c9aaf0d3a54a441a1
6
+ metadata.gz: ca884fd7cd3f02830003fb4fe8e13586fa162c22b328a17c39f0655e08005e03073ac193b6d57c50e3edb619b93bfc316eef873a761fb4bbdaac2d16d05c6375
7
+ data.tar.gz: 3ebcfa3023b2b5c6cb83181382a51253ffca5ce2ed476d9167495da31d19358ed8db3b8bd2401b522295f64312bdad9f51f5884a1de17145474eb3a45458d538
data/CHANGES.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## v0.1.7
2
+
3
+ * ability to route prefill output via data.write config (@glebm)
4
+ * multiple configuration variables renamed (still understands old syntax with deprecation warnings) (@glebm)
5
+
1
6
  ## v0.1.6
2
7
 
3
8
  * New key pattern syntax for i18n-tasks.yml a la globbing (@glebm)
data/README.md CHANGED
@@ -8,8 +8,9 @@ Rails I18n tasks to find missing / unused translations and more. Works with slim
8
8
  Use `rake -T i18n` to get the list of tasks with descriptions. There are 3 tasks available at the moment:
9
9
 
10
10
  * `i18n:missing` task shows all the keys that have not been translated yet *([source](/lib/i18n/tasks/missing.rb))*
11
- * `i18n:prefill` task normalizes locale files, and adds missing keys from base locale to others *([source](/lib/i18n/tasks/prefill.rb))*
12
11
  * `i18n:unused` task shows potentially unused translations *([source](/lib/i18n/tasks/unused.rb))*
12
+ * `i18n:prefill` task normalizes locale files, and adds missing keys from base locale to others *([source](/lib/i18n/tasks/prefill.rb))*
13
+
13
14
 
14
15
  The `i18n:unused` task will detect pattern translations and not report them, e.g.:
15
16
 
@@ -18,7 +19,7 @@ t 'category.' + category.key # 'category.arts_and_crafts' considered used
18
19
  t "category.#{category.key}" # also works
19
20
  ```
20
21
 
21
- Relative keys (`t '.title'`) are supported. Plural keys (key.one/many/other/etc) are supported.
22
+ Relative keys (`t '.title'`) and plural keys (key.one/many/other/etc) are fully supported.
22
23
 
23
24
  For more examples see [the tests](/spec/i18n_tasks_spec.rb).
24
25
 
@@ -36,9 +37,58 @@ gem 'i18n-tasks', '~> 0.1.0'
36
37
 
37
38
  ## Configuration
38
39
 
39
- Tasks may incorrectly report framework i18n keys as missing. You can add `config/i18n-tasks.yml` to work around this:
40
+ Configuration is read from `i18n-tasks/config.yml`.
41
+
42
+ ### Storage
43
+
44
+ ```yaml
45
+ # i18n data storage
46
+ data:
47
+ # The default YAML adapter supports reading from and writing to YAML files
48
+ adapter: yaml
49
+ # yaml adapter read option is a list of glob patterns of files to read from per-locale
50
+ read:
51
+ # this one is default:
52
+ - 'config/locales/%{locale}.yml'
53
+ # this one would add some more files:
54
+ - 'config/locales/*.%{locale}.yml'
55
+ # yaml adapter write option a list of key pattern => output filename "routes" per-locale
56
+ write:
57
+ # keys matched top to bottom
58
+ - ['devise.*', 'config/locales/devise.%{locale}.yml']
59
+ # default catch-all (same as ['*', 'config/locales/%{locale}.yml'])
60
+ - 'config/locales/%{locale}.yml'
61
+ ```
62
+
63
+ ### Usage search
40
64
 
41
65
  ```yaml
66
+ # i18n usage search in source
67
+ search:
68
+ # search these directories (relative to your Rails.root directory, default: 'app/')
69
+ paths:
70
+ - 'app/'
71
+ - 'vendor/'
72
+ # include only files matching this glob pattern (default: blank = include all files)
73
+ include:
74
+ - '*.rb'
75
+ - '*.html.*'
76
+ - '*.text.*'
77
+ # explicitly exclude files (default: blank = exclude no files)
78
+ exclude: '*.js'
79
+ # search uses grep under the hood
80
+ ```
81
+
82
+ ### Fine-tuning
83
+
84
+ Tasks may incorrectly report framework i18n keys as missing, also some patterns may not be detected.
85
+ When all else fails, use the options below.
86
+
87
+ ```yaml
88
+ # do not report these keys as unused
89
+ ignore_unused:
90
+ - category.*.db_name
91
+
42
92
  # do not report these keys as missing (both on blank value and no key)
43
93
  ignore_missing:
44
94
  - devise.errors.unauthorized # ignore this key
@@ -51,33 +101,9 @@ ignore_eq_base:
51
101
  es,fr:
52
102
  - common.brand
53
103
 
54
- # do not report these keys as unused
55
- ignore_unused:
56
- - category.*
57
-
58
104
  # do not report these keys ever
59
105
  ignore:
60
106
  - kaminari.*
61
-
62
- # where to read locale data from
63
- data:
64
- # read paths for a given %{locale} (supports globs)
65
- paths:
66
- - 'config/locales/%{locale}.yml'
67
- # you can also implement a custom storage layer, see the yaml one below
68
- class: I18n::Tasks::Data::Yaml
69
-
70
- # search configuration (grep arguments)
71
- grep:
72
- # search these directories (relative to your Rails.root directory, default: 'app/')
73
- paths:
74
- - 'app/'
75
- # include only files matching this glob pattern (default: blank = include all files)
76
- include:
77
- - '*.rb'
78
- - '*.html*'
79
- # explicitly exclude files (default: blank = exclude no files)
80
- exclude: '*.js'
81
107
  ```
82
108
 
83
109
  ## HTML report
data/lib/i18n/tasks.rb CHANGED
@@ -1,10 +1,8 @@
1
1
  require 'i18n/tasks/version'
2
2
  require 'i18n/tasks/railtie'
3
- require 'i18n/tasks/key_pattern_matching'
4
-
5
- require 'i18n/tasks/data/yaml'
6
- require 'active_support/hash_with_indifferent_access'
7
- require 'active_support/core_ext/string/access'
3
+ require 'active_support/core_ext/hash'
4
+ require 'active_support/core_ext/string'
5
+ require 'term/ansicolor'
8
6
 
9
7
  module I18n
10
8
  module Tasks
@@ -17,6 +15,10 @@ module I18n
17
15
  HashWithIndifferentAccess.new.merge(file.presence || {})
18
16
  end
19
17
  end
18
+
19
+ def warn_deprecated(message)
20
+ STDERR.puts Term::ANSIColor.yellow Term::ANSIColor.bold "i18n-tasks: [DEPRECATED] #{message}"
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -1,19 +1,18 @@
1
1
  # coding: utf-8
2
- require 'term/ansicolor'
3
- require 'i18n/tasks/usage_search'
4
- require 'i18n/tasks/fuzzy_source_keys'
5
- require 'i18n/tasks/plural_keys'
2
+ require 'i18n/tasks/key_pattern_matching'
6
3
  require 'i18n/tasks/relative_keys'
4
+ require 'i18n/tasks/plural_keys'
5
+ require 'i18n/tasks/source_keys'
7
6
  require 'i18n/tasks/translation_data'
8
7
  require 'i18n/tasks/ignore_keys'
9
8
 
10
9
  module I18n
11
10
  module Tasks
12
11
  class BaseTask
13
- include UsageSearch
14
- include PluralKeys
12
+ include KeyPatternMatching
15
13
  include RelativeKeys
16
- include FuzzySourceKeys
14
+ include PluralKeys
15
+ include SourceKeys
17
16
  include TranslationData
18
17
  include IgnoreKeys
19
18
 
@@ -22,6 +21,11 @@ module I18n
22
21
  def config
23
22
  I18n::Tasks.config
24
23
  end
24
+
25
+ def warn_deprecated(message)
26
+ I18n::Tasks.warn_deprecated(message)
27
+ end
28
+
25
29
  end
26
30
  end
27
31
  end
@@ -1,22 +1,62 @@
1
+ require 'i18n/tasks/data_traversal'
2
+ require 'i18n/tasks/key_pattern_matching'
1
3
  module I18n::Tasks
2
4
  module Data
3
5
  class Yaml
6
+ include ::I18n::Tasks::DataTraversal
7
+ include ::I18n::Tasks::KeyPatternMatching
4
8
  attr_reader :options
5
9
 
10
+ DEFAULTS = {
11
+ read: ['config/locales/%{locale}.yml'],
12
+ write: ['config/locales/%{locale}.yml']
13
+ }.with_indifferent_access
14
+
6
15
  def initialize(options)
7
- @options = options
16
+ opt = (options || {}).with_indifferent_access
17
+ if opt.key?(:paths)
18
+ opt[:read] ||= opt.delete(:paths)
19
+ ::I18n::Tasks.warn_deprecated 'please rename "data.paths" key to "data.read" in config/i18n-tasks.yml'
20
+ end
21
+ opt = DEFAULTS.deep_merge(opt)
22
+ @read = opt[:read]
23
+ @write = opt[:write].map { |x| x.is_a?(String) ? ['*', x] : x }.map { |x|
24
+ [key_pattern_to_re(x[0]), x[1]]
25
+ }
8
26
  end
9
27
 
28
+ # get locale tree
10
29
  def get(locale)
11
- options[:paths].map do |path|
12
- Dir.glob path % { locale: locale }
13
- end.flatten.map do |locale_file|
14
- YAML.load_file locale_file
15
- end.inject({}) do |hash, locale_data|
16
- hash.deep_merge! locale_data || {}
17
- hash
30
+ locale = locale.to_s
31
+ (@locale_data ||= {})[locale] ||= begin
32
+ @read.map do |path|
33
+ Dir.glob path % {locale: locale}
34
+ end.flatten.map do |locale_file|
35
+ YAML.load_file locale_file
36
+ end.inject({}) do |hash, locale_data|
37
+ hash.deep_merge! locale_data || {}
38
+ hash
39
+ end[locale.to_s]
40
+ end
41
+ end
42
+
43
+ alias [] get
44
+
45
+ # set locale tree
46
+ def set(locale, value_tree)
47
+ out = {}
48
+ traverse value_tree do |key, value|
49
+ route = @write.detect { |route| route[0] =~ key }
50
+ (out[route[1] % {locale: locale}] ||= []) << [key, value]
51
+ end
52
+ out.each do |path, data|
53
+ File.open(path, 'w') { |f|
54
+ f.write({locale.to_s => list_to_tree(data)}.to_yaml)
55
+ }
18
56
  end
19
57
  end
58
+
59
+ alias []= set
20
60
  end
21
61
  end
22
62
  end
@@ -0,0 +1,40 @@
1
+ module I18n::Tasks::DataTraversal
2
+ # translation of the key found in the passed hash or nil
3
+ # @return [String,nil]
4
+ def t(hash, key)
5
+ key.split('.').inject(hash) { |r, seg| r[seg] if r }
6
+ end
7
+
8
+ # traverse hash, yielding with full key and value
9
+ # @param hash [Hash{String => String,Hash}] translation data to traverse
10
+ # @yield [full_key, value] yields full key and value for every translation in #hash
11
+ # @return [nil]
12
+ def traverse(path = '', hash)
13
+ q = [[path, hash]]
14
+ until q.empty?
15
+ path, value = q.pop
16
+ if value.is_a?(Hash)
17
+ value.each { |k, v| q << ["#{path}.#{k}", v] }
18
+ else
19
+ yield path[1..-1], value
20
+ end
21
+ end
22
+ end
23
+
24
+ def list_to_tree(list)
25
+ list = list.sort
26
+ tree = {}
27
+ list.each do |key, value|
28
+ key_segments = key.to_s.split('.')
29
+ node = key_segments[0..-2].inject(tree) do |r, segment|
30
+ if r.key?(segment)
31
+ r[segment]
32
+ else
33
+ r[segment] = {}
34
+ end
35
+ end
36
+ node[key_segments.last] = value
37
+ end
38
+ tree
39
+ end
40
+ end
@@ -14,7 +14,7 @@ module I18n::Tasks::KeyPatternMatching
14
14
  # convert key.* to key\..*
15
15
  def key_pattern_to_re(key_pattern)
16
16
  if key_pattern.end_with? '.'
17
- $stderr.puts %Q(i18n-tasks: Deprecated "#{key_pattern}", please change to "#{key_pattern += '*'}".)
17
+ warn_deprecated %Q(please change pattern "#{key_pattern}" to "#{key_pattern += '*'}" in config/i18n-tasks.yml)
18
18
  end
19
19
  /^#{key_pattern.
20
20
  gsub(/\./, '\.').
@@ -29,9 +29,9 @@ module I18n
29
29
  # present in base locale, but untranslated in another locale
30
30
  # @return Array{Hash}
31
31
  def keys_missing_translation(locale)
32
- trn = locale_data(locale)[locale]
32
+ trn = data[locale]
33
33
  r = []
34
- traverse base_locale_data do |key, base_value|
34
+ traverse data[base_locale] do |key, base_value|
35
35
  value_in_locale = t(trn, key)
36
36
  if value_in_locale.blank? && !ignore_key?(key, :missing)
37
37
  r << {locale: locale, key: key, type: :blank, base_value: base_value}
@@ -6,29 +6,38 @@ module I18n
6
6
  include Term::ANSIColor
7
7
 
8
8
  def missing(missing)
9
- $stderr.puts bold cyan "Missing keys and translations (#{missing.length})"
9
+ print_title "Missing keys and translations (#{missing.length})"
10
10
  if missing.present?
11
- $stderr.puts "#{bold 'Legend:'} #{red '✗'} key missing, #{yellow bold '∅'} translation blank, #{blue bold '='} value equal to base locale; #{cyan 'value in base locale'}"
11
+ $stderr.puts "#{bold 'Legend:'} #{on_red '✗'} key missing, #{yellow bold '∅'} translation blank, #{blue bold '='} value equal to base locale, #{cyan 'value in base locale'}"
12
12
  key_col_width = missing.map { |x| x[:key] }.max_by(&:length).length + 2
13
13
  missing.each { |m| print_missing_translation m, key_col_width: key_col_width }
14
14
  else
15
- $stderr.puts(bold green 'Good job! No translations missing!')
15
+ print_success 'Good job! No translations missing!'
16
16
  end
17
17
  end
18
18
 
19
19
  def unused(unused)
20
- $stderr.puts bold cyan("Unused i18n keys (#{unused.length})")
20
+ print_title "Unused i18n keys (#{unused.length})"
21
21
  if unused.present?
22
22
  key_col_width = unused.max_by { |x| x[0].length }[0].length + 2
23
23
  unused.each { |(key, value)| puts "#{magenta key.ljust(key_col_width)}#{cyan value.to_s.strip}" }
24
24
  else
25
- $stderr.puts(bold green 'Good job! Every translation is used!')
25
+ print_success 'Good job! Every translation is used!'
26
26
  end
27
27
  end
28
28
 
29
29
  private
30
30
 
31
31
  extend Term::ANSIColor
32
+
33
+ def print_title(title)
34
+ $stderr.puts "#{bold cyan title.strip} #{dark "|"} #{bold "i18n-tasks v#{I18n::Tasks::VERSION}"}"
35
+ end
36
+
37
+ def print_success(message)
38
+ $stderr.puts(bold green message)
39
+ end
40
+
32
41
  STATUS_TEXTS = {
33
42
  none: red("✗".ljust(6)),
34
43
  blank: yellow(bold '∅'.ljust(6)),
@@ -7,17 +7,9 @@ module I18n
7
7
  def perform
8
8
  # Will also rewrite en, good for ordering
9
9
  I18n.available_locales.map(&:to_s).each do |target_locale|
10
- trn = locale_data(target_locale)
11
- prefilled = { target_locale => base_locale_data }.deep_merge(trn)
12
- File.open(locale_file_path(target_locale), 'w'){ |f| f.write prefilled.to_yaml }
10
+ data[target_locale] = data[base_locale].deep_merge(data[target_locale])
13
11
  end
14
12
  end
15
-
16
- # main locale file path (for writing to)
17
- # @return [String]
18
- def locale_file_path(locale)
19
- "config/locales/#{locale}.yml"
20
- end
21
13
  end
22
14
  end
23
15
  end
@@ -1,19 +1,5 @@
1
1
  require 'open3'
2
- module I18n::Tasks::UsageSearch
3
- # grep config, also from config/i18n-tasks.yml
4
- # @return [Hash{String => String,Hash,Array}]
5
- def grep_config
6
- @grep_config ||= (config[:grep] || {}).with_indifferent_access.tap do |conf|
7
- conf[:paths] = ['app/'] if conf[:paths].blank?
8
- end
9
- end
10
-
11
- # whether the key is used in the source
12
- def used_key?(key)
13
- @used_keys ||= find_source_keys.to_set
14
- @used_keys.include?(key)
15
- end
16
-
2
+ module I18n::Tasks::SourceKeys
17
3
  # find all keys in the source (relative keys are returned in absolutized)
18
4
  # @return [Array<String>]
19
5
  def find_source_keys
@@ -33,8 +19,41 @@ module I18n::Tasks::UsageSearch
33
19
  end
34
20
  end
35
21
 
22
+ # whether the key is used in the source
23
+ def used_key?(key)
24
+ @used_keys ||= find_source_keys.to_set
25
+ @used_keys.include?(key)
26
+ end
27
+
28
+ # dynamically generated keys in the source, e.g t("category.#{category_key}")
29
+ def pattern_key?(key)
30
+ @pattern_keys_re ||= compile_start_with_re(pattern_key_prefixes)
31
+ !!(key =~ @pattern_keys_re)
32
+ end
33
+
34
+ # keys in the source that end with a ., e.g. t("category.#{cat.i18n_key}") or t("category." + category.key)
35
+ def pattern_key_prefixes
36
+ @pattern_keys_prefixes ||=
37
+ find_source_keys.select { |k| k =~ /\#{.*?}/ || k.ends_with?('.') }.map { |k| k.split(/\.?#/)[0].presence }.compact
38
+ end
39
+
36
40
  protected
37
41
 
42
+ # grep config, also from config/i18n-tasks.yml
43
+ # @return [Hash{String => String,Hash,Array}]
44
+ def grep_config
45
+ @grep_config ||= begin
46
+ if config.key?(:grep)
47
+ config[:search] ||= config.delete(:grep)
48
+ warn_deprecated 'please rename "grep" key to "search" in config/i18n-tasks.yml'
49
+ end
50
+ search_config = (config[:search] || {}).with_indifferent_access
51
+ search_config.tap do |conf|
52
+ conf[:paths] = %w(app/) if conf[:paths].blank?
53
+ end
54
+ end
55
+ end
56
+
38
57
  # Run grep searching for source keys and return grep output
39
58
  # @return [String] output of the grep command
40
59
  def run_grep
@@ -1,58 +1,28 @@
1
+ require 'i18n/tasks/data_traversal'
2
+ require 'i18n/tasks/data/yaml'
3
+
1
4
  module I18n::Tasks::TranslationData
2
- # locale data hash, with locale name as root
3
- # @return [Hash{String => String,Hash}] locale data in nested hash format
4
- def locale_data(locale)
5
- locale = locale.to_s
6
- (@locale_data ||= {})[locale] ||= data_source.get(locale) || {}
7
- end
5
+ include I18n::Tasks::DataTraversal
8
6
 
9
7
  # I18n data provider
10
- def data_source
11
- return @source if @source
12
- conf = config[:data] || {}
13
- @source = if conf[:class]
14
- conf[:class].constantize.new(conf.except(:class))
15
- else
16
- I18n::Tasks::Data::Yaml.new(
17
- paths: Array(conf[:paths].presence || ['config/locales/%{locale}.yml'])
18
- )
19
- end
20
- end
21
-
22
- # translation of the key found in the passed hash or nil
23
- # @return [String,nil]
24
- def t(hash, key)
25
- key.split('.').inject(hash) { |r, seg| r[seg] if r }
8
+ # @see I18n::Tasks::Data::Yaml
9
+ def data
10
+ return @data if @data
11
+ conf = (config[:data] || {}).with_indifferent_access
12
+ adapter = (conf[:adapter].presence || conf[:class].presence || :yaml).to_s
13
+ if adapter !~ /[A-Z]/
14
+ adapter = "I18n::Tasks::Data::#{adapter.camelize}"
15
+ end
16
+ @data = adapter.constantize.new(conf.except(:adapter, :class))
26
17
  end
27
18
 
28
- # traverse hash, yielding with full key and value
29
- # @param hash [Hash{String => String,Hash}] translation data to traverse
30
- # @yield [full_key, value] yields full key and value for every translation in #hash
31
- # @return [nil]
32
- def traverse(path = '', hash)
33
- q = [[path, hash]]
34
- until q.empty?
35
- path, value = q.pop
36
- if value.is_a?(Hash)
37
- value.each { |k, v| q << ["#{path}.#{k}", v] }
38
- else
39
- yield path[1..-1], value
40
- end
41
- end
19
+ # whether the value for key exists in locale (defaults: base_locale)
20
+ def key_has_value?(key, locale = base_locale)
21
+ t(data[locale], key).present?
42
22
  end
43
23
 
44
24
  # @return [String] default i18n locale
45
25
  def base_locale
46
26
  I18n.default_locale.to_s
47
27
  end
48
-
49
- # @return [Hash{String => String,Hash}] default i18n locale data
50
- def base_locale_data
51
- locale_data(base_locale)[base_locale]
52
- end
53
-
54
- # whether the value for key exists in locale (defaults: base_locale)
55
- def key_has_value?(key, locale = base_locale)
56
- t(locale_data(locale)[locale], key).present?
57
- end
58
28
  end
@@ -6,11 +6,11 @@ module I18n
6
6
  class Unused < BaseTask
7
7
  # @return [Array<[String, String]>] all the unused translations as an array of [key, value] pairs
8
8
  def find_keys
9
- r = []
10
- data = base_locale_data
11
- traverse data do |key, value|
9
+ r = []
10
+ d = self.data[base_locale]
11
+ traverse d do |key, value|
12
12
  next if pattern_key?(key) || ignore_key?(key, :unused)
13
- key = depluralize_key(key, data)
13
+ key = depluralize_key(key, d)
14
14
  r << [key, value] unless used_key?(key)
15
15
  end
16
16
  r.uniq
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module Tasks
3
- VERSION = '0.1.6'
3
+ VERSION = '0.1.7'
4
4
  end
5
5
  end
@@ -9,3 +9,4 @@ p = t 'ignore_eq_base_all.a'
9
9
  p = t 'ignore_eq_base_es.a'
10
10
  p = t 'numeric.a'
11
11
  p = t 'plural.a', count: 2
12
+ p = t 'devise.a'
@@ -1,25 +1,19 @@
1
- # do not report these keys as missing:
2
- ignore_missing:
3
- - ignored_missing_key.a # one key to ignore
4
- - ignored_pattern.* # ignore the whole pattern
5
-
6
- # do not report these keys when they have the same value as the base locale version
7
- ignore_eq_base:
8
- all:
9
- - ignore_eq_base_all.a
10
- es:
11
- - ignore_eq_base_es.a
12
-
13
- # do not report these keys as unused
14
- ignore_unused:
15
- - ignore_unused.a
16
-
17
- # do not report these keys ever
18
- ignore:
19
- - ignore.a
1
+ # i18n data storage
2
+ data:
3
+ # The default YAML adapter supports reading from and writing to YAML files
4
+ adapter: yaml
5
+ # adapter options
6
+ read:
7
+ - 'config/locales/%{locale}.yml'
8
+ - 'config/locales/*.%{locale}.yml'
9
+ write:
10
+ # keys matched top to bottom
11
+ - ['devise.*', 'config/locales/devise.%{locale}.yml']
12
+ # default catch-all (same as ['*', 'config/locales/%{locale}.yml'])
13
+ - 'config/locales/%{locale}.yml'
20
14
 
21
- # grep configuration
22
- grep:
15
+ # i18n usage search in source
16
+ search:
23
17
  # search these directories (relative to your Rails.root directory, default: 'app/')
24
18
  paths:
25
19
  - 'app/'
@@ -31,11 +25,24 @@ grep:
31
25
  - '*.file'
32
26
  # explicitly exclude files (default: blank = exclude no files)
33
27
  exclude: '*.js'
28
+ # search uses grep under the hood
34
29
 
35
- # how to get the locale data
36
- data:
37
- class: I18n::Tasks::Data::Yaml
38
- paths:
39
- # files for a given %{locale}
40
- - 'config/locales/%{locale}.yml'
41
- - 'config/locales/*.%{locale}.yml'
30
+ # do not report these keys ever
31
+ ignore:
32
+ - ignore.a
33
+
34
+ # do not report these keys as unused
35
+ ignore_unused:
36
+ - ignore_unused.a
37
+
38
+ # do not report these keys as missing:
39
+ ignore_missing:
40
+ - ignored_missing_key.a # one key to ignore
41
+ - ignored_pattern.* # ignore the whole pattern
42
+
43
+ # do not report these keys when they have the same value as the base locale version
44
+ ignore_eq_base:
45
+ all:
46
+ - ignore_eq_base_all.a
47
+ es:
48
+ - ignore_eq_base_es.a
@@ -19,10 +19,14 @@ describe 'rake i18n' do
19
19
  end
20
20
 
21
21
  describe 'prefill' do
22
- it 'detects unused' do
22
+ it 'prefills from en' do
23
23
  TestCodebase.in_test_app_dir { YAML.load_file('config/locales/es.yml')['es']['missing_in_es'].should be_nil }
24
24
  TestCodebase.rake_result('i18n:prefill')
25
- TestCodebase.in_test_app_dir { YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a'].should == 'EN_TEXT' }
25
+ TestCodebase.in_test_app_dir {
26
+ YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a'].should == 'EN_TEXT'
27
+ YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a'].should == 'EN_TEXT'
28
+ YAML.load_file('config/locales/devise.es.yml')['es']['devise']['a'].should == 'ES_TEXT'
29
+ }
26
30
  end
27
31
  end
28
32
 
@@ -45,7 +49,8 @@ describe 'rake i18n' do
45
49
  'blank_in_es' => {'a' => v},
46
50
  'relative' => {'index' => {'title' => v}},
47
51
  'numeric' => {'a' => v_num},
48
- 'plural' => {'a' => {'one' => v, 'other' => "%{count} #{v}s"}}
52
+ 'plural' => {'a' => {'one' => v, 'other' => "%{count} #{v}s"}},
53
+ 'devise' => {'a' => v}
49
54
  }.tap { |r|
50
55
  gen = r["bench"] = {}
51
56
  BENCH_KEYS.times { |i| gen["key#{i}"] = v }
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.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-12 00:00:00.000000000 Z
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,7 +128,7 @@ files:
128
128
  - lib/i18n/tasks.rb
129
129
  - lib/i18n/tasks/base_task.rb
130
130
  - lib/i18n/tasks/data/yaml.rb
131
- - lib/i18n/tasks/fuzzy_source_keys.rb
131
+ - lib/i18n/tasks/data_traversal.rb
132
132
  - lib/i18n/tasks/ignore_keys.rb
133
133
  - lib/i18n/tasks/key_pattern_matching.rb
134
134
  - lib/i18n/tasks/missing.rb
@@ -137,9 +137,9 @@ files:
137
137
  - lib/i18n/tasks/prefill.rb
138
138
  - lib/i18n/tasks/railtie.rb
139
139
  - lib/i18n/tasks/relative_keys.rb
140
+ - lib/i18n/tasks/source_keys.rb
140
141
  - lib/i18n/tasks/translation_data.rb
141
142
  - lib/i18n/tasks/unused.rb
142
- - lib/i18n/tasks/usage_search.rb
143
143
  - lib/i18n/tasks/version.rb
144
144
  - lib/tasks/i18n-tasks.rake
145
145
  - spec/fixtures/app/assets/javascripts/application.js
@@ -1,20 +0,0 @@
1
- require 'i18n/tasks/key_pattern_matching'
2
-
3
- # e.g t("category.#{category_key}")
4
- module I18n::Tasks
5
- module FuzzySourceKeys
6
- include KeyPatternMatching
7
-
8
- # dynamically generated keys in the source, e.g t("category.#{category_key}")
9
- def pattern_key?(key)
10
- @pattern_keys_re ||= compile_start_with_re(pattern_key_prefixes)
11
- !!(key =~ @pattern_keys_re)
12
- end
13
-
14
- # keys in the source that end with a ., e.g. t("category.#{cat.i18n_key}") or t("category." + category.key)
15
- def pattern_key_prefixes
16
- @pattern_keys_prefixes ||=
17
- find_source_keys.select { |k| k =~ /\#{.*?}/ || k.ends_with?('.') }.map { |k| k.split(/\.?#/)[0].presence }.compact
18
- end
19
- end
20
- end