fastlane-plugin-google_sheet_localize 0.1.20 → 0.1.51

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 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