diff --git a/CHANGES.md b/CHANGES.md index f334ca59..2b6a3044 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ ## v0.9.19 (not yet released) +Adds a new configuration setting, `data.external`, for locale data from external dependencies (e.g. gems). +This locale data is never considered unused, and is never modified by i18n-tasks. +[#264](https://github.com/glebm/i18n-tasks/issues/264) + Fixes support for calls such as `t @instance_variable, scope: :static_scope` in the non-AST scanner. [#1d2c6d0c](https://github.com/glebm/i18n-tasks/commit/1d2c6d0cb7ee20a8db68c52e33ec3c2a382633e6) diff --git a/lib/i18n/tasks/data.rb b/lib/i18n/tasks/data.rb index c86a1c05..7f20a217 100644 --- a/lib/i18n/tasks/data.rb +++ b/lib/i18n/tasks/data.rb @@ -59,6 +59,10 @@ def key_value?(key, locale = base_locale) !t(key, locale).nil? end + def external_key?(key, locale = base_locale) + data.external(locale)[locale.to_s][key] + end + # Normalize all the locale data in the store (by writing to the store). # # @param [Array] locales locales to normalize. Default: all. diff --git a/lib/i18n/tasks/data/file_system_base.rb b/lib/i18n/tasks/data/file_system_base.rb index 9665c869..a8d61e84 100644 --- a/lib/i18n/tasks/data/file_system_base.rb +++ b/lib/i18n/tasks/data/file_system_base.rb @@ -32,13 +32,20 @@ def initialize(config = {}) end end - # get locale tree + # @param [String, Symbol] locale + # @return [::I18n::Tasks::Data::Siblings] def get(locale) locale = locale.to_s - @trees ||= {} - @trees[locale] ||= Tree::Siblings[locale => {}].merge!( - read_locale(locale) - ) + @trees ||= {} + @trees[locale] ||= read_locale(locale) + end + + # @param [String, Symbol] locale + # @return [::I18n::Tasks::Data::Siblings] + def external(locale) + locale = locale.to_s + @external ||= {} + @external[locale] ||= read_locale(locale, paths: config[:external]) end alias [] get @@ -151,17 +158,17 @@ def router protected - def read_locale(locale) - Array(config[:read]).map do |path| + def read_locale(locale, paths: config[:read]) + Array(paths).flat_map do |path| Dir.glob format(path, locale: locale) - end.reduce(:+).map do |path| + end.map do |path| [path.freeze, load_file(path) || {}] end.map do |path, data| filter_nil_keys! path, data Data::Tree::Siblings.from_nested_hash(data).tap do |s| s.leaves { |x| x.data.update(path: path, locale: locale) } end - end.reduce(:merge!) || Tree::Siblings.null + end.reduce(Tree::Siblings[locale => {}], :merge!) end def filter_nil_keys!(path, data, suffix = []) diff --git a/lib/i18n/tasks/missing_keys.rb b/lib/i18n/tasks/missing_keys.rb index 85d63639..44bd3124 100644 --- a/lib/i18n/tasks/missing_keys.rb +++ b/lib/i18n/tasks/missing_keys.rb @@ -85,7 +85,7 @@ def equal_values_tree(locale, compare_to = base_locale) end def locale_key_missing?(locale, key) - !key_value?(key, locale) && !ignore_key?(key, :missing) + !key_value?(key, locale) && !external_key?(key) && !ignore_key?(key, :missing) end # @param [::I18n::Tasks::Data::Tree::Siblings] forest diff --git a/spec/fixtures/app/views/usages.html.slim b/spec/fixtures/app/views/usages.html.slim index fdf9f17f..23eb4947 100644 --- a/spec/fixtures/app/views/usages.html.slim +++ b/spec/fixtures/app/views/usages.html.slim @@ -1,2 +1,4 @@ p = t 'used.a' b = t 'used.a' + +p = t 'external.used' diff --git a/spec/fixtures/config/i18n-tasks.yml.erb b/spec/fixtures/config/i18n-tasks.yml.erb index 59774a33..9d5bdc7b 100644 --- a/spec/fixtures/config/i18n-tasks.yml.erb +++ b/spec/fixtures/config/i18n-tasks.yml.erb @@ -15,6 +15,8 @@ data: - ['devise.*', 'config/locales/devise.%{locale}.yml'] # default catch-all (same as ['*', 'config/locales/%{locale}.yml']) - 'config/locales/%{locale}.yml' + external: + - 'config/locales/external/%{locale}.yml' yaml: write: line_width: -1 diff --git a/spec/i18n_tasks_spec.rb b/spec/i18n_tasks_spec.rb index 9d97ba86..5c431c31 100644 --- a/spec/i18n_tasks_spec.rb +++ b/spec/i18n_tasks_spec.rb @@ -363,6 +363,10 @@ fs = fixtures_contents.merge( 'config/locales/en.yml' => { 'en' => en_data }.to_yaml, 'config/locales/es.yml' => { 'es' => es_data }.to_yaml, + 'config/locales/external/en.yml' => + { 'en' => { 'external' => { 'used' => 'EN_TEXT', 'unused' => 'EN_TEXT' } } }.to_yaml, + 'config/locales/external/es.yml' => + { 'es' => { 'external' => { 'used' => 'ES_TEXT', 'unused' => 'ES_TEXT' } } }.to_yaml, 'config/locales/old_devise.en.yml' => { 'en' => { 'devise' => { 'a' => 'EN_TEXT' } } }.to_yaml, 'config/locales/old_devise.es.yml' => { 'es' => { 'devise' => { 'a' => 'ES_TEXT' } } }.to_yaml, 'config/locales/unused.en.yml' => { 'en' => { 'unused' => { 'file' => 'EN_TEXT' } } }.to_yaml, diff --git a/templates/config/i18n-tasks.yml b/templates/config/i18n-tasks.yml index 39e9f59b..a5248346 100644 --- a/templates/config/i18n-tasks.yml +++ b/templates/config/i18n-tasks.yml @@ -19,8 +19,6 @@ data: # - config/locales/%{locale}.yml ## More files: # - config/locales/**/*.%{locale}.yml - ## Another gem (replace %#= with %=): - # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml" # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom: # `i18n-tasks normalize -p` will force move the keys according to these rules @@ -30,6 +28,12 @@ data: ## Catch-all default: # - config/locales/%{locale}.yml + # External locale data (e.g. gems). + # This data is not considered unused and is never written to. + external: + ## Example (replace %#= with %=): + # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml" + ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class. # router: conservative_router