locca 2.1.0 → 2.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ff2073ab9c95c9468cba788b05d37cac96ff2a6d
4
- data.tar.gz: 0ae04421b2a1f2e8f6ffc3d33a4bb3f2d9f4be75
2
+ SHA256:
3
+ metadata.gz: cc26bb2f03287b0e7453e9ce7039157d1f002a406c4b056a2bed3679fb0cb39c
4
+ data.tar.gz: b256544ee1dbb061ae8264fb680efe3f5ed483c4b6654fbc1414a464b5d13a31
5
5
  SHA512:
6
- metadata.gz: bfc71e2ecf42f5d8d904bdb83cf1e67fdb8437bdf51bc04761bdc85789955e9d70b097761b18b3a9b6fbd755a6a5e60d5b0c5dda8f403cb72379ca8f213dabff
7
- data.tar.gz: 057d6f0106c0673f1c431cc95510839babdf56f37179650e5609dcc6fa738878a422e3da5fb7aaa33f716480d8c7cebb90952a467ba8db9314355715896fcfd4
6
+ metadata.gz: 5a0bf3b7887825323608e8236fec10951f7115f442648566f2e967942c159c8430be69bef88c6c40483f5324ef0d08cff60af284cacf4b886715fe304d35ae50
7
+ data.tar.gz: 336975865b60608b482bf1b391b18c57ef6ca3249b624534883ce529c34228bbc805b501417701d6b310209b2e065eec93758791db19aa4c5ad84cdc4421381b
data/bin/locca CHANGED
@@ -109,6 +109,24 @@ command :translate do |c|
109
109
  end
110
110
  end
111
111
 
112
+ desc 'Audit translation (find missing / extra / untranslated keys)'
113
+ command :audit do |c|
114
+ c.action do |global_options, options, args|
115
+ work_dir = global_options['work-dir'.to_sym]
116
+ if not work_dir
117
+ work_dir = Dir.getwd
118
+ end
119
+
120
+ success = true
121
+ projects_in_dir(work_dir).each { |project|
122
+ if !$locca.audit(project)
123
+ success = false
124
+ end
125
+ }
126
+ exit!(success)
127
+ end
128
+ end
129
+
112
130
  pre do |global, command, options, args|
113
131
  $locca = Locca::Locca.new()
114
132
  true
@@ -33,6 +33,7 @@ require 'locca/projects/android_project'
33
33
  require 'locca/config_reader'
34
34
  require 'locca/config_validator'
35
35
 
36
+ require 'locca/actions/audit_action'
36
37
  require 'locca/actions/build_action'
37
38
  require 'locca/actions/merge_action'
38
39
  require 'locca/actions/onesky_sync_action'
@@ -58,6 +59,42 @@ require 'babelyoda/strings_parser'
58
59
 
59
60
  module Locca
60
61
  class Locca
62
+ def audit(project)
63
+ if not project
64
+ raise 'Can\'t initialize Locca with nil project'
65
+ end
66
+
67
+ action = AuditAction.new(project, project.collection_builder(), project.collections_generator())
68
+ failed_audit_results = action.execute()
69
+
70
+ failed_audit_results.each do |audit_result|
71
+ puts()
72
+ puts(">>> #{project.name}/#{audit_result.lang}/#{audit_result.collection_name}")
73
+ unless audit_result.missing_keys.empty?
74
+ puts("Missing Keys:")
75
+ audit_result.missing_keys.each do |key|
76
+ puts("- #{key}")
77
+ end
78
+ end
79
+
80
+ unless audit_result.extra_keys.empty?
81
+ puts("Extra Keys:")
82
+ audit_result.extra_keys.each do |key|
83
+ puts("- #{key}")
84
+ end
85
+ end
86
+
87
+ unless audit_result.untranslated_keys.empty?
88
+ puts("Untranslated:")
89
+ audit_result.untranslated_keys.each do |key|
90
+ puts("- #{key}")
91
+ end
92
+ end
93
+ end
94
+
95
+ return failed_audit_results.empty?
96
+ end
97
+
61
98
  def build(project)
62
99
  if not project
63
100
  raise 'Can\'t initialize Locca with nil project'
@@ -96,7 +133,7 @@ module Locca
96
133
  lang = project.base_lang
97
134
  end
98
135
 
99
- action = TranslateAction.new(project, lang, project.collection_builder, project.collection_writer, collection_merger())
136
+ action = TranslateAction.new(project, lang, project.collection_builder(), project.collection_writer(), collection_merger())
100
137
  action.execute()
101
138
  end
102
139
 
@@ -0,0 +1,80 @@
1
+ #
2
+ # The MIT License (MIT)
3
+ #
4
+ # Copyright (c) 2014 Evgeny Shurakov
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+ #
24
+
25
+ require 'locca/audit_result'
26
+
27
+ module Locca
28
+ class AuditAction
29
+ def initialize(project, collection_builder, collections_generator)
30
+ @project = project
31
+ @collections_generator = collections_generator
32
+ @collection_builder = collection_builder
33
+ end
34
+
35
+ def execute()
36
+ generated_collections = @collections_generator.generate()
37
+
38
+ audit_ignore = @project.config_value_for_key('audit_ignore')
39
+ failed_audit_results = []
40
+
41
+ @project.collection_names().each do |collection_name|
42
+ keys_to_ignore = []
43
+ if audit_ignore != nil && audit_ignore.key?(collection_name)
44
+ keys_to_ignore = audit_ignore[collection_name]
45
+ end
46
+
47
+ @project.langs().each do |lang|
48
+ collection_path = @project.path_for_collection(collection_name, lang)
49
+ collection = @collection_builder.collection_at_path(collection_path)
50
+
51
+ audit_result = AuditResult.new(collection_name, lang)
52
+
53
+ generated_collections.each do |generated_collection|
54
+ if generated_collection.name == collection.name
55
+ generated_collection_keys = generated_collection.all_keys().to_set
56
+ collection_keys = collection.all_keys().to_set
57
+
58
+ audit_result.missing_keys = (generated_collection_keys - collection_keys).to_a
59
+ audit_result.extra_keys = (collection_keys - generated_collection_keys).to_a
60
+ end
61
+ end
62
+
63
+ collection.sorted_each do |item|
64
+ if item.translated? || keys_to_ignore.include?(item.key) || audit_result.extra_keys.include?(item.key)
65
+ next
66
+ end
67
+
68
+ audit_result.add_untranslated_key(item.key)
69
+ end
70
+
71
+ unless audit_result.passed?
72
+ failed_audit_results.push(audit_result)
73
+ end
74
+ end
75
+ end
76
+
77
+ return failed_audit_results
78
+ end
79
+ end
80
+ end
@@ -65,8 +65,22 @@ module Locca
65
65
  # 1
66
66
  @generated_collections.each do |generated_collection|
67
67
  @langs.each do |lang|
68
- print "[*] #{@project.name}: fetch: #{lang}/#{generated_collection.name}\n"
69
- data = @onesky.fetch_translations(lang, @project.full_collection_name(generated_collection.name))
68
+ max_attempts = 3
69
+ for attempt in 1..max_attempts do
70
+ print "[*] #{@project.name}: fetch: #{lang}/#{generated_collection.name}\n"
71
+ begin
72
+ data = @onesky.fetch_translations(lang, @project.full_collection_name(generated_collection.name))
73
+ rescue Exception => ex
74
+ if attempt == max_attempts
75
+ raise ex
76
+ end
77
+ puts "[!] #{ex}"
78
+ sleep 2
79
+ else
80
+ break
81
+ end
82
+ end
83
+
70
84
  fetched_collection = @collection_builder.collection_from_datastring(data)
71
85
 
72
86
  local_collection_path = @project.path_for_collection(generated_collection.name, lang)
@@ -113,9 +127,24 @@ module Locca
113
127
 
114
128
  # 4
115
129
  @generated_collections.each do |generated_collection|
116
- print "[*] #{@project.name}: upload: #{@project.base_lang}/#{generated_collection.name}\n"
117
130
  collection_path = @project.path_for_collection(generated_collection.name, @project.base_lang())
118
- @onesky.upload_file(collection_path, @project.one_sky_file_format, prune_missing_strings)
131
+
132
+ max_attempts = 3
133
+ for attempt in 1..max_attempts do
134
+ print "[*] #{@project.name}: upload: #{@project.base_lang}/#{generated_collection.name}\n"
135
+ begin
136
+ @onesky.upload_file(collection_path, @project.one_sky_file_format, prune_missing_strings)
137
+ rescue Exception => ex
138
+ if attempt == max_attempts
139
+ raise ex
140
+ end
141
+ puts "[!] #{ex}"
142
+ sleep 2
143
+ else
144
+ break
145
+ end
146
+ end
147
+
119
148
  end
120
149
  end
121
150
  end
@@ -57,7 +57,7 @@ module Locca
57
57
  item.value.each do |key, value|
58
58
  nodeItem = Nokogiri::XML::Node.new('item', document)
59
59
  nodeItem["quantity"] = key
60
- nodeItem.content = value
60
+ nodeItem.content = prepare_content(value)
61
61
  node.add_child(nodeItem)
62
62
  end
63
63
 
@@ -65,7 +65,7 @@ module Locca
65
65
  else
66
66
  node = Nokogiri::XML::Node.new('string', document)
67
67
  node["name"] = item.key
68
- node.content = item.value
68
+ node.content = prepare_content(item.value)
69
69
  resources.add_child(node)
70
70
  end
71
71
  end
@@ -76,6 +76,10 @@ module Locca
76
76
  io << document.to_xml
77
77
  end
78
78
  end
79
+
80
+ def prepare_content(content)
81
+ return content.gsub(/\n/, "\\n")
82
+ end
79
83
  end
80
84
 
81
85
  end
@@ -0,0 +1,49 @@
1
+ #
2
+ # The MIT License (MIT)
3
+ #
4
+ # Copyright (c) 2014 Evgeny Shurakov
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+ #
24
+
25
+ module Locca
26
+ class AuditResult
27
+ attr_reader :collection_name
28
+ attr_reader :lang
29
+ attr_reader :untranslated_keys
30
+ attr_accessor :missing_keys
31
+ attr_accessor :extra_keys
32
+
33
+ def initialize(collection_name, lang)
34
+ @collection_name = collection_name
35
+ @lang = lang
36
+ @untranslated_keys = []
37
+ @missing_keys = []
38
+ @extra_keys = []
39
+ end
40
+
41
+ def add_untranslated_key(value)
42
+ @untranslated_keys.push(value)
43
+ end
44
+
45
+ def passed?
46
+ return @untranslated_keys.empty? && @missing_keys.empty? && @extra_keys.empty?
47
+ end
48
+ end
49
+ end
@@ -91,8 +91,10 @@ module Locca
91
91
 
92
92
  def collections_generator()
93
93
  source_files = Array.new()
94
- @xcode_target.source_build_phase.files_references.each { |file|
95
- source_files.push(file.real_path.to_s)
94
+ @xcode_target.source_build_phase.files_references.each { |file|
95
+ if !file.path.nil?
96
+ source_files.push(file.real_path.to_s)
97
+ end
96
98
  }
97
99
  return CollectionsGenerator.new(source_files, Genstrings.new(), collection_builder())
98
100
  end
@@ -22,5 +22,5 @@
22
22
  # SOFTWARE.
23
23
  #
24
24
  module Locca
25
- VERSION = '2.1.0'
25
+ VERSION = '2.2.6'
26
26
  end
metadata CHANGED
@@ -1,141 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locca
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shurakov Evgeny
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-12 00:00:00.000000000 Z
11
+ date: 2020-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '5.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - '>='
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - ">="
25
31
  - !ruby/object:Gem::Version
26
- version: '0'
32
+ version: '5.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: mocha
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - '>='
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.5'
40
+ - - ">="
32
41
  - !ruby/object:Gem::Version
33
- version: '0'
42
+ version: '1.5'
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - '>='
47
+ - - "~>"
39
48
  - !ruby/object:Gem::Version
40
- version: '0'
49
+ version: '1.5'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '1.5'
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: rake
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
- - - '>='
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '12.0'
60
+ - - ">="
46
61
  - !ruby/object:Gem::Version
47
- version: '0'
62
+ version: '12.0'
48
63
  type: :development
49
64
  prerelease: false
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
- - - '>='
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '12.0'
70
+ - - ">="
53
71
  - !ruby/object:Gem::Version
54
- version: '0'
72
+ version: '12.0'
55
73
  - !ruby/object:Gem::Dependency
56
74
  name: rdoc
57
75
  requirement: !ruby/object:Gem::Requirement
58
76
  requirements:
59
- - - '>='
77
+ - - "~>"
60
78
  - !ruby/object:Gem::Version
61
- version: '0'
79
+ version: '6.0'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '6.0'
62
83
  type: :development
63
84
  prerelease: false
64
85
  version_requirements: !ruby/object:Gem::Requirement
65
86
  requirements:
66
- - - '>='
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6.0'
90
+ - - ">="
67
91
  - !ruby/object:Gem::Version
68
- version: '0'
92
+ version: '6.0'
69
93
  - !ruby/object:Gem::Dependency
70
94
  name: gli
71
95
  requirement: !ruby/object:Gem::Requirement
72
96
  requirements:
73
- - - '>='
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '2.0'
100
+ - - ">="
74
101
  - !ruby/object:Gem::Version
75
- version: '0'
102
+ version: '2.0'
76
103
  type: :runtime
77
104
  prerelease: false
78
105
  version_requirements: !ruby/object:Gem::Requirement
79
106
  requirements:
80
- - - '>='
107
+ - - "~>"
81
108
  - !ruby/object:Gem::Version
82
- version: '0'
109
+ version: '2.0'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '2.0'
83
113
  - !ruby/object:Gem::Dependency
84
114
  name: rest-client
85
115
  requirement: !ruby/object:Gem::Requirement
86
116
  requirements:
87
- - - '>='
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '2.0'
120
+ - - ">="
88
121
  - !ruby/object:Gem::Version
89
- version: '0'
122
+ version: '2.0'
90
123
  type: :runtime
91
124
  prerelease: false
92
125
  version_requirements: !ruby/object:Gem::Requirement
93
126
  requirements:
94
- - - '>='
127
+ - - "~>"
95
128
  - !ruby/object:Gem::Version
96
- version: '0'
129
+ version: '2.0'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '2.0'
97
133
  - !ruby/object:Gem::Dependency
98
134
  name: nokogiri
99
135
  requirement: !ruby/object:Gem::Requirement
100
136
  requirements:
101
- - - '>='
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '1.8'
140
+ - - ">="
102
141
  - !ruby/object:Gem::Version
103
- version: '0'
142
+ version: '1.8'
104
143
  type: :runtime
105
144
  prerelease: false
106
145
  version_requirements: !ruby/object:Gem::Requirement
107
146
  requirements:
108
- - - '>='
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '1.8'
150
+ - - ">="
109
151
  - !ruby/object:Gem::Version
110
- version: '0'
152
+ version: '1.8'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: xcodeproj
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
- - - '>='
157
+ - - "~>"
116
158
  - !ruby/object:Gem::Version
117
- version: '0'
159
+ version: '1.5'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '1.5'
118
163
  type: :runtime
119
164
  prerelease: false
120
165
  version_requirements: !ruby/object:Gem::Requirement
121
166
  requirements:
122
- - - '>='
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '1.5'
170
+ - - ">="
123
171
  - !ruby/object:Gem::Version
124
- version: '0'
172
+ version: '1.5'
125
173
  - !ruby/object:Gem::Dependency
126
174
  name: json
127
175
  requirement: !ruby/object:Gem::Requirement
128
176
  requirements:
129
- - - '>='
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '2.1'
180
+ - - ">="
130
181
  - !ruby/object:Gem::Version
131
- version: '0'
182
+ version: '2.1'
132
183
  type: :runtime
133
184
  prerelease: false
134
185
  version_requirements: !ruby/object:Gem::Requirement
135
186
  requirements:
136
- - - '>='
187
+ - - "~>"
137
188
  - !ruby/object:Gem::Version
138
- version: '0'
189
+ version: '2.1'
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '2.1'
139
193
  description:
140
194
  email: inbox@shurakov.name
141
195
  executables:
@@ -144,9 +198,12 @@ extensions: []
144
198
  extra_rdoc_files:
145
199
  - README.rdoc
146
200
  files:
201
+ - README.rdoc
147
202
  - bin/locca
148
203
  - lib/babelyoda/strings_lexer.rb
149
204
  - lib/babelyoda/strings_parser.rb
205
+ - lib/locca.rb
206
+ - lib/locca/actions/audit_action.rb
150
207
  - lib/locca/actions/build_action.rb
151
208
  - lib/locca/actions/merge_action.rb
152
209
  - lib/locca/actions/onesky_sync_action.rb
@@ -154,6 +211,7 @@ files:
154
211
  - lib/locca/android_collection_writer.rb
155
212
  - lib/locca/android_collections_generator.rb
156
213
  - lib/locca/android_strings_parser.rb
214
+ - lib/locca/audit_result.rb
157
215
  - lib/locca/collection.rb
158
216
  - lib/locca/collection_builder.rb
159
217
  - lib/locca/collection_item.rb
@@ -172,8 +230,6 @@ files:
172
230
  - lib/locca/projects/xcode_project.rb
173
231
  - lib/locca/sync/onesky.rb
174
232
  - lib/locca/version.rb
175
- - lib/locca.rb
176
- - README.rdoc
177
233
  homepage: https://github.com/eshurakov/locca
178
234
  licenses:
179
235
  - MIT
@@ -185,17 +241,16 @@ require_paths:
185
241
  - lib
186
242
  required_ruby_version: !ruby/object:Gem::Requirement
187
243
  requirements:
188
- - - '>='
244
+ - - ">="
189
245
  - !ruby/object:Gem::Version
190
246
  version: '0'
191
247
  required_rubygems_version: !ruby/object:Gem::Requirement
192
248
  requirements:
193
- - - '>='
249
+ - - ">="
194
250
  - !ruby/object:Gem::Version
195
251
  version: '0'
196
252
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.0.14
253
+ rubygems_version: 3.1.2
199
254
  signing_key:
200
255
  specification_version: 4
201
256
  summary: Application localization kit