spaceship 0.0.15 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/assets/languageMapping.json +224 -0
  3. data/lib/spaceship.rb +20 -63
  4. data/lib/spaceship/base.rb +71 -14
  5. data/lib/spaceship/client.rb +9 -274
  6. data/lib/spaceship/launcher.rb +1 -1
  7. data/lib/spaceship/portal/app.rb +125 -0
  8. data/lib/spaceship/portal/certificate.rb +273 -0
  9. data/lib/spaceship/portal/device.rb +102 -0
  10. data/lib/spaceship/portal/portal.rb +6 -0
  11. data/lib/spaceship/portal/portal_base.rb +13 -0
  12. data/lib/spaceship/portal/portal_client.rb +289 -0
  13. data/lib/spaceship/portal/provisioning_profile.rb +369 -0
  14. data/lib/spaceship/portal/spaceship.rb +94 -0
  15. data/lib/spaceship/{ui → portal/ui}/select_team.rb +0 -0
  16. data/lib/spaceship/tunes/app_screenshot.rb +28 -0
  17. data/lib/spaceship/tunes/app_status.rb +63 -0
  18. data/lib/spaceship/tunes/app_submission.rb +149 -0
  19. data/lib/spaceship/tunes/app_version.rb +337 -0
  20. data/lib/spaceship/tunes/application.rb +253 -0
  21. data/lib/spaceship/tunes/build.rb +128 -0
  22. data/lib/spaceship/tunes/build_train.rb +79 -0
  23. data/lib/spaceship/tunes/language_converter.rb +44 -0
  24. data/lib/spaceship/tunes/language_item.rb +54 -0
  25. data/lib/spaceship/tunes/processing_build.rb +30 -0
  26. data/lib/spaceship/tunes/spaceship.rb +26 -0
  27. data/lib/spaceship/tunes/tester.rb +177 -0
  28. data/lib/spaceship/tunes/tunes.rb +12 -0
  29. data/lib/spaceship/tunes/tunes_base.rb +15 -0
  30. data/lib/spaceship/tunes/tunes_client.rb +360 -0
  31. data/lib/spaceship/version.rb +1 -1
  32. metadata +27 -7
  33. data/lib/spaceship/app.rb +0 -125
  34. data/lib/spaceship/certificate.rb +0 -271
  35. data/lib/spaceship/device.rb +0 -100
  36. data/lib/spaceship/provisioning_profile.rb +0 -367
@@ -0,0 +1,369 @@
1
+ module Spaceship
2
+ module Portal
3
+ # Represents a provisioning profile of the Apple Dev Portal
4
+ class ProvisioningProfile < PortalBase
5
+ # @return (String) The ID generated by the Dev Portal
6
+ # You'll probably not really need this value
7
+ # @example
8
+ # "2MAY7NPHAA"
9
+ attr_accessor :id
10
+
11
+ # @return (String) The UDID of this provisioning profile
12
+ # This value is used for example for code signing
13
+ # It is also contained in the actual profile
14
+ # @example
15
+ # "23d7df3b-9767-4e85-a1ea-1df4d8f32fec"
16
+ attr_accessor :uuid
17
+
18
+ # @return (DateTime) The date and time of when the profile
19
+ # expires.
20
+ # @example
21
+ # #<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>
22
+ attr_accessor :expires
23
+
24
+ # @return (String) The profile distribution type. You probably want to
25
+ # use the class type to detect the profile type instead of this string.
26
+ # @example AppStore Profile
27
+ # "store"
28
+ # @example AdHoc Profile
29
+ # "adhoc"
30
+ # @example Development Profile
31
+ # "limited"
32
+ attr_accessor :distribution_method
33
+
34
+ # @return (String) The name of this profile
35
+ # @example
36
+ # "com.krausefx.app AppStore"
37
+ attr_accessor :name
38
+
39
+ # @return (String) The status of this profile
40
+ # @example Active (profile is fine)
41
+ # "Active"
42
+ # @example Expired (time ran out)
43
+ # "Expired"
44
+ # @example Invalid (e.g. code signing identity not available any more)
45
+ # "Invalid"
46
+ attr_accessor :status
47
+
48
+ # @return (String) The type of the profile (development or distribution).
49
+ # You'll probably not need this value
50
+ # @example Distribution
51
+ # "iOS Distribution"
52
+ # @example Development
53
+ # "iOS Development"
54
+ attr_accessor :type
55
+
56
+ # @return (String) This will always be "2"
57
+ # @example
58
+ # "2"
59
+ attr_accessor :version
60
+
61
+ # @return (String) The supported platform for this profile
62
+ # @example
63
+ # "ios"
64
+ attr_accessor :platform
65
+
66
+ # No information about this attribute
67
+ attr_accessor :managing_app
68
+
69
+ # A reference to the app this profile is for.
70
+ # You can then easily access the value directly
71
+ # @return (App) The app this profile is for
72
+ #
73
+ # @example Example Value
74
+ # <Spaceship::App
75
+ # @app_id="2UMR2S6PAA"
76
+ # @name="App Name"
77
+ # @platform="ios"
78
+ # @prefix="5A997XSAAA"
79
+ # @bundle_id="com.krausefx.app"
80
+ # @is_wildcard=false
81
+ # @dev_push_enabled=false
82
+ # @prod_push_enabled=false>
83
+ #
84
+ # @example Usage
85
+ # profile.app.name
86
+ attr_accessor :app
87
+
88
+ # @return (Array) A list of certificates used for this profile
89
+ # @example Example Value
90
+ # [
91
+ # <Spaceship::Certificate::Production
92
+ # @status=nil
93
+ # @id="XC5PH8D4AA"
94
+ # @name="iOS Distribution"
95
+ # @created=nil
96
+ # @expires=#<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>
97
+ # @owner_type="team"
98
+ # @owner_name=nil
99
+ # @owner_id=nil
100
+ # @type_display_id="R58UK2EWAA">]
101
+ # ]
102
+ #
103
+ # @example Usage
104
+ # profile.certificates.first.id
105
+ attr_accessor :certificates
106
+
107
+ # @return (Array) A list of devices this profile is enabled for.
108
+ # This will always be [] for AppStore profiles
109
+ #
110
+ # @example Example Value
111
+ # <Spaceship::Device
112
+ # @id="WXQ7V239BE"
113
+ # @name="Grahams iPhone 4s"
114
+ # @udid="ba0ac7d70f7a14c6fa02ef0e02f4fe9c5178e2f7"
115
+ # @platform="ios"
116
+ # @status="c">]
117
+ #
118
+ # @example Usage
119
+ # profile.devices.first.name
120
+ attr_accessor :devices
121
+
122
+ attr_mapping({
123
+ 'provisioningProfileId' => :id,
124
+ 'UUID' => :uuid,
125
+ 'dateExpire' => :expires,
126
+ 'distributionMethod' => :distribution_method,
127
+ 'name' => :name,
128
+ 'status' => :status,
129
+ 'type' => :type,
130
+ 'version' => :version,
131
+ 'proProPlatform' => :platform,
132
+ 'managingApp' => :managing_app,
133
+ 'appId' => :app
134
+ })
135
+
136
+ class << self
137
+ # @return (String) The profile type used for web requests to the Dev Portal
138
+ # @example
139
+ # "limited"
140
+ # "store"
141
+ # "adhoc"
142
+ # "inhouse"
143
+ def type
144
+ raise "You cannot create a ProvisioningProfile without a type. Use a subclass."
145
+ end
146
+
147
+ # Create a new object based on a hash.
148
+ # This is used to create a new object based on the server response.
149
+ def factory(attrs)
150
+ # Ad Hoc Profiles look exactly like App Store profiles, but usually include devices
151
+ attrs['distributionMethod'] = 'adhoc' if attrs['distributionMethod'] == 'store' && attrs['devices'].size > 0
152
+ # available values of `distributionMethod` at this point: ['adhoc', 'store', 'limited']
153
+
154
+ klass = case attrs['distributionMethod']
155
+ when 'limited'
156
+ Development
157
+ when 'store'
158
+ AppStore
159
+ when 'adhoc'
160
+ AdHoc
161
+ when 'inhouse'
162
+ InHouse
163
+ else
164
+ raise "Can't find class '#{attrs['distributionMethod']}'"
165
+ end
166
+
167
+ attrs['appId'] = App.factory(attrs['appId'])
168
+ attrs['devices'].map! { |device| Device.factory(device) }
169
+ attrs['certificates'].map! { |cert| Certificate.factory(cert) }
170
+
171
+ klass.client = @client
172
+ klass.new(attrs)
173
+ end
174
+
175
+ # @return (String) The human readable name of this profile type.
176
+ # @example
177
+ # "AppStore"
178
+ # "AdHoc"
179
+ # "Development"
180
+ # "InHouse"
181
+ def pretty_type
182
+ name.split('::').last
183
+ end
184
+
185
+ # Create a new provisioning profile
186
+ # @param name (String): The name of the provisioning profile on the Dev Portal
187
+ # @param bundle_id (String): The app identifier, this paramter is required
188
+ # @param certificate (Certificate): The certificate that should be used with this
189
+ # provisioning profile. You can also pass an array of certificates to this method. This will
190
+ # only work for development profiles
191
+ # @param devices (Array) (optional): An array of Device objects that should be used in this profile.
192
+ # It is recommend to not pass devices as spaceship will automatically add all devices for AdHoc
193
+ # and Development profiles and add none for AppStore and Enterprise Profiles
194
+ # @return (ProvisioningProfile): The profile that was just created
195
+ def create!(name: nil, bundle_id: nil, certificate: nil, devices: [])
196
+ raise "Missing required parameter 'bundle_id'" if bundle_id.to_s.empty?
197
+ raise "Missing required parameter 'certificate'. e.g. use `Spaceship::Certificate::Production.all.first`" if certificate.to_s.empty?
198
+
199
+ app = Spaceship::App.find(bundle_id)
200
+ raise "Could not find app with bundle id '#{bundle_id}'" unless app
201
+
202
+ # Fill in sensible default values
203
+ name ||= [bundle_id, self.pretty_type].join(' ')
204
+
205
+ devices = [] if (self == AppStore or self == InHouse) # App Store Profiles MUST NOT have devices
206
+
207
+ certificate_parameter = certificate.collect { |c| c.id } if certificate.kind_of?Array
208
+ certificate_parameter ||= [certificate.id]
209
+
210
+ # Fix https://github.com/KrauseFx/fastlane/issues/349
211
+ certificate_parameter = certificate_parameter.first if certificate_parameter.count == 1
212
+
213
+ if devices.nil? or devices.count == 0
214
+ if self == Development or self == AdHoc
215
+ # For Development and AdHoc we usually want all devices by default
216
+ devices = Spaceship::Device.all
217
+ end
218
+ end
219
+
220
+ profile = client.create_provisioning_profile!(name,
221
+ self.type,
222
+ app.app_id,
223
+ certificate_parameter,
224
+ devices.map {|d| d.id} )
225
+ self.new(profile)
226
+ end
227
+
228
+ # @return (Array) Returns all profiles registered for this account
229
+ # If you're calling this from a subclass (like AdHoc), this will
230
+ # only return the profiles that are of this type
231
+ def all
232
+ profiles = client.provisioning_profiles.map do |profile|
233
+ self.factory(profile)
234
+ end
235
+
236
+ # filter out the profiles managed by xcode
237
+ profiles.delete_if do |profile|
238
+ profile.managed_by_xcode?
239
+ end
240
+
241
+ return profiles if self == ProvisioningProfile
242
+
243
+ # only return the profiles that match the class
244
+ profiles.select do |profile|
245
+ profile.class == self
246
+ end
247
+ end
248
+
249
+ # @return (Array) Returns an array of provisioning
250
+ # profiles matching the bundle identifier
251
+ # Returns [] if no profiles were found
252
+ # This may also contain invalid or expired profiles
253
+ def find_by_bundle_id(bundle_id)
254
+ all.find_all do |profile|
255
+ profile.app.bundle_id == bundle_id
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+ # Represents a Development profile from the Dev Portal
262
+ class Development < ProvisioningProfile
263
+ def self.type
264
+ 'limited'
265
+ end
266
+ end
267
+
268
+ # Represents an AppStore profile from the Dev Portal
269
+ class AppStore < ProvisioningProfile
270
+ def self.type
271
+ 'store'
272
+ end
273
+ end
274
+
275
+ # Represents an AdHoc profile from the Dev Portal
276
+ class AdHoc < ProvisioningProfile
277
+ def self.type
278
+ 'adhoc'
279
+ end
280
+ end
281
+
282
+ # Represents an Enterprise InHouse profile from the Dev Portal
283
+ class InHouse < ProvisioningProfile
284
+ def self.type
285
+ 'inhouse'
286
+ end
287
+ end
288
+
289
+ # Download the current provisioning profile. This will *not* store
290
+ # the provisioning profile on the file system. Instead this method
291
+ # will return the content of the profile.
292
+ # @return (String) The content of the provisioning profile
293
+ # You'll probably want to store it on the file system
294
+ # @example
295
+ # File.write("path.mobileprovision", profile.download)
296
+ def download
297
+ client.download_provisioning_profile(self.id)
298
+ end
299
+
300
+ # Delete the provisioning profile
301
+ def delete!
302
+ client.delete_provisioning_profile!(self.id)
303
+ end
304
+
305
+ # Repair an existing provisioning profile
306
+ # alias to update!
307
+ # @return (ProvisioningProfile) A new provisioning profile, as
308
+ # the repair method will generate a profile with a new ID
309
+ def repair!
310
+ update!
311
+ end
312
+
313
+ # Updates the provisioning profile from the local data
314
+ # e.g. after you added new devices to the profile
315
+ # This will also update the code signing identity if necessary
316
+ # @return (ProvisioningProfile) A new provisioning profile, as
317
+ # the repair method will generate a profile with a new ID
318
+ def update!
319
+ unless certificate_valid?
320
+ if self.kind_of?Development
321
+ self.certificates = [Spaceship::Certificate::Development.all.first]
322
+ elsif self.kind_of?InHouse
323
+ self.certificates = [Spaceship::Certificate::InHouse.all.first]
324
+ else
325
+ self.certificates = [Spaceship::Certificate::Production.all.first]
326
+ end
327
+ end
328
+
329
+ client.repair_provisioning_profile!(
330
+ self.id,
331
+ self.name,
332
+ self.distribution_method,
333
+ self.app.app_id,
334
+ self.certificates.map { |c| c.id },
335
+ self.devices.map { |d| d.id }
336
+ )
337
+
338
+ # We need to fetch the provisioning profile again, as the ID changes
339
+ profile = Spaceship::ProvisioningProfile.all.find do |profile|
340
+ profile.name == self.name # we can use the name as it's valid
341
+ end
342
+
343
+ return profile
344
+ end
345
+
346
+ # Is the certificate of this profile available?
347
+ # @return (Bool) is the certificate valid?
348
+ def certificate_valid?
349
+ return false if (certificates || []).count == 0
350
+ certificates.each do |c|
351
+ if Spaceship::Certificate.all.collect { |s| s.id }.include?(c.id)
352
+ return true
353
+ end
354
+ end
355
+ return false
356
+ end
357
+
358
+ # @return (Bool) Is the current provisioning profile valid?
359
+ def valid?
360
+ return (status == 'Active' and certificate_valid?)
361
+ end
362
+
363
+ # @return (Bool) Is this profile managed by Xcode?
364
+ def managed_by_xcode?
365
+ managing_app == 'Xcode'
366
+ end
367
+ end
368
+ end
369
+ end
@@ -0,0 +1,94 @@
1
+ module Spaceship
2
+ module Portal
3
+ class << self
4
+ # This client stores the default client when using the lazy syntax
5
+ # Spaceship.app instead of using the spaceship launcher
6
+ attr_accessor :client
7
+
8
+ # Authenticates with Apple's web services. This method has to be called once
9
+ # to generate a valid session. The session will automatically be used from then
10
+ # on.
11
+ #
12
+ # This method will automatically use the username from the Appfile (if available)
13
+ # and fetch the password from the Keychain (if available)
14
+ #
15
+ # @param user (String) (optional): The username (usually the email address)
16
+ # @param password (String) (optional): The password
17
+ #
18
+ # @raise InvalidUserCredentialsError: raised if authentication failed
19
+ #
20
+ # @return (Spaceship::Client) The client the login method was called for
21
+ def login(user = nil, password = nil)
22
+ @client = PortalClient.login(user, password)
23
+ end
24
+
25
+ # Open up the team selection for the user (if necessary).
26
+ #
27
+ # If the user is in multiple teams, a team selection is shown.
28
+ # The user can then select a team by entering the number
29
+ #
30
+ # Additionally, the team ID is shown next to each team name
31
+ # so that the user can use the environment variable `FASTLANE_TEAM_ID`
32
+ # for future user.
33
+ #
34
+ # @return (String) The ID of the select team. You also get the value if
35
+ # the user is only in one team.
36
+ def select_team
37
+ @client.select_team
38
+ end
39
+
40
+ # Helper methods for managing multiple instances of spaceship
41
+
42
+ # @return (Class) Access the apps for the spaceship
43
+ def app
44
+ Spaceship::App.set_client(@client)
45
+ end
46
+
47
+ # @return (Class) Access the devices for the spaceship
48
+ def device
49
+ Spaceship::Device.set_client(@client)
50
+ end
51
+
52
+ # @return (Class) Access the certificates for the spaceship
53
+ def certificate
54
+ Spaceship::Certificate.set_client(@client)
55
+ end
56
+
57
+ # @return (Class) Access the provisioning profiles for the spaceship
58
+ def provisioning_profile
59
+ Spaceship::ProvisioningProfile.set_client(@client)
60
+ end
61
+ end
62
+ end
63
+
64
+ # Legacy code to support `Spaceship.app` without `Portal`
65
+ class << self
66
+ def login(user = nil, password = nil)
67
+ Spaceship::Portal.login(user, password)
68
+ end
69
+
70
+ def select_team
71
+ Spaceship::Portal.select_team
72
+ end
73
+
74
+ def app
75
+ Spaceship::Portal.app
76
+ end
77
+
78
+ def device
79
+ Spaceship::Portal.device
80
+ end
81
+
82
+ def certificate
83
+ Spaceship::Portal.certificate
84
+ end
85
+
86
+ def provisioning_profile
87
+ Spaceship::Portal.provisioning_profile
88
+ end
89
+
90
+ def client
91
+ Spaceship::Portal.client
92
+ end
93
+ end
94
+ end