Skip to content

Commit

Permalink
Add check-normalized
Browse files Browse the repository at this point in the history
Adds a new task, `check-normalized`, and the corresponding specs, to
verify that all the locale files are normalized.

Fixes #249
  • Loading branch information
glebm committed Aug 10, 2017
1 parent 0b535af commit 536ea38
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Style/FormatStringToken:
Style/GuardClause:
Enabled: false

Style/IndentHeredoc:
Layout/IndentHeredoc:
# TODO(glebm): Remove this when we update the minimum Ruby version to 2.3+.
Enabled: false

Expand Down
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
## v0.9.17

Adds a new task, `check-normalized`, and the corresponding specs, to verify that all the locale files are normalized.
[#249](https://github.com/glebm/i18n-tasks/issues/249)

Fixes an issue with normalization not happening in certain cases.
[#91b593d7](https://github.com/glebm/i18n-tasks/commit/91b593d7259460e2a3aa7fd731d878e8e35707fc)

There is now a minitest template file available.
[#250](https://github.com/glebm/i18n-tasks/pull/250)

Internally, Erubi is now used instead of Erubis for parsing the config file.
[#247](https://github.com/glebm/i18n-tasks/issues/247)

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ Run `i18n-tasks` to get the list of all the tasks with short descriptions.

### Check health

`i18n-tasks health` checks if any keys are missing or not used:
`i18n-tasks health` checks if any keys are missing or not used,
and that all the locale files are normalized (auto-formatted):

```console
$ i18n-tasks health
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ en:
%{value_or_default_or_human_key}
desc:
add_missing: add missing keys to locale data
check_normalized: verify that all translation data is normalized
config: display i18n-tasks configuration
data: show locale data
data_merge: merge locale data with trees
Expand Down
1 change: 1 addition & 0 deletions config/locales/ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ru:
%{value_or_default_or_human_key}
desc:
add_missing: добавить недостающие ключи к переводам
check_normalized: проверить, что все файлы переводов нормализованы
config: показать конфигурацию
data: показать данные переводов
data_merge: добавить дерево к переводам
Expand Down
14 changes: 13 additions & 1 deletion lib/i18n/tasks/command/commands/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@ module Data
args: %i[locales pattern_router]

def normalize(opt = {})
i18n.normalize_store! opt[:locales], opt[:pattern_router]
i18n.normalize_store! locales: opt[:locales],
force_pattern_router: opt[:pattern_router]
end

cmd :check_normalized,
pos: '[locale ...]',
desc: t('i18n_tasks.cmd.desc.check_normalized'),
args: %i[locales]

def check_normalized(opt)
non_normalized = i18n.non_normalized_paths locales: opt[:locales]
terminal_report.check_normalized_results(non_normalized)
:exit_1 unless non_normalized.empty?
end

cmd :mv,
Expand Down
2 changes: 1 addition & 1 deletion lib/i18n/tasks/command/commands/health.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def health(opt = {})
fail CommandError, t('i18n_tasks.health.no_keys_detected')
end
terminal_report.forest_stats forest, stats
[missing(opt), unused(opt)].detect { |result| result == :exit_1 }
[missing(opt), unused(opt), check_normalized(opt)].detect { |result| result == :exit_1 }
end
end
end
Expand Down
21 changes: 15 additions & 6 deletions lib/i18n/tasks/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,25 @@ def key_value?(key, locale = base_locale)
!t(key, locale).nil?
end

# write to store, normalizing all data
def normalize_store!(from = nil, pattern_router = false)
from = locales unless from
router = pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
# Normalize all the locale data in the store (by writing to the store).
#
# @param [Array<String>] locales locales to normalize. Default: all.
# @param [Boolean] force_pattern_router Whether to use pattern router regardless of the config.
def normalize_store!(locales: nil, force_pattern_router: false)
locales = self.locales unless locales
router = force_pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
data.with_router(router) do
Array(from).each do |target_locale|
# store handles normalization
Array(locales).each do |target_locale|
# The store handles actual normalization:
data[target_locale] = data[target_locale]
end
end
end

# @param [Array<String>] locales locales to check. Default: all.
# @return [Array<String>] paths to data that requires normalization
def non_normalized_paths(locales: nil)
Array(locales || self.locales).flat_map { |locale| data.non_normalized_paths(locale) }
end
end
end
5 changes: 5 additions & 0 deletions lib/i18n/tasks/data/file_formats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ def write_tree(path, tree)
::File.open(path, 'w') { |f| f.write content }
end

def normalized?(path, tree)
return false unless File.file?(path)
read_file(path) == adapter_dump(tree.to_hash(true), self.class.adapter_name_for_path(path))
end

module ClassMethods
# @param pattern [String] File.fnmatch pattern
# @param adapter [responds to parse(string)->hash and dump(hash)->string]
Expand Down
8 changes: 8 additions & 0 deletions lib/i18n/tasks/data/file_system_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ def set(locale, tree)
@available_locales = nil
end

# @param [String] locale
# @return [Array<String>] paths to files that are not normalized
def non_normalized_paths(locale)
router.route(locale, get(locale))
.reject { |path, tree_slice| normalized?(path, tree_slice) }
.map(&:first)
end

def write(forest)
forest.each { |root| set(root.key, root) }
end
Expand Down
10 changes: 10 additions & 0 deletions lib/i18n/tasks/reports/terminal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ def mv_results(results)
end
end

def check_normalized_results(non_normalized)
if non_normalized.empty?
print_success 'All data is normalized'
return
end
log_stderr Rainbow('The following data requires normalization:').yellow
puts non_normalized
log_stderr Rainbow('Run `i18n-tasks normalize` to fix').yellow
end

private

def missing_key_info(leaf)
Expand Down
13 changes: 13 additions & 0 deletions spec/i18n_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,17 @@
expect(unused_keys).to be_empty,
"#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
end

it 'files are normalized' do
# Skip this test if on TRAVIS + MRI.
if ENV['TRAVIS'] && defined?(RUBY_ENGINE) && RUBY_ENGINE != 'jruby'
skip 'Travis CI has an older version of libyaml where the formatting differs.'
end

non_normalized = i18n.non_normalized_paths
error_message = "The following files need to be normalized:\n" \
"#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
'Please run `i18n-tasks normalize` to fix'
expect(non_normalized).to be_empty, error_message
end
end
8 changes: 8 additions & 0 deletions templates/minitest/i18n_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ def test_no_unused_keys
assert_empty @unused_keys,
"#{@unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
end

def test_files_are_normalized
non_normalized = @i18n.non_normalized_paths
error_message = "The following files need to be normalized:\n" \
"#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
'Please run `i18n-tasks normalize` to fix'
assert_empty non_normalized, error_message
end
end
8 changes: 8 additions & 0 deletions templates/rspec/i18n_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@
expect(unused_keys).to be_empty,
"#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
end

it 'files are normalized' do
non_normalized = i18n.non_normalized_paths
error_message = "The following files need to be normalized:\n" \
"#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
'Please run `i18n-tasks normalize` to fix'
expect(non_normalized).to be_empty, error_message
end
end

0 comments on commit 536ea38

Please sign in to comment.