locraft 1.2.0 → 1.3.0
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/bin/locraft +1 -1
- data/lib/locraft/config.rb +17 -11
- data/lib/locraft/constants_generator.rb +12 -17
- data/lib/locraft/csv_parser.rb +11 -45
- data/lib/locraft/extractor.rb +21 -7
- data/lib/locraft/google_drive_wrapper.rb +18 -8
- data/lib/locraft/info_plist_generator.rb +19 -15
- data/lib/locraft/localization.rb +30 -0
- data/lib/locraft/resources/sample_locraft.config +3 -2
- data/lib/locraft/strings_generator.rb +31 -0
- data/lib/locraft.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cf55e11bdceb1841fb6634cdb0a7c542a007e84
|
4
|
+
data.tar.gz: 77890f235af48f9363d4f4137bf96b39ade76f6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7eeb6f98a5128a0e1c841121e71ea079b8f8b0d839bb563ed22e455f1296770a0afa7c7233304c7508ec13fbeb16ddc218fba7c72bbc52b8b788abc83a47706e
|
7
|
+
data.tar.gz: 7e696aee22acb23c0327c507bb046c0d910f2f4ef5b4d549e9107a6d7e795cbddae27d2acf5eff4544e510a9ea7f8affec39a8aab34663f9290fe56a94f82e61
|
data/bin/locraft
CHANGED
data/lib/locraft/config.rb
CHANGED
@@ -6,7 +6,6 @@ module Locraft
|
|
6
6
|
class Config
|
7
7
|
attr_accessor :langs
|
8
8
|
attr_accessor :default_lang
|
9
|
-
attr_accessor :destination_dir
|
10
9
|
attr_accessor :gdoc_file
|
11
10
|
attr_accessor :gdoc_sheet
|
12
11
|
attr_accessor :gdoc_keys_column
|
@@ -14,17 +13,16 @@ module Locraft
|
|
14
13
|
attr_accessor :dev_lang
|
15
14
|
attr_accessor :dev_prefix
|
16
15
|
attr_accessor :macro_file
|
17
|
-
attr_accessor :
|
16
|
+
attr_accessor :macro_destination
|
18
17
|
attr_accessor :strings_basename
|
18
|
+
attr_accessor :strings_destination
|
19
19
|
attr_accessor :info_plist_basename
|
20
|
+
attr_accessor :info_plist_destination
|
20
21
|
|
21
22
|
# fill automatically in load_from method
|
22
23
|
attr_accessor :from_file
|
23
24
|
|
24
25
|
def initialize
|
25
|
-
self.info_plist_basename = 'InfoPlist'
|
26
|
-
self.strings_basename = 'Localizable'
|
27
|
-
self.destination_dir = './Localizations'
|
28
26
|
self.default_lang = 'English'
|
29
27
|
self.gdoc_sheet = 0
|
30
28
|
self.gdoc_keys_column = 'Keys'
|
@@ -32,7 +30,11 @@ module Locraft
|
|
32
30
|
self.dev_lang = OBJC
|
33
31
|
self.dev_prefix = 'XYZ'
|
34
32
|
self.macro_file = 'LocalizedConstants'
|
35
|
-
self.
|
33
|
+
self.macro_destination = './'
|
34
|
+
self.strings_basename = 'Localizable'
|
35
|
+
self.strings_destination = './Localizations'
|
36
|
+
self.info_plist_basename = 'InfoPlist'
|
37
|
+
self.info_plist_destination = './Localizations'
|
36
38
|
self.langs = {
|
37
39
|
'English' => 'en',
|
38
40
|
'Russian' => 'ru'
|
@@ -45,7 +47,7 @@ module Locraft
|
|
45
47
|
begin
|
46
48
|
config = eval(File.read(file), binding, 'config loading problem')
|
47
49
|
config.from_file = file
|
48
|
-
return config if Config
|
50
|
+
return config if config.is_a? Config
|
49
51
|
|
50
52
|
warn "[#{file}] isn't a Locraft::Config, but #{config.class}."
|
51
53
|
rescue SyntaxError, StandardError => e
|
@@ -53,12 +55,16 @@ module Locraft
|
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
56
|
-
def
|
57
|
-
File.expand_path('../' +
|
58
|
+
def relative_strings_destination
|
59
|
+
File.expand_path('../' + strings_destination, from_file)
|
60
|
+
end
|
61
|
+
|
62
|
+
def relative_plist_destination
|
63
|
+
File.expand_path('../' + info_plist_destination, from_file)
|
58
64
|
end
|
59
65
|
|
60
|
-
def
|
61
|
-
File.expand_path('../' +
|
66
|
+
def relative_macro_destination
|
67
|
+
File.expand_path('../' + macro_destination, from_file)
|
62
68
|
end
|
63
69
|
|
64
70
|
def strings_file
|
@@ -1,35 +1,31 @@
|
|
1
1
|
require_relative 'config'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
module Locraft
|
4
5
|
class ConstantsGenerator
|
6
|
+
include FileUtils
|
7
|
+
|
5
8
|
OBJC_CONST_TEMPLATE_H = 'extern NSString *const __nonnull %{const};'
|
6
9
|
OBJC_CONST_TEMPLATE_M = 'NSString *const %{const} = @"%{key}";'
|
7
10
|
SWIFT_CONST_TEMPLATE = 'let %{const}: String = "%{key}"'
|
8
11
|
|
9
|
-
def initialize(config)
|
12
|
+
def initialize(config, localizations)
|
10
13
|
@config = config
|
14
|
+
@localizations = localizations
|
11
15
|
end
|
12
16
|
|
13
17
|
def generate
|
18
|
+
destination_dir = @config.relative_macro_destination
|
19
|
+
mkdir_p destination_dir unless Dir.exist?(destination_dir)
|
14
20
|
if @config.dev_lang.equal?(OBJC)
|
15
|
-
write_to("#{
|
16
|
-
write_to("#{
|
21
|
+
write_to("#{destination_dir}/#{files_name}.h", h_file)
|
22
|
+
write_to("#{destination_dir}/#{files_name}.m", m_file)
|
17
23
|
else
|
18
|
-
write_to("#{
|
24
|
+
write_to("#{destination_dir}/#{files_name}.swift", swift_file)
|
19
25
|
end
|
20
|
-
|
21
26
|
puts "constants files was created for [#{@config.dev_lang}] language"
|
22
27
|
end
|
23
28
|
|
24
|
-
def strings_lines
|
25
|
-
File.readlines(strings_file).select { |l| l =~ /".*"\s*=\s*".*";/ }
|
26
|
-
end
|
27
|
-
|
28
|
-
def strings_file
|
29
|
-
to_add = "#{@config.langs.values.first}.lproj/#{@config.strings_file}"
|
30
|
-
File.join(@config.relative_destination_dir, to_add)
|
31
|
-
end
|
32
|
-
|
33
29
|
def write_to(file, content)
|
34
30
|
File.open(file, 'w+') do |f|
|
35
31
|
f.puts files_header + "\n"
|
@@ -61,9 +57,8 @@ module Locraft
|
|
61
57
|
end
|
62
58
|
|
63
59
|
def constants_keys
|
64
|
-
|
65
|
-
key
|
66
|
-
{ key: key, const: constant_from(key) }
|
60
|
+
@localizations.select { |l| l.valid? }.map do |l|
|
61
|
+
{ key: l.key, const: constant_from(l.key) }
|
67
62
|
end
|
68
63
|
end
|
69
64
|
|
data/lib/locraft/csv_parser.rb
CHANGED
@@ -1,65 +1,31 @@
|
|
1
1
|
require_relative 'config'
|
2
|
+
require_relative 'localization'
|
2
3
|
require 'csv'
|
3
|
-
require 'fileutils'
|
4
4
|
|
5
5
|
module Locraft
|
6
6
|
class CSVParser
|
7
|
-
include FileUtils
|
8
|
-
|
9
7
|
def initialize(config)
|
10
8
|
@config = config
|
11
9
|
end
|
12
10
|
|
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)
|
23
|
-
@config.langs.keys.each do |lang|
|
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))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
11
|
def csv_rows(body)
|
31
12
|
csv = CSV.new(body, headers: true)
|
32
13
|
csv.to_a.map(&:to_hash)
|
33
14
|
end
|
34
15
|
|
35
|
-
# return
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
content += '/* %{comment} */' % hash unless hash[:comment].nil?
|
42
|
-
content += %(\n"%{key}" = "%{value}";\n\n) % hash
|
43
|
-
end
|
16
|
+
# return localizations hash like #{ 'Lang' => [array of localizations] }
|
17
|
+
def parse_csv(csv_body)
|
18
|
+
rows = csv_rows(csv_body)
|
19
|
+
localizations_hash = {}
|
20
|
+
@config.langs.keys.each do |lang|
|
21
|
+
localizations_hash[lang] = parse_rows_for_lang(rows, lang)
|
44
22
|
end
|
45
|
-
|
23
|
+
localizations_hash
|
46
24
|
end
|
47
25
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
comment = row[@config.gdoc_comments_column]
|
52
|
-
{
|
53
|
-
comment: comment&.strip,
|
54
|
-
value: value&.strip,
|
55
|
-
key: key&.strip
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def mkdir_for_lang(lang)
|
60
|
-
lproj_dir = "#{@config.relative_destination_dir}/#{@config.langs[lang]}.lproj"
|
61
|
-
mkdir_p lproj_dir unless Dir.exist?(lproj_dir)
|
62
|
-
lproj_dir
|
26
|
+
# return localizations array
|
27
|
+
def parse_rows_for_lang(rows, lang)
|
28
|
+
rows.map { |row| Localization.load_with_csv_row(row, @config, lang) }
|
63
29
|
end
|
64
30
|
end
|
65
31
|
end
|
data/lib/locraft/extractor.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative 'config'
|
|
2
2
|
require_relative 'csv_parser'
|
3
3
|
require_relative 'info_plist_generator'
|
4
4
|
require_relative 'constants_generator'
|
5
|
+
require_relative 'strings_generator'
|
5
6
|
require_relative 'google_drive_wrapper'
|
6
7
|
|
7
8
|
module Locraft
|
@@ -11,16 +12,29 @@ module Locraft
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def extract
|
14
|
-
|
15
|
-
csv_file = GoogleDriveWrapper.new(@config).export_worksheet
|
15
|
+
csv = GoogleDriveWrapper.new(@config).export_worksheet_csv
|
16
16
|
csv_parser = CSVParser.new(@config)
|
17
|
-
csv_parser.
|
17
|
+
localizations_hash = csv_parser.parse_csv(csv)
|
18
|
+
if localizations_hash[@config.default_lang].nil?
|
19
|
+
warn 'extract ERROR: no localizations given'
|
20
|
+
else
|
21
|
+
generate_strings(localizations_hash)
|
22
|
+
generate_info_plist(localizations_hash)
|
23
|
+
generate_constant(localizations_hash)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_strings(localizations_hash)
|
28
|
+
StringsGenerator.new(@config, localizations_hash).generate
|
29
|
+
end
|
18
30
|
|
19
|
-
|
20
|
-
InfoPlistGenerator.new(@config).generate
|
31
|
+
def generate_info_plist(localizations_hash)
|
32
|
+
InfoPlistGenerator.new(@config, localizations_hash).generate
|
33
|
+
end
|
21
34
|
|
22
|
-
|
23
|
-
|
35
|
+
def generate_constant(localizations_hash)
|
36
|
+
localizations = localizations_hash[@config.default_lang]
|
37
|
+
ConstantsGenerator.new(@config, localizations).generate
|
24
38
|
end
|
25
39
|
end
|
26
40
|
end
|
@@ -14,8 +14,8 @@ module Locraft
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def authenticate
|
17
|
-
mkdir_p @config.
|
18
|
-
token_file = File.join(@config.
|
17
|
+
mkdir_p @config.relative_strings_destination unless Dir.exist?(@config.relative_strings_destination)
|
18
|
+
token_file = File.join(@config.relative_strings_destination, SESSION_TOKEN_FILE)
|
19
19
|
@session = GoogleDrive.saved_session(token_file)
|
20
20
|
end
|
21
21
|
|
@@ -24,18 +24,28 @@ module Locraft
|
|
24
24
|
@session.spreadsheet_by_title(name)
|
25
25
|
end
|
26
26
|
|
27
|
-
# return
|
27
|
+
# return worksheet
|
28
28
|
def export_worksheet
|
29
29
|
worksheets = doc_named(@config.gdoc_file).worksheets
|
30
30
|
if worksheets.count > @config.gdoc_sheet
|
31
|
-
|
32
|
-
file = File.join(@config.relative_destination_dir, EXPORTED_CSV_FILE)
|
33
|
-
File.delete(file) if File.exist?(file)
|
34
|
-
sheet.export_as_file(file)
|
35
|
-
file
|
31
|
+
worksheets[@config.gdoc_sheet]
|
36
32
|
else
|
37
33
|
warn 'gdrive_wrapper worksheet export error: sheet number in config out of bounds!'
|
38
34
|
end
|
39
35
|
end
|
36
|
+
|
37
|
+
# return exported worksheet file path
|
38
|
+
def export_worksheet_file
|
39
|
+
sheet = export_worksheet
|
40
|
+
file = File.join(@config.relative_strings_destination, EXPORTED_CSV_FILE)
|
41
|
+
File.delete(file) if File.exist?(file)
|
42
|
+
sheet.export_as_file(file)
|
43
|
+
end
|
44
|
+
|
45
|
+
# return worksheet as string in csv format
|
46
|
+
def export_worksheet_csv
|
47
|
+
worksheet = export_worksheet
|
48
|
+
worksheet.export_as_string
|
49
|
+
end
|
40
50
|
end
|
41
51
|
end
|
@@ -1,28 +1,32 @@
|
|
1
1
|
require_relative 'config'
|
2
|
+
require_relative 'localization'
|
3
|
+
require 'fileutils'
|
2
4
|
|
3
5
|
module Locraft
|
4
6
|
class InfoPlistGenerator
|
5
|
-
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
def initialize(config, localizations_hash)
|
6
10
|
@config = config
|
11
|
+
@localizations_hash = localizations_hash
|
7
12
|
end
|
8
13
|
|
9
14
|
def generate
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
puts "- #{info_file} created"
|
15
|
+
@config.langs.each do |lang, val|
|
16
|
+
localizations = @localizations_hash[lang]
|
17
|
+
destination_dir = "#{@config.relative_plist_destination}/#{val}.lproj"
|
18
|
+
file = "#{destination_dir}/#{@config.info_plist_file}"
|
19
|
+
mkdir_p destination_dir unless Dir.exist?(destination_dir)
|
20
|
+
File.open(file, 'w+') do |f|
|
21
|
+
f.puts info_plist_with(localizations)
|
22
|
+
end
|
23
|
+
puts "info plist generated: [#{file}]"
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
|
-
def
|
24
|
-
filter = /
|
25
|
-
|
27
|
+
def info_plist_with(localizations)
|
28
|
+
filter = /(NS|CF).*/
|
29
|
+
localizations.select { |l| l.key =~ filter }.map(&:to_line).join("\n")
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Locraft
|
2
|
+
class Localization
|
3
|
+
attr_accessor :language
|
4
|
+
attr_accessor :comment
|
5
|
+
attr_accessor :key
|
6
|
+
attr_accessor :value
|
7
|
+
|
8
|
+
def self.load_with_csv_row(row, config, lang)
|
9
|
+
localization = Localization.new
|
10
|
+
localization.language = lang
|
11
|
+
localization.comment = row[config.gdoc_comments_column]&.strip
|
12
|
+
localization.key = (row[config.gdoc_keys_column] || row[config.default_lang])&.strip
|
13
|
+
localization.value = (row[lang] || row[config.default_lang])&.strip
|
14
|
+
localization
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
!(key.nil? or value.nil?)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_line
|
22
|
+
content = ''
|
23
|
+
if valid?
|
24
|
+
content += "/* #{comment} */" unless comment.nil?
|
25
|
+
content += %(\n"#{key}" = "#{value}";\n)
|
26
|
+
end
|
27
|
+
content
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -12,7 +12,6 @@ Locraft::Config.new do |conf|
|
|
12
12
|
'Russian' => 'ru'
|
13
13
|
} # default: {'English' => 'en', 'Russian' => 'ru'}
|
14
14
|
|
15
|
-
conf.destination_dir = './Localizations' # strings destination directory related to this file, default: './Localizations'
|
16
15
|
conf.default_lang = 'English' # default: 'English'
|
17
16
|
conf.gdoc_sheet = 0 # default: 0
|
18
17
|
conf.gdoc_keys_column = 'Keys' # default: 'Keys'
|
@@ -20,7 +19,9 @@ Locraft::Config.new do |conf|
|
|
20
19
|
conf.dev_prefix = 'XYZ' # default: 'XYZ'
|
21
20
|
conf.dev_lang = OBJC # OBJC or SWIFT, default: OBJC
|
22
21
|
conf.macro_file = 'LocalizedConstants' # default: 'LocalizedConstants'
|
23
|
-
conf.
|
22
|
+
conf.macro_destination = './' # default: './'
|
24
23
|
conf.strings_basename = 'Localizable' # default: 'Localizable'
|
24
|
+
conf.strings_destination = './Localizations' # strings destination directory related to this file, default: './Localizations'
|
25
25
|
conf.info_plist_basename = 'InfoPlist' # default: 'InfoPlist'
|
26
|
+
conf.info_plist_destination = './Localizations' # info plist destination directory related to this file, default: './Localizations'
|
26
27
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
require_relative 'localization'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Locraft
|
6
|
+
class StringsGenerator
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
def initialize(config, localizations_hash)
|
10
|
+
@config = config
|
11
|
+
@localizations_hash = localizations_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate
|
15
|
+
@config.langs.each do |lang, val|
|
16
|
+
localizations = @localizations_hash[lang]
|
17
|
+
destination_dir = "#{@config.relative_strings_destination}/#{val}.lproj"
|
18
|
+
file = "#{destination_dir}/#{@config.strings_file}"
|
19
|
+
mkdir_p destination_dir unless Dir.exist?(destination_dir)
|
20
|
+
File.open(file, 'w+') do |f|
|
21
|
+
f.puts strings_file_with(localizations)
|
22
|
+
end
|
23
|
+
puts "strings file generated: [#{file}]"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def strings_file_with(localizations)
|
28
|
+
localizations.select { |l| l.valid? }.map(&:to_line).join("\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/locraft.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require_relative 'locraft/config'
|
2
|
+
require_relative 'locraft/localization'
|
2
3
|
require_relative 'locraft/initializer'
|
3
4
|
require_relative 'locraft/runner'
|
4
5
|
require_relative 'locraft/extractor'
|
5
6
|
require_relative 'locraft/info_plist_generator'
|
6
7
|
require_relative 'locraft/constants_generator'
|
8
|
+
require_relative 'locraft/strings_generator'
|
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.
|
4
|
+
version: 1.3.0
|
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-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google_drive
|
@@ -97,9 +97,11 @@ files:
|
|
97
97
|
- lib/locraft/google_drive_wrapper.rb
|
98
98
|
- lib/locraft/info_plist_generator.rb
|
99
99
|
- lib/locraft/initializer.rb
|
100
|
+
- lib/locraft/localization.rb
|
100
101
|
- lib/locraft/resources/constants_files_header.txt
|
101
102
|
- lib/locraft/resources/sample_locraft.config
|
102
103
|
- lib/locraft/runner.rb
|
104
|
+
- lib/locraft/strings_generator.rb
|
103
105
|
homepage: https://github.com/app-craft/locraft
|
104
106
|
licenses:
|
105
107
|
- MIT
|