locca 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +1 -0
- data/bin/locca +87 -0
- data/lib/babelyoda/strings_lexer.rb +17 -0
- data/lib/babelyoda/strings_parser.rb +72 -0
- data/lib/locca.rb +82 -0
- data/lib/locca/actions/build_action.rb +51 -0
- data/lib/locca/actions/merge_action.rb +44 -0
- data/lib/locca/collection.rb +88 -0
- data/lib/locca/collection_builder.rb +47 -0
- data/lib/locca/collection_item.rb +62 -0
- data/lib/locca/collection_item_condensed_formatter.rb +35 -0
- data/lib/locca/collection_item_default_formatter.rb +39 -0
- data/lib/locca/collection_merger.rb +63 -0
- data/lib/locca/collection_writer.rb +47 -0
- data/lib/locca/collections_generator.rb +41 -0
- data/lib/locca/config_reader.rb +32 -0
- data/lib/locca/config_validator.rb +47 -0
- data/lib/locca/genstrings.rb +47 -0
- data/lib/locca/project.rb +54 -0
- data/lib/locca/project_dir_locator.rb +53 -0
- data/lib/locca/project_factory.rb +63 -0
- data/lib/locca/version.rb +26 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c932554b9be74b84f6218393fa08c900a66d26b2
|
4
|
+
data.tar.gz: c16b9a45ccc2f36c1be19692de62ced14d0ffd0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ac6fa5e4c42f18b568827720619d52c53b41500aa404d29f7ba37c3eb7d736095542f69f34cba8ab210946977eb541cb455ac78e412a1b1d357d07ed68d4adcb
|
7
|
+
data.tar.gz: fbb62afd2df2aa68e452ab7a4aefbdc5ad1a39b6686cff31859fcec222b4441213f8a78a1db253398c2409bf7985f0ac631ae1dfe00fb54393337267ce51c969
|
data/README.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= locca
|
data/bin/locca
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (c) 2014 Evgeny Shurakov
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'gli'
|
27
|
+
require 'locca'
|
28
|
+
require 'set'
|
29
|
+
|
30
|
+
include GLI::App
|
31
|
+
|
32
|
+
program_desc 'Application localization kit'
|
33
|
+
|
34
|
+
version Locca::VERSION
|
35
|
+
|
36
|
+
desc 'Work dir'
|
37
|
+
arg_name '<path>'
|
38
|
+
flag ['work-dir'.to_sym]
|
39
|
+
|
40
|
+
desc 'Create and update language files from source code'
|
41
|
+
command :build do |c|
|
42
|
+
c.action do |global_options, options, args|
|
43
|
+
|
44
|
+
work_dir = global_options['work-dir'.to_sym]
|
45
|
+
if not work_dir
|
46
|
+
work_dir = Dir.getwd
|
47
|
+
end
|
48
|
+
project_dir_locator = Locca::ProjectDirLocator.new()
|
49
|
+
config_reader = Locca::ConfigReader.new()
|
50
|
+
config_validator = Locca::ConfigValidator.new(['code_dir', 'lang_dir'])
|
51
|
+
project_factory = Locca::ProjectFactory.new(project_dir_locator, config_reader, config_validator)
|
52
|
+
|
53
|
+
project = project_factory.new_project(work_dir)
|
54
|
+
|
55
|
+
$locca.build(project)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'Merge translations from source file to destination file (add missing, update existing)'
|
60
|
+
command :merge do |c|
|
61
|
+
c.action do |global_options, options, args|
|
62
|
+
if args.count != 2
|
63
|
+
raise 'You should pass source file path and destination file path'
|
64
|
+
end
|
65
|
+
$locca.merge(args[0], args[1])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
pre do |global, command, options, args|
|
70
|
+
$locca = Locca::Locca.new()
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
post do |global, command, options, args|
|
75
|
+
# Post logic here
|
76
|
+
# Use skips_post before a command to skip this
|
77
|
+
# block on that command only
|
78
|
+
end
|
79
|
+
|
80
|
+
on_error do |exception|
|
81
|
+
# Error logic here
|
82
|
+
# return false to skip default error handling
|
83
|
+
puts exception.backtrace
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
exit run(ARGV)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Babelyoda
|
2
|
+
class StringsLexer
|
3
|
+
TOKENS = [ :multiline_comment, :singleline_comment, :string, :equal_sign, :semicolon, :space ].freeze
|
4
|
+
REGEXP = Regexp.new("/\\*\\s*(.*?)\\s*\\*/|\\s*(//.*?\n)|\"((?:\\\\?+.)*?)\"|(\\s*=\\s*)|(\\s*;\\s*)|(\\s*)", Regexp::MULTILINE)
|
5
|
+
|
6
|
+
def lex(str)
|
7
|
+
str.scan(REGEXP).each do |m|
|
8
|
+
idx = m.index { |x| x }
|
9
|
+
if TOKENS[idx] == :space
|
10
|
+
next
|
11
|
+
end
|
12
|
+
|
13
|
+
yield TOKENS[idx], m[idx]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
module Babelyoda
|
3
|
+
class StringsParser
|
4
|
+
Bit = Struct.new(:token, :value)
|
5
|
+
|
6
|
+
def initialize(lexer)
|
7
|
+
@lexer = lexer
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(str, &block)
|
11
|
+
@block = block
|
12
|
+
bitstream = []
|
13
|
+
@lexer.lex(str) do | token, value |
|
14
|
+
bitstream << Bit.new(token, value)
|
15
|
+
end
|
16
|
+
while bitstream.size > 0
|
17
|
+
record = produce(bitstream)
|
18
|
+
@block.call(record[:string_for_key], record[:value], record[:comment]) if record
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def produce(bs)
|
23
|
+
match_bs(bs, :multiline_comment, :string, :equal_sign, :string, :semicolon) do |bits|
|
24
|
+
result = {}
|
25
|
+
result[:string_for_key] = bits[1]
|
26
|
+
result[:comment] = bits[0]
|
27
|
+
result[:value] = bits[3]
|
28
|
+
return result
|
29
|
+
end
|
30
|
+
match_bs(bs, :singleline_comment, :string, :equal_sign, :string, :semicolon) do |bits|
|
31
|
+
result = {}
|
32
|
+
result[:string_for_key] = bits[1]
|
33
|
+
result[:comment] = bits[0]
|
34
|
+
result[:value] = bits[3]
|
35
|
+
return result
|
36
|
+
end
|
37
|
+
match_bs(bs, :string, :equal_sign, :string, :semicolon) do |bits|
|
38
|
+
result = {}
|
39
|
+
result[:string_for_key] = bits[0]
|
40
|
+
result[:value] = bits[2]
|
41
|
+
return result
|
42
|
+
end
|
43
|
+
match_bs(bs, :singleline_comment) do |bits|
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
match_bs(bs, :multiline_comment) do |bits|
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
raise "Syntax error: #{bs.shift(5).inspect}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def match_bs(bs, *tokens)
|
53
|
+
return unless bs.size >= tokens.size
|
54
|
+
tokens.each_with_index do |token, idx|
|
55
|
+
return unless bs[idx][:token] == token
|
56
|
+
end
|
57
|
+
yield bs.shift(tokens.size).map { |bit| bit[:value] }
|
58
|
+
end
|
59
|
+
|
60
|
+
def cleanup_comment(str)
|
61
|
+
if str.match(/^\/\/\s*/)
|
62
|
+
str.sub(/^\/\/\s*/, '')
|
63
|
+
else
|
64
|
+
str.sub(/^\/\*\s*/, '').sub(/\s*\*\/$/, '')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def cleanup_string(str)
|
69
|
+
str.sub(/^\"/, '').sub(/\"$/, '')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/locca.rb
ADDED
@@ -0,0 +1,82 @@
|
|
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/version'
|
26
|
+
|
27
|
+
require 'locca/project'
|
28
|
+
require 'locca/project_dir_locator'
|
29
|
+
require 'locca/project_factory'
|
30
|
+
|
31
|
+
require 'locca/config_reader'
|
32
|
+
require 'locca/config_validator'
|
33
|
+
|
34
|
+
require 'locca/actions/build_action'
|
35
|
+
require 'locca/actions/merge_action'
|
36
|
+
|
37
|
+
require 'locca/collections_generator'
|
38
|
+
require 'locca/collection_merger'
|
39
|
+
require 'locca/collection_builder'
|
40
|
+
require 'locca/collection_writer'
|
41
|
+
require 'locca/collection_item_condensed_formatter'
|
42
|
+
require 'locca/collection_item_default_formatter'
|
43
|
+
|
44
|
+
require 'locca/genstrings'
|
45
|
+
|
46
|
+
require 'babelyoda/strings_lexer'
|
47
|
+
require 'babelyoda/strings_parser'
|
48
|
+
|
49
|
+
module Locca
|
50
|
+
class Locca
|
51
|
+
def build(project)
|
52
|
+
if not project
|
53
|
+
raise 'Can\'t initialize Locca with nil project'
|
54
|
+
end
|
55
|
+
|
56
|
+
genstrings = Genstrings.new()
|
57
|
+
collection_builder = collection_builder()
|
58
|
+
collections_generator = CollectionsGenerator.new(genstrings, collection_builder)
|
59
|
+
|
60
|
+
action = BuildAction.new(project, collection_builder, collection_writer(), collections_generator, collection_merger())
|
61
|
+
action.execute()
|
62
|
+
end
|
63
|
+
|
64
|
+
def merge(src_file, dst_file)
|
65
|
+
action = MergeAction.new(src_file, dst_file, collection_builder(), collection_writer(), collection_merger())
|
66
|
+
action.execute()
|
67
|
+
end
|
68
|
+
|
69
|
+
def collection_builder()
|
70
|
+
parser = Babelyoda::StringsParser.new(Babelyoda::StringsLexer.new())
|
71
|
+
return CollectionBuilder.new(File, parser)
|
72
|
+
end
|
73
|
+
|
74
|
+
def collection_writer()
|
75
|
+
return CollectionWriter.new(File, CollectionItemDefaultFormatter.new())
|
76
|
+
end
|
77
|
+
|
78
|
+
def collection_merger()
|
79
|
+
return CollectionMerger.new()
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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/collection_merger'
|
26
|
+
|
27
|
+
module Locca
|
28
|
+
class BuildAction
|
29
|
+
def initialize(project, collection_builder, collection_writer, collections_generator, collection_merger)
|
30
|
+
@project = project
|
31
|
+
@collections_generator = collections_generator
|
32
|
+
@collection_merger = collection_merger
|
33
|
+
@collection_builder = collection_builder
|
34
|
+
@collection_writer = collection_writer
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute()
|
38
|
+
generated_collections = @collections_generator.generate(@project.code_dir())
|
39
|
+
langs = @project.langs()
|
40
|
+
|
41
|
+
generated_collections.each do |generated_collection|
|
42
|
+
langs.each do |lang|
|
43
|
+
collection_path = @project.path_for_collection(generated_collection.name, lang)
|
44
|
+
collection = @collection_builder.collection_at_path(collection_path)
|
45
|
+
@collection_merger.merge(generated_collection, collection, (CollectionMerger::ACTION_ADD | CollectionMerger::ACTION_DELETE))
|
46
|
+
@collection_writer.write_to_path(collection, collection_path)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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/collection_merger'
|
26
|
+
|
27
|
+
module Locca
|
28
|
+
class MergeAction
|
29
|
+
def initialize(src_file, dst_file, collection_builder, collection_writer, collection_merger)
|
30
|
+
@src_file = src_file
|
31
|
+
@dst_file = dst_file
|
32
|
+
@collection_merger = collection_merger
|
33
|
+
@collection_builder = collection_builder
|
34
|
+
@collection_writer = collection_writer
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute()
|
38
|
+
src_collection = @collection_builder.collection_at_path(@src_file)
|
39
|
+
dst_collection = @collection_builder.collection_at_path(@dst_file)
|
40
|
+
@collection_merger.merge(src_collection, dst_collection, (CollectionMerger::ACTION_ADD | CollectionMerger::ACTION_UPDATE))
|
41
|
+
@collection_writer.write_to_path(dst_collection, @dst_file)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,88 @@
|
|
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 Collection
|
27
|
+
attr_accessor :name
|
28
|
+
attr_accessor :lang
|
29
|
+
|
30
|
+
def initialize(name = nil, lang = nil)
|
31
|
+
@name = name
|
32
|
+
@lang = lang
|
33
|
+
@items = {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_item(item)
|
37
|
+
if !item || !item.key
|
38
|
+
raise ArgumentError, 'item or item.key is nil'
|
39
|
+
end
|
40
|
+
@items[item.key] = item
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_item_for_key(key)
|
44
|
+
return @items.delete(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def item_for_key(key)
|
48
|
+
return @items[key]
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_key?(key)
|
52
|
+
return @items.has_key?(key)
|
53
|
+
end
|
54
|
+
|
55
|
+
def all_keys
|
56
|
+
return @items.keys
|
57
|
+
end
|
58
|
+
|
59
|
+
def translated?
|
60
|
+
@items.each do |key, item|
|
61
|
+
if !item.translated?
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
|
69
|
+
def count
|
70
|
+
return @items.count
|
71
|
+
end
|
72
|
+
|
73
|
+
def each
|
74
|
+
@items.each do |key, item|
|
75
|
+
yield(item)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def sorted_each
|
80
|
+
sorted_keys = all_keys.sort(&:casecmp)
|
81
|
+
sorted_keys.each do |key|
|
82
|
+
yield(@items[key])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_s ; "<#{self.class}: lang = #{lang}, name = #{name}>" ; end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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
|
+
require_relative 'collection'
|
25
|
+
require_relative 'collection_item'
|
26
|
+
|
27
|
+
module Locca
|
28
|
+
class CollectionBuilder
|
29
|
+
def initialize(file_manager, parser)
|
30
|
+
@file_manager = file_manager
|
31
|
+
@parser = parser
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection_at_path(path)
|
35
|
+
name = File.basename(path, '.strings')
|
36
|
+
collection = Collection.new(name)
|
37
|
+
|
38
|
+
@file_manager.open(path, 'rb:BOM|UTF-8:UTF-8') do |file|
|
39
|
+
@parser.parse(file.read()) do |key, value, comment|
|
40
|
+
collection.add_item(CollectionItem.new(key, value, comment))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
return collection
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,62 @@
|
|
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 CollectionItem
|
27
|
+
attr_reader :key
|
28
|
+
attr_reader :value
|
29
|
+
attr_reader :comment
|
30
|
+
|
31
|
+
def initialize(key, value = nil, comment = nil)
|
32
|
+
@key = key
|
33
|
+
@value = value
|
34
|
+
@comment = comment
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize_copy(source)
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def ==(item)
|
42
|
+
if item
|
43
|
+
return @key == item.key && @value == item.value && @comment == item.comment
|
44
|
+
else
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def translated?
|
50
|
+
value = nil
|
51
|
+
if @value
|
52
|
+
value = @value.gsub(/%\d+\$/, "%")
|
53
|
+
end
|
54
|
+
|
55
|
+
if @key == value
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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 CollectionItemCondensedFormatter
|
27
|
+
def format_item(item)
|
28
|
+
key = item.key.gsub(/([^\\])"/, "\\1\\\"")
|
29
|
+
value = item.value.gsub(/([^\\])"/, "\\1\\\"")
|
30
|
+
|
31
|
+
return "\"#{key}\" = \"#{value}\";"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,39 @@
|
|
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 CollectionItemDefaultFormatter
|
27
|
+
def format_item(item)
|
28
|
+
key = item.key.gsub(/([^\\])"/, "\\1\\\"")
|
29
|
+
value = item.value.gsub(/([^\\])"/, "\\1\\\"")
|
30
|
+
|
31
|
+
result = ""
|
32
|
+
result << "/* #{item.comment} */\n" if item.comment
|
33
|
+
result << "\"#{key}\" = \"#{value}\";\n"
|
34
|
+
|
35
|
+
return result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,63 @@
|
|
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 CollectionMerger
|
27
|
+
ACTION_ADD = (1 << 0)
|
28
|
+
ACTION_DELETE = (1 << 1)
|
29
|
+
ACTION_UPDATE = (1 << 2)
|
30
|
+
|
31
|
+
def merge(src_collection, dst_collection, actions = (ACTION_ADD | ACTION_DELETE))
|
32
|
+
if not src_collection or not dst_collection
|
33
|
+
raise ArgumentError, 'Source and Destination Collections should be set'
|
34
|
+
end
|
35
|
+
|
36
|
+
dst_keys = nil
|
37
|
+
if (actions & ACTION_DELETE) != 0
|
38
|
+
dst_keys = dst_collection.all_keys
|
39
|
+
end
|
40
|
+
|
41
|
+
src_collection.each do |src_item|
|
42
|
+
dst_item = dst_collection.item_for_key(src_item.key)
|
43
|
+
|
44
|
+
if (actions & ACTION_ADD) != 0 && !dst_item
|
45
|
+
dst_collection.add_item(src_item.dup)
|
46
|
+
elsif (actions & ACTION_UPDATE) != 0 && dst_item
|
47
|
+
dst_collection.add_item(src_item.dup)
|
48
|
+
end
|
49
|
+
|
50
|
+
if dst_keys
|
51
|
+
dst_keys.delete(src_item.key)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if dst_keys
|
56
|
+
dst_keys.each do |key|
|
57
|
+
dst_collection.remove_item_for_key(key)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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 CollectionWriter
|
27
|
+
def initialize(file_manager, formatter)
|
28
|
+
@file_manager = file_manager
|
29
|
+
@formatter = formatter
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_to_path(collection, filepath)
|
33
|
+
if not filepath
|
34
|
+
raise ArgumentException, 'filepath can\'t be nil'
|
35
|
+
end
|
36
|
+
|
37
|
+
FileUtils.mkdir_p(@file_manager.dirname(filepath))
|
38
|
+
|
39
|
+
@file_manager.open(filepath, "w") do |io|
|
40
|
+
collection.sorted_each do |item|
|
41
|
+
io << @formatter.format_item(item)
|
42
|
+
io << "\n"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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 CollectionsGenerator
|
27
|
+
def initialize(genstrings, collection_builder)
|
28
|
+
@genstrings = genstrings
|
29
|
+
@collection_builder = collection_builder
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate(code_dir)
|
33
|
+
result = Array.new()
|
34
|
+
@genstrings.generate(code_dir) do |filepath|
|
35
|
+
collection = @collection_builder.collection_at_path(filepath)
|
36
|
+
result.push(collection)
|
37
|
+
end
|
38
|
+
return result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
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
|
+
require 'yaml'
|
25
|
+
|
26
|
+
module Locca
|
27
|
+
class ConfigReader
|
28
|
+
def read(path)
|
29
|
+
return YAML.load_file(path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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 ConfigValidator
|
27
|
+
attr_accessor :fields
|
28
|
+
|
29
|
+
def initialize(fields = nil)
|
30
|
+
@fields = fields
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate(hash)
|
34
|
+
if not @fields
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
|
38
|
+
@fields.each do |field|
|
39
|
+
if not hash.has_key?(field)
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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
|
+
require 'open3'
|
25
|
+
require 'fileutils'
|
26
|
+
require 'tmpdir'
|
27
|
+
|
28
|
+
module Locca
|
29
|
+
class Genstrings
|
30
|
+
def generate(code_dir)
|
31
|
+
Dir.mktmpdir do |tmp_dir|
|
32
|
+
command = "find #{code_dir} -iname \"*.m\" -or -iname \"*.mm\" -or -iname \"*.c\" | xargs genstrings -o '#{tmp_dir}'"
|
33
|
+
stdout, stderr, status = Open3.capture3(command)
|
34
|
+
|
35
|
+
STDERR.puts(stderr)
|
36
|
+
|
37
|
+
if status.success?
|
38
|
+
Dir.glob(File.join(tmp_dir, '*.strings')) do |filename|
|
39
|
+
yield(filename)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise "genstrings failed"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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 Project
|
27
|
+
attr_reader :dir
|
28
|
+
attr_reader :code_dir
|
29
|
+
attr_reader :lang_dir
|
30
|
+
|
31
|
+
attr_reader :base_lang
|
32
|
+
|
33
|
+
def initialize(dir, config)
|
34
|
+
@dir = dir
|
35
|
+
|
36
|
+
@code_dir = File.join(dir, config['code_dir'])
|
37
|
+
@lang_dir = File.join(dir, config['lang_dir'])
|
38
|
+
|
39
|
+
@base_lang = config['base_lang']
|
40
|
+
end
|
41
|
+
|
42
|
+
def langs
|
43
|
+
result = Set.new()
|
44
|
+
Dir.glob(File.join(@lang_dir, '*.lproj')) do |filepath|
|
45
|
+
result.add(File.basename(filepath, '.lproj'))
|
46
|
+
end
|
47
|
+
return result
|
48
|
+
end
|
49
|
+
|
50
|
+
def path_for_collection(collection_name, lang)
|
51
|
+
return File.join(@lang_dir, "#{lang}.lproj", "#{collection_name}.strings")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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 ProjectDirLocator
|
27
|
+
|
28
|
+
def locate(dir)
|
29
|
+
if not File.directory?(dir)
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
while dir
|
34
|
+
if File.directory?(File.join(dir, ".locca"))
|
35
|
+
return dir
|
36
|
+
end
|
37
|
+
|
38
|
+
new_dir = File.expand_path('..', dir)
|
39
|
+
if new_dir == dir
|
40
|
+
break
|
41
|
+
end
|
42
|
+
dir = new_dir
|
43
|
+
end
|
44
|
+
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def config_path(project_dir)
|
49
|
+
return File.join(project_dir, '.locca/config')
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,63 @@
|
|
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
|
+
require_relative 'project'
|
25
|
+
|
26
|
+
module Locca
|
27
|
+
class ProjectNotFoundError < RuntimeError
|
28
|
+
end
|
29
|
+
|
30
|
+
class ConfigNotFoundError < RuntimeError
|
31
|
+
end
|
32
|
+
|
33
|
+
class ConfigNotValidError < RuntimeError
|
34
|
+
end
|
35
|
+
|
36
|
+
class ProjectFactory
|
37
|
+
|
38
|
+
def initialize(project_dir_locator, config_reader, config_validator)
|
39
|
+
@project_dir_locator = project_dir_locator
|
40
|
+
@config_reader = config_reader
|
41
|
+
@config_validator = config_validator
|
42
|
+
end
|
43
|
+
|
44
|
+
def new_project(project_dir)
|
45
|
+
project_dir = @project_dir_locator.locate(project_dir)
|
46
|
+
if not project_dir
|
47
|
+
raise ProjectNotFoundError, 'Can\'t find .locca dir (also checked parent dirs)'
|
48
|
+
end
|
49
|
+
|
50
|
+
config = @config_reader.read(@project_dir_locator.config_path(project_dir))
|
51
|
+
if not config
|
52
|
+
raise ConfigNotFoundError, 'Can\'t find .locca/config'
|
53
|
+
end
|
54
|
+
|
55
|
+
if not @config_validator.validate(config)
|
56
|
+
raise ConfigNotValidError, 'Config .locca/config is not valid'
|
57
|
+
end
|
58
|
+
|
59
|
+
return Project.new(project_dir, config)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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
|
+
module Locca
|
25
|
+
VERSION = '0.9.1'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: locca
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shurakov Evgeny
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mocha
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
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: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gli
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email: inbox@shurakov.name
|
85
|
+
executables:
|
86
|
+
- locca
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files:
|
89
|
+
- README.rdoc
|
90
|
+
files:
|
91
|
+
- bin/locca
|
92
|
+
- lib/babelyoda/strings_lexer.rb
|
93
|
+
- lib/babelyoda/strings_parser.rb
|
94
|
+
- lib/locca/actions/build_action.rb
|
95
|
+
- lib/locca/actions/merge_action.rb
|
96
|
+
- lib/locca/collection.rb
|
97
|
+
- lib/locca/collection_builder.rb
|
98
|
+
- lib/locca/collection_item.rb
|
99
|
+
- lib/locca/collection_item_condensed_formatter.rb
|
100
|
+
- lib/locca/collection_item_default_formatter.rb
|
101
|
+
- lib/locca/collection_merger.rb
|
102
|
+
- lib/locca/collection_writer.rb
|
103
|
+
- lib/locca/collections_generator.rb
|
104
|
+
- lib/locca/config_reader.rb
|
105
|
+
- lib/locca/config_validator.rb
|
106
|
+
- lib/locca/genstrings.rb
|
107
|
+
- lib/locca/project.rb
|
108
|
+
- lib/locca/project_dir_locator.rb
|
109
|
+
- lib/locca/project_factory.rb
|
110
|
+
- lib/locca/version.rb
|
111
|
+
- lib/locca.rb
|
112
|
+
- README.rdoc
|
113
|
+
homepage: https://github.com/eshurakov/locca
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.0.3
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Application localization kit
|
138
|
+
test_files: []
|