fastlane-plugin-google_sheet_localize 0.1.20 → 0.1.51

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e981832345e489a2346adcc3901d5fae7700b379b1e02009cca1e55e8ab5fc6
4
- data.tar.gz: df90ee04b2d43aac2229738b8b06f85426331771730acbbbbd83b036e313b70e
3
+ metadata.gz: d17878398029568feb9ee6bd27af8636db4f8210f52c2a08dd07c90a4892586b
4
+ data.tar.gz: 1dc64c0e36953f70154bb5c191695ea2fafa918d45947ff3bafd57f28e575bbc
5
5
  SHA512:
6
- metadata.gz: 293d36b523297fd849f035d85709610f9c8760774b64604d47b30480d117a236243c0b0cbe1d78f578af6045989d3857ea6e63fba07717b30e73b24957581577
7
- data.tar.gz: 1b493e47d984de4e389fefad74eca3692dea3bd9d82eb4b25fb1d6834321a2fb4a8ed8fbe65f8838b0592e57e4d1c49b76b668d67c57102870f1fcc8a014dc67
6
+ metadata.gz: 4e683cd4c804e51b9b8617368afeeed0d2c19373d7c02fd7d659691d9193a11500632043b7e1077dd7b1ef4c6736262c58d996b35466cfd815c67e1410d22289
7
+ data.tar.gz: 616c2f44afe6521c56900e861594767e906965ed7e7cf676210ef5a57d03fc0e5b346494df3c1001f40dc422aceb85495bac686ef3f60ed88d996f2365d58f75
data/README.md CHANGED
@@ -14,30 +14,13 @@ fastlane add_plugin google_sheet_localize
14
14
 
15
15
  Creates .strings files for iOS and strings.xml files for Android
16
16
 
17
- to use our plugin you have to duplicate this google sheet: https://docs.google.com/spreadsheets/d/1fwRj1ZFPu2XlrDqkaqmIpJulqR5OVFEZnN35a9v37yc/edit?usp=sharing
18
-
19
- Google Drive access token:
20
- https://medium.com/@osanda.deshan/getting-google-oauth-access-token-using-google-apis-18b2ba11a11a
21
-
22
- * The language_titles (the columns which should be exported)
23
- * The default_language (If a string is not present in a specific language, this is the fallback)
24
- * The base_language (The language which is placed in the base values folder)
17
+ **Note to author:** Add a more detailed description about this plugin here. If your plugin contains multiple actions, make sure to mention them here.
25
18
 
26
19
  ## Example
27
20
 
28
- ```ruby
29
- lane :localize do
30
- google_sheet_localize(service_account_path: "./fastlane/google_drive_credentials.json",
31
- sheet_id: "sheet id",
32
- platform: "ios",
33
- tabs: ["3TV"], #array of tab titles in google sheet
34
- localization_path: "./Kit/TVKit",
35
- language_titles: ["de", "en"], #language titles in google sheet
36
- default_language: "de", #default language for google sheet
37
- base_language: "en") #ios: Base.lproj android: values
38
- end
39
- ```
21
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
40
22
 
23
+ **Note to author:** Please set up a sample project to make it easy for users to explore what your plugin does. Provide everything that is necessary to try out the plugin in this project (including a sample Xcode/Android project if necessary)
41
24
 
42
25
  ## Run tests for this plugin
43
26
 
@@ -13,43 +13,41 @@ module Fastlane
13
13
  tabs = params[:tabs]
14
14
  platform = params[:platform]
15
15
  path = params[:localization_path]
16
- language_titles = params[:language_titles]
17
- default_language = params[:default_language]
18
- base_language = params[:base_language]
19
16
 
20
17
  spreadsheet = session.spreadsheet_by_url(spreadsheet_id)
18
+
19
+ # Get the first worksheet
21
20
  worksheet = spreadsheet.worksheets.first
22
21
 
23
- result = []
22
+ languages = self.numberOfLanguages(worksheet)
24
23
 
25
- for i in 0..worksheet.max_cols
24
+ result = []
26
25
 
26
+ for i in 2..1+languages
27
27
  title = worksheet.rows[0][i]
28
28
 
29
- if language_titles.include?(title)
29
+ language = {
30
+ 'language' => title,
31
+ 'items' => []
32
+ }
30
33
 
31
- language = {
32
- 'language' => title,
33
- 'items' => []
34
- }
34
+ filterdWorksheets = []
35
35
 
36
- filterdWorksheets = []
36
+ if tabs.count == 0
37
+ filterdWorksheets = spreadsheet.worksheets
38
+ else
39
+ filterdWorksheets = spreadsheet.worksheets.select { |item| tabs.include?(item.title) }
40
+ end
37
41
 
38
- if tabs.count == 0
39
- filterdWorksheets = spreadsheet.worksheets
40
- else
41
- filterdWorksheets = spreadsheet.worksheets.select { |item| tabs.include?(item.title) }
42
- end
42
+ filterdWorksheets.each { |worksheet|
43
+ contentRows = worksheet.rows.drop(1)
44
+ language['items'].concat(self.generateJSONObject(contentRows, i))
45
+ }
43
46
 
44
- filterdWorksheets.each { |worksheet|
45
- contentRows = worksheet.rows.drop(1)
46
- language['items'].concat(self.generateJSONObject(contentRows, i))
47
- }
47
+ result.push(language)
48
48
 
49
- result.push(language)
50
- end
51
49
  end
52
- self.createFiles(result, platform, path, default_language, base_language)
50
+ self.createFiles(result, platform, path)
53
51
  end
54
52
 
55
53
  def self.generateJSONObject(contentRows, index)
@@ -66,6 +64,12 @@ module Fastlane
66
64
 
67
65
  end
68
66
 
67
+ def self.writeToJSONFile(languages)
68
+ File.open("output.json","w") do |f|
69
+ f.write(JSON.pretty_generate(languages))
70
+ end
71
+ end
72
+
69
73
  def self.generateSingleObject(row, column)
70
74
  identifierIos = row[0]
71
75
  identifierAndroid = row[1]
@@ -83,15 +87,8 @@ module Fastlane
83
87
 
84
88
  end
85
89
 
86
- def self.filterUnusedRows(items, identifier)
87
- return items.select { |item|
88
- currentIdentifier = item[identifier]
89
- currentIdentifier != "NR" && currentIdentifier != "" && currentIdentifier != "TBD"
90
- }
91
- end
92
-
93
- def self.createFiles(languages, platform, destinationPath, defaultLanguage, base_language)
94
- self.createFilesForLanguages(languages, platform, destinationPath, defaultLanguage, base_language)
90
+ def self.createFiles(languages, platform, destinationPath)
91
+ languages.each { |language| self.createFileForLanguage(language, platform, destinationPath) }
95
92
 
96
93
  if platform == "ios"
97
94
 
@@ -100,37 +97,27 @@ module Fastlane
100
97
 
101
98
  filteredItems = languages[0]["items"].select { |item|
102
99
  iosIdentifier = item['identifierIos']
103
- iosIdentifier != "NR" && iosIdentifier != "" && !iosIdentifier.include?('//') && iosIdentifier != "TBD"
100
+ iosIdentifier != "NR" && iosIdentifier != "" && !iosIdentifier.include?('//')
104
101
  }
105
102
 
106
103
  File.open(swiftFilepath, "w") do |f|
107
- f.write("import Foundation\n\n// swiftlint:disable all\npublic struct Localization {\n")
104
+ f.write("import Foundation\n\n\npublic struct Localization {\n")
108
105
  filteredItems.each { |item|
109
106
 
110
107
  identifier = item['identifierIos']
111
108
 
112
- values = identifier.dup.split(".")
109
+ values = identifier.dup.gsub('.', ' ').split(" ")
113
110
 
114
111
  constantName = ""
115
112
 
116
113
  values.each_with_index do |item, index|
117
114
  if index == 0
118
- item[0] = item[0].downcase
119
- constantName += item
115
+ constantName += item.downcase
120
116
  else
121
- item[0] = item[0].upcase
122
- constantName += item
117
+ constantName += item.capitalize
123
118
  end
124
119
  end
125
120
 
126
- if constantName == "continue"
127
- constantName = "`continue`"
128
- end
129
-
130
- if constantName == "switch"
131
- constantName = "`switch`"
132
- end
133
-
134
121
  text = self.mapInvalidPlaceholder(item['text'])
135
122
 
136
123
  arguments = self.findArgumentsInText(text)
@@ -148,191 +135,67 @@ module Fastlane
148
135
  end
149
136
  end
150
137
 
151
- def self.createFilesForLanguages(languages, platform, destinationPath, defaultLanguage, base_language)
152
-
153
- languages.each { |language|
154
-
138
+ def self.createFileForLanguage(language, platform, destinationPath)
155
139
  if platform == "ios"
156
140
 
157
- filteredItems = self.filterUnusedRows(language["items"],'identifierIos')
141
+ swiftFilename = "Localization.swift"
142
+ swiftFilepath = "#{destinationPath}/#{swiftFilename}"
158
143
 
159
- stringFileName = "Localizable.strings"
160
- pluralsFileName = "Plurals.stringsdict"
161
-
162
- languageName = language['language']
163
-
164
- if languageName == base_language
165
- languageName = "Base"
166
- end
144
+ filteredItems = language["items"].select { |item|
145
+ iosIdentifier = item['identifierIos']
146
+ iosIdentifier != "NR" && iosIdentifier != ""
147
+ }
167
148
 
168
- stringFilepath = "#{destinationPath}/#{languageName}.lproj/#{stringFileName}"
169
- pluralsFilepath = "#{destinationPath}/#{languageName}.lproj/#{pluralsFileName}"
170
- FileUtils.mkdir_p "#{destinationPath}/#{languageName}.lproj"
171
-
172
- File.open(stringFilepath, "w") do |f|
173
- filteredItems.each_with_index { |item, index|
149
+ filename = "Localizable.strings"
150
+ filepath = "#{destinationPath}/#{language['language']}.lproj/#{filename}"
151
+ FileUtils.mkdir_p language['language']
152
+ File.open(filepath, "w") do |f|
153
+ filteredItems.each { |item|
174
154
 
175
155
  text = self.mapInvalidPlaceholder(item['text'])
176
156
  comment = item['comment']
177
157
  identifier = item['identifierIos']
178
158
 
179
159
  line = ""
160
+
180
161
  if identifier.include?('//')
181
162
  line = "\n\n#{identifier}\n"
182
163
  else
183
-
184
- if !text.include?("one|")
185
-
186
- if text == "" || text == "TBD"
187
- default_language_object = languages.select { |languageItem| languageItem['language'] == defaultLanguage }.first["items"]
188
- default_language_object = self.filterUnusedRows(default_language_object,'identifierIos')
189
-
190
- defaultLanguageText = default_language_object[index]['text']
191
- puts "found empty text for:\n\tidentifier: #{identifier}\n\tlanguage:#{language['language']}\n\treplacing it with: #{defaultLanguageText}"
192
- text = self.mapInvalidPlaceholder(defaultLanguageText)
193
- end
194
-
195
- line = "\"#{identifier}\" = \"#{text}\";"
196
- if !comment.to_s.empty?
197
- line = line + " //#{comment}\n"
198
- else
199
- line = line + "\n"
200
- end
201
- end
164
+ line = "\"#{identifier}\" = \"#{text}\";"
165
+ if !comment.to_s.empty?
166
+ line = line + " //#{comment}\n"
167
+ else
168
+ line = line + "\n"
202
169
  end
203
- f.write(line)
204
- }
205
- end
206
-
207
- File.open(pluralsFilepath, "w") do |f|
208
-
209
- f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
210
- f.write("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n")
211
- f.write("<plist version=\"1.0\">\n")
212
- f.write("<dict>\n")
213
-
214
- filteredItems.each_with_index { |item, index|
215
-
216
- text = self.mapInvalidPlaceholder(item['text'])
217
- identifier = item['identifierIos']
218
-
219
- if !identifier.include?('//') && text.include?("one|")
220
- if text == "" || text == "TBD"
221
- default_language_object = languages.select { |languageItem| languageItem['language'] == defaultLanguage }.first["items"]
222
- default_language_object = self.filterUnusedRows(default_language_object,'identifierIos')
223
-
224
- defaultLanguageText = default_language_object[index]['text']
225
- puts "found empty text for:\n\tidentifier: #{identifier}\n\tlanguage:#{language['language']}\n\treplacing it with: #{defaultLanguageText}"
226
- text = self.mapInvalidPlaceholder(defaultLanguageText)
227
- end
228
-
229
- text = text.gsub("\n", "|")
230
-
231
- formatIdentifier = identifier.gsub(".", "")
232
-
233
- f.write("\t\t<key>#{identifier}</key>\n")
234
- f.write("\t\t<dict>\n")
235
- f.write("\t\t\t<key>NSStringLocalizedFormatKey</key>\n")
236
- f.write("\t\t\t<string>%#@#{formatIdentifier}@</string>\n")
237
- f.write("\t\t\t<key>#{formatIdentifier}</key>\n")
238
- f.write("\t\t\t<dict>\n")
239
- f.write("\t\t\t\t<key>NSStringFormatSpecTypeKey</key>\n")
240
- f.write("\t\t\t\t<string>NSStringPluralRuleType</string>\n")
241
- f.write("\t\t\t\t<key>NSStringFormatValueTypeKey</key>\n")
242
- f.write("\t\t\t\t<string>d</string>\n")
243
-
244
- text.split("|").each_with_index { |word, wordIndex|
245
- if wordIndex % 2 == 0
246
- f.write("\t\t\t\t<key>#{word}</key>\n")
247
- else
248
- f.write("\t\t\t\t<string>#{word}</string>\n")
249
- end
250
- }
251
- f.write("\t\t\t</dict>\n")
252
- f.write("\t\t</dict>\n")
253
170
  end
171
+
172
+ f.write(line)
254
173
  }
255
- f.write("</dict>\n")
256
- f.write("</plist>\n")
257
174
  end
258
175
  end
259
176
 
260
177
  if platform == "android"
261
- languageDir = language['language']
262
-
263
- if languageDir == base_language
264
- languageDir = "values"
265
- else
266
- languageDir = "values-#{languageDir}"
267
- end
268
-
269
- FileUtils.mkdir_p "#{destinationPath}/#{languageDir}"
270
- File.open("#{destinationPath}/#{languageDir}/strings.xml", "w") do |f|
178
+ FileUtils.mkdir_p "values-#{language['language']}"
179
+ File.open("values-#{language['language']}/strings.xml", "w") do |f|
271
180
  f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
272
181
  f.write("<resources>\n")
273
-
274
- filteredItems = self.filterUnusedRows(language["items"],'identifierAndroid')
275
-
276
- filteredItems.each_with_index { |item, index|
277
-
278
- comment = item['comment']
279
- identifier = item['identifierAndroid']
280
- text = item['text']
281
-
282
- line = ""
283
-
284
- if !comment.to_s.empty?
285
- line = line + "\t<!--#{comment}-->\n"
286
- end
287
-
288
- if text == "" || text == "TBD"
289
- default_language_object = languages.select { |languageItem| languageItem['language'] == defaultLanguage }.first["items"]
290
- default_language_object = self.filterUnusedRows(default_language_object,'identifierAndroid')
291
-
292
- defaultLanguageText = default_language_object[index]['text']
293
- puts "found empty text for:\n\tidentifier: #{identifier}\n\tlanguage:#{language['language']}\n\treplacing it with: #{defaultLanguageText}"
294
- text = defaultLanguageText
295
- end
296
-
297
- text = text.gsub(/\\?'/, "\\\\'")
298
-
299
- if text.include?("one|")
300
-
301
- text = text.gsub("\n", "|")
302
-
303
- line = line + "\t<plurals name=\"#{identifier}\">\n"
304
-
305
- plural = ""
306
-
307
- text.split("|").each_with_index { |word, wordIndex|
308
- if wordIndex % 2 == 0
309
- plural = "\t\t<item quantity=\"#{word}\">"
310
- else
311
- plural = plural + "<![CDATA[\"#{word}\"]]></item>\n"
312
- line = line + plural
313
- end
314
- }
315
- line = line + "\t</plurals>\n"
316
- else
317
- line = line + "\t<string name=\"#{identifier}\"><![CDATA[#{text}]]></string>\n"
318
- end
319
-
320
- f.write(line)
182
+ language["items"].each { |item|
183
+ f.write("\t<!--#{item['comment']}-->\n\t<string name=\"#{item['identifierAndroid']}\"><![CDATA[#{item['text']}]]></string>\n")
321
184
  }
322
185
  f.write("</resources>\n")
323
186
  end
324
187
  end
325
- }
326
188
  end
327
189
 
328
190
  def self.createiOSFileEndString()
329
- return "\n\nprivate class LocalizationHelper { }\n\nextension Localization {\n\tprivate static func localized(identifier key: String, _ args: CVarArg...) -> String {\n\t\tlet format = NSLocalizedString(key, tableName: nil, bundle: Bundle(for: LocalizationHelper.self), comment: \"\")\n\n\t\tguard !args.isEmpty else { return format }\n\n\t\treturn String(format: format, locale: .current, arguments: args)\n\t}\n}"
191
+ return "\n\nextension Localization {\n\tprivate static func localized(identifier key: String, _ args: CVarArg...) -> String {\n\t\tlet format = NSLocalizedString(key, tableName: nil, bundle: Bundle.main, comment: \"\")\n\n\t\tguard !args.isEmpty else { return format }\n\n\t\treturn String(format: format, locale: Locale.current, arguments: args)\n\t}\n}"
330
192
  end
331
193
 
332
194
  def self.createiOSFunction(constantName, identifier, arguments, comment)
333
195
  functionTitle = "\n\t///Sheet comment: #{comment}\n\tpublic static func #{constantName}("
334
196
 
335
197
  arguments.each_with_index do |item, index|
198
+ puts item
336
199
  functionTitle = functionTitle + "_ arg#{index}: #{item[:type]}"
337
200
  if index < arguments.count - 1
338
201
  functionTitle = functionTitle + ", "
@@ -354,11 +217,6 @@ module Fastlane
354
217
  end
355
218
 
356
219
  def self.findArgumentsInText(text)
357
-
358
- if text.include?("one|")
359
- text = text.dup.split("|")[1]
360
- end
361
-
362
220
  result = Array.new
363
221
  filtered = self.mapInvalidPlaceholder(text)
364
222
 
@@ -387,10 +245,15 @@ module Fastlane
387
245
  end
388
246
 
389
247
  def self.mapInvalidPlaceholder(text)
390
- filtered = text.gsub('%s', '%@').gsub('"', '\"')
248
+ filtered = text.gsub('%s', '%@')
391
249
  return filtered
392
250
  end
393
251
 
252
+ def self.numberOfLanguages(worksheet)
253
+ i = worksheet.num_cols
254
+ return i - 3
255
+ end
256
+
394
257
  def self.description
395
258
  "Creates .strings files for iOS and strings.xml files for Android"
396
259
  end
@@ -429,24 +292,8 @@ module Fastlane
429
292
  FastlaneCore::ConfigItem.new(key: :tabs,
430
293
  env_name: "TABS",
431
294
  description: "Array of all Google Sheet Tabs",
432
- default_value: [],
433
- optional: true,
434
- type: Array),
435
- FastlaneCore::ConfigItem.new(key: :language_titles,
436
- env_name: "LANGUAGE_TITLES",
437
- description: "Alle language titles",
438
295
  optional: false,
439
296
  type: Array),
440
- FastlaneCore::ConfigItem.new(key: :default_language,
441
- env_name: "DEFAULT_LANGUAGE",
442
- description: "Default Language",
443
- optional: false,
444
- type: String),
445
- FastlaneCore::ConfigItem.new(key: :base_language,
446
- env_name: "BASE_LANGUAGE",
447
- description: "Base language for Xcode projects",
448
- optional: true,
449
- type: String),
450
297
  FastlaneCore::ConfigItem.new(key: :localization_path,
451
298
  env_name: "LOCALIZATION_PATH",
452
299
  description: "Output path",
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module GoogleSheetLocalize
3
- VERSION = "0.1.20"
3
+ VERSION = "0.1.51"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-google_sheet_localize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20
4
+ version: 0.1.51
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Hahn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-08 00:00:00.000000000 Z
11
+ date: 2019-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: google_drive
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: pry
29
15
  requirement: !ruby/object:Gem::Requirement