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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fe3879a8123332988ecd29815ef12bbedb1d59a
4
- data.tar.gz: bdf77254d90621d1fe30917b8d9d90a5cdbfbc9b
3
+ metadata.gz: 13c9c96a7e6c5750ce9478d68136427daf2a7c4b
4
+ data.tar.gz: afb3993a8d061a0af1e1573ac0d5901eecf457a4
5
5
  SHA512:
6
- metadata.gz: eb81ff95220d37fd96a521822a0b93cd3f33bcb708f44bd74e942daaf659e5bac5abf816b6af5cade11160c354a9fe8af7726b9e30261effe051ab3ca0ea64e6
7
- data.tar.gz: d6dc93ddea1e7d0b9a203c93b8c10cd5578347fc8b0a6b73c452142071bf92dfeac2e51f5df423d2f67808e4b3143c900715d2540ff892d521fda93657655667
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.
@@ -27,9 +27,6 @@ module Gym
27
27
 
28
28
  config[:output_name] ||= Gym.project.app_name
29
29
 
30
- # we do it here, since the value is optional and should be pre-filled by fastlane if necessary
31
- config[:export_method] ||= "app-store"
32
-
33
30
  return config
34
31
  end
35
32
 
@@ -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
- ErrorHandler.handle_empty_archive unless path
47
-
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
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 = { method: Gym.config[:export_method] }
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
- default_value: true,
81
- is_string: false),
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
- default_value: false,
87
- is_string: false),
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
@@ -1,4 +1,4 @@
1
1
  module Gym
2
- VERSION = "1.5.0"
2
+ VERSION = "1.6.0"
3
3
  DESCRIPTION = "Building your iOS apps has never been easier"
4
4
  end
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.5.0
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-04 00:00:00.000000000 Z
11
+ date: 2016-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastlane_core