lokale 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/a.sh +2 -2
- data/lib/lokale.rb +43 -27
- data/lib/lokale/agent.rb +94 -11
- data/lib/lokale/config.rb +53 -45
- data/lib/lokale/lokalefile.rb +61 -58
- data/lib/lokale/model.rb +4 -0
- data/lib/lokale/version.rb +1 -1
- data/lokale.gemspec +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8306f8c00603bf616bf961689c9936e9a28f901a
|
4
|
+
data.tar.gz: e7d128b7bca1c820bfd51372a688679f1be7cf0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e257d6840e3d282a1255a77570eda0db65956dde7fb26a863befd216f6efe5393c00025463611dc4547360a35582e959664be6849258f14fcd531f7ad5085227
|
7
|
+
data.tar.gz: '09a4e2acce57ba98840c9b097eac20195f6df8ed8933a5547868533cc3b1c5e0469743dbbe8f0a48fbc29bc785cfb6be74627a40c35f6b8a38c03db5c4e3b47f'
|
data/a.sh
CHANGED
data/lib/lokale.rb
CHANGED
@@ -6,38 +6,45 @@ require 'lokale/reporter'
|
|
6
6
|
require 'lokale/lokalefile'
|
7
7
|
require 'lokale/agent'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
module Lokale
|
10
|
+
class Action
|
11
|
+
def print(str)
|
12
|
+
puts str.blue
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def perform(agent, reporter)
|
16
|
+
send(("perform_" + @type.to_s).to_sym, agent, reporter)
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def perform_summary(agent, reporter)
|
20
|
+
print "Printing summary...".blue
|
21
|
+
reporter.print_summary
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def perform_copy_base(agent, reporter)
|
25
|
+
print "Copying `en` strings files to `Base`...".blue
|
26
|
+
agent.copy_base
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def perform_append(agent, reporter)
|
30
|
+
print "Appending new macro calls to localization files...".blue
|
31
|
+
agent.append_new_macro_calls
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
def perform_export(agent, reporter)
|
35
|
+
print "Preparing xliff files with new localized strings...".blue
|
36
|
+
agent.export_xliffs
|
37
|
+
end
|
38
|
+
|
39
|
+
def perform_import(agent, reporter)
|
40
|
+
print "Attempting to import new strings...".blue
|
41
|
+
agent.try_to_import
|
42
|
+
end
|
37
43
|
|
38
|
-
|
39
|
-
|
40
|
-
|
44
|
+
def perform_create_config(agent, reporter)
|
45
|
+
print "Creating config file...".blue
|
46
|
+
Config.get.create_default_file
|
47
|
+
end
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -67,7 +74,16 @@ module Lokale
|
|
67
74
|
|
68
75
|
def read_config
|
69
76
|
Config.init
|
70
|
-
Config.get.
|
77
|
+
Config.get.project_path = @project_path
|
78
|
+
Config.get.project_name = @project_name
|
79
|
+
|
80
|
+
begin
|
81
|
+
Config.get.read_lokalefile
|
82
|
+
rescue Exception => e
|
83
|
+
puts "Error reading config file".red
|
84
|
+
puts e
|
85
|
+
exit
|
86
|
+
end
|
71
87
|
end
|
72
88
|
|
73
89
|
def init_workers
|
data/lib/lokale/agent.rb
CHANGED
@@ -3,6 +3,7 @@ require "lokale/colorize"
|
|
3
3
|
require "lokale/util"
|
4
4
|
require "lokale/model"
|
5
5
|
require "xliffle"
|
6
|
+
require "xliffer"
|
6
7
|
require "set"
|
7
8
|
|
8
9
|
|
@@ -28,6 +29,7 @@ module Lokale
|
|
28
29
|
|
29
30
|
class LString
|
30
31
|
def write_format
|
32
|
+
note = @note || "(no comment)"
|
31
33
|
"/* #{note} */\n\"#{key}\" = \"#{str}\";\n"
|
32
34
|
end
|
33
35
|
|
@@ -35,6 +37,14 @@ module Lokale
|
|
35
37
|
"\"#{key}\" = \"#{str}\";"
|
36
38
|
end
|
37
39
|
|
40
|
+
def self.from_xliff_string(s, lang)
|
41
|
+
str = LString.new(s.id, s.target, s.note, lang)
|
42
|
+
str.source = s.source
|
43
|
+
str
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
38
48
|
attr_accessor :source
|
39
49
|
|
40
50
|
def for_export(lang)
|
@@ -130,37 +140,40 @@ module Lokale
|
|
130
140
|
end
|
131
141
|
|
132
142
|
def try_to_import
|
143
|
+
@importer.import_strings(self, @writer)
|
133
144
|
end
|
134
145
|
end
|
135
146
|
|
136
147
|
class Writer
|
137
148
|
def find_append_point(content)
|
138
|
-
ignore_after = content =~ /^\s*?\/\/\s*?\n\s*?\/\/\s*?MARK/
|
139
|
-
string_regexp =
|
149
|
+
ignore_after = (content =~ /^\s*?\/\/\s*?\n\s*?\/\/\s*?MARK/) || Float::INFINITY
|
150
|
+
string_regexp = /^".*?"\s*=\s*".*"\s*;/
|
140
151
|
|
141
|
-
append_at = content.match(string_regexp).end(0)
|
152
|
+
append_at = content.match(string_regexp).end(0)
|
142
153
|
return if append_at.nil?
|
143
154
|
next_try = append_at
|
144
155
|
while next_try < ignore_after
|
145
156
|
append_at = next_try
|
146
|
-
|
157
|
+
next_match = content.match(string_regexp, next_try)
|
158
|
+
break if next_match.nil?
|
159
|
+
next_try = next_match.end(0)
|
147
160
|
end
|
148
161
|
|
149
|
-
append_at
|
162
|
+
append_at
|
150
163
|
end
|
151
164
|
|
152
165
|
def append_new_strings(lstrings, file)
|
153
166
|
content = file.content
|
154
167
|
|
155
|
-
puts "Appending #{lstrings.size} new strings to file #{file.lang}/#{file.full_name}"
|
168
|
+
puts "Appending #{lstrings.size} new strings to file #{file.lang}/#{file.full_name}:"
|
156
169
|
lstrings.each { |ls| puts ls.pretty }
|
157
170
|
puts
|
158
171
|
|
159
172
|
append_at = find_append_point(content)
|
160
|
-
data_to_append = "\n" + lstrings.map { |ls| ls.write_format }.join("\n")
|
173
|
+
data_to_append = "\n\n" + lstrings.map { |ls| ls.write_format }.join("\n").chomp("\n")
|
161
174
|
|
162
175
|
content.insert(append_at, data_to_append)
|
163
|
-
|
176
|
+
file.write(content)
|
164
177
|
end
|
165
178
|
end
|
166
179
|
|
@@ -207,7 +220,8 @@ module Lokale
|
|
207
220
|
def export(diffs)
|
208
221
|
# puts "Exporting stuff"
|
209
222
|
diffs.each do |d|
|
210
|
-
|
223
|
+
missing_count = d.missing_strings.values.map { |e| e.size }.reduce(:+)
|
224
|
+
puts "Writing xliff for `#{d.lang}` language. Missing strings count: #{missing_count}"
|
211
225
|
|
212
226
|
xliffle = Xliffle.new
|
213
227
|
d.missing_strings.each do |lfile, strings|
|
@@ -217,14 +231,83 @@ module Lokale
|
|
217
231
|
end
|
218
232
|
end
|
219
233
|
|
220
|
-
file_name =
|
234
|
+
file_name = xliff_name(d.lang)
|
221
235
|
File.write(file_name, xliffle.to_xliff)
|
222
236
|
end
|
223
237
|
end
|
238
|
+
|
239
|
+
def xliff_name(lang)
|
240
|
+
date = Time.now.strftime("%d.%m.%y")
|
241
|
+
"export.#{date}.#{lang}.xliff"
|
242
|
+
end
|
224
243
|
end
|
225
244
|
|
226
245
|
class Importer
|
227
|
-
|
246
|
+
class Diff
|
247
|
+
attr_accessor :name, :lang, :lstrings
|
248
|
+
|
249
|
+
def self.from_file(xliff_path)
|
250
|
+
begin
|
251
|
+
xliff = XLIFFer::XLIFF.new(File.open(xliff_path))
|
252
|
+
rescue Exception => e
|
253
|
+
puts "Failed to parse `#{xliff_path}` file."
|
254
|
+
end
|
255
|
+
|
256
|
+
diffs = []
|
257
|
+
|
258
|
+
xliff.files.each do |f|
|
259
|
+
next if f.target_language == Config.get.main_lang
|
260
|
+
next if f.source_language != Config.get.main_lang
|
261
|
+
|
262
|
+
diff = Diff.new
|
263
|
+
diff.name = f.original
|
264
|
+
diff.lang = f.target_language
|
265
|
+
diff.lstrings = f.strings
|
266
|
+
.map { |s| LString.from_xliff_string(s, f.target_language) }
|
267
|
+
.delete_if { |ls| ls.target.nil? }
|
268
|
+
next if diff.lstrings.empty?
|
269
|
+
|
270
|
+
diffs << diff
|
271
|
+
end
|
272
|
+
diffs
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def import_strings(agent, writer)
|
277
|
+
xliff_paths = agent.proj_files
|
278
|
+
.select { |f| f =~ /\.xliff$/ }
|
279
|
+
.delete_if { |f| f =~ /export/ }
|
280
|
+
# .select { |f| puts "select #{f}, #{f =~ /\.xliff^/}"; f =~ /\.xliff^/ }
|
281
|
+
# .delete_if { |f| puts "delete #{f}, #{f =~ /export/}"; f =~ /export/ }
|
282
|
+
|
283
|
+
return if xliff_paths.empty?
|
284
|
+
diffs = xliff_paths.flat_map { |p| Diff.from_file(p) }
|
285
|
+
diffs.each do |d|
|
286
|
+
lf = file_for_diff(d, agent.lfiles)
|
287
|
+
next if lf.nil?
|
288
|
+
|
289
|
+
content = lf.content
|
290
|
+
strings_to_append = []
|
291
|
+
|
292
|
+
d.lstrings.each do |ls|
|
293
|
+
string_regexp = /^\s*?"#{ls.key}"\s*?=\s*?"(.*?)";/
|
294
|
+
if content =~ string_regexp
|
295
|
+
if $1 != ls.str
|
296
|
+
puts "#{lf.lang}/#{lf.full_name} update \"#{ls.key.blue}\": \"#{$1}\" -> \"#{ls.str.blue}\""
|
297
|
+
content.sub! string_regexp, "\"#{ls.key}\" = \"#{ls.str}\";"
|
298
|
+
end
|
299
|
+
else
|
300
|
+
strings_to_append << ls
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
lf.write content
|
305
|
+
writer.append_new_strings(strings_to_append, lf) unless strings_to_append.empty?
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def file_for_diff(diff, all_lfiles)
|
310
|
+
all_lfiles.select { |lf| lf.full_name == diff.name && lf.lang == diff.lang }.sample
|
228
311
|
end
|
229
312
|
end
|
230
313
|
end
|
data/lib/lokale/config.rb
CHANGED
@@ -2,66 +2,74 @@
|
|
2
2
|
require "optparse"
|
3
3
|
require "lokale/util"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
module Lokale
|
6
|
+
class Action
|
7
|
+
attr_accessor :type, :arg
|
8
|
+
|
9
|
+
def initialize(type)
|
10
|
+
@type = type
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.summary; Action.new(:summary) end
|
14
|
+
def self.copy_base; Action.new(:copy_base) end
|
15
|
+
def self.append; Action.new(:append) end
|
16
|
+
def self.export; Action.new(:export) end
|
17
|
+
def self.import; Action.new(:import) end
|
18
|
+
def self.create_config; Action.new(:create_config) end
|
10
19
|
end
|
11
20
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def self.export; Action.new(:export) end
|
16
|
-
def self.import; Action.new(:import) end
|
17
|
-
end
|
21
|
+
class Config
|
22
|
+
attr_accessor :actions
|
23
|
+
attr_accessor :project_path, :project_name
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
def self.init
|
26
|
+
return unless @config.nil?
|
21
27
|
|
22
|
-
|
23
|
-
return unless @config.nil?
|
28
|
+
actions = []
|
24
29
|
|
25
|
-
|
30
|
+
OptionParser.new do |opts|
|
31
|
+
opts.banner = "Usage: lokale [-bsh]"
|
26
32
|
|
27
|
-
|
28
|
-
|
33
|
+
opts.on("-b", "--copy-base", "Copies 'en' localization files to 'Base'") do |n|
|
34
|
+
actions << Action.copy_base
|
35
|
+
end
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
37
|
+
opts.on("-s", "--summary", "Prints project summary") do |n|
|
38
|
+
actions << Action.summary
|
39
|
+
end
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
opts.on("-a", "--append", "Appends new strings to english localization file") do |n|
|
42
|
+
actions << Action.append
|
43
|
+
end
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
opts.on("-e", "--export", "Creates xliff files with missing localization") do |n|
|
46
|
+
actions << Action.export
|
47
|
+
end
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
49
|
+
opts.on("-i", "--import", "Looks for xliffs in project dir and imports whatever possible") do |n|
|
50
|
+
actions << Action.import
|
51
|
+
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
opts.on("-f", "--create-config-file", "Create default `.lokale` config file") do |n|
|
54
|
+
actions << Action.create_config
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
57
|
+
opts.on("-h", "--help", "Prints this help") do
|
58
|
+
puts opts
|
59
|
+
exit
|
60
|
+
end
|
61
|
+
end.parse!
|
55
62
|
|
56
|
-
|
63
|
+
actions << Action.summary if actions.empty?
|
57
64
|
|
58
|
-
|
59
|
-
|
60
|
-
|
65
|
+
@config = Config.new
|
66
|
+
@config.actions = actions
|
67
|
+
end
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
69
|
+
def self.get
|
70
|
+
init if @config.nil?
|
71
|
+
@config
|
72
|
+
end
|
65
73
|
end
|
66
74
|
end
|
67
75
|
|
data/lib/lokale/lokalefile.rb
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
require "lokale/config"
|
3
3
|
require "lokale/model"
|
4
4
|
|
5
|
-
|
5
|
+
module Lokale
|
6
|
+
DEFAULT_LOKALEFILE = <<FILE
|
6
7
|
|
7
8
|
add_macro "NSLocalizedString" do |m|
|
8
9
|
m.localization_file = "Localizable.strings"
|
@@ -21,78 +22,80 @@ main_language "en"
|
|
21
22
|
base_language "Base"
|
22
23
|
|
23
24
|
FILE
|
25
|
+
end
|
24
26
|
|
27
|
+
module Lokale
|
28
|
+
class Config
|
29
|
+
def read_lokalefile
|
30
|
+
if File.file? lokalefile_path
|
31
|
+
read_config_from_file(lokalefile_path)
|
32
|
+
else
|
33
|
+
read_default_config
|
34
|
+
end
|
35
|
+
end
|
25
36
|
|
26
|
-
|
27
|
-
|
28
|
-
|
37
|
+
def read_default_config
|
38
|
+
reset_config
|
39
|
+
instance_eval(DEFAULT_LOKALEFILE)
|
40
|
+
end
|
29
41
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
42
|
+
def read_config_from_file(file_path)
|
43
|
+
content = File.read(file_path)
|
44
|
+
reset_config
|
45
|
+
instance_eval(content)
|
46
|
+
fill_defaults
|
34
47
|
end
|
35
|
-
end
|
36
48
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
49
|
+
def create_default_file
|
50
|
+
if File.file? lokalefile_path
|
51
|
+
puts "Config file `#{lokalefile_path.blue}` already exists."
|
52
|
+
else
|
53
|
+
File.write(lokalefile_path, DEFAULT_LOKALEFILE)
|
54
|
+
puts "Created config file at `#{lokalefile_path.blue}`"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
41
58
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
instance_eval(content)
|
46
|
-
fill_defaults
|
47
|
-
end
|
48
|
-
end
|
59
|
+
def lokalefile_path
|
60
|
+
File.join(@project_path, ".lokale")
|
61
|
+
end
|
49
62
|
|
50
63
|
|
51
|
-
class Config
|
52
64
|
|
53
|
-
|
54
|
-
|
65
|
+
attr_reader :macros
|
66
|
+
attr_reader :main_lang, :base_lang
|
55
67
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
68
|
+
def reset_config
|
69
|
+
@macros = nil
|
70
|
+
@main_lang = nil
|
71
|
+
@base_lang = nil
|
72
|
+
end
|
61
73
|
|
62
|
-
|
63
|
-
|
64
|
-
|
74
|
+
def fill_defaults
|
75
|
+
default = Config.new
|
76
|
+
default.read_default_config
|
65
77
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
78
|
+
@macros ||= default.macros
|
79
|
+
@main_lang ||= default.main_lang
|
80
|
+
@base_lang ||= default.base_lang
|
81
|
+
end
|
70
82
|
|
71
|
-
|
83
|
+
private
|
72
84
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
def add_macro(name)
|
86
|
+
macro = Lokale::Macro.new(name)
|
87
|
+
yield macro
|
88
|
+
@macros ||= []
|
89
|
+
@macros << macro
|
90
|
+
end
|
91
|
+
|
92
|
+
def main_language(l)
|
93
|
+
@main_lang = l
|
94
|
+
end
|
83
95
|
|
84
|
-
|
85
|
-
|
96
|
+
def base_language(l)
|
97
|
+
@base_lang = l
|
98
|
+
end
|
86
99
|
end
|
87
100
|
end
|
88
101
|
|
89
|
-
|
90
|
-
def test
|
91
|
-
Config.get.read_lokalefile File.dirname(__FILE__)
|
92
|
-
p Config.get.macros
|
93
|
-
p Config.get.main_lang
|
94
|
-
p Config.get.base_lang
|
95
|
-
end
|
96
|
-
|
97
|
-
# test
|
98
|
-
|
data/lib/lokale/model.rb
CHANGED
data/lib/lokale/version.rb
CHANGED
data/lokale.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lokale
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Onizhuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xliffle
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.2.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xliffer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.3
|
27
41
|
description: Write a longer description or delete this line.
|
28
42
|
email:
|
29
43
|
- anton.onizhuk@gmail.com
|