rails_translation_manager 0.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +20 -0
- data/Jenkinsfile +3 -1
- data/Rakefile +13 -7
- data/config/locales/plurals.rb +49 -0
- data/lib/rails_translation_manager/cleaner.rb +14 -0
- data/lib/rails_translation_manager/i18n_tasks_option_parser.rb +10 -0
- data/lib/rails_translation_manager/importer.rb +32 -14
- data/lib/rails_translation_manager/locale_checker/all_locales.rb +61 -0
- data/lib/rails_translation_manager/locale_checker/base_checker.rb +13 -0
- data/lib/rails_translation_manager/locale_checker/incompatible_plurals.rb +79 -0
- data/lib/rails_translation_manager/locale_checker/locale_checker_helper.rb +23 -0
- data/lib/rails_translation_manager/locale_checker/missing_english_locales.rb +31 -0
- data/lib/rails_translation_manager/locale_checker/missing_foreign_locales.rb +31 -0
- data/lib/rails_translation_manager/locale_checker/plural_forms.rb +16 -0
- data/lib/rails_translation_manager/locale_checker.rb +50 -0
- data/lib/rails_translation_manager/version.rb +1 -1
- data/lib/rails_translation_manager.rb +21 -3
- data/lib/tasks/translation.rake +43 -42
- data/rails_translation_manager.gemspec +6 -2
- data/spec/locales/cleaner/clean.yml +5 -0
- data/spec/locales/cleaner/with_whitespace.yml +5 -0
- data/spec/locales/importer/fr.csv +8 -0
- data/spec/locales/importer/hy_with_byte_order_mark.csv +4 -0
- data/spec/locales/in_sync/cy/browse.yml +12 -0
- data/spec/locales/in_sync/en/browse.yml +8 -0
- data/spec/locales/out_of_sync/cy.yml +3 -0
- data/spec/locales/out_of_sync/en.yml +6 -0
- data/spec/rails_translation_manager/cleaner_spec.rb +13 -0
- data/spec/rails_translation_manager/importer_spec.rb +93 -0
- data/spec/rails_translation_manager/locale_checker/all_locales_spec.rb +24 -0
- data/spec/rails_translation_manager/locale_checker/incompatible_plurals_spec.rb +94 -0
- data/spec/rails_translation_manager/locale_checker/locale_checker_helper_spec.rb +61 -0
- data/spec/rails_translation_manager/locale_checker/missing_english_locales_spec.rb +72 -0
- data/spec/rails_translation_manager/locale_checker/missing_foreign_locales_spec.rb +80 -0
- data/spec/rails_translation_manager/locale_checker/plural_forms_spec.rb +27 -0
- data/spec/rails_translation_manager/locale_checker_spec.rb +68 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/tasks.rb +7 -0
- data/spec/tasks/translation_spec.rb +127 -0
- data/test/rails_translation_manager/yaml_writer_test.rb +2 -0
- data/tmp/.gitkeep +0 -0
- metadata +117 -18
- data/lib/rails_translation_manager/stealer.rb +0 -85
- data/lib/rails_translation_manager/validator.rb +0 -92
- data/test/rails_translation_manager/importer_test.rb +0 -132
- data/test/rails_translation_manager/stealer_test.rb +0 -251
- data/test/rails_translation_manager/validator_test.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e7ef3e878a1b5ffc7ae48ad8f683887e79073b3f34a5a3439656f5f7abb6e20
|
4
|
+
data.tar.gz: 2aac75f9cae7275812da73da0973de515baf0d78eb63e64182e683f8717696ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0b2fa6abaadb21ea912976b1092c6459ea0194a8e19092c522e38224da218395d230936d0d4a0aa830e3d37bd9f6eb6ac1e4909bd5406369c0aa99d1a4d13f4
|
7
|
+
data.tar.gz: 0dbbefe8208052b63f5ddc80734340ed7985b199f9113aaf5457c48d50e34e889e7379a20c61963b002343f4fb0d35aacc0307b442a15a2b7fbdea77c25349dd
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## 1.1.2
|
2
|
+
|
3
|
+
Handle importing files that contain Byte Order Marks. https://github.com/alphagov/rails_translation_manager/pull/27
|
4
|
+
|
5
|
+
## 1.1.1
|
6
|
+
|
7
|
+
Fix Rails Translation Manager / Rails naming clash for class. https://github.com/alphagov/rails_translation_manager/pull/26
|
8
|
+
|
9
|
+
## 1.1.0
|
10
|
+
|
11
|
+
Allow multiple files per language to be imported. https://github.com/alphagov/rails_translation_manager/pull/20
|
12
|
+
|
13
|
+
## 1.0.0
|
14
|
+
|
15
|
+
Adds logic to verify locale files are in sync with each other and have the
|
16
|
+
correct plural forms. Also introduces RSpec into the Gem which will replace
|
17
|
+
Minitest in the coming iterations.
|
18
|
+
|
19
|
+
Integrates RTM with I18n-tasks. Adds wrappers around `add-missing` & `normalize` tasks, adds Cleaner class to remove the whitespace added by i18n-tasks, adds tests and byebug gem as a debugging tool.
|
20
|
+
|
1
21
|
## 0.1.0
|
2
22
|
|
3
23
|
Don't change the $LOAD_PATH in translation.rake.
|
data/Jenkinsfile
CHANGED
data/Rakefile
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
-
|
2
|
-
require "rake/testtask"
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rake/testtask'
|
6
|
+
require 'rails_i18n'
|
7
|
+
|
8
|
+
Rake::TestTask.new('test') do |t|
|
9
|
+
t.description = 'Run tests'
|
10
|
+
t.libs << 'test'
|
11
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
12
|
t.verbose = true
|
9
13
|
end
|
10
14
|
|
11
|
-
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task default: %i[spec test]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
{
|
4
|
+
# Dari - this isn't an iso code. Probably should be 'prs' as per ISO 639-3.
|
5
|
+
dr: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
6
|
+
# Latin America and Caribbean Spanish
|
7
|
+
"es-419": { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
8
|
+
# Scottish Gaelic
|
9
|
+
gd: { i18n: { plural: { keys: %i[one two few other],
|
10
|
+
rule: lambda do |n|
|
11
|
+
if [1, 11].include?(n)
|
12
|
+
:one
|
13
|
+
elsif [2, 12].include?(n)
|
14
|
+
:two
|
15
|
+
elsif [3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19].include?(n)
|
16
|
+
:few
|
17
|
+
else
|
18
|
+
:other
|
19
|
+
end
|
20
|
+
end } } },
|
21
|
+
# Gujarati
|
22
|
+
gu: { i18n: { plural: { keys: %i[one other], rule: ->(n) { [0, 1].include?(n) ? :one : :other } } } },
|
23
|
+
# Armenian
|
24
|
+
hy: { i18n: { plural: { keys: %i[one other], rule: ->(n) { [0, 1].include?(n) ? :one : :other } } } },
|
25
|
+
# Kazakh
|
26
|
+
kk: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
27
|
+
# Pashto
|
28
|
+
ps: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
29
|
+
# Punjabi Shahmukhi
|
30
|
+
"pa-pk": { i18n: { plural: { keys: %i[one other], rule: ->(n) { [0, 1].include?(n) ? :one : :other } } } },
|
31
|
+
# Sinhalese
|
32
|
+
si: { i18n: { plural: { keys: %i[one other], rule: ->(n) { [0, 1].include?(n) ? :one : :other } } } },
|
33
|
+
# Somali
|
34
|
+
so: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
35
|
+
# Albanian
|
36
|
+
sq: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
37
|
+
# Norwegian
|
38
|
+
no: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
39
|
+
# Tamil
|
40
|
+
ta: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
41
|
+
# Turkmen
|
42
|
+
tk: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
43
|
+
# Uzbek
|
44
|
+
uz: { i18n: { plural: { keys: %i[one other], rule: ->(n) { n == 1 ? :one : :other } } } },
|
45
|
+
# Chinese Hong Kong
|
46
|
+
'zh-hk' => { i18n: { plural: { keys: %i[other], rule: -> { :other } } } },
|
47
|
+
# Chinese Taiwan
|
48
|
+
'zh-tw' => { i18n: { plural: { keys: %i[other], rule: -> { :other } } } }
|
49
|
+
}
|
@@ -5,36 +5,39 @@ require_relative "yaml_writer"
|
|
5
5
|
class RailsTranslationManager::Importer
|
6
6
|
include YAMLWriter
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
attr_reader :locale, :csv_path, :import_directory, :multiple_files_per_language
|
9
|
+
|
10
|
+
def initialize(locale:, csv_path:, import_directory:, multiple_files_per_language:)
|
10
11
|
@locale = locale
|
12
|
+
@csv_path = csv_path
|
11
13
|
@import_directory = import_directory
|
14
|
+
@multiple_files_per_language = multiple_files_per_language
|
12
15
|
end
|
13
16
|
|
14
17
|
def import
|
15
|
-
csv = CSV.read(
|
16
|
-
|
17
|
-
csv
|
18
|
+
csv = CSV.read(csv_path, encoding: "bom|utf-8", headers: true, header_converters: :downcase)
|
19
|
+
|
20
|
+
multiple_files_per_language ? import_csv_into_multiple_files(csv) : import_csv(csv)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def import_csv(csv, import_yml_path = File.join(import_directory, "#{locale}.yml"))
|
26
|
+
data = csv.each_with_object({}) do |row, hash|
|
18
27
|
key = row["key"]
|
19
28
|
key_parts = key.split(".")
|
20
29
|
if key_parts.length > 1
|
21
|
-
leaf_node = (
|
30
|
+
leaf_node = (hash[key_parts.first] ||= {})
|
22
31
|
key_parts[1..-2].each do |part|
|
23
32
|
leaf_node = (leaf_node[part] ||= {})
|
24
33
|
end
|
25
34
|
leaf_node[key_parts.last] = parse_translation(row["translation"])
|
26
35
|
else
|
27
|
-
|
36
|
+
hash[key_parts.first] = parse_translation(row["translation"])
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
31
|
-
write_yaml(import_yml_path, {
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def import_yml_path
|
37
|
-
File.join(@import_directory, "#{@locale}.yml")
|
40
|
+
write_yaml(import_yml_path, { locale.to_s => data })
|
38
41
|
end
|
39
42
|
|
40
43
|
def parse_translation(translation)
|
@@ -55,4 +58,19 @@ class RailsTranslationManager::Importer
|
|
55
58
|
translation
|
56
59
|
end
|
57
60
|
end
|
61
|
+
|
62
|
+
def import_csv_into_multiple_files(csv)
|
63
|
+
group_csv_by_file(csv).each do |group|
|
64
|
+
language_dir = File.join(import_directory, locale)
|
65
|
+
|
66
|
+
Dir.mkdir(language_dir) unless Dir.exists?(language_dir)
|
67
|
+
|
68
|
+
import_yml_path = File.join(import_directory, locale, "#{group[0]}.yml")
|
69
|
+
import_csv(group[1], import_yml_path)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def group_csv_by_file(csv)
|
74
|
+
csv.group_by { |row| row["key"].split(".").first }
|
75
|
+
end
|
58
76
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AllLocales
|
4
|
+
attr_reader :locale_path
|
5
|
+
|
6
|
+
def initialize(locale_path)
|
7
|
+
@locale_path = locale_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate
|
11
|
+
paths = locale_file_paths.compact
|
12
|
+
|
13
|
+
raise NoLocaleFilesFound, "No locale files found for the supplied path" if paths.blank?
|
14
|
+
|
15
|
+
paths.flat_map do |locale_group|
|
16
|
+
{
|
17
|
+
locale: locale_group[:locale],
|
18
|
+
keys: all_keys_for_locale(locale_group)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def locale_file_paths
|
26
|
+
I18n.available_locales.map do |locale|
|
27
|
+
grouped_paths = Dir[locale_path].select do |path|
|
28
|
+
locale = locale.downcase
|
29
|
+
|
30
|
+
path =~ %r{/#{locale}/} || path =~ %r{/#{locale}\.yml$}
|
31
|
+
end
|
32
|
+
|
33
|
+
{ locale: locale.downcase, paths: grouped_paths } if grouped_paths.present?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def all_keys_for_locale(locale_group)
|
38
|
+
locale_group[:paths].flat_map do |path|
|
39
|
+
keys_from_file(file_path: path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def keys_from_file(locale_hash: nil, key_chain: nil, locale_keys: [], file_path: nil)
|
44
|
+
locale_hash ||= YAML.load_file(file_path)
|
45
|
+
keys = locale_hash.keys
|
46
|
+
keys.each do |key|
|
47
|
+
if locale_hash.fetch(key).is_a?(Hash)
|
48
|
+
keys_from_file(locale_hash: locale_hash.fetch(key), key_chain: "#{key_chain}.#{key}", locale_keys: locale_keys)
|
49
|
+
else
|
50
|
+
keys.each do |final_key|
|
51
|
+
locale_keys << "#{key_chain}.#{final_key}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# remove locale prefix from keys, e.g: ".en.browse.page" -> "browse.page"
|
57
|
+
locale_keys.uniq.map { |key| key.split(".")[2..].join(".") }
|
58
|
+
end
|
59
|
+
|
60
|
+
class NoLocaleFilesFound < StandardError; end
|
61
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class IncompatiblePlurals < BaseChecker
|
4
|
+
include LocaleCheckerHelper
|
5
|
+
|
6
|
+
def report
|
7
|
+
format_plural_errors if plural_errors.present?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def format_plural_errors
|
13
|
+
<<~OUTPUT.chomp
|
14
|
+
\e[31m[ERROR]\e[0m Incompatible plural forms, for:
|
15
|
+
|
16
|
+
#{plural_errors.join("\n\n")}
|
17
|
+
|
18
|
+
\e[1mIf the keys reported above are not plurals, rename them avoiding plural keywords: #{PLURAL_KEYS}\e[22m
|
19
|
+
OUTPUT
|
20
|
+
end
|
21
|
+
|
22
|
+
def plural_errors
|
23
|
+
@plural_errors ||= grouped_plural_keys_for_locale.flat_map do |plurals|
|
24
|
+
plural_form = all_plural_forms[plurals[:locale]]
|
25
|
+
|
26
|
+
if plural_form.blank?
|
27
|
+
"- \e[31m[ERROR]\e[0m Please add plural form for '#{plurals[:locale]}' <link to future documentation>"
|
28
|
+
else
|
29
|
+
incompatible_plurals(plurals, plural_form)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def incompatible_plurals(plurals, plural_form)
|
35
|
+
error_messages = plurals[:groups].map do |plural_group|
|
36
|
+
actual_plural_form = plural_group[:keys].sort
|
37
|
+
|
38
|
+
next if actual_plural_form == plural_form.sort
|
39
|
+
|
40
|
+
"- '#{plurals[:locale]}', with parent '#{plural_group[:parent]}'. Expected: #{plural_form}, actual: #{actual_plural_form}"
|
41
|
+
end
|
42
|
+
|
43
|
+
error_messages.compact
|
44
|
+
end
|
45
|
+
|
46
|
+
def grouped_plural_keys_for_locale
|
47
|
+
all_locales.map do |locale|
|
48
|
+
{
|
49
|
+
locale: locale[:locale],
|
50
|
+
groups: grouped_plural_keys(only_plurals(locale[:keys]))
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def grouped_plural_keys(keys)
|
56
|
+
# %w[parent.key parent.other_key] -> [{ parent: "parent", keys: %w[key other_key] }]
|
57
|
+
group_by_parent_keys(keys).map do |plural_key_group|
|
58
|
+
{
|
59
|
+
parent: plural_key_group.first,
|
60
|
+
keys: plural_key_group.last.map { |key_chain| key_chain.split(".").last.to_sym }
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def group_by_parent_keys(keys)
|
66
|
+
# %w[parent.key parent.other_key] -> { "parent" => %w[parent.key parent.other_key] }
|
67
|
+
keys.group_by do |key|
|
68
|
+
key.split('.')[0..-2].join('.')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def only_plurals(keys)
|
73
|
+
keys.select { |key| key_is_plural?(key) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def all_plural_forms
|
77
|
+
@all_plural_forms ||= PluralForms.all
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LocaleCheckerHelper
|
4
|
+
PLURAL_KEYS = %w[zero one two few many other].freeze
|
5
|
+
|
6
|
+
def exclude_plurals(keys)
|
7
|
+
keys.reject { |key| key_is_plural?(key) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def group_keys(locales)
|
11
|
+
locales.keys.group_by do |key|
|
12
|
+
locales[key]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def english_keys_excluding_plurals(all_locales)
|
17
|
+
exclude_plurals(all_locales.find { |locale| locale[:locale] == :en }[:keys])
|
18
|
+
end
|
19
|
+
|
20
|
+
def key_is_plural?(key)
|
21
|
+
PLURAL_KEYS.include?(key.split(".").last)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MissingEnglishLocales < BaseChecker
|
4
|
+
include LocaleCheckerHelper
|
5
|
+
|
6
|
+
def report
|
7
|
+
grouped_missing_keys = group_keys(missing_english_locales)
|
8
|
+
|
9
|
+
format_missing_english_locales(grouped_missing_keys) if grouped_missing_keys.present?
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def format_missing_english_locales(keys)
|
15
|
+
formatted_keys = keys.to_a.map do |group|
|
16
|
+
"\e[1mMissing English keys:\e[22m #{group[0]}\n\e[1mFound in:\e[22m #{group[1]}"
|
17
|
+
end
|
18
|
+
|
19
|
+
"\e[31m[ERROR]\e[0m Missing English locales, either remove these keys from the foreign locales or add them to the English locales\n\n#{formatted_keys.join("\n\n")}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def missing_english_locales
|
23
|
+
all_locales.each_with_object({}) do |locale, hsh|
|
24
|
+
missing_keys = exclude_plurals(locale[:keys]) - english_keys_excluding_plurals(all_locales)
|
25
|
+
|
26
|
+
next if missing_keys.blank?
|
27
|
+
|
28
|
+
hsh[locale[:locale]] = missing_keys
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MissingForeignLocales < BaseChecker
|
4
|
+
include LocaleCheckerHelper
|
5
|
+
|
6
|
+
def report
|
7
|
+
grouped_missing_keys = group_keys(missing_foreign_locales)
|
8
|
+
|
9
|
+
format_missing_foreign_locales(grouped_missing_keys) if grouped_missing_keys.present?
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def format_missing_foreign_locales(keys)
|
15
|
+
formatted_keys = keys.to_a.map do |group|
|
16
|
+
"\e[1mMissing foreign keys:\e[22m #{group[0]}\n\e[1mAbsent from:\e[22m #{group[1]}"
|
17
|
+
end
|
18
|
+
|
19
|
+
"\e[31m[ERROR]\e[0m Missing foreign locales, either add these keys to the foreign locales or remove them from the English locales\e[0m\n\n#{formatted_keys.join("\n\n")}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def missing_foreign_locales
|
23
|
+
all_locales.each_with_object({}) do |locale, hsh|
|
24
|
+
missing_keys = english_keys_excluding_plurals(all_locales) - exclude_plurals(locale[:keys])
|
25
|
+
|
26
|
+
next if missing_keys.blank?
|
27
|
+
|
28
|
+
hsh[locale[:locale]] = missing_keys
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class PluralForms
|
4
|
+
def self.all
|
5
|
+
I18n.available_locales.each_with_object({}) do |locale, hsh|
|
6
|
+
begin
|
7
|
+
# fetches plural form (rule) from rails-i18n for locale
|
8
|
+
plural_form = I18n.with_locale(locale) { I18n.t!("i18n.plural.keys") }.sort
|
9
|
+
rescue I18n::MissingTranslationData
|
10
|
+
plural_form = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
hsh[locale.downcase] = plural_form
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsTranslationManager
|
4
|
+
class LocaleChecker
|
5
|
+
attr_reader :locale_path
|
6
|
+
|
7
|
+
CHECKER_CLASSES = [MissingEnglishLocales,
|
8
|
+
MissingForeignLocales,
|
9
|
+
IncompatiblePlurals].freeze
|
10
|
+
|
11
|
+
def initialize(locale_path)
|
12
|
+
@locale_path = locale_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_locales
|
16
|
+
output_result
|
17
|
+
rescue AllLocales::NoLocaleFilesFound => e
|
18
|
+
puts e
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def output_result
|
25
|
+
errors = checker_errors.compact
|
26
|
+
|
27
|
+
if errors.blank?
|
28
|
+
puts "Locale files are in sync, nice job!"
|
29
|
+
true
|
30
|
+
else
|
31
|
+
errors.each do |error_message|
|
32
|
+
puts "\n"
|
33
|
+
puts error_message
|
34
|
+
puts "\n"
|
35
|
+
end
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def checker_errors
|
41
|
+
CHECKER_CLASSES.flat_map do |checker|
|
42
|
+
checker.new(all_locales).report
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def all_locales
|
47
|
+
@all_locales ||= AllLocales.new(locale_path).generate
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,9 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rails_translation_manager/version"
|
2
4
|
require "rails_translation_manager/railtie" if defined?(Rails)
|
3
5
|
require "rails-i18n"
|
4
6
|
|
7
|
+
require "rails_translation_manager/locale_checker/base_checker"
|
8
|
+
require "rails_translation_manager/locale_checker/locale_checker_helper"
|
9
|
+
require "rails_translation_manager/locale_checker/missing_foreign_locales"
|
10
|
+
require "rails_translation_manager/locale_checker/missing_english_locales"
|
11
|
+
require "rails_translation_manager/locale_checker/plural_forms"
|
12
|
+
require "rails_translation_manager/locale_checker/incompatible_plurals"
|
13
|
+
require "rails_translation_manager/locale_checker/all_locales"
|
14
|
+
require "rails_translation_manager/locale_checker"
|
15
|
+
require "rails_translation_manager/cleaner"
|
16
|
+
require "rails_translation_manager/exporter"
|
17
|
+
require "rails_translation_manager/importer"
|
18
|
+
|
5
19
|
module RailsTranslationManager
|
6
|
-
|
7
|
-
|
8
|
-
|
20
|
+
rails_i18n_path = Gem::Specification.find_by_name("rails-i18n").gem_dir
|
21
|
+
rails_translation_manager = Gem::Specification.find_by_name("rails_translation_manager").gem_dir
|
22
|
+
|
23
|
+
I18n.load_path.concat(
|
24
|
+
Dir["#{rails_i18n_path}/rails/pluralization/*.rb"],
|
25
|
+
["#{rails_translation_manager}/config/locales/plurals.rb"]
|
26
|
+
)
|
9
27
|
end
|