lokale 0.1.3 → 0.1.4
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/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
|