locraft 1.1.1 → 1.1.2
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/lib/locraft/config.rb +15 -10
- data/lib/locraft/constants_generator.rb +18 -20
- data/lib/locraft/csv_parser.rb +37 -22
- data/lib/locraft/extractor.rb +2 -4
- data/lib/locraft/google_drive_wrapper.rb +5 -7
- data/lib/locraft/info_plist_generator.rb +6 -8
- data/lib/locraft/initializer.rb +1 -3
- data/lib/locraft/runner.rb +3 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 646cc80f22f86b648222b63b0d3972073c6228ad
|
4
|
+
data.tar.gz: a89aeb11a41d07fcfd86ba01007e12462520a14c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1954e7acaf2abfb3f8f5fd8404da1a608cd7065be8744aa8a1998d288b7cd00e4c9b2b3410727c5c1d3f275beef930f7daeb0772c97396a3cc3cf3f712e7c35d
|
7
|
+
data.tar.gz: 3a20b2b9c02e941d917e858b82f26ecd47c6c533861d4b37cbc73be799b7001adc9083723590c4ee59de1c4989aa681940bab51de7204f7d228649dc38867a42
|
data/lib/locraft/config.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
module Locraft
|
2
|
-
|
3
2
|
STRINGS_EXTENSION = '.strings'
|
4
3
|
SWIFT = 'swift'
|
5
4
|
OBJC = 'objc'
|
6
5
|
|
7
6
|
class Config
|
8
|
-
|
9
7
|
attr_accessor :langs
|
10
8
|
attr_accessor :default_lang
|
11
9
|
attr_accessor :destination_dir
|
@@ -38,8 +36,8 @@ module Locraft
|
|
38
36
|
self.macro_destination_dir = './'
|
39
37
|
self.keys_separator = '.'
|
40
38
|
self.langs = {
|
41
|
-
|
42
|
-
|
39
|
+
'English' => 'en',
|
40
|
+
'Russian' => 'ru'
|
43
41
|
}
|
44
42
|
yield self if block_given?
|
45
43
|
end
|
@@ -51,19 +49,26 @@ module Locraft
|
|
51
49
|
config.from_file = file
|
52
50
|
return config if Config === config
|
53
51
|
|
54
|
-
warn
|
55
|
-
rescue SyntaxError,
|
56
|
-
warn
|
52
|
+
warn "[#{file}] isn't a Locraft::Config, but #{config.class}."
|
53
|
+
rescue SyntaxError, StandardError => e
|
54
|
+
warn "Invalid config in [#{file}]: #{e}"
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
60
58
|
def relative_destination_dir
|
61
|
-
File.expand_path('../' +
|
59
|
+
File.expand_path('../' + destination_dir, from_file)
|
62
60
|
end
|
63
61
|
|
64
62
|
def relative_macro_destination_dir
|
65
|
-
File.expand_path('../' +
|
63
|
+
File.expand_path('../' + macro_destination_dir, from_file)
|
66
64
|
end
|
67
65
|
|
66
|
+
def strings_file
|
67
|
+
"#{strings_basename}#{STRINGS_EXTENSION}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def info_plist_file
|
71
|
+
"#{info_plist_basename}#{STRINGS_EXTENSION}"
|
72
|
+
end
|
68
73
|
end
|
69
|
-
end
|
74
|
+
end
|
@@ -2,7 +2,6 @@ require_relative 'config'
|
|
2
2
|
|
3
3
|
module Locraft
|
4
4
|
class ConstantsGenerator
|
5
|
-
|
6
5
|
OBJC_CONST_TEMPLATE_H = 'extern NSString *const __nonnull %{const};'
|
7
6
|
OBJC_CONST_TEMPLATE_M = 'NSString *const %{const} = @"%{key}";'
|
8
7
|
SWIFT_CONST_TEMPLATE = 'let %{const}: String = @"%{key}"'
|
@@ -13,27 +12,27 @@ module Locraft
|
|
13
12
|
|
14
13
|
def generate
|
15
14
|
if @config.dev_lang.equal?(OBJC)
|
16
|
-
|
17
|
-
|
15
|
+
write_to("#{@config.relative_macro_destination_dir}/#{files_name}.h", h_file)
|
16
|
+
write_to("#{@config.relative_macro_destination_dir}/#{files_name}.m", m_file)
|
18
17
|
else
|
19
|
-
|
18
|
+
write_to("#{@config.relative_macro_destination_dir}/#{files_name}.swift", swift_file)
|
20
19
|
end
|
21
20
|
|
22
|
-
puts
|
21
|
+
puts "constants files was created for [#{@config.dev_lang}] language"
|
23
22
|
end
|
24
23
|
|
25
24
|
def strings_lines
|
26
|
-
File.readlines(
|
25
|
+
File.readlines(strings_file).select { |l| l =~ /".*"\s*=\s*".*";/ }
|
27
26
|
end
|
28
27
|
|
29
28
|
def strings_file
|
30
|
-
to_add =
|
29
|
+
to_add = "#{@config.langs.values.first}.lproj/#{@config.strings_file}"
|
31
30
|
File.join(@config.relative_destination_dir, to_add)
|
32
31
|
end
|
33
32
|
|
34
33
|
def write_to(file, content)
|
35
34
|
File.open(file, 'w+') do |f|
|
36
|
-
f.puts
|
35
|
+
f.puts files_header + "\n"
|
37
36
|
f.puts content
|
38
37
|
end
|
39
38
|
end
|
@@ -47,31 +46,30 @@ module Locraft
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def m_file
|
50
|
-
file = %
|
51
|
-
file +
|
49
|
+
file = %(#import "#{files_name}.h"\n)
|
50
|
+
file + constants_keys.map { |d| OBJC_CONST_TEMPLATE_M % d }.join("\n")
|
52
51
|
end
|
53
52
|
|
54
53
|
def h_file
|
55
|
-
file =
|
56
|
-
file +
|
54
|
+
file = "@import Foundation;\n"
|
55
|
+
file + constants_keys.map { |d| OBJC_CONST_TEMPLATE_H % d }.join("\n")
|
57
56
|
end
|
58
57
|
|
59
58
|
def swift_file
|
60
|
-
file =
|
61
|
-
file +
|
59
|
+
file = "import Foundation\n"
|
60
|
+
file + constants_keys.map { |d| SWIFT_CONST_TEMPLATE % d }.join("\n")
|
62
61
|
end
|
63
62
|
|
64
63
|
def constants_keys
|
65
|
-
|
66
|
-
key = l.match(
|
67
|
-
{ :
|
64
|
+
strings_lines.map do |l|
|
65
|
+
key = l.match(/"(.*)"\s*=/)[1]
|
66
|
+
{ key: key, const: constant_from(key) }
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
71
70
|
def constant_from(key)
|
72
|
-
inside = key.split(/[#{@config.keys_separator}\s]/).map
|
73
|
-
|
71
|
+
inside = key.split(/[#{@config.keys_separator}\s]/).map(&:capitalize).join
|
72
|
+
"k#{@config.dev_prefix}#{inside}Localized"
|
74
73
|
end
|
75
|
-
|
76
74
|
end
|
77
75
|
end
|
data/lib/locraft/csv_parser.rb
CHANGED
@@ -4,44 +4,59 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
module Locraft
|
6
6
|
class CSVParser
|
7
|
+
include FileUtils
|
7
8
|
|
8
|
-
def initialize(
|
9
|
+
def initialize(config)
|
9
10
|
@config = config
|
10
|
-
@csv_body = File.read(csv_file)
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
13
|
+
def parse_csv_file_to_strings(csv_file)
|
14
|
+
if File.file?(csv_file)
|
15
|
+
parse_csv_to_strings(File.read(csv_file))
|
16
|
+
else
|
17
|
+
warn "CSVParser ERROR: there is no such a csv_file [#{csv_file}]"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_csv_to_strings(csv_body)
|
22
|
+
rows = csv_rows(csv_body)
|
16
23
|
@config.langs.keys.each do |lang|
|
17
|
-
|
24
|
+
lproj_dir = mkdir_for_lang(lang)
|
25
|
+
localizable_file = "#{lproj_dir}/#{@config.strings_file}"
|
26
|
+
File.write(localizable_file, parse_rows_for_lang(rows, lang))
|
18
27
|
end
|
19
28
|
end
|
20
29
|
|
21
|
-
|
30
|
+
def csv_rows(body)
|
31
|
+
csv = CSV.new(body, headers: true)
|
32
|
+
csv.to_a.map(&:to_hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
# return strings file content
|
22
36
|
def parse_rows_for_lang(rows, lang)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
unless hash[:key].nil?
|
30
|
-
file.puts '/* %{comment} */' % hash unless hash[:comment].nil?
|
31
|
-
file.puts %Q{"%{key}" = "%{value}";\n\n} % hash
|
32
|
-
end
|
37
|
+
content = ''
|
38
|
+
rows.each do |row|
|
39
|
+
hash = row_hash(row, lang)
|
40
|
+
unless hash[:key].nil?
|
41
|
+
content += '/* %{comment} */' % hash unless hash[:comment].nil?
|
42
|
+
content += %(\n"%{key}" = "%{value}";\n\n) % hash
|
33
43
|
end
|
34
44
|
end
|
35
|
-
|
45
|
+
content
|
36
46
|
end
|
37
47
|
|
38
48
|
def row_hash(row, lang)
|
39
49
|
{
|
40
|
-
|
41
|
-
|
42
|
-
|
50
|
+
comment: row[@config.gdoc_comments_column],
|
51
|
+
value: row[lang] || row[@config.default_lang],
|
52
|
+
key: row[@config.gdoc_keys_column] || row[@config.default_lang]
|
43
53
|
}
|
44
54
|
end
|
45
55
|
|
56
|
+
def mkdir_for_lang(lang)
|
57
|
+
lproj_dir = "#{@config.relative_destination_dir}/#{@config.langs[lang]}.lproj"
|
58
|
+
mkdir_p lproj_dir unless Dir.exist?(lproj_dir)
|
59
|
+
lproj_dir
|
60
|
+
end
|
46
61
|
end
|
47
|
-
end
|
62
|
+
end
|
data/lib/locraft/extractor.rb
CHANGED
@@ -6,7 +6,6 @@ require_relative 'google_drive_wrapper'
|
|
6
6
|
|
7
7
|
module Locraft
|
8
8
|
class Extractor
|
9
|
-
|
10
9
|
def initialize(config_file)
|
11
10
|
@config = Config.load_from(config_file)
|
12
11
|
end
|
@@ -14,8 +13,8 @@ module Locraft
|
|
14
13
|
def extract
|
15
14
|
# generate localized strings files
|
16
15
|
csv_file = GoogleDriveWrapper.new(@config).export_worksheet
|
17
|
-
csv_parser = CSVParser.new(
|
18
|
-
csv_parser.
|
16
|
+
csv_parser = CSVParser.new(@config)
|
17
|
+
csv_parser.parse_csv_file_to_strings(csv_file)
|
19
18
|
|
20
19
|
# generate .plist files
|
21
20
|
InfoPlistGenerator.new(@config).generate
|
@@ -23,6 +22,5 @@ module Locraft
|
|
23
22
|
# generate constants
|
24
23
|
ConstantsGenerator.new(@config).generate
|
25
24
|
end
|
26
|
-
|
27
25
|
end
|
28
26
|
end
|
@@ -4,6 +4,7 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
module Locraft
|
6
6
|
class GoogleDriveWrapper
|
7
|
+
include FileUtils
|
7
8
|
|
8
9
|
EXPORTED_CSV_FILE = 'google_doc_sheet.csv'
|
9
10
|
SESSION_TOKEN_FILE = '.locraft_gdrive_token'
|
@@ -13,21 +14,19 @@ module Locraft
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def authenticate
|
16
|
-
|
17
|
+
mkdir_p @config.relative_destination_dir unless Dir.exist?(@config.relative_destination_dir)
|
17
18
|
token_file = File.join(@config.relative_destination_dir, SESSION_TOKEN_FILE)
|
18
19
|
@session = GoogleDrive.saved_session(token_file)
|
19
20
|
end
|
20
21
|
|
21
22
|
def doc_named(name)
|
22
|
-
unless @session
|
23
|
-
authenticate
|
24
|
-
end
|
23
|
+
authenticate unless @session
|
25
24
|
@session.spreadsheet_by_title(name)
|
26
25
|
end
|
27
26
|
|
28
27
|
# return exported file path
|
29
28
|
def export_worksheet
|
30
|
-
worksheets =
|
29
|
+
worksheets = doc_named(@config.gdoc_file).worksheets
|
31
30
|
if worksheets.count > @config.gdoc_sheet
|
32
31
|
sheet = worksheets[@config.gdoc_sheet]
|
33
32
|
file = File.join(@config.relative_destination_dir, EXPORTED_CSV_FILE)
|
@@ -37,6 +36,5 @@ module Locraft
|
|
37
36
|
warn 'gdrive_wrapper worksheet export error: sheet number in config out of bounds!'
|
38
37
|
end
|
39
38
|
end
|
40
|
-
|
41
39
|
end
|
42
|
-
end
|
40
|
+
end
|
@@ -2,29 +2,27 @@ require_relative 'config'
|
|
2
2
|
|
3
3
|
module Locraft
|
4
4
|
class InfoPlistGenerator
|
5
|
-
|
6
5
|
def initialize(config)
|
7
6
|
@config = config
|
8
7
|
end
|
9
8
|
|
10
9
|
def generate
|
11
10
|
dir = @config.relative_destination_dir
|
12
|
-
folders = Dir.entries(dir).select { |d| d =~
|
11
|
+
folders = Dir.entries(dir).select { |d| d =~ /.+(.lproj)/ }.map { |d| File.join(dir, d) }
|
13
12
|
folders.each { |f| generate_info_plist_in_lproj(f) }
|
14
13
|
end
|
15
14
|
|
16
15
|
def generate_info_plist_in_lproj(folder)
|
17
|
-
localizable_file = File.join(folder,
|
18
|
-
info_file = File.join(folder,
|
16
|
+
localizable_file = File.join(folder, @config.strings_file.to_s)
|
17
|
+
info_file = File.join(folder, @config.info_plist_file.to_s)
|
19
18
|
File.write(info_file, info_plist_from(localizable_file))
|
20
19
|
|
21
|
-
puts
|
20
|
+
puts "- #{info_file} created"
|
22
21
|
end
|
23
22
|
|
24
23
|
def info_plist_from(localizable_file)
|
25
|
-
filter =
|
24
|
+
filter = /"(NS|CF).*"\s*=\s*".*";/
|
26
25
|
File.readlines(localizable_file).select { |l| l =~ filter }.join("\n")
|
27
26
|
end
|
28
|
-
|
29
27
|
end
|
30
|
-
end
|
28
|
+
end
|
data/lib/locraft/initializer.rb
CHANGED
@@ -3,7 +3,6 @@ module Locraft
|
|
3
3
|
SAMPLE_CONFIG_FILE = './locraft.config'
|
4
4
|
|
5
5
|
class Initializer
|
6
|
-
|
7
6
|
def self.init
|
8
7
|
config = File.read(File.expand_path('../resources/sample_locraft.config', __FILE__))
|
9
8
|
if File.file? SAMPLE_CONFIG_FILE
|
@@ -12,6 +11,5 @@ module Locraft
|
|
12
11
|
File.write(SAMPLE_CONFIG_FILE, config)
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
|
-
end
|
15
|
+
end
|
data/lib/locraft/runner.rb
CHANGED
@@ -4,23 +4,21 @@ require 'thor'
|
|
4
4
|
|
5
5
|
module Locraft
|
6
6
|
class Runner < Thor
|
7
|
-
|
8
7
|
desc 'init', 'create sample locraft.config'
|
9
8
|
def init
|
10
9
|
Initializer.init
|
11
10
|
end
|
12
11
|
|
13
12
|
desc 'extract', 'extract strings from google drive and parse them into {.strings, .plist} files. Then create constants'
|
14
|
-
option :config, :
|
13
|
+
option :config, default: SAMPLE_CONFIG_FILE, aliases: '-c', type: :string, desc: 'configuration file'
|
15
14
|
def extract
|
16
15
|
config_file = options[:config]
|
17
16
|
if File.file? config_file
|
18
17
|
extractor = Extractor.new(options[:config])
|
19
18
|
extractor.extract
|
20
19
|
else
|
21
|
-
warn %
|
20
|
+
warn %(Error: there is no such a file "#{config_file}".)
|
22
21
|
end
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
|
-
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sroik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google_drive
|