gym 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -0
- data/lib/gym/detect_values.rb +0 -3
- data/lib/gym/generators/package_command_generator.rb +16 -0
- data/lib/gym/generators/package_command_generator_legacy.rb +16 -0
- data/lib/gym/generators/package_command_generator_xcode7.rb +88 -7
- data/lib/gym/options.rb +21 -4
- data/lib/gym/runner.rb +55 -1
- data/lib/gym/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13c9c96a7e6c5750ce9478d68136427daf2a7c4b
|
4
|
+
data.tar.gz: afb3993a8d061a0af1e1573ac0d5901eecf457a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a77d189a4dede36bd556e06a5541276096bbb7b7f1de9b5794839c0204a969eccb0952d4bcd3332b40ea0bc13dd5a7fb90a875e01810345700b4ad67808eab62
|
7
|
+
data.tar.gz: 500a09c5d97e61643a4a1879dfedb5dfe4720e13a79171777d1922afeee9fc962706315e9b65fda382de594199e3bf5c500ce40eea4dcfdfc5b9f0612a2a7753
|
data/README.md
CHANGED
@@ -158,6 +158,28 @@ output_directory "./build" # store the ipa in this folder
|
|
158
158
|
output_name "MyApp" # the name of the ipa file
|
159
159
|
```
|
160
160
|
|
161
|
+
## Export options
|
162
|
+
|
163
|
+
Since Xcode 7, `gym` is using new Xcode API which allows us to specify export options using `plist` file. By default `gym` creates this file for you and you are able to modify some parameters by using `export_method`, `export_team_id`, `include_symbols` or `include_bitcode`. If you want to have more options, like creating manifest file or app thinning, you can provide your own `plist` file:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
export_options "./ExportOptions.plist"
|
167
|
+
```
|
168
|
+
|
169
|
+
or you can provide hash of values directly in the `Gymfile`:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
export_options(
|
173
|
+
method: "ad-hoc",
|
174
|
+
manifest: {
|
175
|
+
appURL: "https://example.com/My App.ipa",
|
176
|
+
},
|
177
|
+
thinning: "<thin-for-all-variants>"
|
178
|
+
)
|
179
|
+
```
|
180
|
+
|
181
|
+
For the list of available options run `xcodebuild -help`.
|
182
|
+
|
161
183
|
# Automating the whole process
|
162
184
|
|
163
185
|
`gym` works great together with [fastlane](https://fastlane.tools), which connects all deployment tools into one streamlined workflow.
|
data/lib/gym/detect_values.rb
CHANGED
@@ -29,6 +29,22 @@ module Gym
|
|
29
29
|
generator.dsym_path
|
30
30
|
end
|
31
31
|
|
32
|
+
def manifest_path
|
33
|
+
generator.manifest_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def app_thinning_path
|
37
|
+
generator.app_thinning_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def app_thinning_size_report_path
|
41
|
+
generator.app_thinning_size_report_path
|
42
|
+
end
|
43
|
+
|
44
|
+
def apps_path
|
45
|
+
generator.apps_path
|
46
|
+
end
|
47
|
+
|
32
48
|
# The generator we need to use for the currently used Xcode version
|
33
49
|
def generator
|
34
50
|
if Gym.config[:use_legacy_build_api]
|
@@ -56,6 +56,22 @@ module Gym
|
|
56
56
|
def dsym_path
|
57
57
|
Dir[BuildCommandGenerator.archive_path + "/**/*.app.dSYM"].last
|
58
58
|
end
|
59
|
+
|
60
|
+
def manifest_path
|
61
|
+
""
|
62
|
+
end
|
63
|
+
|
64
|
+
def app_thinning_path
|
65
|
+
""
|
66
|
+
end
|
67
|
+
|
68
|
+
def app_thinning_size_report_path
|
69
|
+
""
|
70
|
+
end
|
71
|
+
|
72
|
+
def apps_path
|
73
|
+
""
|
74
|
+
end
|
59
75
|
end
|
60
76
|
end
|
61
77
|
end
|
@@ -43,10 +43,20 @@ module Gym
|
|
43
43
|
def ipa_path
|
44
44
|
unless Gym.cache[:ipa_path]
|
45
45
|
path = Dir[File.join(temporary_output_path, "*.ipa")].last
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
if path
|
47
|
+
# Try to find IPA file in the output directory, used when app thinning was not set
|
48
|
+
Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
|
49
|
+
FileUtils.mv(path, Gym.cache[:ipa_path]) if File.expand_path(path).downcase != File.expand_path(Gym.cache[:ipa_path]).downcase
|
50
|
+
elsif Dir.exist?(apps_path)
|
51
|
+
# Try to find "generic" IPA file inside "Apps" folder, used when app thinning was set
|
52
|
+
files = Dir[File.join(apps_path, "*.ipa")]
|
53
|
+
# Generic IPA file doesn't have suffix so its name is the shortest
|
54
|
+
path = files.min_by(&:length)
|
55
|
+
Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
|
56
|
+
FileUtils.cp(path, Gym.cache[:ipa_path]) if File.expand_path(path).downcase != File.expand_path(Gym.cache[:ipa_path]).downcase
|
57
|
+
else
|
58
|
+
ErrorHandler.handle_empty_archive unless path
|
59
|
+
end
|
50
60
|
end
|
51
61
|
Gym.cache[:ipa_path]
|
52
62
|
end
|
@@ -62,16 +72,87 @@ module Gym
|
|
62
72
|
return Gym.cache[:config_path]
|
63
73
|
end
|
64
74
|
|
75
|
+
# The path to the manifest plist file
|
76
|
+
def manifest_path
|
77
|
+
Gym.cache[:manifest_path] ||= File.join(temporary_output_path, "manifest.plist")
|
78
|
+
end
|
79
|
+
|
80
|
+
# The path to the app-thinning plist file
|
81
|
+
def app_thinning_path
|
82
|
+
Gym.cache[:app_thinning] ||= File.join(temporary_output_path, "app-thinning.plist")
|
83
|
+
end
|
84
|
+
|
85
|
+
# The path to the App Thinning Size Report file
|
86
|
+
def app_thinning_size_report_path
|
87
|
+
Gym.cache[:app_thinning_size_report] ||= File.join(temporary_output_path, "App Thinning Size Report.txt")
|
88
|
+
end
|
89
|
+
|
90
|
+
# The path to the Apps folder
|
91
|
+
def apps_path
|
92
|
+
Gym.cache[:apps_path] ||= File.join(temporary_output_path, "Apps")
|
93
|
+
end
|
94
|
+
|
65
95
|
private
|
66
96
|
|
97
|
+
def normalize_export_options(hash)
|
98
|
+
# Normalize some values
|
99
|
+
hash[:onDemandResourcesAssetPacksBaseURL] = URI.escape(hash[:onDemandResourcesAssetPacksBaseURL]) if hash[:onDemandResourcesAssetPacksBaseURL]
|
100
|
+
if hash[:manifest]
|
101
|
+
hash[:manifest][:appURL] = URI.escape(hash[:manifest][:appURL]) if hash[:manifest][:appURL]
|
102
|
+
hash[:manifest][:displayImageURL] = URI.escape(hash[:manifest][:displayImageURL]) if hash[:manifest][:displayImageURL]
|
103
|
+
hash[:manifest][:fullSizeImageURL] = URI.escape(hash[:manifest][:fullSizeImageURL]) if hash[:manifest][:fullSizeImageURL]
|
104
|
+
hash[:manifest][:assetPackManifestURL] = URI.escape(hash[:manifest][:assetPackManifestURL]) if hash[:manifest][:assetPackManifestURL]
|
105
|
+
end
|
106
|
+
hash
|
107
|
+
end
|
108
|
+
|
109
|
+
def keys_to_symbols(hash)
|
110
|
+
# Convert keys to symbols
|
111
|
+
hash = hash.each_with_object({}) do |(k, v), memo|
|
112
|
+
memo[k.to_sym] = v
|
113
|
+
memo
|
114
|
+
end
|
115
|
+
hash
|
116
|
+
end
|
117
|
+
|
118
|
+
def read_export_options
|
119
|
+
# Reads export options
|
120
|
+
if Gym.config[:export_options]
|
121
|
+
if Gym.config[:export_options].kind_of?(Hash)
|
122
|
+
# Reads options from hash
|
123
|
+
hash = normalize_export_options(Gym.config[:export_options])
|
124
|
+
else
|
125
|
+
# Reads optoins from file
|
126
|
+
hash = Plist.parse_xml(Gym.config[:export_options])
|
127
|
+
# Convert keys to symbols
|
128
|
+
hash = keys_to_symbols(hash)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Saves configuration for later use
|
132
|
+
Gym.config[:export_method] ||= hash[:method]
|
133
|
+
Gym.config[:include_symbols] = hash[:uploadSymbols] if Gym.config[:include_symbols].nil?
|
134
|
+
Gym.config[:include_bitcode] = hash[:uploadBitcode] if Gym.config[:include_bitcode].nil?
|
135
|
+
Gym.config[:export_team_id] ||= hash[:teamID]
|
136
|
+
else
|
137
|
+
hash = {}
|
138
|
+
# Sets default values
|
139
|
+
Gym.config[:export_method] ||= "app-store"
|
140
|
+
Gym.config[:include_symbols] = true if Gym.config[:include_symbols].nil?
|
141
|
+
Gym.config[:include_bitcode] = false if Gym.config[:include_bitcode].nil?
|
142
|
+
end
|
143
|
+
hash
|
144
|
+
end
|
145
|
+
|
67
146
|
def config_content
|
68
147
|
require 'plist'
|
69
148
|
|
70
|
-
hash =
|
149
|
+
hash = read_export_options
|
71
150
|
|
151
|
+
# Overrides export options if needed
|
152
|
+
hash[:method] = Gym.config[:export_method]
|
72
153
|
if Gym.config[:export_method] == 'app-store'
|
73
|
-
hash[:uploadSymbols] = (Gym.config[:include_symbols] ? true : false)
|
74
|
-
hash[:uploadBitcode] = (Gym.config[:include_bitcode] ? true : false)
|
154
|
+
hash[:uploadSymbols] = (Gym.config[:include_symbols] ? true : false) unless Gym.config[:include_symbols].nil?
|
155
|
+
hash[:uploadBitcode] = (Gym.config[:include_bitcode] ? true : false) unless Gym.config[:include_bitcode].nil?
|
75
156
|
end
|
76
157
|
hash[:teamID] = Gym.config[:export_team_id] if Gym.config[:export_team_id]
|
77
158
|
|
data/lib/gym/options.rb
CHANGED
@@ -21,6 +21,10 @@ module Gym
|
|
21
21
|
UI.user_error!("Workspace file not found at path '#{v}'") unless File.exist?(v)
|
22
22
|
UI.user_error!("Workspace file invalid") unless File.directory?(v)
|
23
23
|
UI.user_error!("Workspace file is not a workspace, must end with .xcworkspace") unless v.include?(".xcworkspace")
|
24
|
+
end,
|
25
|
+
conflicting_options: [:project],
|
26
|
+
conflict_block: proc do |value|
|
27
|
+
UI.user_error!("You can only pass either a 'workspace' or a '#{value.key}', not both")
|
24
28
|
end),
|
25
29
|
FastlaneCore::ConfigItem.new(key: :project,
|
26
30
|
short_option: "-p",
|
@@ -32,6 +36,10 @@ module Gym
|
|
32
36
|
UI.user_error!("Project file not found at path '#{v}'") unless File.exist?(v)
|
33
37
|
UI.user_error!("Project file invalid") unless File.directory?(v)
|
34
38
|
UI.user_error!("Project file is not a project file, must end with .xcodeproj") unless v.include?(".xcodeproj")
|
39
|
+
end,
|
40
|
+
conflicting_options: [:workspace],
|
41
|
+
conflict_block: proc do |value|
|
42
|
+
UI.user_error!("You can only pass either a 'project' or a '#{value.key}', not both")
|
35
43
|
end),
|
36
44
|
FastlaneCore::ConfigItem.new(key: :scheme,
|
37
45
|
short_option: "-s",
|
@@ -77,14 +85,14 @@ module Gym
|
|
77
85
|
short_option: "-m",
|
78
86
|
env_name: "GYM_INCLUDE_SYMBOLS",
|
79
87
|
description: "Should the ipa file include symbols?",
|
80
|
-
|
81
|
-
|
88
|
+
is_string: false,
|
89
|
+
optional: true),
|
82
90
|
FastlaneCore::ConfigItem.new(key: :include_bitcode,
|
83
91
|
short_option: "-z",
|
84
92
|
env_name: "GYM_INCLUDE_BITCODE",
|
85
93
|
description: "Should the ipa include bitcode?",
|
86
|
-
|
87
|
-
|
94
|
+
is_string: false,
|
95
|
+
optional: true),
|
88
96
|
FastlaneCore::ConfigItem.new(key: :use_legacy_build_api,
|
89
97
|
env_name: "GYM_USE_LEGACY_BUILD_API",
|
90
98
|
description: "Don't use the new API because of https://openradar.appspot.com/radar?id=4952000420642816",
|
@@ -105,6 +113,15 @@ module Gym
|
|
105
113
|
av = %w(app-store ad-hoc package enterprise development developer-id)
|
106
114
|
UI.user_error!("Unsupported export_method, must be: #{av}") unless av.include?(value)
|
107
115
|
end),
|
116
|
+
FastlaneCore::ConfigItem.new(key: :export_options,
|
117
|
+
env_name: "GYM_EXPORT_OPTIONS",
|
118
|
+
description: "Specifies path to export options plist. User xcodebuild -help to print the full set of available options",
|
119
|
+
is_string: false,
|
120
|
+
optional: true,
|
121
|
+
conflicting_options: [:use_legacy_build_api],
|
122
|
+
conflict_block: proc do |value|
|
123
|
+
UI.user_error!("'#{value.key}' must be false to use 'export_options'")
|
124
|
+
end),
|
108
125
|
|
109
126
|
# Very optional
|
110
127
|
FastlaneCore::ConfigItem.new(key: :archive_path,
|
data/lib/gym/runner.rb
CHANGED
@@ -17,7 +17,13 @@ module Gym
|
|
17
17
|
package_app
|
18
18
|
fix_package
|
19
19
|
compress_and_move_dsym
|
20
|
-
move_ipa
|
20
|
+
path = move_ipa
|
21
|
+
move_manifest
|
22
|
+
move_app_thinning
|
23
|
+
move_app_thinning_size_report
|
24
|
+
move_apps_folder
|
25
|
+
|
26
|
+
path
|
21
27
|
elsif Gym.project.mac?
|
22
28
|
compress_and_move_dsym
|
23
29
|
copy_mac_app
|
@@ -148,6 +154,54 @@ module Gym
|
|
148
154
|
app_path
|
149
155
|
end
|
150
156
|
|
157
|
+
# Move the manifest.plist if exists into the output directory
|
158
|
+
def move_manifest
|
159
|
+
if File.exist?(PackageCommandGenerator.manifest_path)
|
160
|
+
FileUtils.mv(PackageCommandGenerator.manifest_path, File.expand_path(Gym.config[:output_directory]), force: true)
|
161
|
+
manifest_path = File.join(File.expand_path(Gym.config[:output_directory]), File.basename(PackageCommandGenerator.manifest_path))
|
162
|
+
|
163
|
+
UI.success "Successfully exported the manifest.plist file:"
|
164
|
+
UI.message manifest_path
|
165
|
+
manifest_path
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Move the app-thinning.plist file into the output directory
|
170
|
+
def move_app_thinning
|
171
|
+
if File.exist?(PackageCommandGenerator.app_thinning_path)
|
172
|
+
FileUtils.mv(PackageCommandGenerator.app_thinning_path, File.expand_path(Gym.config[:output_directory]), force: true)
|
173
|
+
app_thinning_path = File.join(File.expand_path(Gym.config[:output_directory]), File.basename(PackageCommandGenerator.app_thinning_path))
|
174
|
+
|
175
|
+
UI.success "Successfully exported the app-thinning.plist file:"
|
176
|
+
UI.message app_thinning_path
|
177
|
+
app_thinning_path
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Move the App Thinning Size Report.txt file into the output directory
|
182
|
+
def move_app_thinning_size_report
|
183
|
+
if File.exist?(PackageCommandGenerator.app_thinning_size_report_path)
|
184
|
+
FileUtils.mv(PackageCommandGenerator.app_thinning_size_report_path, File.expand_path(Gym.config[:output_directory]), force: true)
|
185
|
+
app_thinning_size_report_path = File.join(File.expand_path(Gym.config[:output_directory]), File.basename(PackageCommandGenerator.app_thinning_size_report_path))
|
186
|
+
|
187
|
+
UI.success "Successfully exported the App Thinning Size Report.txt file:"
|
188
|
+
UI.message app_thinning_size_report_path
|
189
|
+
app_thinning_size_report_path
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Move the Apps folder to the output directory
|
194
|
+
def move_apps_folder
|
195
|
+
if Dir.exist?(PackageCommandGenerator.apps_path)
|
196
|
+
FileUtils.mv(PackageCommandGenerator.apps_path, File.expand_path(Gym.config[:output_directory]), force: true)
|
197
|
+
apps_path = File.join(File.expand_path(Gym.config[:output_directory]), File.basename(PackageCommandGenerator.apps_path))
|
198
|
+
|
199
|
+
UI.success "Successfully exported Apps folder:"
|
200
|
+
UI.message apps_path
|
201
|
+
apps_path
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
151
205
|
private
|
152
206
|
|
153
207
|
def find_archive_path
|
data/lib/gym/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gym
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastlane_core
|