gym 1.5.0 → 1.6.0

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