fastlane-plugin-lokalise 1.0.1
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +70 -0
- data/lib/fastlane/plugin/lokalise.rb +16 -0
- data/lib/fastlane/plugin/lokalise/actions/add_keys_to_lokalise_action.rb +115 -0
- data/lib/fastlane/plugin/lokalise/actions/lokalise_action.rb +184 -0
- data/lib/fastlane/plugin/lokalise/actions/lokalise_metadata_action.rb +687 -0
- data/lib/fastlane/plugin/lokalise/helper/lokalise_helper.rb +16 -0
- data/lib/fastlane/plugin/lokalise/version.rb +5 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a5e7e187badad268439404f393a092153774eb6778d8732ce92e4379db96546f
|
4
|
+
data.tar.gz: 195d0918db2c6cdfe1d92c721106172c15d5d51214884ed2b04c63d8f12e550f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ecf0b5fda98a53918cb169384e007f7c27bedc6217926fbd3635d9bfc563867ee1e563a6fc62794cc51e216bb95e52bf6b749fdd46e1ab3f67be4af6f0ced5cd
|
7
|
+
data.tar.gz: c63f815688f58cf1344e84db50f67bc7d3a807cefe8f2a8ca673e06c731eb1054efcfccd3ecb6bbbfd94fe1bd6e1dff85d3be864eac706b6519532874b98400e
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Abbas Jaffery <basoukazuma@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Lokalise Fastlane Plugin
|
2
|
+
|
3
|
+
This project is a port of the [lokalise-fastlane-actions](https://github.com/lokalise/lokalise-fastlane-actions) project. The goal is for it to be packaged as a Fastlane Plugin that can be imported as a gem.
|
4
|
+
|
5
|
+
|
6
|
+
## Install
|
7
|
+
|
8
|
+
This can be added with the following command:
|
9
|
+
```bash
|
10
|
+
fastlane add_plugin lokalise
|
11
|
+
```
|
12
|
+
|
13
|
+
Or added to the Pluginfile as:
|
14
|
+
```
|
15
|
+
gem 'fastlane-plugin-lokalise', git: 'https://github.com/BasouKazuma/fastlane-plugin-lokalise'
|
16
|
+
```
|
17
|
+
|
18
|
+
|
19
|
+
## Actions
|
20
|
+
|
21
|
+
### lokalise
|
22
|
+
|
23
|
+
This action downloads .strings and .stringsdict files to destination folder.
|
24
|
+
|
25
|
+
Parameters:
|
26
|
+
|
27
|
+
- `api_token`. Your API token. Can be set up using enviromental parameter `LOKALISE_API_TOKEN`
|
28
|
+
- `project_identifier`. Your Project ID. Can be set up using enviromental parameter `LOKALISE_PROJECT_ID`
|
29
|
+
- `destination`. Localization files destination.
|
30
|
+
- `clean_destination`. Cleans destination folder if set to `true` *(`false` by default)*.
|
31
|
+
- `languages`. Languages to download *(must be passed as array of strings, leave empty to download all)*.
|
32
|
+
- `include_comments`. Include comments in exported files.
|
33
|
+
- `use_original`. Use original filenames/formats.
|
34
|
+
|
35
|
+
### lokalise_metadata
|
36
|
+
|
37
|
+
This action imports metadata from files generated by Deliver action and uploads iTunes Connect metadata using information from Lokalise.
|
38
|
+
|
39
|
+
- `api_token`. Your API token. Can be set up using enviromental parameter `LOKALISE_API_TOKEN`
|
40
|
+
- `project_identifier`. Your Project ID. Can be set up using enviromental parameter `LOKALISE_PROJECT_ID`
|
41
|
+
- `action`. Action to perform *(can be `update_lokalise_itunes`, `download_lokalise_itunes`, `update_itunes`, `update_lokalise_googleplay` or `update_googleplay`)*.
|
42
|
+
- `add_languages`. Add missing languages to lokalise *(`false` by default)*.
|
43
|
+
- `override_translation`. Override translations in lokalise.
|
44
|
+
- `release_number`. Application release number. Required with `update_googleplay` action.
|
45
|
+
- `validate_only`. Only validate the metadata. Used with `update_googleplay` action *(`false` by default)*.
|
46
|
+
|
47
|
+
### add_keys_to_lokalise
|
48
|
+
|
49
|
+
This actions allow you upload keys to Lokalise.
|
50
|
+
|
51
|
+
Parameters:
|
52
|
+
|
53
|
+
- `api_token`. Your API token. Can be set up using enviromental parameter `LOKALISE_API_TOKEN`
|
54
|
+
- `project_identifier`. Your Project ID. Can be set up using enviromental parameter `LOKALISE_PROJECT_ID`
|
55
|
+
- `platform_mask`. Platform mask to asign to keys *(1 is iOS, 2 is Android, 4 is Web and 16 is Other)*.
|
56
|
+
- `keys`. Keys to add *(must be passed as array of strings)*.
|
57
|
+
|
58
|
+
|
59
|
+
## Development
|
60
|
+
|
61
|
+
This can be locally built and installed as a gem by doing the following on the repo:
|
62
|
+
```bash
|
63
|
+
bundle install
|
64
|
+
rake install
|
65
|
+
```
|
66
|
+
|
67
|
+
This can be published using:
|
68
|
+
```bash
|
69
|
+
rake release
|
70
|
+
```
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/lokalise/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Lokalise
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Lokalise.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Actions
|
5
|
+
class AddKeysToLokaliseAction < Action
|
6
|
+
|
7
|
+
|
8
|
+
def self.run(params)
|
9
|
+
|
10
|
+
token = params[:api_token]
|
11
|
+
project_identifier = params[:project_identifier]
|
12
|
+
keys = params[:keys]
|
13
|
+
platform_mask = params[:platform_mask]
|
14
|
+
|
15
|
+
keysObjects = []
|
16
|
+
|
17
|
+
keys.each do |key|
|
18
|
+
keysObjects << {
|
19
|
+
key: key,
|
20
|
+
platform_mask: platform_mask
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
request_data = {
|
25
|
+
api_token: token,
|
26
|
+
id: project_identifier,
|
27
|
+
data: keysObjects.to_json
|
28
|
+
}
|
29
|
+
|
30
|
+
uri = URI("https://api.lokalise.co/api/string/set")
|
31
|
+
request = Net::HTTP::Post.new(uri)
|
32
|
+
request.set_form_data(request_data)
|
33
|
+
|
34
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
35
|
+
http.use_ssl = true
|
36
|
+
response = http.request(request)
|
37
|
+
|
38
|
+
jsonResponse = JSON.parse(response.body)
|
39
|
+
raise "Bad response 🉐\n#{response.body}".red unless jsonResponse.kind_of? Hash
|
40
|
+
if jsonResponse["response"]["status"] == "success" then
|
41
|
+
inserted = jsonResponse["result"]["inserted"]
|
42
|
+
updated = jsonResponse["result"]["updated"]
|
43
|
+
Helper.log.info "Keys uploaded. #{inserted} inserted and #{updated} updated 🚀".green
|
44
|
+
elsif jsonResponse["response"]["status"] == "error"
|
45
|
+
code = jsonResponse["response"]["code"]
|
46
|
+
message = jsonResponse["response"]["message"]
|
47
|
+
raise "Response error code #{code} (#{message}) 📟".red
|
48
|
+
else
|
49
|
+
raise "Bad response 🉐\n#{jsonResponse}".red
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
#####################################################
|
55
|
+
# @!group Documentation
|
56
|
+
#####################################################
|
57
|
+
|
58
|
+
|
59
|
+
def self.description
|
60
|
+
"Add keys to lokalise"
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def self.available_options
|
65
|
+
[
|
66
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
67
|
+
env_name: "LOKALISE_API_TOKEN",
|
68
|
+
description: "API Token for Lokalise",
|
69
|
+
is_string: true,
|
70
|
+
verify_block: proc do |value|
|
71
|
+
raise "No API token for Lokalise given, pass using `api_token: 'token'`".red unless (value and not value.empty?)
|
72
|
+
end),
|
73
|
+
FastlaneCore::ConfigItem.new(key: :project_identifier,
|
74
|
+
env_name: "LOKALISE_PROJECT_ID",
|
75
|
+
description: "Lokalise Project Identifier",
|
76
|
+
is_string: true,
|
77
|
+
verify_block: proc do |value|
|
78
|
+
raise "No Project Identifier for Lokalise given, pass using `project_identifier: 'identifier'`".red unless (value and not value.empty?)
|
79
|
+
end),
|
80
|
+
FastlaneCore::ConfigItem.new(key: :platform_mask,
|
81
|
+
description: "Platform mask where 1 is iOS, 2 is Android, 4 is Web and 16 is Other",
|
82
|
+
optional: true,
|
83
|
+
is_string: false,
|
84
|
+
default_value: 1,
|
85
|
+
verify_block: proc do |value|
|
86
|
+
raise "Platfrom mask is an integer value".red unless value.is_a?(Integer)
|
87
|
+
end),
|
88
|
+
FastlaneCore::ConfigItem.new(key: :keys,
|
89
|
+
description: "Keys to add",
|
90
|
+
optional: false,
|
91
|
+
is_string: false,
|
92
|
+
verify_block: proc do |value|
|
93
|
+
raise "Keys must be passed as array of strings".red unless (value.kind_of? Array and not value.empty?)
|
94
|
+
value.each_with_index do |key, index|
|
95
|
+
raise "Key at index #{index} must be string".red unless key.kind_of? String
|
96
|
+
raise "Key at index #{index} can't be empty".red if key.empty?
|
97
|
+
end
|
98
|
+
end)
|
99
|
+
]
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def self.authors
|
104
|
+
"Fedya-L"
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def self.is_supported?(platform)
|
109
|
+
[:ios, :mac].include? platform
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'zip'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class LokaliseAction < Action
|
8
|
+
|
9
|
+
def self.run(params)
|
10
|
+
|
11
|
+
token = params[:api_token]
|
12
|
+
project_identifier = params[:project_identifier]
|
13
|
+
destination = params[:destination]
|
14
|
+
clean_destination = params[:clean_destination]
|
15
|
+
include_comments = params[:include_comments] ? 1 : 0
|
16
|
+
use_original = params[:use_original] ? 1 : 0
|
17
|
+
|
18
|
+
request_data = {
|
19
|
+
api_token: token,
|
20
|
+
id: project_identifier,
|
21
|
+
type: "strings",
|
22
|
+
use_original: use_original,
|
23
|
+
bundle_filename: "Localization.zip",
|
24
|
+
bundle_structure: "%LANG_ISO%.lproj/Localizable.%FORMAT%",
|
25
|
+
ota_plugin_bundle: 0,
|
26
|
+
export_empty: "base",
|
27
|
+
include_comments: include_comments
|
28
|
+
}
|
29
|
+
|
30
|
+
languages = params[:languages]
|
31
|
+
if languages.kind_of? Array then
|
32
|
+
request_data["langs"] = languages.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
tags = params[:tags]
|
36
|
+
if tags.kind_of? Array then
|
37
|
+
request_data["include_tags"] = tags.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
uri = URI("https://api.lokalise.co/api/project/export")
|
41
|
+
request = Net::HTTP::Post.new(uri)
|
42
|
+
request.set_form_data(request_data)
|
43
|
+
|
44
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
45
|
+
http.use_ssl = true
|
46
|
+
response = http.request(request)
|
47
|
+
|
48
|
+
|
49
|
+
jsonResponse = JSON.parse(response.body)
|
50
|
+
UI.error "Bad response 🉐\n#{response.body}" unless jsonResponse.kind_of? Hash
|
51
|
+
if jsonResponse["response"]["status"] == "success" && jsonResponse["bundle"]["file"].kind_of?(String) then
|
52
|
+
UI.message "Downloading localizations archive 📦"
|
53
|
+
FileUtils.mkdir_p("lokalisetmp")
|
54
|
+
fileURL = jsonResponse["bundle"]["full_file"]
|
55
|
+
uri = URI(fileURL)
|
56
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
57
|
+
http.use_ssl = true
|
58
|
+
zipRequest = Net::HTTP::Get.new(uri)
|
59
|
+
response = http.request(zipRequest)
|
60
|
+
if response.content_type == "application/zip" or response.content_type == "application/octet-stream" then
|
61
|
+
FileUtils.mkdir_p("lokalisetmp")
|
62
|
+
open("lokalisetmp/a.zip", "wb") { |file|
|
63
|
+
file.write(response.body)
|
64
|
+
}
|
65
|
+
unzip_file("lokalisetmp/a.zip", destination, clean_destination)
|
66
|
+
FileUtils.remove_dir("lokalisetmp")
|
67
|
+
UI.success "Localizations extracted to #{destination} 📗 📕 📘"
|
68
|
+
else
|
69
|
+
UI.error "Response did not include ZIP"
|
70
|
+
end
|
71
|
+
elsif jsonResponse["response"]["status"] == "error"
|
72
|
+
code = jsonResponse["response"]["code"]
|
73
|
+
message = jsonResponse["response"]["message"]
|
74
|
+
UI.error "Response error code #{code} (#{message}) 📟"
|
75
|
+
else
|
76
|
+
UI.error "Bad response 🉐\n#{jsonResponse}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def self.unzip_file(file, destination, clean_destination)
|
82
|
+
Zip::File.open(file) { |zip_file|
|
83
|
+
if clean_destination then
|
84
|
+
UI.message "Cleaning destination folder ♻️"
|
85
|
+
FileUtils.remove_dir(destination)
|
86
|
+
FileUtils.mkdir_p(destination)
|
87
|
+
end
|
88
|
+
UI.message "Unarchiving localizations to destination 📚"
|
89
|
+
zip_file.each { |f|
|
90
|
+
f_path= File.join(destination, f.name)
|
91
|
+
FileUtils.mkdir_p(File.dirname(f_path))
|
92
|
+
FileUtils.rm(f_path) if File.file? f_path
|
93
|
+
zip_file.extract(f, f_path)
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
#####################################################
|
100
|
+
# @!group Documentation
|
101
|
+
#####################################################
|
102
|
+
|
103
|
+
|
104
|
+
def self.description
|
105
|
+
"Download Lokalise localization"
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def self.available_options
|
110
|
+
[
|
111
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
112
|
+
env_name: "LOKALISE_API_TOKEN",
|
113
|
+
description: "API Token for Lokalise",
|
114
|
+
verify_block: proc do |value|
|
115
|
+
UI.user_error! "No API token for Lokalise given, pass using `api_token: 'token'`" unless (value and not value.empty?)
|
116
|
+
end),
|
117
|
+
FastlaneCore::ConfigItem.new(key: :project_identifier,
|
118
|
+
env_name: "LOKALISE_PROJECT_ID",
|
119
|
+
description: "Lokalise Project ID",
|
120
|
+
verify_block: proc do |value|
|
121
|
+
UI.user_error! "No Project Identifier for Lokalise given, pass using `project_identifier: 'identifier'`" unless (value and not value.empty?)
|
122
|
+
end),
|
123
|
+
FastlaneCore::ConfigItem.new(key: :destination,
|
124
|
+
description: "Localization destination",
|
125
|
+
verify_block: proc do |value|
|
126
|
+
UI.user_error! "Things are pretty bad" unless (value and not value.empty?)
|
127
|
+
UI.user_error! "Directory you passed is in your imagination" unless File.directory?(value)
|
128
|
+
end),
|
129
|
+
FastlaneCore::ConfigItem.new(key: :clean_destination,
|
130
|
+
description: "Clean destination folder",
|
131
|
+
optional: true,
|
132
|
+
is_string: false,
|
133
|
+
default_value: false,
|
134
|
+
verify_block: proc do |value|
|
135
|
+
UI.user_error! "Clean destination should be true or false" unless [true, false].include? value
|
136
|
+
end),
|
137
|
+
FastlaneCore::ConfigItem.new(key: :languages,
|
138
|
+
description: "Languages to download",
|
139
|
+
optional: true,
|
140
|
+
is_string: false,
|
141
|
+
verify_block: proc do |value|
|
142
|
+
UI.user_error! "Language codes should be passed as array" unless value.kind_of? Array
|
143
|
+
end),
|
144
|
+
FastlaneCore::ConfigItem.new(key: :include_comments,
|
145
|
+
description: "Include comments in exported files",
|
146
|
+
optional: true,
|
147
|
+
is_string: false,
|
148
|
+
default_value: false,
|
149
|
+
verify_block: proc do |value|
|
150
|
+
UI.user_error! "Include comments should be true or false" unless [true, false].include? value
|
151
|
+
end),
|
152
|
+
FastlaneCore::ConfigItem.new(key: :use_original,
|
153
|
+
description: "Use original filenames/formats (bundle_structure parameter is ignored then)",
|
154
|
+
optional: true,
|
155
|
+
is_string: false,
|
156
|
+
default_value: false,
|
157
|
+
verify_block: proc do |value|
|
158
|
+
UI.user_error! "Use original should be true of false." unless [true, false].include?(value)
|
159
|
+
end),
|
160
|
+
FastlaneCore::ConfigItem.new(key: :tags,
|
161
|
+
description: "Include only the keys tagged with a given set of tags",
|
162
|
+
optional: true,
|
163
|
+
is_string: false,
|
164
|
+
verify_block: proc do |value|
|
165
|
+
UI.user_error! "Tags should be passed as array" unless value.kind_of? Array
|
166
|
+
end),
|
167
|
+
|
168
|
+
]
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
def self.authors
|
173
|
+
"Fedya-L"
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def self.is_supported?(platform)
|
178
|
+
[:ios, :mac].include? platform
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,687 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Actions
|
5
|
+
class LokaliseMetadataAction < Action
|
6
|
+
|
7
|
+
@params
|
8
|
+
def self.run(params)
|
9
|
+
@params = params
|
10
|
+
action = params[:action]
|
11
|
+
|
12
|
+
case action
|
13
|
+
when "update_itunes"
|
14
|
+
key_file = metadata_key_file_itunes()
|
15
|
+
metadata = get_metadata_from_lokalise_itunes()
|
16
|
+
run_deliver_action(metadata)
|
17
|
+
when "download_lokalise_itunes"
|
18
|
+
key_file = metadata_key_file_itunes()
|
19
|
+
metadata = get_metadata_from_lokalise_itunes()
|
20
|
+
write_lokalise_translations_to_itunes_metadata(metadata)
|
21
|
+
when "update_googleplay"
|
22
|
+
release_number = params[:release_number]
|
23
|
+
UI.user_error! "Release number is required when using `update_googleplay` action (should be an integer and greater that 0)" unless (release_number and release_number.is_a?(Integer) and release_number > 0)
|
24
|
+
key_file = metadata_key_file_googleplay
|
25
|
+
metadata = get_metadata_from_lokalise_googleplay()
|
26
|
+
save_metadata_to_files(metadata, release_number)
|
27
|
+
run_supply_action(params[:validate_only])
|
28
|
+
when "update_lokalise_itunes"
|
29
|
+
metadata = get_metadata_itunes_connect()
|
30
|
+
add_languages = params[:add_languages]
|
31
|
+
override_translation = params[:override_translation]
|
32
|
+
if add_languages == true
|
33
|
+
create_languages(metadata.keys, true)
|
34
|
+
end
|
35
|
+
if override_translation == true
|
36
|
+
upload_metadata_itunes(metadata) unless metadata.empty?
|
37
|
+
else
|
38
|
+
lokalise_metadata = get_metadata_from_lokalise_itunes()
|
39
|
+
filtered_metadata = filter_metadata(metadata, lokalise_metadata)
|
40
|
+
upload_metadata_itunes(filtered_metadata) unless filtered_metadata.empty?
|
41
|
+
end
|
42
|
+
when "update_lokalise_googleplay"
|
43
|
+
metadata = get_metadata_google_play()
|
44
|
+
add_languages = params[:add_languages]
|
45
|
+
override_translation = params[:override_translation]
|
46
|
+
if add_languages == true
|
47
|
+
create_languages(metadata.keys, false)
|
48
|
+
end
|
49
|
+
if override_translation == true
|
50
|
+
upload_metadata_google_play(metadata) unless metadata.empty?
|
51
|
+
else
|
52
|
+
lokalise_metadata = get_metadata_from_lokalise_googleplay()
|
53
|
+
filtered_metadata = filter_metadata(metadata, lokalise_metadata)
|
54
|
+
upload_metadata_google_play(filtered_metadata) unless filtered_metadata.empty?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def self.create_languages(languages, for_itunes)
|
61
|
+
data = {
|
62
|
+
iso: languages.map { |language| fix_language_name(language, for_itunes, true) } .to_json
|
63
|
+
}
|
64
|
+
make_request("language/add", data)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def self.filter_metadata(metadata, other_metadata)
|
69
|
+
filtered_metadata = {}
|
70
|
+
metadata.each { |language, translations|
|
71
|
+
other_translations = other_metadata[language]
|
72
|
+
filtered_translations = {}
|
73
|
+
|
74
|
+
if other_translations != nil && other_translations.empty? == false
|
75
|
+
translations.each { |key, value|
|
76
|
+
other_value = other_translations[key]
|
77
|
+
filtered_translations[key] = value unless other_value != nil && other_value.empty? == false
|
78
|
+
}
|
79
|
+
else
|
80
|
+
filtered_translations = translations
|
81
|
+
end
|
82
|
+
|
83
|
+
filtered_metadata[language] = filtered_translations unless filtered_translations.empty?
|
84
|
+
}
|
85
|
+
return filtered_metadata
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
def self.write_lokalise_translations_to_itunes_metadata(metadata)
|
90
|
+
metadata_key_file_itunes().each { |key, parameter|
|
91
|
+
final_translations = {}
|
92
|
+
metadata.each { |lang, translations|
|
93
|
+
if translations.empty? == false
|
94
|
+
translation = translations[key]
|
95
|
+
final_translations[lang] = translation if translation != nil && translation.empty? == false
|
96
|
+
path = File.join('.', 'fastlane', 'metadata', lang)
|
97
|
+
filename = "#{parameter}.txt"
|
98
|
+
output_file = File.join(path, filename)
|
99
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
100
|
+
puts "Updating '#{output_file}'..."
|
101
|
+
File.open(output_file, 'wb') do |file|
|
102
|
+
file.write(final_translations[lang])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
}
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def self.run_deliver_action(metadata)
|
111
|
+
config = FastlaneCore::Configuration.create(Actions::DeliverAction.available_options, {})
|
112
|
+
config.load_configuration_file("Deliverfile")
|
113
|
+
config[:metadata_path] = "./fastlane/no_metadata"
|
114
|
+
config[:screenshots_path] = "./fastlane/no_screenshot"
|
115
|
+
config[:skip_screenshots] = true
|
116
|
+
config[:run_precheck_before_submit] = false
|
117
|
+
config[:skip_binary_upload] = true
|
118
|
+
config[:skip_app_version_update] = true
|
119
|
+
config[:force] = true
|
120
|
+
|
121
|
+
metadata_key_file_itunes().each { |key, parameter|
|
122
|
+
final_translations = {}
|
123
|
+
|
124
|
+
metadata.each { |lang, translations|
|
125
|
+
if translations.empty? == false
|
126
|
+
translation = translations[key]
|
127
|
+
final_translations[lang] = translation if translation != nil && translation.empty? == false
|
128
|
+
end
|
129
|
+
}
|
130
|
+
|
131
|
+
config[parameter.to_sym] = final_translations
|
132
|
+
}
|
133
|
+
|
134
|
+
Actions::DeliverAction.run(config)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def self.run_supply_action(validate_only)
|
139
|
+
config = FastlaneCore::Configuration.create(Actions::SupplyAction.available_options, {})
|
140
|
+
config[:skip_upload_apk] = true
|
141
|
+
config[:skip_upload_aab] = true
|
142
|
+
config[:skip_upload_screenshots] = true
|
143
|
+
config[:skip_upload_images] = true
|
144
|
+
config[:validate_only] = validate_only
|
145
|
+
|
146
|
+
Actions::SupplyAction.run(config)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def self.save_metadata_to_files(metadata, release_number)
|
151
|
+
|
152
|
+
translations = {}
|
153
|
+
|
154
|
+
metadata_key_file_googleplay().each { |key, parameter|
|
155
|
+
final_translations = {}
|
156
|
+
|
157
|
+
metadata.each { |lang, translations|
|
158
|
+
if translations.empty? == false
|
159
|
+
translation = translations[key]
|
160
|
+
final_translations[lang] = translation if translation != nil && translation.empty? == false
|
161
|
+
end
|
162
|
+
}
|
163
|
+
|
164
|
+
translations[parameter.to_sym] = final_translations
|
165
|
+
}
|
166
|
+
|
167
|
+
FileUtils.rm_rf(Dir['fastlane/metadata/android/*'])
|
168
|
+
|
169
|
+
translations.each { |key, parameter|
|
170
|
+
parameter.each { |lang, text|
|
171
|
+
path = "fastlane/metadata/android/#{lang}/#{key}.txt"
|
172
|
+
if "#{key}" == "changelogs"
|
173
|
+
path = "fastlane/metadata/android/#{lang}/changelogs/#{release_number}.txt"
|
174
|
+
end
|
175
|
+
dirname = File.dirname(path)
|
176
|
+
unless File.directory?(dirname)
|
177
|
+
FileUtils.mkdir_p(dirname)
|
178
|
+
end
|
179
|
+
File.write(path, text)
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
def self.make_request(path, data)
|
187
|
+
|
188
|
+
request_data = {
|
189
|
+
api_token: @params[:api_token],
|
190
|
+
id: @params[:project_identifier]
|
191
|
+
}.merge(data)
|
192
|
+
|
193
|
+
uri = URI("https://api.lokalise.co/api/#{path}")
|
194
|
+
request = Net::HTTP::Post.new(uri)
|
195
|
+
request.set_form_data(request_data)
|
196
|
+
|
197
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
198
|
+
http.use_ssl = true
|
199
|
+
response = http.request(request)
|
200
|
+
|
201
|
+
jsonResponse = JSON.parse(response.body)
|
202
|
+
raise "Bad response 🉐\n#{response.body}" unless jsonResponse.kind_of? Hash
|
203
|
+
if jsonResponse["response"]["status"] == "success" then
|
204
|
+
UI.success "Response #{jsonResponse} 🚀"
|
205
|
+
elsif jsonResponse["response"]["status"] == "error"
|
206
|
+
code = jsonResponse["response"]["code"]
|
207
|
+
message = jsonResponse["response"]["message"]
|
208
|
+
raise "Response error code #{code} (#{message}) 📟"
|
209
|
+
else
|
210
|
+
raise "Bad response 🉐\n#{jsonResponse}"
|
211
|
+
end
|
212
|
+
return jsonResponse
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
def self.upload_metadata(metadata_keys, for_itunes, metadata)
|
217
|
+
|
218
|
+
keys = []
|
219
|
+
|
220
|
+
metadata_keys.each do |key, value|
|
221
|
+
key = make_key_object_from_metadata(key, metadata, for_itunes)
|
222
|
+
if key
|
223
|
+
keys << key
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
data = {
|
228
|
+
data: keys.to_json
|
229
|
+
}
|
230
|
+
|
231
|
+
make_request("string/set", data)
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
def self.upload_metadata_itunes(metadata)
|
236
|
+
upload_metadata(metadata_key_file_itunes, true, metadata)
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
def self.upload_metadata_google_play(metadata)
|
241
|
+
upload_metadata(metadata_key_file_googleplay, false, metadata)
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
def self.make_key_object_from_metadata(key, metadata, for_itunes)
|
246
|
+
key_data = {
|
247
|
+
"key" => key,
|
248
|
+
"platform_mask" => 16,
|
249
|
+
"translations" => {}
|
250
|
+
}
|
251
|
+
metadata.each { |iso_code, data|
|
252
|
+
translation = data[key]
|
253
|
+
unless translation == nil || translation.empty?
|
254
|
+
key_data["translations"][fix_language_name(iso_code, for_itunes, true)] = translation
|
255
|
+
end
|
256
|
+
}
|
257
|
+
unless key_data["translations"].empty?
|
258
|
+
return key_data
|
259
|
+
else
|
260
|
+
return nil
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
def self.get_metadata_google_play()
|
266
|
+
available_languages = google_play_languages
|
267
|
+
return get_metadata(available_languages, "fastlane/metadata/android/", false)
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
def self.get_metadata_itunes_connect()
|
272
|
+
available_languages = itunes_connect_languages
|
273
|
+
return get_metadata(available_languages, "fastlane/metadata/", true)
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
def self.get_metadata(available_languages, folder, for_itunes)
|
278
|
+
complete_metadata = {}
|
279
|
+
|
280
|
+
available_languages.each { |iso_code|
|
281
|
+
language_directory = "#{folder}#{iso_code}"
|
282
|
+
if Dir.exist? language_directory
|
283
|
+
language_metadata = {}
|
284
|
+
if for_itunes
|
285
|
+
metadata_key_file_itunes().each { |key, file|
|
286
|
+
populate_hash_key_from_file(language_metadata, key, language_directory + "/#{file}.txt")
|
287
|
+
}
|
288
|
+
else
|
289
|
+
metadata_key_file_googleplay().each { |key, file|
|
290
|
+
if file == "changelogs"
|
291
|
+
changelog_directory = "#{folder}#{iso_code}/changelogs"
|
292
|
+
files = Dir.entries("#{changelog_directory}")
|
293
|
+
collectedFiles = files.collect { |s| s.partition(".").first.to_i }
|
294
|
+
sortedFiles = collectedFiles.sort
|
295
|
+
populate_hash_key_from_file(language_metadata, key, language_directory + "/changelogs/#{sortedFiles.last}.txt")
|
296
|
+
else
|
297
|
+
populate_hash_key_from_file(language_metadata, key, language_directory + "/#{file}.txt")
|
298
|
+
end
|
299
|
+
}
|
300
|
+
end
|
301
|
+
complete_metadata[iso_code] = language_metadata
|
302
|
+
end
|
303
|
+
}
|
304
|
+
|
305
|
+
return complete_metadata
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
def self.get_metadata_from_lokalise(valid_keys, for_itunes)
|
310
|
+
|
311
|
+
data = {
|
312
|
+
platform_mask: 16,
|
313
|
+
keys: valid_keys.to_json,
|
314
|
+
}
|
315
|
+
|
316
|
+
response = make_request("string/list", data)
|
317
|
+
|
318
|
+
if for_itunes
|
319
|
+
valid_languages = itunes_connect_languages_in_lokalise()
|
320
|
+
else
|
321
|
+
valid_languages = google_play_languages_in_lokalise()
|
322
|
+
end
|
323
|
+
metadata = {}
|
324
|
+
|
325
|
+
response["strings"].each { |lang, translation_objects|
|
326
|
+
if valid_languages.include?(lang)
|
327
|
+
translations = {}
|
328
|
+
translation_objects.each { |object|
|
329
|
+
if for_itunes
|
330
|
+
key = object["key_ios"]
|
331
|
+
else
|
332
|
+
key = object["key_android"]
|
333
|
+
end
|
334
|
+
translation = object["translation"]
|
335
|
+
if valid_keys.include?(key) && translation != nil && translation.empty? == false
|
336
|
+
translations[key] = translation
|
337
|
+
end
|
338
|
+
}
|
339
|
+
if translations.empty? == false
|
340
|
+
metadata[fix_language_name(lang, for_itunes)] = translations
|
341
|
+
end
|
342
|
+
end
|
343
|
+
}
|
344
|
+
return metadata
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
|
349
|
+
def self.get_metadata_from_lokalise_itunes()
|
350
|
+
valid_keys = metadata_keys_itunes()
|
351
|
+
return get_metadata_from_lokalise(valid_keys, true)
|
352
|
+
end
|
353
|
+
|
354
|
+
|
355
|
+
def self.get_metadata_from_lokalise_googleplay()
|
356
|
+
valid_keys = metadata_keys_googleplay()
|
357
|
+
return get_metadata_from_lokalise(valid_keys, false)
|
358
|
+
end
|
359
|
+
|
360
|
+
|
361
|
+
def self.populate_hash_key_from_file(hash, key, filepath)
|
362
|
+
begin
|
363
|
+
text = File.read filepath
|
364
|
+
text.chomp!
|
365
|
+
hash[key] = text unless text.empty?
|
366
|
+
rescue => exception
|
367
|
+
raise exception
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
|
372
|
+
def self.metadata_keys_itunes()
|
373
|
+
return metadata_key_file_itunes().keys
|
374
|
+
end
|
375
|
+
|
376
|
+
|
377
|
+
def self.metadata_keys_googleplay()
|
378
|
+
return metadata_key_file_googleplay().keys
|
379
|
+
end
|
380
|
+
|
381
|
+
|
382
|
+
def self.metadata_key_file_itunes()
|
383
|
+
return {
|
384
|
+
"appstore.app.name" => "name",
|
385
|
+
"appstore.app.description" => "description",
|
386
|
+
"appstore.app.keywords" => "keywords",
|
387
|
+
"appstore.app.promotional_text" => "promotional_text",
|
388
|
+
"appstore.app.release_notes" => "release_notes",
|
389
|
+
"appstore.app.subtitle" => "subtitle",
|
390
|
+
"appstore.app.marketing_url" => "marketing_url",
|
391
|
+
"appstore.app.privacy_url" => "privacy_url",
|
392
|
+
"appstore.app.support_url" => "support_url",
|
393
|
+
}
|
394
|
+
end
|
395
|
+
|
396
|
+
|
397
|
+
def self.metadata_key_file_googleplay()
|
398
|
+
return {
|
399
|
+
"googleplay.app.title" => "title",
|
400
|
+
"googleplay.app.full_description" => "full_description",
|
401
|
+
"googleplay.app.short_description" => "short_description",
|
402
|
+
"googleplay.app.changelogs" => "changelogs",
|
403
|
+
}
|
404
|
+
end
|
405
|
+
|
406
|
+
|
407
|
+
def self.itunes_connect_languages_in_lokalise()
|
408
|
+
return itunes_connect_languages().map { |lang|
|
409
|
+
fix_language_name(lang, true, true)
|
410
|
+
}
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
def self.google_play_languages_in_lokalise()
|
415
|
+
return google_play_languages().map { |lang|
|
416
|
+
fix_language_name(lang, false, true)
|
417
|
+
}
|
418
|
+
end
|
419
|
+
|
420
|
+
|
421
|
+
def self.itunes_connect_languages()
|
422
|
+
return [
|
423
|
+
"cs",
|
424
|
+
"da",
|
425
|
+
"de-DE",
|
426
|
+
"el",
|
427
|
+
"en-AU",
|
428
|
+
"en-CA",
|
429
|
+
"en-GB",
|
430
|
+
"en-US",
|
431
|
+
"es-MX",
|
432
|
+
"es-ES",
|
433
|
+
"fi",
|
434
|
+
"fr-FR",
|
435
|
+
"fr-CA",
|
436
|
+
"id",
|
437
|
+
"it",
|
438
|
+
"ja",
|
439
|
+
"ko",
|
440
|
+
"ms",
|
441
|
+
"nl-NL",
|
442
|
+
"no",
|
443
|
+
"pt-BR",
|
444
|
+
"pt-PT",
|
445
|
+
"ru",
|
446
|
+
"sv",
|
447
|
+
"th",
|
448
|
+
"tr",
|
449
|
+
"vi",
|
450
|
+
"zh-Hans",
|
451
|
+
"zh-Hant"
|
452
|
+
]
|
453
|
+
end
|
454
|
+
|
455
|
+
|
456
|
+
def self.google_play_languages()
|
457
|
+
return [
|
458
|
+
'af',
|
459
|
+
'am',
|
460
|
+
'ar',
|
461
|
+
'hy',
|
462
|
+
'az-AZ',
|
463
|
+
'eu-ES',
|
464
|
+
'be',
|
465
|
+
'bn-BD',
|
466
|
+
'bg',
|
467
|
+
'my',
|
468
|
+
'ca',
|
469
|
+
'zh-CN',
|
470
|
+
'zh-TW',
|
471
|
+
'zh-HK',
|
472
|
+
'hr',
|
473
|
+
'cs',
|
474
|
+
'da',
|
475
|
+
'nl-NL',
|
476
|
+
'en-AU',
|
477
|
+
'en-CA',
|
478
|
+
'en-IN',
|
479
|
+
'en-SG',
|
480
|
+
'en-ZA',
|
481
|
+
'en-GB',
|
482
|
+
'en-US',
|
483
|
+
'et-EE',
|
484
|
+
'fil',
|
485
|
+
'fi',
|
486
|
+
'fr-CA',
|
487
|
+
'fr-FR',
|
488
|
+
'gl-ES',
|
489
|
+
'ka-GE',
|
490
|
+
'de-DE',
|
491
|
+
'el-GR',
|
492
|
+
'he',
|
493
|
+
'hi-IN',
|
494
|
+
'hu',
|
495
|
+
'is-IS',
|
496
|
+
'id',
|
497
|
+
'it-IT',
|
498
|
+
'ja',
|
499
|
+
'kn-IN',
|
500
|
+
'km-KH',
|
501
|
+
'ko',
|
502
|
+
'ky',
|
503
|
+
'lo',
|
504
|
+
'lv-LV',
|
505
|
+
'lt-LT',
|
506
|
+
'mk-MK',
|
507
|
+
'ms',
|
508
|
+
'ml-IN',
|
509
|
+
'mr',
|
510
|
+
'mn-MN',
|
511
|
+
'ne-NP',
|
512
|
+
'no',
|
513
|
+
'fa',
|
514
|
+
'pl',
|
515
|
+
'pt-BR',
|
516
|
+
'pt-PT',
|
517
|
+
'ro',
|
518
|
+
'ru-RU',
|
519
|
+
'sr',
|
520
|
+
'si',
|
521
|
+
'sk',
|
522
|
+
'sl-SI',
|
523
|
+
'es-419',
|
524
|
+
'es-ES',
|
525
|
+
'es-US',
|
526
|
+
'sw',
|
527
|
+
'sv-SE',
|
528
|
+
'ta-IN',
|
529
|
+
'te-IN',
|
530
|
+
'th',
|
531
|
+
'tr',
|
532
|
+
'uk',
|
533
|
+
'vi',
|
534
|
+
'zu'
|
535
|
+
]
|
536
|
+
end
|
537
|
+
|
538
|
+
|
539
|
+
def self.fix_language_name(name, for_itunes, for_lokalise = false)
|
540
|
+
if for_itunes
|
541
|
+
if for_lokalise
|
542
|
+
name = name.gsub("-","_")
|
543
|
+
name = "en" if name == "en_US"
|
544
|
+
name = "de" if name == "de_DE"
|
545
|
+
name = "es" if name == "es_ES"
|
546
|
+
name = "fr" if name == "fr_FR"
|
547
|
+
else
|
548
|
+
name = name.gsub("_","-")
|
549
|
+
name = "en-US" if name == "en"
|
550
|
+
name = "de-DE" if name == "de"
|
551
|
+
name = "es-ES" if name == "es"
|
552
|
+
name = "fr-FR" if name == "fr"
|
553
|
+
end
|
554
|
+
else
|
555
|
+
if for_lokalise
|
556
|
+
name = name.gsub("-","_")
|
557
|
+
name = "tr" if name == "tr_TR"
|
558
|
+
name = "hy" if name == "hy_AM"
|
559
|
+
name = "my" if name == "my_MM"
|
560
|
+
name = "ms" if name == "ms_MY"
|
561
|
+
name = "cs" if name == "cs_CZ"
|
562
|
+
name = "da" if name == "da_DK"
|
563
|
+
name = "et_EE" if name == "et"
|
564
|
+
name = "fi" if name == "fi_FI"
|
565
|
+
name = "he" if name == "iw_IL"
|
566
|
+
name = "hu" if name == "hu_HU"
|
567
|
+
name = "ja" if name == "ja_JP"
|
568
|
+
name = "ko" if name == "ko_KR"
|
569
|
+
name = "ky" if name == "ky_KG"
|
570
|
+
name = "lo" if name == "lo_LA"
|
571
|
+
name = "lv_LV" if name == "lv"
|
572
|
+
name = "lt_LT" if name == "lt"
|
573
|
+
name = "mr" if name == "mr_IN"
|
574
|
+
name = "no" if name == "no_NO"
|
575
|
+
name = "pl" if name == "pl_PL"
|
576
|
+
name = "si" if name == "si_LK"
|
577
|
+
name = "sl_SI" if name == "sl"
|
578
|
+
else
|
579
|
+
name = name.gsub("_","-")
|
580
|
+
name = "tr-TR" if name == "tr"
|
581
|
+
name = "hy-AM" if name == "hy"
|
582
|
+
name = "my-MM" if name == "my"
|
583
|
+
name = "ms-MY" if name == "ms"
|
584
|
+
name = "cs-CZ" if name == "cs"
|
585
|
+
name = "da-DK" if name == "da"
|
586
|
+
name = "et" if name == "et-EE"
|
587
|
+
name = "fi-FI" if name == "fi"
|
588
|
+
name = "iw-IL" if name == "he"
|
589
|
+
name = "hu-HU" if name == "hu"
|
590
|
+
name = "ja-JP" if name == "ja"
|
591
|
+
name = "ko-KR" if name == "ko"
|
592
|
+
name = "ky-KG" if name == "ky"
|
593
|
+
name = "lo-LA" if name == "lo"
|
594
|
+
name = "lv" if name == "lv-LV"
|
595
|
+
name = "lt" if name == "lt-LT"
|
596
|
+
name = "mr-IN" if name == "mr"
|
597
|
+
name = "no-NO" if name == "no"
|
598
|
+
name = "pl-PL" if name == "pl"
|
599
|
+
name = "si-LK" if name == "si"
|
600
|
+
name = "sl" if name == "sl-SI"
|
601
|
+
end
|
602
|
+
end
|
603
|
+
return name
|
604
|
+
end
|
605
|
+
|
606
|
+
|
607
|
+
#####################################################
|
608
|
+
# @!group Documentation
|
609
|
+
#####################################################
|
610
|
+
|
611
|
+
|
612
|
+
def self.description
|
613
|
+
"Upload metadata to lokalise."
|
614
|
+
end
|
615
|
+
|
616
|
+
|
617
|
+
def self.details
|
618
|
+
"This action scans fastlane/metadata folder and uploads metadata to lokalise.co"
|
619
|
+
end
|
620
|
+
|
621
|
+
|
622
|
+
def self.available_options
|
623
|
+
[
|
624
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
625
|
+
env_name: "LOKALISE_API_TOKEN",
|
626
|
+
description: "API Token for Lokalise",
|
627
|
+
verify_block: proc do |value|
|
628
|
+
UI.user_error! "No API token for Lokalise given, pass using `api_token: 'token'`" unless (value and not value.empty?)
|
629
|
+
end),
|
630
|
+
FastlaneCore::ConfigItem.new(key: :project_identifier,
|
631
|
+
env_name: "LOKALISE_PROJECT_ID",
|
632
|
+
description: "Lokalise Project ID",
|
633
|
+
verify_block: proc do |value|
|
634
|
+
UI.user_error! "No Project Identifier for Lokalise given, pass using `project_identifier: 'identifier'`" unless (value and not value.empty?)
|
635
|
+
end),
|
636
|
+
FastlaneCore::ConfigItem.new(key: :add_languages,
|
637
|
+
description: "Add missing languages in lokalise",
|
638
|
+
optional: true,
|
639
|
+
is_string: false,
|
640
|
+
default_value: false,
|
641
|
+
verify_block: proc do |value|
|
642
|
+
UI.user_error! "Add languages should be true or false" unless [true, false].include? value
|
643
|
+
end),
|
644
|
+
FastlaneCore::ConfigItem.new(key: :override_translation,
|
645
|
+
description: "Override translations in lokalise",
|
646
|
+
optional: true,
|
647
|
+
is_string: false,
|
648
|
+
default_value: false,
|
649
|
+
verify_block: proc do |value|
|
650
|
+
UI.user_error! "Override translation should be true or false" unless [true, false].include? value
|
651
|
+
end),
|
652
|
+
FastlaneCore::ConfigItem.new(key: :action,
|
653
|
+
description: "Action to perform (can be update_lokalise_itunes or update_lokalise_googleplay or update_itunes or update_googleplay)",
|
654
|
+
optional: false,
|
655
|
+
is_string: true,
|
656
|
+
verify_block: proc do |value|
|
657
|
+
UI.user_error! "Action should be update_lokalise_googleplay or update_lokalise_itunes or update_itunes or update_googleplay" unless ["update_lokalise_itunes", "download_lokalise_itunes", "update_lokalise_googleplay", "update_itunes", "update_googleplay"].include? value
|
658
|
+
end),
|
659
|
+
FastlaneCore::ConfigItem.new(key: :release_number,
|
660
|
+
description: "Release number is required to update google play",
|
661
|
+
optional: true,
|
662
|
+
is_string: false),
|
663
|
+
FastlaneCore::ConfigItem.new(key: :validate_only,
|
664
|
+
description: "Only validate the metadata (works with only update_googleplay action)",
|
665
|
+
optional: true,
|
666
|
+
is_string: false,
|
667
|
+
default_value: false,
|
668
|
+
verify_block: proc do |value|
|
669
|
+
UI.user_error! "Validate only should be true or false" unless [true, false].include? value
|
670
|
+
end),
|
671
|
+
]
|
672
|
+
end
|
673
|
+
|
674
|
+
|
675
|
+
def self.authors
|
676
|
+
["Fedya-L"]
|
677
|
+
end
|
678
|
+
|
679
|
+
|
680
|
+
def self.is_supported?(platform)
|
681
|
+
[:ios, :mac].include? platform
|
682
|
+
end
|
683
|
+
|
684
|
+
|
685
|
+
end
|
686
|
+
end
|
687
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
5
|
+
|
6
|
+
module Helper
|
7
|
+
class LokaliseHelper
|
8
|
+
# class methods that you define here become available in your action
|
9
|
+
# as `Helper::LokaliseHelper.your_method`
|
10
|
+
#
|
11
|
+
def self.show_message
|
12
|
+
UI.message("Hello from the lokalise plugin helper!")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-lokalise
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Abbas Jaffery
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: zip
|
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
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
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: bundler
|
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: rspec
|
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: rspec_junit_formatter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.49.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.49.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-require_tools
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: fastlane
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.112.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.112.0
|
153
|
+
description:
|
154
|
+
email: basoukazuma@gmail.com
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- LICENSE
|
160
|
+
- README.md
|
161
|
+
- lib/fastlane/plugin/lokalise.rb
|
162
|
+
- lib/fastlane/plugin/lokalise/actions/add_keys_to_lokalise_action.rb
|
163
|
+
- lib/fastlane/plugin/lokalise/actions/lokalise_action.rb
|
164
|
+
- lib/fastlane/plugin/lokalise/actions/lokalise_metadata_action.rb
|
165
|
+
- lib/fastlane/plugin/lokalise/helper/lokalise_helper.rb
|
166
|
+
- lib/fastlane/plugin/lokalise/version.rb
|
167
|
+
homepage: https://github.com/BasouKazuma/fastlane-plugin-lokalise
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
metadata: {}
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
requirements: []
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 2.7.7
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Sync metadata with Lokalise
|
191
|
+
test_files: []
|