babelyoda 2.1.20 → 2.2.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0347f2782ffb4abd2e513b84f86015ed1d0a4ff
4
+ data.tar.gz: 4393ec8e01b4b536f34dbf90ab0195550c1259d3
5
+ SHA512:
6
+ metadata.gz: 7f9e9a76f375f4419b78b7fe46b833e6a86145db2f5f965e2d62a91bf3c873ab86e754b3e57c669bcb546259762f0f1401c7c0b497b3701e39e90e942411a0c8
7
+ data.tar.gz: 79671401dbaa7345b650501ced99e265f5572c1feeeefe5d6336e35f07cf7d8041d1ea81b5f8f83984863c0f8c85620b67073120f5fa312142c21117eaa89122
data/CHANGELOG CHANGED
@@ -3,3 +3,4 @@ v1.4.0. Better command line options handling + Bugfixes.
3
3
  v1.5.0. Fixed a major bug in localization of XIB files.
4
4
  v2.0.0. Full re-write. Yay!
5
5
  v2.1.14. Fix merging of pluralized keys: translated values are now preserved correctly.
6
+ v2.2.0. Add a task checking for long translations.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2012 Andrey Subbotin
1
+ Copyright (c) 2010-2016 Andrey Subbotin
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -20,7 +20,8 @@ The following people contributed patches, made suggestions or made otherwise hel
20
20
 
21
21
  * [Ivan Moskalev](https://github.com/ivanmoskalev)
22
22
  * [Alexander Denisov](https://github.com/StoneSpb)
23
+ * [Mikhail Chupin](https://github.com/ilmarion)
23
24
 
24
25
  ## Copyright
25
26
 
26
- Copyright (c) 2010-2014 Andrey Subbotin. See LICENSE for details.
27
+ Copyright (c) 2010-2016 Andrey Subbotin. See LICENSE for details.
@@ -5,7 +5,7 @@ require "babelyoda/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "babelyoda"
7
7
  s.version = Babelyoda::VERSION
8
- s.authors = ["Andrey Subbotin", "Ivan Moskalev", "Alexander Denisov"]
8
+ s.authors = ["Andrey Subbotin", "Ivan Moskalev", "Alexander Denisov", "Mikhail Chupin"]
9
9
  s.email = ["andrey@subbotin.me"]
10
10
  s.homepage = "http://github.com/eploko/babelyoda"
11
11
  s.summary = "Xcode project localization made easy"
@@ -8,6 +8,8 @@ require_relative 'babelyoda/git'
8
8
  require_relative 'babelyoda/ibtool'
9
9
  require_relative 'babelyoda/keyset'
10
10
  require_relative 'babelyoda/localization_key'
11
+ require_relative 'babelyoda/length_checker'
12
+ require_relative 'babelyoda/length_checker_params'
11
13
  require_relative 'babelyoda/localization_value'
12
14
  require_relative 'babelyoda/logger'
13
15
  require_relative 'babelyoda/rake'
@@ -247,17 +249,7 @@ namespace :babelyoda do
247
249
 
248
250
  desc "Verifies all local translations are present"
249
251
  task :verify do
250
- combined_keyset = Babelyoda::Keyset.new('babelyoda.verify')
251
- spec.strings_files.each do |filename|
252
- dev_lang_strings = Babelyoda::Strings.new(filename, spec.development_language).read
253
- combined_keyset.merge!(dev_lang_strings)
254
- spec.localization_languages.each do |language|
255
- lang_strings = Babelyoda::Strings.new(File.localized(filename, language), language).read
256
- combined_keyset.merge!(lang_strings)
257
- end
258
- end
259
- combined_keyset.drop_empty!
260
-
252
+ combined_keyset = combined_keyset(spec, 'babelyoda.verify')
261
253
  count = {}
262
254
  spec.all_languages.each { |lang| count[lang.to_sym] = 0}
263
255
 
@@ -281,6 +273,23 @@ namespace :babelyoda do
281
273
  end
282
274
  exit 1 unless all_found
283
275
  end
276
+
277
+ desc "Checks localizations length"
278
+ task :check_localizations_length do
279
+ combined_keyset = combined_keyset(spec, 'babelyoda.check_length')
280
+ dev_lang = spec.development_language.to_sym
281
+ params = spec.length_checker_params
282
+ checker = Babelyoda::LengthChecker.new(dev_lang, params)
283
+ checker.long_translations(combined_keyset).each_pair do |lang, translations|
284
+ $logger.warn lang.to_s
285
+ translations.each do |t|
286
+ $logger.warn "/* #{t.context} */"
287
+ $logger.warn "'#{t.text}' >>> '#{t.dev_text}'"
288
+ $logger.warn ""
289
+ end
290
+ $logger.warn ""
291
+ end
292
+ end
284
293
 
285
294
  namespace :remote do
286
295
 
@@ -321,3 +330,17 @@ def strings_filename(keyset_name, lang)
321
330
  File.join("#{lang}.lproj", "#{keyset_name}.strings")
322
331
  end
323
332
  end
333
+
334
+ def combined_keyset(spec, keyset_name)
335
+ keyset = Babelyoda::Keyset.new(keyset_name)
336
+ spec.strings_files.each do |filename|
337
+ dev_lang_strings = Babelyoda::Strings.new(filename, spec.development_language).read
338
+ keyset.merge!(dev_lang_strings)
339
+ spec.localization_languages.each do |language|
340
+ lang_strings = Babelyoda::Strings.new(File.localized(filename, language), language).read
341
+ keyset.merge!(lang_strings)
342
+ end
343
+ end
344
+ keyset.drop_empty!
345
+ keyset
346
+ end
@@ -0,0 +1,67 @@
1
+ module Babelyoda
2
+ class LengthChecker
3
+ def initialize(dev_language, params)
4
+ @dev_language = dev_language
5
+ @params = params
6
+ end
7
+
8
+ def long_translations(keyset)
9
+ long_translations = {}
10
+
11
+ keyset.keys.each_value do |key|
12
+ dev_value = key.values[@dev_language]
13
+ dev_text = longest_translation(dev_value)
14
+ dev_len = dev_text.length.to_f
15
+
16
+ key.values.each_value do |value|
17
+ text = longest_translation(value)
18
+ len = text.nil? ? 0 : text.length
19
+ ratio = len/dev_len
20
+ big_ratio = ratio >= @params.ratio
21
+ big_delta = (len - dev_len) >= @params.delta
22
+
23
+ if big_ratio && big_delta
24
+ lang = value.language.to_sym
25
+ translation = Babelyoda::LongTranslation.new(dev_text, text, key.context)
26
+ if long_translations.has_key?(lang)
27
+ long_translations[lang].push(translation)
28
+ else
29
+ long_translations[lang] = [translation]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ long_translations
35
+ end
36
+
37
+ private
38
+
39
+ def longest_translation(localizaition_value)
40
+ if localizaition_value.plural?
41
+ translation = localizaition_value.text.values.max_by {|str| str.nil? ? 0 : str.length}
42
+ else
43
+ translation = localizaition_value.text
44
+ end
45
+ translation
46
+ end
47
+ end
48
+
49
+ class LongTranslation
50
+ attr_accessor :dev_text
51
+ attr_accessor :text
52
+ attr_accessor :context
53
+
54
+ def initialize(dev_text, text, context)
55
+ @dev_text = dev_text
56
+ @text = text
57
+ @context = context
58
+ end
59
+
60
+ def ==(other_obj)
61
+ dev_texts_equal = @dev_text == other_obj.dev_text
62
+ texts_equal = @text == other_obj.text
63
+ contexts_equal = @context == other_obj.context
64
+ dev_texts_equal && texts_equal && contexts_equal
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'specification_loader'
2
+
3
+ module Babelyoda
4
+ class LengthCheckerParams
5
+ include Babelyoda::SpecificationLoader
6
+
7
+ attr_accessor :ratio
8
+ attr_accessor :delta
9
+ end
10
+ end
@@ -16,6 +16,7 @@ module Babelyoda
16
16
  attr_accessor :xib_files
17
17
  attr_accessor :strings_files
18
18
  attr_accessor :scm
19
+ attr_accessor :length_checker_params
19
20
 
20
21
  FILENAME = 'Babelfile'
21
22
 
@@ -1,3 +1,3 @@
1
1
  module Babelyoda
2
- VERSION = "2.1.20"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -0,0 +1,106 @@
1
+ require 'babelyoda/keyset'
2
+ require 'babelyoda/length_checker'
3
+ require 'babelyoda/length_checker_params'
4
+ require 'babelyoda/strings_lexer'
5
+ require 'babelyoda/strings_parser'
6
+
7
+ describe "length checker" do
8
+ before(:example) do
9
+ @ratio = 2
10
+ @delta = 3
11
+ @params = Babelyoda::LengthCheckerParams.new()
12
+ @params.ratio = @ratio
13
+ @params.delta = @delta
14
+ @dev_lang = :dev_lang
15
+ @lang1 = :lang1
16
+ @lang2 = :lang2
17
+ @checker = Babelyoda::LengthChecker.new(@dev_lang, @params)
18
+ end
19
+
20
+ describe "finding long translations in keyset" do
21
+ def add_lang_strings_to_keyset(lang, strings, keyset)
22
+ lexer = Babelyoda::StringsLexer.new
23
+ parser = Babelyoda::StringsParser.new(lexer, lang)
24
+ parser.parse(strings) do |record|
25
+ keyset.merge_key!(record)
26
+ end
27
+ end
28
+
29
+ def generate_keyset(dev_str, lang1_str, lang2_str)
30
+ keyset = Babelyoda::Keyset.new("test_keyset")
31
+ add_lang_strings_to_keyset(@dev_lang, dev_str, keyset)
32
+ add_lang_strings_to_keyset(@lang1, lang1_str, keyset)
33
+ add_lang_strings_to_keyset(@lang2, lang2_str, keyset)
34
+ keyset
35
+ end
36
+
37
+ it "doesn't find anything in empty keyset" do
38
+ empty_keyset = Babelyoda::Keyset.new("empty_keyset")
39
+
40
+ expect(@checker.long_translations(empty_keyset)).to be_empty
41
+ end
42
+
43
+ context "when has only non-plural keys" do
44
+ it "finds long translations" do
45
+ dev_str = <<-EOF
46
+ /* comment hi */
47
+ "Hi" = "Hi";
48
+ /* comment hello */
49
+ "Hello" = "Hello";
50
+ EOF
51
+
52
+ lang1_str = <<-EOF
53
+ /* comment hi */
54
+ "Hi" = "HiHi";
55
+ /* comment hello */
56
+ "Hello" = "HelloHello";
57
+ EOF
58
+
59
+ lang2_str = <<-EOF
60
+ /* comment hi */
61
+ "Hi" = "HiHiHiHi";
62
+ /* comment hello */
63
+ "Hello" = "HelloHelloHello";
64
+ EOF
65
+
66
+ keyset = generate_keyset(dev_str, lang1_str, lang2_str)
67
+ lang1_hello_problem = Babelyoda::LongTranslation.new("Hello", "HelloHello", "comment hello")
68
+ lang2_hi_problem = Babelyoda::LongTranslation.new("Hi", "HiHiHiHi", "comment hi")
69
+ lang2_hello_problem = Babelyoda::LongTranslation.new("Hello", "HelloHelloHello", "comment hello")
70
+ expected = {}
71
+ expected[@lang1] = [lang1_hello_problem]
72
+ expected[@lang2] = [lang2_hi_problem, lang2_hello_problem]
73
+
74
+ expect(@checker.long_translations(keyset)).to eq(expected)
75
+ end
76
+ end
77
+
78
+ context "when has plural keys" do
79
+ it "compares longest plural variants" do
80
+ dev_str = <<-EOF
81
+ /* comment min */
82
+ "%[one]u min" = "min";
83
+ "%[many]u min" = "minutes";
84
+ EOF
85
+
86
+ lang1_str = <<-EOF
87
+ /* comment min */
88
+ "%[one]u min" = "minminmin";
89
+ "%[many]u min" = "minutes";
90
+ EOF
91
+
92
+ lang2_str = <<-EOF
93
+ /* comment min */
94
+ "%[one]u min" = "minminmin";
95
+ "%[many]u min" = "minutesminutes";
96
+ EOF
97
+
98
+ keyset = generate_keyset(dev_str, lang1_str, lang2_str)
99
+ lang2_problem = Babelyoda::LongTranslation.new("minutes", "minutesminutes", "comment min")
100
+ expected = {@lang2 => [lang2_problem]}
101
+
102
+ expect(@checker.long_translations(keyset)).to eq(expected)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -24,4 +24,9 @@ Babelyoda::Specification.new do |s|
24
24
  s.resources_folder = 'Resources'
25
25
  s.xib_files = FileList['{Classes,Resources}/**/en.lproj/*.{xib}']
26
26
  s.strings_files = FileList['{Classes,Resources}/**/en.lproj/*.{strings}']
27
+
28
+ s.length_checker_params = Babelyoda::LengthCheckerParams.new do |p|
29
+ p.ratio = 1.5
30
+ p.delta = 10
31
+ end
27
32
  end
metadata CHANGED
@@ -1,212 +1,192 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babelyoda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.20
5
- prerelease:
4
+ version: 2.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Andrey Subbotin
9
8
  - Ivan Moskalev
10
9
  - Alexander Denisov
10
+ - Mikhail Chupin
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-11-26 00:00:00.000000000 Z
14
+ date: 2016-10-14 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
18
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
19
  requirements:
21
- - - ! '>='
20
+ - - '>='
22
21
  - !ruby/object:Gem::Version
23
22
  version: '0'
24
23
  type: :development
25
24
  prerelease: false
26
25
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
26
  requirements:
29
- - - ! '>='
27
+ - - '>='
30
28
  - !ruby/object:Gem::Version
31
29
  version: '0'
32
30
  - !ruby/object:Gem::Dependency
33
31
  name: guard
34
32
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
33
  requirements:
37
- - - ! '>='
34
+ - - '>='
38
35
  - !ruby/object:Gem::Version
39
36
  version: '0'
40
37
  type: :development
41
38
  prerelease: false
42
39
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
40
  requirements:
45
- - - ! '>='
41
+ - - '>='
46
42
  - !ruby/object:Gem::Version
47
43
  version: '0'
48
44
  - !ruby/object:Gem::Dependency
49
45
  name: guard-rspec
50
46
  requirement: !ruby/object:Gem::Requirement
51
- none: false
52
47
  requirements:
53
- - - ! '>='
48
+ - - '>='
54
49
  - !ruby/object:Gem::Version
55
50
  version: '0'
56
51
  type: :development
57
52
  prerelease: false
58
53
  version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
54
  requirements:
61
- - - ! '>='
55
+ - - '>='
62
56
  - !ruby/object:Gem::Version
63
57
  version: '0'
64
58
  - !ruby/object:Gem::Dependency
65
59
  name: ruby_gntp
66
60
  requirement: !ruby/object:Gem::Requirement
67
- none: false
68
61
  requirements:
69
- - - ! '>='
62
+ - - '>='
70
63
  - !ruby/object:Gem::Version
71
64
  version: '0'
72
65
  type: :development
73
66
  prerelease: false
74
67
  version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
68
  requirements:
77
- - - ! '>='
69
+ - - '>='
78
70
  - !ruby/object:Gem::Version
79
71
  version: '0'
80
72
  - !ruby/object:Gem::Dependency
81
73
  name: awesome_print
82
74
  requirement: !ruby/object:Gem::Requirement
83
- none: false
84
75
  requirements:
85
76
  - - ~>
86
77
  - !ruby/object:Gem::Version
87
78
  version: '1.0'
88
- - - ! '>='
79
+ - - '>='
89
80
  - !ruby/object:Gem::Version
90
81
  version: 1.0.2
91
82
  type: :runtime
92
83
  prerelease: false
93
84
  version_requirements: !ruby/object:Gem::Requirement
94
- none: false
95
85
  requirements:
96
86
  - - ~>
97
87
  - !ruby/object:Gem::Version
98
88
  version: '1.0'
99
- - - ! '>='
89
+ - - '>='
100
90
  - !ruby/object:Gem::Version
101
91
  version: 1.0.2
102
92
  - !ruby/object:Gem::Dependency
103
93
  name: rake
104
94
  requirement: !ruby/object:Gem::Requirement
105
- none: false
106
95
  requirements:
107
96
  - - ~>
108
97
  - !ruby/object:Gem::Version
109
98
  version: '0.9'
110
- - - ! '>='
99
+ - - '>='
111
100
  - !ruby/object:Gem::Version
112
101
  version: 0.9.2.2
113
102
  type: :runtime
114
103
  prerelease: false
115
104
  version_requirements: !ruby/object:Gem::Requirement
116
- none: false
117
105
  requirements:
118
106
  - - ~>
119
107
  - !ruby/object:Gem::Version
120
108
  version: '0.9'
121
- - - ! '>='
109
+ - - '>='
122
110
  - !ruby/object:Gem::Version
123
111
  version: 0.9.2.2
124
112
  - !ruby/object:Gem::Dependency
125
113
  name: rchardet19
126
114
  requirement: !ruby/object:Gem::Requirement
127
- none: false
128
115
  requirements:
129
116
  - - ~>
130
117
  - !ruby/object:Gem::Version
131
118
  version: '1.3'
132
- - - ! '>='
119
+ - - '>='
133
120
  - !ruby/object:Gem::Version
134
121
  version: 1.3.5
135
122
  type: :runtime
136
123
  prerelease: false
137
124
  version_requirements: !ruby/object:Gem::Requirement
138
- none: false
139
125
  requirements:
140
126
  - - ~>
141
127
  - !ruby/object:Gem::Version
142
128
  version: '1.3'
143
- - - ! '>='
129
+ - - '>='
144
130
  - !ruby/object:Gem::Version
145
131
  version: 1.3.5
146
132
  - !ruby/object:Gem::Dependency
147
133
  name: builder
148
134
  requirement: !ruby/object:Gem::Requirement
149
- none: false
150
135
  requirements:
151
136
  - - ~>
152
137
  - !ruby/object:Gem::Version
153
138
  version: '3.0'
154
- - - ! '>='
139
+ - - '>='
155
140
  - !ruby/object:Gem::Version
156
141
  version: 3.0.0
157
142
  type: :runtime
158
143
  prerelease: false
159
144
  version_requirements: !ruby/object:Gem::Requirement
160
- none: false
161
145
  requirements:
162
146
  - - ~>
163
147
  - !ruby/object:Gem::Version
164
148
  version: '3.0'
165
- - - ! '>='
149
+ - - '>='
166
150
  - !ruby/object:Gem::Version
167
151
  version: 3.0.0
168
152
  - !ruby/object:Gem::Dependency
169
153
  name: nokogiri
170
154
  requirement: !ruby/object:Gem::Requirement
171
- none: false
172
155
  requirements:
173
156
  - - ~>
174
157
  - !ruby/object:Gem::Version
175
158
  version: '1.5'
176
- - - ! '>='
159
+ - - '>='
177
160
  - !ruby/object:Gem::Version
178
161
  version: 1.5.5
179
162
  type: :runtime
180
163
  prerelease: false
181
164
  version_requirements: !ruby/object:Gem::Requirement
182
- none: false
183
165
  requirements:
184
166
  - - ~>
185
167
  - !ruby/object:Gem::Version
186
168
  version: '1.5'
187
- - - ! '>='
169
+ - - '>='
188
170
  - !ruby/object:Gem::Version
189
171
  version: 1.5.5
190
172
  - !ruby/object:Gem::Dependency
191
173
  name: log4r
192
174
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
175
  requirements:
195
176
  - - ~>
196
177
  - !ruby/object:Gem::Version
197
178
  version: '1'
198
- - - ! '>='
179
+ - - '>='
199
180
  - !ruby/object:Gem::Version
200
181
  version: 1.1.10
201
182
  type: :runtime
202
183
  prerelease: false
203
184
  version_requirements: !ruby/object:Gem::Requirement
204
- none: false
205
185
  requirements:
206
186
  - - ~>
207
187
  - !ruby/object:Gem::Version
208
188
  version: '1'
209
- - - ! '>='
189
+ - - '>='
210
190
  - !ruby/object:Gem::Version
211
191
  version: 1.1.10
212
192
  description: A simple utility to push/pull l10n resources of an Xcode project to/from
@@ -234,6 +214,8 @@ files:
234
214
  - lib/babelyoda/git_versions.rb
235
215
  - lib/babelyoda/ibtool.rb
236
216
  - lib/babelyoda/keyset.rb
217
+ - lib/babelyoda/length_checker.rb
218
+ - lib/babelyoda/length_checker_params.rb
237
219
  - lib/babelyoda/localization_key.rb
238
220
  - lib/babelyoda/localization_value.rb
239
221
  - lib/babelyoda/logger.rb
@@ -249,6 +231,7 @@ files:
249
231
  - lib/babelyoda/version.rb
250
232
  - lib/babelyoda/xib.rb
251
233
  - spec/lib/babelyoda/keyset_spec.rb
234
+ - spec/lib/babelyoda/length_checker_spec.rb
252
235
  - spec/lib/babelyoda/localization_key_spec.rb
253
236
  - spec/lib/babelyoda/localization_value_spec.rb
254
237
  - spec/lib/babelyoda/specification_spec.rb
@@ -260,26 +243,25 @@ files:
260
243
  - templates/Babelfile.erb
261
244
  homepage: http://github.com/eploko/babelyoda
262
245
  licenses: []
246
+ metadata: {}
263
247
  post_install_message:
264
248
  rdoc_options: []
265
249
  require_paths:
266
250
  - lib
267
251
  required_ruby_version: !ruby/object:Gem::Requirement
268
- none: false
269
252
  requirements:
270
- - - ! '>='
253
+ - - '>='
271
254
  - !ruby/object:Gem::Version
272
255
  version: '0'
273
256
  required_rubygems_version: !ruby/object:Gem::Requirement
274
- none: false
275
257
  requirements:
276
- - - ! '>='
258
+ - - '>='
277
259
  - !ruby/object:Gem::Version
278
260
  version: '0'
279
261
  requirements: []
280
262
  rubyforge_project: babelyoda
281
- rubygems_version: 1.8.23.2
263
+ rubygems_version: 2.0.14.1
282
264
  signing_key:
283
- specification_version: 3
265
+ specification_version: 4
284
266
  summary: Xcode project localization made easy
285
267
  test_files: []