spaceship 0.23.0 → 0.24.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 +4 -4
- data/lib/spaceship/client.rb +35 -7
- data/lib/spaceship/du/du_client.rb +1 -1
- data/lib/spaceship/du/upload_file.rb +1 -1
- data/lib/spaceship/portal/certificate.rb +2 -2
- data/lib/spaceship/tunes/app_submission.rb +4 -4
- data/lib/spaceship/tunes/app_trailer.rb +2 -4
- data/lib/spaceship/tunes/app_version.rb +3 -3
- data/lib/spaceship/tunes/application.rb +24 -5
- data/lib/spaceship/tunes/build.rb +24 -6
- data/lib/spaceship/tunes/build_details.rb +48 -0
- data/lib/spaceship/tunes/build_train.rb +3 -3
- data/lib/spaceship/tunes/language_item.rb +1 -1
- data/lib/spaceship/tunes/tunes.rb +1 -0
- data/lib/spaceship/tunes/tunes_client.rb +18 -2
- data/lib/spaceship/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a0aa9495ff354e1c5b95d9e37c3d4bbe3fdd78a
|
4
|
+
data.tar.gz: 4cb03238dd2e3c63d807b8b15e989b818845f6b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 178f2df3b4200629861bccb40f34ad30c6abb5510caa70eb7d55b4a5a670b2b60fa3d7edc1d1a104b884f30fc735e7ec22c09d564887be0c5d77a033ad5ed0e4
|
7
|
+
data.tar.gz: e3a7a94c04cdb8c41a1545b6e477306befe94d8007c1f567a9a9391ad9422af66f649b87719afa46244ee8a3adfe4e739ead4b8c20f99f8c4307609404083b0d
|
data/lib/spaceship/client.rb
CHANGED
@@ -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 <
|
43
|
+
class InvalidUserCredentialsError < BasicPreferredInfoError; end
|
33
44
|
|
34
45
|
# Raised when no user credentials were passed at all
|
35
|
-
class NoUserCredentialsError <
|
46
|
+
class NoUserCredentialsError < BasicPreferredInfoError; end
|
36
47
|
|
37
|
-
class UnexpectedResponse < StandardError
|
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 <
|
68
|
+
class AppleTimeoutError < BasicPreferredInfoError; end
|
41
69
|
|
42
70
|
# Raised when 401 is received from portal request
|
43
|
-
class UnauthorizedAccessError <
|
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
|
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
|
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'] =
|
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).
|
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
|
-
|
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
|
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
|
119
|
-
attrs
|
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
|
172
|
-
attrs
|
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" =>
|
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
|
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
|
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
|
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
|
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.
|
120
|
-
train: self.
|
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.
|
154
|
-
train: self.
|
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.
|
203
|
-
train: self.
|
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
|
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
|
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
|
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 <
|
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'].
|
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,
|
data/lib/spaceship/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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
|