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
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RailsTranslationManager::LocaleChecker do
|
6
|
+
context "when the locales are valid" do
|
7
|
+
it "calls each checker class" do
|
8
|
+
described_class::CHECKER_CLASSES.each do |checker|
|
9
|
+
expect_any_instance_of(checker).to receive(:report)
|
10
|
+
end
|
11
|
+
|
12
|
+
described_class.new("spec/locales/in_sync/**/*.yml").validate_locales
|
13
|
+
end
|
14
|
+
|
15
|
+
it "outputs a confirmation" do
|
16
|
+
expect { described_class.new("spec/locales/in_sync/**/*.yml").validate_locales }
|
17
|
+
.to output("Locale files are in sync, nice job!\n").to_stdout
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns true" do
|
21
|
+
expect(described_class.new("spec/locales/in_sync/**/*.yml").validate_locales)
|
22
|
+
.to eq(true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the locales are not valid" do
|
27
|
+
it "calls each checker class" do
|
28
|
+
described_class::CHECKER_CLASSES.each do |checker|
|
29
|
+
expect_any_instance_of(checker).to receive(:report)
|
30
|
+
end
|
31
|
+
|
32
|
+
described_class.new("spec/locales/out_of_sync/*.yml").validate_locales
|
33
|
+
end
|
34
|
+
|
35
|
+
it "outputs the report" do
|
36
|
+
printed = capture_stdout do
|
37
|
+
described_class.new("spec/locales/out_of_sync/*.yml").validate_locales
|
38
|
+
end
|
39
|
+
|
40
|
+
expect(printed.scan(/\[ERROR\]/).count).to eq(3)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns false" do
|
44
|
+
expect(described_class.new("spec/locales/out_of_sync/*.yml").validate_locales)
|
45
|
+
.to eq(false)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when the locale path doesn't relate to any YAML files" do
|
50
|
+
it "doesn't call any checker classes" do
|
51
|
+
described_class::CHECKER_CLASSES.each do |checker|
|
52
|
+
expect_any_instance_of(checker).to_not receive(:report)
|
53
|
+
end
|
54
|
+
|
55
|
+
described_class.new("some/random/path").validate_locales
|
56
|
+
end
|
57
|
+
|
58
|
+
it "outputs an error message" do
|
59
|
+
expect { described_class.new("some/random/path").validate_locales }
|
60
|
+
.to output("No locale files found for the supplied path\n").to_stdout
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns false" do
|
64
|
+
expect(described_class.new("some/random/path").validate_locales)
|
65
|
+
.to eq(false)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails_translation_manager"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.before do
|
7
|
+
I18n.available_locales = %i[en cy]
|
8
|
+
config.before { allow($stdout).to receive(:puts) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def capture_stdout(&blk)
|
12
|
+
old = $stdout
|
13
|
+
$stdout = fake = StringIO.new
|
14
|
+
blk.call
|
15
|
+
fake.string
|
16
|
+
ensure
|
17
|
+
$stdout = old
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require_relative "../../spec/support/tasks"
|
3
|
+
|
4
|
+
describe "rake tasks" do
|
5
|
+
before do
|
6
|
+
fake_rails = double()
|
7
|
+
fake_rails.stub(:root) { Pathname.new("spec") }
|
8
|
+
stub_const("Rails", fake_rails)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "translation:import", type: :task do
|
12
|
+
let(:task) { Rake::Task["translation:import"] }
|
13
|
+
let(:csv_path) { "path/to/import/fr.csv" }
|
14
|
+
let!(:importer_instance) { stub_importer }
|
15
|
+
|
16
|
+
it "outputs to stdout" do
|
17
|
+
expect { task.execute(csv_path: csv_path) }
|
18
|
+
.to output("Imported CSV from: #{csv_path} to #{Rails.root.join("config", "locales")}\n")
|
19
|
+
.to_stdout
|
20
|
+
end
|
21
|
+
|
22
|
+
it "calls the Importer class with the csv and import paths" do
|
23
|
+
task.execute(csv_path: csv_path)
|
24
|
+
|
25
|
+
expect(RailsTranslationManager::Importer)
|
26
|
+
.to have_received(:new)
|
27
|
+
.with(locale: "fr",
|
28
|
+
csv_path: csv_path,
|
29
|
+
import_directory: Rails.root.join("config", "locales"),
|
30
|
+
multiple_files_per_language: false)
|
31
|
+
expect(importer_instance).to have_received(:import)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "translation:import:all", type: :task do
|
36
|
+
let(:task) { Rake::Task["translation:import:all"] }
|
37
|
+
let(:csv_directory) { "locales/importer" }
|
38
|
+
let!(:importer_instance) { stub_importer }
|
39
|
+
|
40
|
+
it "outputs to stdout" do
|
41
|
+
expect { task.execute(csv_directory: csv_directory) }
|
42
|
+
.to output("Imported all CSVs from: #{csv_directory} to #{Rails.root.join("config", "locales")}\n")
|
43
|
+
.to_stdout
|
44
|
+
end
|
45
|
+
|
46
|
+
it "calls the importer class for each target path" do
|
47
|
+
task.execute(csv_directory: csv_directory, multiple_files_per_language: true)
|
48
|
+
import_paths = Dir["spec/locales/importer/*.csv"]
|
49
|
+
|
50
|
+
import_paths.each do |csv_path|
|
51
|
+
expect(RailsTranslationManager::Importer)
|
52
|
+
.to have_received(:new)
|
53
|
+
.with(locale: File.basename(csv_path, ".csv"),
|
54
|
+
csv_path: csv_path,
|
55
|
+
import_directory: Rails.root.join("config", "locales"),
|
56
|
+
multiple_files_per_language: true)
|
57
|
+
end
|
58
|
+
|
59
|
+
expect(importer_instance).to have_received(:import).exactly(import_paths.count)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "translation:add_missing", type: :task do
|
64
|
+
let(:task) { Rake::Task["translation:add_missing"] }
|
65
|
+
let!(:cleaner_instance) { stub_cleaner }
|
66
|
+
|
67
|
+
before do
|
68
|
+
allow(I18n::Tasks::CLI).to receive(:start)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "triggers Cleaner and allows to receive the right arguments" do
|
72
|
+
task.execute
|
73
|
+
expect(RailsTranslationManager::Cleaner)
|
74
|
+
.to have_received(:new)
|
75
|
+
.with(Rails.root.join("config", "locales"))
|
76
|
+
expect(cleaner_instance).to have_received(:clean)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "triggers i18n task and allows to receive the right arguments" do
|
80
|
+
task.execute(locale: "fr")
|
81
|
+
expect(I18n::Tasks::CLI).to have_received(:start).with(
|
82
|
+
["add-missing", "--nil-value", ["-l", "fr"]]
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "translation:normalize", type: :task do
|
88
|
+
let(:task) { Rake::Task["translation:normalize"] }
|
89
|
+
let!(:cleaner_instance) { stub_cleaner }
|
90
|
+
|
91
|
+
before do
|
92
|
+
allow(I18n::Tasks::CLI).to receive(:start)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "triggers Cleaner and allows to receive the right arguments" do
|
96
|
+
task.execute(locale_directory: "config/locales")
|
97
|
+
expect(RailsTranslationManager::Cleaner)
|
98
|
+
.to have_received(:new)
|
99
|
+
.with(Rails.root.join("config", "locales"))
|
100
|
+
expect(cleaner_instance).to have_received(:clean)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "triggers i18n task and allows to receive the right arguments" do
|
104
|
+
task.execute
|
105
|
+
expect(I18n::Tasks::CLI).to have_received(:start).with(["normalize"])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def stub_importer
|
110
|
+
importer_instance = instance_double(RailsTranslationManager::Importer)
|
111
|
+
allow(RailsTranslationManager::Importer).to receive(:new)
|
112
|
+
.and_return(importer_instance)
|
113
|
+
allow(importer_instance).to receive(:import)
|
114
|
+
|
115
|
+
importer_instance
|
116
|
+
end
|
117
|
+
|
118
|
+
def stub_cleaner
|
119
|
+
cleaner_instance = instance_double(RailsTranslationManager::Cleaner)
|
120
|
+
allow(RailsTranslationManager::Cleaner)
|
121
|
+
.to receive(:new)
|
122
|
+
.and_return(cleaner_instance)
|
123
|
+
allow(cleaner_instance).to receive(:clean)
|
124
|
+
|
125
|
+
cleaner_instance
|
126
|
+
end
|
127
|
+
end
|
data/tmp/.gitkeep
ADDED
File without changes
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_translation_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edd Sowden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,35 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: csv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: i18n-tasks
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails-i18n
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - ">="
|
@@ -42,16 +70,16 @@ dependencies:
|
|
42
70
|
name: bundler
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
|
-
- - "
|
73
|
+
- - ">="
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
75
|
+
version: '0'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
|
-
- - "
|
80
|
+
- - ">="
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rake
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +108,34 @@ dependencies:
|
|
80
108
|
- - ">="
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
83
139
|
description: ''
|
84
140
|
email:
|
85
141
|
- edd.sowden@digital.cabinet-office.gov.uk
|
@@ -97,22 +153,49 @@ files:
|
|
97
153
|
- LICENSE.txt
|
98
154
|
- README.md
|
99
155
|
- Rakefile
|
156
|
+
- config/locales/plurals.rb
|
100
157
|
- lib/rails_translation_manager.rb
|
158
|
+
- lib/rails_translation_manager/cleaner.rb
|
101
159
|
- lib/rails_translation_manager/exporter.rb
|
160
|
+
- lib/rails_translation_manager/i18n_tasks_option_parser.rb
|
102
161
|
- lib/rails_translation_manager/importer.rb
|
162
|
+
- lib/rails_translation_manager/locale_checker.rb
|
163
|
+
- lib/rails_translation_manager/locale_checker/all_locales.rb
|
164
|
+
- lib/rails_translation_manager/locale_checker/base_checker.rb
|
165
|
+
- lib/rails_translation_manager/locale_checker/incompatible_plurals.rb
|
166
|
+
- lib/rails_translation_manager/locale_checker/locale_checker_helper.rb
|
167
|
+
- lib/rails_translation_manager/locale_checker/missing_english_locales.rb
|
168
|
+
- lib/rails_translation_manager/locale_checker/missing_foreign_locales.rb
|
169
|
+
- lib/rails_translation_manager/locale_checker/plural_forms.rb
|
103
170
|
- lib/rails_translation_manager/railtie.rb
|
104
|
-
- lib/rails_translation_manager/stealer.rb
|
105
|
-
- lib/rails_translation_manager/validator.rb
|
106
171
|
- lib/rails_translation_manager/version.rb
|
107
172
|
- lib/rails_translation_manager/yaml_writer.rb
|
108
173
|
- lib/tasks/translation.rake
|
109
174
|
- rails_translation_manager.gemspec
|
175
|
+
- spec/locales/cleaner/clean.yml
|
176
|
+
- spec/locales/cleaner/with_whitespace.yml
|
177
|
+
- spec/locales/importer/fr.csv
|
178
|
+
- spec/locales/importer/hy_with_byte_order_mark.csv
|
179
|
+
- spec/locales/in_sync/cy/browse.yml
|
180
|
+
- spec/locales/in_sync/en/browse.yml
|
181
|
+
- spec/locales/out_of_sync/cy.yml
|
182
|
+
- spec/locales/out_of_sync/en.yml
|
183
|
+
- spec/rails_translation_manager/cleaner_spec.rb
|
184
|
+
- spec/rails_translation_manager/importer_spec.rb
|
185
|
+
- spec/rails_translation_manager/locale_checker/all_locales_spec.rb
|
186
|
+
- spec/rails_translation_manager/locale_checker/incompatible_plurals_spec.rb
|
187
|
+
- spec/rails_translation_manager/locale_checker/locale_checker_helper_spec.rb
|
188
|
+
- spec/rails_translation_manager/locale_checker/missing_english_locales_spec.rb
|
189
|
+
- spec/rails_translation_manager/locale_checker/missing_foreign_locales_spec.rb
|
190
|
+
- spec/rails_translation_manager/locale_checker/plural_forms_spec.rb
|
191
|
+
- spec/rails_translation_manager/locale_checker_spec.rb
|
192
|
+
- spec/spec_helper.rb
|
193
|
+
- spec/support/tasks.rb
|
194
|
+
- spec/tasks/translation_spec.rb
|
110
195
|
- test/rails_translation_manager/exporter_test.rb
|
111
|
-
- test/rails_translation_manager/importer_test.rb
|
112
|
-
- test/rails_translation_manager/stealer_test.rb
|
113
|
-
- test/rails_translation_manager/validator_test.rb
|
114
196
|
- test/rails_translation_manager/yaml_writer_test.rb
|
115
197
|
- test/test_helper.rb
|
198
|
+
- tmp/.gitkeep
|
116
199
|
homepage: ''
|
117
200
|
licenses:
|
118
201
|
- MIT
|
@@ -132,15 +215,31 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
215
|
- !ruby/object:Gem::Version
|
133
216
|
version: '0'
|
134
217
|
requirements: []
|
135
|
-
|
136
|
-
rubygems_version: 2.7.6
|
218
|
+
rubygems_version: 3.0.3
|
137
219
|
signing_key:
|
138
220
|
specification_version: 4
|
139
221
|
summary: Tasks to manage translation files
|
140
222
|
test_files:
|
223
|
+
- spec/locales/cleaner/clean.yml
|
224
|
+
- spec/locales/cleaner/with_whitespace.yml
|
225
|
+
- spec/locales/importer/fr.csv
|
226
|
+
- spec/locales/importer/hy_with_byte_order_mark.csv
|
227
|
+
- spec/locales/in_sync/cy/browse.yml
|
228
|
+
- spec/locales/in_sync/en/browse.yml
|
229
|
+
- spec/locales/out_of_sync/cy.yml
|
230
|
+
- spec/locales/out_of_sync/en.yml
|
231
|
+
- spec/rails_translation_manager/cleaner_spec.rb
|
232
|
+
- spec/rails_translation_manager/importer_spec.rb
|
233
|
+
- spec/rails_translation_manager/locale_checker/all_locales_spec.rb
|
234
|
+
- spec/rails_translation_manager/locale_checker/incompatible_plurals_spec.rb
|
235
|
+
- spec/rails_translation_manager/locale_checker/locale_checker_helper_spec.rb
|
236
|
+
- spec/rails_translation_manager/locale_checker/missing_english_locales_spec.rb
|
237
|
+
- spec/rails_translation_manager/locale_checker/missing_foreign_locales_spec.rb
|
238
|
+
- spec/rails_translation_manager/locale_checker/plural_forms_spec.rb
|
239
|
+
- spec/rails_translation_manager/locale_checker_spec.rb
|
240
|
+
- spec/spec_helper.rb
|
241
|
+
- spec/support/tasks.rb
|
242
|
+
- spec/tasks/translation_spec.rb
|
141
243
|
- test/rails_translation_manager/exporter_test.rb
|
142
|
-
- test/rails_translation_manager/importer_test.rb
|
143
|
-
- test/rails_translation_manager/stealer_test.rb
|
144
|
-
- test/rails_translation_manager/validator_test.rb
|
145
244
|
- test/rails_translation_manager/yaml_writer_test.rb
|
146
245
|
- test/test_helper.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require "i18n"
|
3
|
-
require_relative "yaml_writer"
|
4
|
-
|
5
|
-
class RailsTranslationManager::Stealer
|
6
|
-
include YAMLWriter
|
7
|
-
|
8
|
-
# locale is the locale name as a string.
|
9
|
-
# source_app_path is the path to the root of the app to steal from.
|
10
|
-
# mapping_file_path is the path to a YAML file mapping translation keys in
|
11
|
-
# the source app to those in the target app. For example:
|
12
|
-
# document.type: content_item.format
|
13
|
-
# document.published: content_item.metadata.published
|
14
|
-
# which will import everything under "document.type" and "document.published"
|
15
|
-
# in the source app, and write it to "content_item.format" and
|
16
|
-
# "content_item.metadata.published" in the target app.
|
17
|
-
# locales_path is the path to the locale files to output, which is usually
|
18
|
-
# Rails.root.join('config/locales').
|
19
|
-
# The process will preserve data already in the output file if it is not
|
20
|
-
# referenced in the mapping, but will always override data belonging to keys
|
21
|
-
# that are in the mapping.
|
22
|
-
def initialize(locale, source_app_path, mapping_file_path, locales_path)
|
23
|
-
@locale = locale
|
24
|
-
@source_app_path = source_app_path
|
25
|
-
@mapping_file_path = mapping_file_path
|
26
|
-
@locales_path = locales_path
|
27
|
-
end
|
28
|
-
|
29
|
-
def steal_locale
|
30
|
-
target_data = convert_locale(get_target_data)
|
31
|
-
write_yaml(target_locale_path, target_data)
|
32
|
-
end
|
33
|
-
|
34
|
-
def convert_locale(target_data)
|
35
|
-
mapping_data.each do |source, target|
|
36
|
-
data = source_data[@locale]
|
37
|
-
source.split('.').each { |key| data = data.fetch(key, {}) }
|
38
|
-
set_recursive(target_data[@locale], target.split("."), data)
|
39
|
-
end
|
40
|
-
target_data
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def set_recursive(hash, keys, data)
|
46
|
-
if keys.empty?
|
47
|
-
data
|
48
|
-
else
|
49
|
-
key = keys.shift
|
50
|
-
hash.tap do |h|
|
51
|
-
h.merge!({ key => set_recursive(hash.fetch(key, {}), keys, data)})
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def source_locale_path
|
57
|
-
File.join(@source_app_path, 'config', 'locales', "#{@locale}.yml")
|
58
|
-
end
|
59
|
-
|
60
|
-
def source_data
|
61
|
-
@source_data ||= YAML.load_file(source_locale_path)
|
62
|
-
end
|
63
|
-
|
64
|
-
def target_locale_path
|
65
|
-
File.join(@locales_path, "#{@locale}.yml")
|
66
|
-
end
|
67
|
-
|
68
|
-
def default_target_data
|
69
|
-
{ @locale => {} }
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_target_data
|
73
|
-
if File.exist?(target_locale_path)
|
74
|
-
YAML.load_file(target_locale_path) || default_target_data
|
75
|
-
else
|
76
|
-
default_target_data
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def mapping_data
|
81
|
-
@mapping_data ||= YAML.load_file(@mapping_file_path)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
@@ -1,92 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'logger'
|
3
|
-
|
4
|
-
class RailsTranslationManager::Validator
|
5
|
-
def initialize(translation_file_path, logger = Logger.new(nil))
|
6
|
-
@translation_file_path = translation_file_path
|
7
|
-
@logger = logger
|
8
|
-
end
|
9
|
-
|
10
|
-
def check!
|
11
|
-
@logger.info "Checking translation files in '#{@translation_file_path}' for unexpected interpolation keys"
|
12
|
-
@logger.info "Loading reference file (#{reference_file_name})"
|
13
|
-
@logger.info "Checking..."
|
14
|
-
reference = load_translation_file("#{@translation_file_path}/#{reference_file_name}")
|
15
|
-
Dir["#{@translation_file_path}/*.yml"].reject do |entry|
|
16
|
-
File.basename(entry) == reference_file_name
|
17
|
-
end.inject([]) do |errors, entry|
|
18
|
-
translation_file = load_translation_file(entry)
|
19
|
-
errors + unexpected_substitution_keys(reference, translation_file)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def unexpected_substitution_keys(reference, translation_file)
|
24
|
-
reference_substitutions = substitutions_in(reference)
|
25
|
-
target_substitutions = substitutions_in(translation_file)
|
26
|
-
|
27
|
-
targets_by_path = target_substitutions.each_with_object({}) do |target, hash|
|
28
|
-
hash[exclude_locale_from_path(target.path)] = target
|
29
|
-
end
|
30
|
-
|
31
|
-
reference_substitutions.each_with_object([]) do |reference, unexpected_substitutions|
|
32
|
-
target = targets_by_path[exclude_locale_from_path(reference.path)]
|
33
|
-
next if target.nil? || reference.has_all_substitutions?(target)
|
34
|
-
unexpected_substitutions << UnexpectedSubstition.new(target, reference)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def substitutions_in(translation_file)
|
39
|
-
flatten(translation_file).reject do |translation|
|
40
|
-
translation.substitutions.empty?
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
class TranslationEntry < Struct.new(:path, :value)
|
45
|
-
def substitutions
|
46
|
-
@substitutions ||= self.value.scan(/%{([^}]*)}/)
|
47
|
-
end
|
48
|
-
|
49
|
-
def has_all_substitutions?(other)
|
50
|
-
(other.substitutions - self.substitutions).empty?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class UnexpectedSubstition < Struct.new(:target, :reference)
|
55
|
-
def to_s
|
56
|
-
missing = (self.reference.substitutions - self.target.substitutions)
|
57
|
-
extras = (self.target.substitutions - self.reference.substitutions)
|
58
|
-
message = %Q{Key "#{target.path.join('.')}":}
|
59
|
-
if extras.any?
|
60
|
-
message << %Q{ Extra substitutions: ["#{extras.join('", "')}"].}
|
61
|
-
end
|
62
|
-
if missing.any?
|
63
|
-
message << %Q{ Missing substitutions: ["#{missing.join('", "')}"].}
|
64
|
-
end
|
65
|
-
message
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def flatten(translation_file, path = [])
|
70
|
-
translation_file.map do |key, value|
|
71
|
-
case value
|
72
|
-
when Hash
|
73
|
-
flatten(value, path + [key])
|
74
|
-
else
|
75
|
-
TranslationEntry.new(path + [key], value || "")
|
76
|
-
end
|
77
|
-
end.flatten
|
78
|
-
end
|
79
|
-
|
80
|
-
def load_translation_file(filename)
|
81
|
-
YAML.load_file(filename)
|
82
|
-
end
|
83
|
-
|
84
|
-
def reference_file_name
|
85
|
-
"en.yml"
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
def exclude_locale_from_path(path)
|
90
|
-
path[1..-1]
|
91
|
-
end
|
92
|
-
end
|