spaceship 0.23.0 → 0.24.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: a9452203d446ab2eb76810e8ee4a50d7b838ad91
4
- data.tar.gz: f90ffe947881c20f13fc1186dede47bbeb26d2f2
3
+ metadata.gz: 8a0aa9495ff354e1c5b95d9e37c3d4bbe3fdd78a
4
+ data.tar.gz: 4cb03238dd2e3c63d807b8b15e989b818845f6b0
5
5
  SHA512:
6
- metadata.gz: 27ee1ad437139635ca1b28356482cd7127c9f4ef314c2822c5554518d1cc18dfba3ccf171eaaf9085609b13d6038a300b104628b13d53d2a857588132d9e4c63
7
- data.tar.gz: 849de99bac3737816bf33ca79854786bfc5a21d7e57793f6f0f5d4ea69d2a52c520cca5dbd4f7901b53757e388f9700becbf758f2d12646401665216364f7cd9
6
+ metadata.gz: 178f2df3b4200629861bccb40f34ad30c6abb5510caa70eb7d55b4a5a670b2b60fa3d7edc1d1a104b884f30fc735e7ec22c09d564887be0c5d77a033ad5ed0e4
7
+ data.tar.gz: e3a7a94c04cdb8c41a1545b6e477306befe94d8007c1f567a9a9391ad9422af66f649b87719afa46244ee8a3adfe4e739ead4b8c20f99f8c4307609404083b0d
@@ -28,19 +28,47 @@ module Spaceship
28
28
  # /tmp/spaceship[time]_[pid].log by default
29
29
  attr_accessor :logger
30
30
 
31
+ # Base class for errors that want to present their message as
32
+ # preferred error info for fastlane error handling. See:
33
+ # fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb
34
+ class BasicPreferredInfoError < StandardError
35
+ TITLE = 'The request could not be completed because:'.freeze
36
+
37
+ def preferred_error_info
38
+ message ? [TITLE, message] : nil
39
+ end
40
+ end
41
+
31
42
  # Invalid user credentials were provided
32
- class InvalidUserCredentialsError < StandardError; end
43
+ class InvalidUserCredentialsError < BasicPreferredInfoError; end
33
44
 
34
45
  # Raised when no user credentials were passed at all
35
- class NoUserCredentialsError < StandardError; end
46
+ class NoUserCredentialsError < BasicPreferredInfoError; end
36
47
 
37
- class UnexpectedResponse < StandardError; end
48
+ class UnexpectedResponse < StandardError
49
+ attr_reader :error_info
50
+
51
+ def initialize(error_info = nil)
52
+ super(error_info)
53
+ @error_info = error_info
54
+ end
55
+
56
+ def preferred_error_info
57
+ return nil unless @error_info.kind_of?(Hash) && @error_info['resultString']
58
+
59
+ [
60
+ "Apple provided the following error info:",
61
+ @error_info['resultString'],
62
+ @error_info['userString']
63
+ ].compact.uniq # sometimes 'resultString' and 'userString' are the same value
64
+ end
65
+ end
38
66
 
39
67
  # Raised when 302 is received from portal request
40
- class AppleTimeoutError < StandardError; end
68
+ class AppleTimeoutError < BasicPreferredInfoError; end
41
69
 
42
70
  # Raised when 401 is received from portal request
43
- class UnauthorizedAccessError < StandardError; end
71
+ class UnauthorizedAccessError < BasicPreferredInfoError; end
44
72
 
45
73
  # Authenticates with Apple's web services. This method has to be called once
46
74
  # to generate a valid session. The session will automatically be used from then
@@ -238,7 +266,7 @@ module Spaceship
238
266
 
239
267
  def request(method, url_or_path = nil, params = nil, headers = {}, &block)
240
268
  headers.merge!(csrf_tokens)
241
- headers.merge!({ 'User-Agent' => USER_AGENT })
269
+ headers['User-Agent'] = USER_AGENT
242
270
 
243
271
  # Before encoding the parameters, log them
244
272
  log_request(method, url_or_path, params)
@@ -297,7 +325,7 @@ module Spaceship
297
325
  end
298
326
 
299
327
  if content.nil?
300
- raise UnexpectedResponse.new, response.body
328
+ raise UnexpectedResponse.new(response.body)
301
329
  else
302
330
  store_csrf_tokens(response)
303
331
  content
@@ -62,7 +62,7 @@ module Spaceship
62
62
  req.headers['X-Apple-Upload-ContentProviderId'] = content_provider_id
63
63
  req.headers['X-Original-Filename'] = upload_file.file_name
64
64
  req.headers['X-Apple-Upload-Validation-RuleSets'] = du_validation_rule_set if du_validation_rule_set
65
- req.headers['Content-Length'] = "#{upload_file.file_size}"
65
+ req.headers['Content-Length'] = upload_file.file_size.to_s
66
66
  req.headers['Connection'] = "keep-alive"
67
67
  end
68
68
 
@@ -12,7 +12,7 @@ module Spaceship
12
12
  class << self
13
13
  def from_path(path)
14
14
  raise "Image must exists at path: #{path}" unless File.exist?(path)
15
- path = remove_alpha_channel(path) if File.extname(path).downcase == '.png'
15
+ path = remove_alpha_channel(path) if File.extname(path).casecmp('.png').zero?
16
16
 
17
17
  content_type = Utilities.content_type(path)
18
18
  self.new(
@@ -193,8 +193,8 @@ module Spaceship
193
193
  csr = OpenSSL::X509::Request.new
194
194
  csr.version = 0
195
195
  csr.subject = OpenSSL::X509::Name.new([
196
- ['CN', 'PEM', OpenSSL::ASN1::UTF8STRING]
197
- ])
196
+ ['CN', 'PEM', OpenSSL::ASN1::UTF8STRING]
197
+ ])
198
198
  csr.public_key = key.public_key
199
199
  csr.sign(key, OpenSSL::Digest::SHA1.new)
200
200
  return [csr, key]
@@ -98,14 +98,14 @@ module Spaceship
98
98
  def factory(attrs)
99
99
  # fill content rights section if iTC returns nil
100
100
  if attrs["contentRights"].nil?
101
- attrs.merge!("contentRights" => {
101
+ attrs["contentRights"] = {
102
102
  "containsThirdPartyContent" => {
103
103
  "value" => nil
104
104
  },
105
105
  "hasRights" => {
106
106
  "value" => nil
107
107
  }
108
- })
108
+ }
109
109
  end
110
110
 
111
111
  obj = self.new(attrs)
@@ -115,8 +115,8 @@ module Spaceship
115
115
  # @param application (Spaceship::Tunes::Application) The app this submission is for
116
116
  def create(application, version)
117
117
  attrs = client.prepare_app_submissions(application.apple_id, application.edit_version.version_id)
118
- attrs.merge!(application: application)
119
- attrs.merge!(version: version)
118
+ attrs[:application] = application
119
+ attrs[:version] = version
120
120
 
121
121
  return self.factory(attrs)
122
122
  end
@@ -40,8 +40,7 @@ module Spaceship
40
40
  end
41
41
 
42
42
  def reset!(attrs = {})
43
- update_raw_data!
44
- ({
43
+ update_raw_data!({
45
44
  video_asset_token: nil,
46
45
  picture_asset_token: nil,
47
46
  descriptionXML: nil,
@@ -54,8 +53,7 @@ module Spaceship
54
53
  video_status: nil,
55
54
  device_type: nil,
56
55
  language: nil
57
- }.merge(attrs)
58
- )
56
+ }.merge(attrs))
59
57
  end
60
58
 
61
59
  private
@@ -168,8 +168,8 @@ module Spaceship
168
168
  attrs = client.app_version(app_id, is_live)
169
169
  return nil unless attrs
170
170
 
171
- attrs.merge!(application: application)
172
- attrs.merge!(is_live: is_live)
171
+ attrs[:application] = application
172
+ attrs[:is_live] = is_live
173
173
 
174
174
  return self.factory(attrs)
175
175
  end
@@ -429,7 +429,7 @@ module Spaceship
429
429
 
430
430
  trailer.merge!({
431
431
  "pictureAssetToken" => video_preview_data["token"],
432
- "previewFrameTimeCode" => "#{ts}",
432
+ "previewFrameTimeCode" => ts.to_s,
433
433
  "isPortrait" => Utilities.portrait?(video_preview_path)
434
434
  })
435
435
  else # removing trailer
@@ -130,7 +130,7 @@ module Spaceship
130
130
 
131
131
  def details
132
132
  attrs = client.app_details(apple_id)
133
- attrs.merge!(application: self)
133
+ attrs[:application] = self
134
134
  Tunes::AppDetails.factory(attrs)
135
135
  end
136
136
 
@@ -138,7 +138,7 @@ module Spaceship
138
138
  ensure_not_a_bundle
139
139
  versions = client.versions_history(apple_id, platform)
140
140
  versions.map do |attrs|
141
- attrs.merge!(application: self)
141
+ attrs[:application] = self
142
142
  Tunes::AppVersionHistory.factory(attrs)
143
143
  end
144
144
  end
@@ -193,12 +193,31 @@ module Spaceship
193
193
  # @!group Builds
194
194
  #####################################################
195
195
 
196
- # A reference to all the build trains
196
+ # TestFlight: A reference to all the build trains
197
197
  # @return [Hash] a hash, the version number being the key
198
198
  def build_trains
199
199
  Tunes::BuildTrain.all(self, self.apple_id)
200
200
  end
201
201
 
202
+ # The numbers of all build trains that were uploaded
203
+ # @return [Array] An array of train version numbers
204
+ def all_build_train_numbers
205
+ client.all_build_trains(app_id: self.apple_id).fetch("trains").collect do |current|
206
+ current["versionString"]
207
+ end
208
+ end
209
+
210
+ # Receive the build details for a specific build
211
+ # useful if the app is not listed in the TestFlight build list
212
+ # which might happen if you don't use TestFlight
213
+ # This is used to receive dSYM files from Apple
214
+ def all_builds_for_train(train: nil)
215
+ client.all_builds_for_train(app_id: self.apple_id, train: train).fetch("items", []).collect do |attrs|
216
+ attrs[:apple_id] = self.apple_id
217
+ Tunes::Build.factory(attrs)
218
+ end
219
+ end
220
+
202
221
  # @return [Array]A list of binaries which are not even yet processing based on the version
203
222
  # These are all build that have no information except the upload date
204
223
  # Those builds can also be the builds that are stuck on iTC.
@@ -206,7 +225,7 @@ module Spaceship
206
225
  data = client.build_trains(apple_id, 'internal') # we need to fetch all trains here to get the builds
207
226
 
208
227
  builds = data.fetch('processingBuilds', []).collect do |attrs|
209
- attrs.merge!(build_train: self)
228
+ attrs[:build_train] = self
210
229
  Tunes::ProcessingBuild.factory(attrs)
211
230
  end
212
231
 
@@ -220,7 +239,7 @@ module Spaceship
220
239
  data = client.build_trains(apple_id, 'internal') # we need to fetch all trains here to get the builds
221
240
 
222
241
  builds = data.fetch('processingBuilds', []).collect do |attrs|
223
- attrs.merge!(build_train: self)
242
+ attrs[:build_train] = self
224
243
  Tunes::ProcessingBuild.factory(attrs)
225
244
  end
226
245
 
@@ -6,6 +6,11 @@ module Spaceship
6
6
  # @!group General metadata
7
7
  #####################################################
8
8
 
9
+ # @return (String) The App identifier of this app, provided by iTunes Connect
10
+ # @example
11
+ # "1013943394"
12
+ attr_accessor :apple_id
13
+
9
14
  # @return (Spaceship::Tunes::BuildTrain) A reference to the build train this build is contained in
10
15
  attr_accessor :build_train
11
16
 
@@ -112,12 +117,25 @@ module Spaceship
112
117
  self.internal_expiry_date ||= 0
113
118
  end
114
119
 
120
+ def details
121
+ response = client.build_details(app_id: self.apple_id,
122
+ train: self.train_version,
123
+ build_number: self.build_version)
124
+ response['apple_id'] = self.apple_id
125
+ BuildDetails.factory(response)
126
+ end
127
+
128
+ def apple_id
129
+ return @apple_id if @apple_id
130
+ return self.build_train.application.apple_id
131
+ end
132
+
115
133
  def update_build_information!(whats_new: nil,
116
134
  description: nil,
117
135
  feedback_email: nil)
118
136
  parameters = {
119
- app_id: self.build_train.application.apple_id,
120
- train: self.build_train.version_string,
137
+ app_id: self.apple_id,
138
+ train: self.train_version,
121
139
  build_number: self.build_version,
122
140
  platform: self.platform
123
141
  }.merge({
@@ -150,8 +168,8 @@ module Spaceship
150
168
  # }
151
169
  def submit_for_beta_review!(metadata)
152
170
  parameters = {
153
- app_id: self.build_train.application.apple_id,
154
- train: self.build_train.version_string,
171
+ app_id: self.apple_id,
172
+ train: self.train_version,
155
173
  build_number: self.build_version,
156
174
  platform: self.platform,
157
175
 
@@ -199,8 +217,8 @@ module Spaceship
199
217
 
200
218
  # This will cancel the review process for this TestFlight build
201
219
  def cancel_beta_review!
202
- client.remove_testflight_build_from_review!(app_id: self.build_train.application.apple_id,
203
- train: self.build_train.version_string,
220
+ client.remove_testflight_build_from_review!(app_id: self.apple_id,
221
+ train: self.train_version,
204
222
  build_number: self.build_version,
205
223
  platform: self.platform)
206
224
  end
@@ -0,0 +1,48 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents the details of a build
4
+ class BuildDetails < TunesBase
5
+ # @return (String) The App identifier of this app, provided by iTunes Connect
6
+ # @example
7
+ # "1013943394"
8
+ attr_accessor :apple_id
9
+
10
+ # @return (String) Link to the dSYM file (not always available)
11
+ # lol, it's unencrypted http
12
+ attr_accessor :dsym_url
13
+
14
+ # @return [Bool]
15
+ attr_accessor :include_symbols
16
+
17
+ # @return [Integer]
18
+ attr_accessor :number_of_asset_packs
19
+
20
+ # @return [Bool]
21
+ attr_accessor :contains_odr
22
+
23
+ # e.g. "13A340"
24
+ attr_accessor :build_sdk
25
+
26
+ # @return [String] e.g. "MyApp.ipa"
27
+ attr_accessor :file_name
28
+
29
+ attr_mapping(
30
+ 'apple_id' => :apple_id,
31
+ 'dsymurl' => :dsym_url,
32
+ 'includesSymbols' => :include_symbols,
33
+ 'numberOfAssetPacks' => :number_of_asset_packs,
34
+ 'containsODR' => :contains_odr,
35
+ 'buildSdk' => :build_sdk,
36
+ 'fileName' => :file_name
37
+ )
38
+
39
+ class << self
40
+ # Create a new object based on a hash.
41
+ # This is used to create a new object based on the server response.
42
+ def factory(attrs)
43
+ self.new(attrs)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -49,7 +49,7 @@ module Spaceship
49
49
 
50
50
  result = {}
51
51
  trains.each do |attrs|
52
- attrs.merge!(application: application)
52
+ attrs[:application] = application
53
53
  current = self.factory(attrs)
54
54
  result[current.version_string] = current
55
55
  end
@@ -62,12 +62,12 @@ module Spaceship
62
62
  super
63
63
 
64
64
  @builds = (self.raw_data['builds'] || []).collect do |attrs|
65
- attrs.merge!(build_train: self)
65
+ attrs[:build_train] = self
66
66
  Tunes::Build.factory(attrs)
67
67
  end
68
68
 
69
69
  @processing_builds = (self.raw_data['buildsInProcessing'] || []).collect do |attrs|
70
- attrs.merge!(build_train: self)
70
+ attrs[:build_train] = self
71
71
  Tunes::Build.factory(attrs)
72
72
  end
73
73
 
@@ -26,7 +26,7 @@ module Spaceship
26
26
  end
27
27
  return result if result
28
28
 
29
- raise "Language '#{lang}' is not activated for this app version."
29
+ raise "Language '#{lang}' is not activated / available for this app version."
30
30
  end
31
31
 
32
32
  # @return (Array) An array containing all languages that are already available
@@ -15,6 +15,7 @@ require 'spaceship/tunes/user_detail'
15
15
  require 'spaceship/tunes/app_screenshot'
16
16
  require 'spaceship/tunes/language_converter'
17
17
  require 'spaceship/tunes/build'
18
+ require 'spaceship/tunes/build_details'
18
19
  require 'spaceship/tunes/processing_build'
19
20
  require 'spaceship/tunes/build_train'
20
21
  require 'spaceship/tunes/device_type'
@@ -2,7 +2,7 @@ module Spaceship
2
2
  # rubocop:disable Metrics/ClassLength
3
3
  class TunesClient < Spaceship::Client
4
4
  # ITunesConnectError is only thrown when iTunes Connect raises an exception
5
- class ITunesConnectError < StandardError
5
+ class ITunesConnectError < BasicPreferredInfoError
6
6
  end
7
7
 
8
8
  # raised if the server failed to save temporarily
@@ -80,7 +80,7 @@ module Spaceship
80
80
 
81
81
  if t_name.length > 0
82
82
  teams.each do |t|
83
- t_id = t['contentProvider']['contentProviderId'].to_s if t['contentProvider']['name'].downcase == t_name.downcase
83
+ t_id = t['contentProvider']['contentProviderId'].to_s if t['contentProvider']['name'].casecmp(t_name.downcase).zero?
84
84
  end
85
85
  end
86
86
 
@@ -574,6 +574,22 @@ module Spaceship
574
574
  handle_itc_response(r.body)
575
575
  end
576
576
 
577
+ # All build trains, even if there is no TestFlight
578
+ def all_build_trains(app_id: nil)
579
+ r = request(:get, "ra/apps/#{app_id}/buildHistory?platform=ios")
580
+ handle_itc_response(r.body)
581
+ end
582
+
583
+ def all_builds_for_train(app_id: nil, train: nil)
584
+ r = request(:get, "ra/apps/#{app_id}/trains/#{train}/buildHistory?platform=ios")
585
+ handle_itc_response(r.body)
586
+ end
587
+
588
+ def build_details(app_id: nil, train: nil, build_number: nil)
589
+ r = request(:get, "ra/apps/#{app_id}/platforms/ios/trains/#{train}/builds/#{build_number}/details")
590
+ handle_itc_response(r.body)
591
+ end
592
+
577
593
  def update_build_information!(app_id: nil,
578
594
  train: nil,
579
595
  build_number: nil,
@@ -1,3 +1,3 @@
1
1
  module Spaceship
2
- VERSION = "0.23.0"
2
+ VERSION = "0.24.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spaceship
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-09 00:00:00.000000000 Z
12
+ date: 2016-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: credentials_manager
@@ -241,14 +241,14 @@ dependencies:
241
241
  requirements:
242
242
  - - "~>"
243
243
  - !ruby/object:Gem::Version
244
- version: 0.32.1
244
+ version: 0.38.0
245
245
  type: :development
246
246
  prerelease: false
247
247
  version_requirements: !ruby/object:Gem::Requirement
248
248
  requirements:
249
249
  - - "~>"
250
250
  - !ruby/object:Gem::Version
251
- version: 0.32.1
251
+ version: 0.38.0
252
252
  description: Because you would rather spend your time building stuff than fighting
253
253
  provisioning
254
254
  email:
@@ -297,6 +297,7 @@ files:
297
297
  - lib/spaceship/tunes/app_version_states_history.rb
298
298
  - lib/spaceship/tunes/application.rb
299
299
  - lib/spaceship/tunes/build.rb
300
+ - lib/spaceship/tunes/build_details.rb
300
301
  - lib/spaceship/tunes/build_train.rb
301
302
  - lib/spaceship/tunes/device_type.rb
302
303
  - lib/spaceship/tunes/language_converter.rb
@@ -332,7 +333,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
332
333
  version: '0'
333
334
  requirements: []
334
335
  rubyforge_project:
335
- rubygems_version: 2.5.1
336
+ rubygems_version: 2.4.5.1
336
337
  signing_key:
337
338
  specification_version: 4
338
339
  summary: Because you would rather spend your time building stuff than fighting provisioning