cocoapods-trunk 0.6.0 → 1.4.1
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 +5 -5
- data/.rubocop_cocoapods.yml +29 -2
- data/.travis.yml +16 -15
- data/CHANGELOG.md +258 -9
- data/Gemfile +3 -1
- data/Gemfile.lock +103 -70
- data/README.md +1 -1
- data/cocoapods-trunk.gemspec +4 -4
- data/lib/cocoapods_trunk.rb +1 -1
- data/lib/pod/command/trunk/add_owner.rb +4 -1
- data/lib/pod/command/trunk/delete.rb +70 -0
- data/lib/pod/command/trunk/deprecate.rb +48 -0
- data/lib/pod/command/trunk/info.rb +2 -0
- data/lib/pod/command/trunk/me.rb +2 -0
- data/lib/pod/command/trunk/push.rb +73 -21
- data/lib/pod/command/trunk/register.rb +10 -7
- data/lib/pod/command/trunk/remove_owner.rb +4 -1
- data/lib/pod/command/trunk.rb +44 -9
- data/spec/command/trunk/addowner_spec.rb +2 -2
- data/spec/command/trunk/delete_spec.rb +68 -0
- data/spec/command/trunk/deprecate_spec.rb +58 -0
- data/spec/command/trunk/info_spec.rb +1 -1
- data/spec/command/trunk/me_spec.rb +2 -2
- data/spec/command/trunk/push_spec.rb +193 -9
- data/spec/command/trunk/register_spec.rb +2 -2
- data/spec/command/trunk/remove_owner_spec.rb +1 -1
- data/spec/command/trunk_spec.rb +1 -1
- data/spec/spec_helper.rb +30 -7
- metadata +36 -25
data/lib/pod/command/trunk.rb
CHANGED
|
@@ -11,20 +11,22 @@ module Pod
|
|
|
11
11
|
self.summary = 'Interact with the CocoaPods API (e.g. publishing new specs)'
|
|
12
12
|
|
|
13
13
|
SCHEME_AND_HOST = ENV['TRUNK_SCHEME_AND_HOST'] || 'https://trunk.cocoapods.org'
|
|
14
|
-
BASE_URL = "#{SCHEME_AND_HOST}/api/v1"
|
|
14
|
+
BASE_URL = "#{SCHEME_AND_HOST}/api/v1".freeze
|
|
15
15
|
|
|
16
|
-
require 'pod/command/trunk/register'
|
|
17
|
-
require 'pod/command/trunk/me'
|
|
18
16
|
require 'pod/command/trunk/add_owner'
|
|
19
|
-
require 'pod/command/trunk/
|
|
20
|
-
require 'pod/command/trunk/
|
|
17
|
+
require 'pod/command/trunk/delete'
|
|
18
|
+
require 'pod/command/trunk/deprecate'
|
|
21
19
|
require 'pod/command/trunk/info'
|
|
20
|
+
require 'pod/command/trunk/me'
|
|
21
|
+
require 'pod/command/trunk/push'
|
|
22
|
+
require 'pod/command/trunk/register'
|
|
23
|
+
require 'pod/command/trunk/remove_owner'
|
|
22
24
|
|
|
23
25
|
private
|
|
24
26
|
|
|
25
27
|
def request_url(action, url, *args)
|
|
26
28
|
response = create_request(action, url, *args)
|
|
27
|
-
if (400...600).
|
|
29
|
+
if (400...600).cover?(response.status_code)
|
|
28
30
|
print_error(response.body)
|
|
29
31
|
end
|
|
30
32
|
response
|
|
@@ -50,7 +52,7 @@ module Pod
|
|
|
50
52
|
rescue JSON::ParserError
|
|
51
53
|
json = {}
|
|
52
54
|
end
|
|
53
|
-
error = json['error'] || "An unexpected error
|
|
55
|
+
error = json['error'] || "An unexpected error occurred: #{body}"
|
|
54
56
|
|
|
55
57
|
case data = json['data']
|
|
56
58
|
when Hash
|
|
@@ -62,12 +64,40 @@ module Pod
|
|
|
62
64
|
end.flatten
|
|
63
65
|
count = lines.size
|
|
64
66
|
lines.unshift "The following #{'validation'.pluralize(count)} failed:"
|
|
65
|
-
error +=
|
|
67
|
+
error += "\n" << lines.join("\n")
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
raise Informative, error
|
|
69
71
|
end
|
|
70
72
|
|
|
73
|
+
def print_messages(data_url, messages, spec = nil, action = nil)
|
|
74
|
+
if verbose? || spec.nil?
|
|
75
|
+
# Using UI.labeled here is dangerous, as it wraps the URL and indents
|
|
76
|
+
# it, which breaks the URL when you try to copy-paste it.
|
|
77
|
+
UI.puts " - Data URL: #{data_url}"
|
|
78
|
+
|
|
79
|
+
server_logs = messages.map do |entry|
|
|
80
|
+
at, message = entry.to_a.flatten
|
|
81
|
+
"#{formatted_time(at)}: #{message}"
|
|
82
|
+
end
|
|
83
|
+
UI.labeled 'Log messages', server_logs
|
|
84
|
+
else
|
|
85
|
+
separator = '-' * 80
|
|
86
|
+
UI.puts
|
|
87
|
+
UI.puts separator
|
|
88
|
+
UI.puts " 🎉 Congrats"
|
|
89
|
+
UI.puts
|
|
90
|
+
UI.puts " 🚀 #{spec.name} (#{spec.version}) successfully #{action}"
|
|
91
|
+
unless messages.empty?
|
|
92
|
+
at = messages.first.to_a.flatten.first
|
|
93
|
+
UI.puts " 📅 #{formatted_time(at)}"
|
|
94
|
+
end
|
|
95
|
+
UI.puts " 🌎 https://cocoapods.org/pods/#{spec.name}"
|
|
96
|
+
UI.puts " 👍 Tell your friends!"
|
|
97
|
+
UI.puts separator
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
71
101
|
def json(response)
|
|
72
102
|
JSON.parse(response.body)
|
|
73
103
|
end
|
|
@@ -95,7 +125,7 @@ module Pod
|
|
|
95
125
|
|
|
96
126
|
def formatted_time(time_string)
|
|
97
127
|
require 'active_support/time'
|
|
98
|
-
@tz_offset ||= Time.zone_offset(
|
|
128
|
+
@tz_offset ||= Time.zone_offset(time_zone)
|
|
99
129
|
@current_year ||= Date.today.year
|
|
100
130
|
|
|
101
131
|
time = Time.parse(time_string) + @tz_offset
|
|
@@ -106,6 +136,11 @@ module Pod
|
|
|
106
136
|
end
|
|
107
137
|
formatted
|
|
108
138
|
end
|
|
139
|
+
|
|
140
|
+
def time_zone
|
|
141
|
+
out, = Executable.capture_command('/bin/date', %w(+%Z), :capture => :out)
|
|
142
|
+
out.strip
|
|
143
|
+
end
|
|
109
144
|
end
|
|
110
145
|
end
|
|
111
146
|
end
|
|
@@ -39,8 +39,8 @@ module Pod
|
|
|
39
39
|
|
|
40
40
|
it 'should successfully add an owner' do
|
|
41
41
|
url = 'https://trunk.cocoapods.org/api/v1/pods/QueryKit/owners'
|
|
42
|
-
|
|
43
|
-
with(:body =>
|
|
42
|
+
stub_request(:patch, url).
|
|
43
|
+
with(:body => '{"email":"kyle@cocoapods.org"}',
|
|
44
44
|
:headers => { 'Authorization' => 'Token 527d11fe429f3426cb8dbeba183a0d80' }).
|
|
45
45
|
to_return(:status => 200, :body => '[]', :headers => {})
|
|
46
46
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
|
2
|
+
require 'tmpdir'
|
|
3
|
+
|
|
4
|
+
module Pod
|
|
5
|
+
describe Command::Trunk::Delete do
|
|
6
|
+
describe 'CLAide' do
|
|
7
|
+
it 'registers it self' do
|
|
8
|
+
Command.parse(%w( trunk delete )).should.be.instance_of Command::Trunk::Delete
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should error without a pod name' do
|
|
13
|
+
command = Command.parse(%w( trunk delete ))
|
|
14
|
+
lambda { command.validate! }.should.raise CLAide::Help
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should error without a version' do
|
|
18
|
+
command = Command.parse(%w( trunk delete Stencil ))
|
|
19
|
+
lambda { command.validate! }.should.raise CLAide::Help
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'confirms deletion' do
|
|
23
|
+
UI.inputs += %w(garbage true false)
|
|
24
|
+
command = Command.parse(%w( trunk delete Stencil 1.0.0 ))
|
|
25
|
+
command.send(:confirm_deletion?).should.be.true
|
|
26
|
+
command.send(:confirm_deletion?).should.be.false
|
|
27
|
+
|
|
28
|
+
UI.output.should == <<-OUTPUT.gsub(/^>$/, '> ')
|
|
29
|
+
\e[33mWARNING: It is generally considered bad behavior to remove versions of a Pod that others are depending on!
|
|
30
|
+
Please consider using the `deprecate` command instead.\e[0m
|
|
31
|
+
Are you sure you want to delete this Pod version?
|
|
32
|
+
>
|
|
33
|
+
Are you sure you want to delete this Pod version?
|
|
34
|
+
>
|
|
35
|
+
\e[33mWARNING: It is generally considered bad behavior to remove versions of a Pod that others are depending on!
|
|
36
|
+
Please consider using the `deprecate` command instead.\e[0m
|
|
37
|
+
Are you sure you want to delete this Pod version?
|
|
38
|
+
>
|
|
39
|
+
OUTPUT
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'does not delete if the user does not confirm' do
|
|
43
|
+
Command::Trunk::Delete.any_instance.expects(:confirm_deletion?).returns(false)
|
|
44
|
+
Command::Trunk::Delete.any_instance.expects(:delete).never
|
|
45
|
+
Command::Trunk::Delete.invoke(%w(Stencil 1.0.0))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should show information for a pod' do
|
|
49
|
+
response = {
|
|
50
|
+
'messages' => [
|
|
51
|
+
{
|
|
52
|
+
'2015-12-05 02:00:25 UTC' => 'Push for `Stencil 1.0.0` initiated.',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
'2015-12-05 02:00:26 UTC' => 'Push for `Stencil 1.0.0` has been pushed (1.02409270 s).',
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
'data_url' => 'https://raw.githubusercontent.com/CocoaPods/Specs/ce4efe9f986d297008e8c61010a4b0d5881c50d0/Specs/Stencil/1.0.0/Stencil.podspec.json',
|
|
59
|
+
}
|
|
60
|
+
Command::Trunk::Delete.any_instance.expects(:delete).returns(response)
|
|
61
|
+
UI.inputs << 'TRUE '
|
|
62
|
+
Command::Trunk::Delete.invoke(%w(Stencil 1.0.0))
|
|
63
|
+
|
|
64
|
+
UI.output.should.include 'Data URL: https://raw.githubusercontent'
|
|
65
|
+
UI.output.should.include 'Push for `Stencil 1.0.0` initiated'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
|
2
|
+
require 'tmpdir'
|
|
3
|
+
|
|
4
|
+
module Pod
|
|
5
|
+
describe Command::Trunk::Deprecate do
|
|
6
|
+
describe 'CLAide' do
|
|
7
|
+
it 'registers it self' do
|
|
8
|
+
Command.parse(%w( trunk deprecate )).should.be.instance_of Command::Trunk::Deprecate
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should error without a pod name' do
|
|
13
|
+
command = Command.parse(%w( trunk deprecate ))
|
|
14
|
+
lambda { command.validate! }.should.raise CLAide::Help
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
before do
|
|
18
|
+
@push_response = {
|
|
19
|
+
'messages' => [
|
|
20
|
+
{
|
|
21
|
+
'2015-12-05 02:00:25 UTC' => 'Push for `Stencil 0.96.3` initiated.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
'2015-12-05 02:00:26 UTC' => 'Push for `Stencil 0.96.3` has been pushed (1.02409270 s).',
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
'data_url' => 'https://raw.githubusercontent.com/CocoaPods/Specs/ce4efe9f986d297008e8c61010a4b0d5881c50d0/Specs/Stencil/0.96.3/Stencil.podspec.json',
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should show information for a pod' do
|
|
32
|
+
Command::Trunk::Deprecate.any_instance.expects(:deprecate).returns(@push_response)
|
|
33
|
+
Command::Trunk::Deprecate.invoke(%w(Stencil))
|
|
34
|
+
|
|
35
|
+
UI.output.should.include 'Data URL: https://raw.githubusercontent'
|
|
36
|
+
UI.output.should.include 'Push for `Stencil 0.96.3` initiated'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should send the proper network request' do
|
|
40
|
+
redirect = 'http://redirected.com'
|
|
41
|
+
stub_request(:patch, 'https://trunk.cocoapods.org/api/v1/pods/Stencil/deprecated').
|
|
42
|
+
with(:body => hash_including('in_favor_of' => 'Stamp')).
|
|
43
|
+
to_return(:status => 201, :headers => { :location => redirect })
|
|
44
|
+
|
|
45
|
+
stub_request(:get, redirect).
|
|
46
|
+
to_return(:status => 200, :body => @push_response.to_json)
|
|
47
|
+
|
|
48
|
+
Command::Trunk::Deprecate.invoke(%w(Stencil --in-favor-of=Stamp))
|
|
49
|
+
|
|
50
|
+
UI.output.should == <<-EOS
|
|
51
|
+
- Data URL: https://raw.githubusercontent.com/CocoaPods/Specs/ce4efe9f986d297008e8c61010a4b0d5881c50d0/Specs/Stencil/0.96.3/Stencil.podspec.json
|
|
52
|
+
- Log messages:
|
|
53
|
+
- December 5th, 2015 02:00: Push for `Stencil 0.96.3` initiated.
|
|
54
|
+
- December 5th, 2015 02:00: Push for `Stencil 0.96.3` has been pushed (1.02409270 s).
|
|
55
|
+
EOS
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -16,7 +16,7 @@ module Pod
|
|
|
16
16
|
|
|
17
17
|
it 'should show information for a pod' do
|
|
18
18
|
url = 'https://trunk.cocoapods.org/api/v1/pods/Stencil'
|
|
19
|
-
|
|
19
|
+
stub_request(:get, url).to_return(:body => {
|
|
20
20
|
'owners' => [
|
|
21
21
|
{
|
|
22
22
|
'name' => 'Kyle Fuller',
|
|
@@ -4,13 +4,13 @@ module Pod
|
|
|
4
4
|
describe Command::Trunk::Me do
|
|
5
5
|
describe 'CLAide' do
|
|
6
6
|
it 'registers it self' do
|
|
7
|
-
Command.parse(%w(
|
|
7
|
+
Command.parse(%w( trunk me )).should.be.instance_of Command::Trunk::Me
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "should error if we don't have a token" do
|
|
12
12
|
Netrc.any_instance.stubs(:[]).returns(nil)
|
|
13
|
-
command = Command.parse(%w(
|
|
13
|
+
command = Command.parse(%w( trunk me ))
|
|
14
14
|
lambda { command.validate! }.should.raise CLAide::Help
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -3,9 +3,27 @@ require 'tmpdir'
|
|
|
3
3
|
|
|
4
4
|
module Pod
|
|
5
5
|
describe Command::Trunk::Push do
|
|
6
|
+
def success_json
|
|
7
|
+
{
|
|
8
|
+
'messages' => [
|
|
9
|
+
{
|
|
10
|
+
'2015-12-05 02:00:25 UTC' => "Push for `BananaLib 0.96.3' initiated.",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
'2015-12-05 02:00:26 UTC' => "Push for `BananaLib 0.96.3' has been pushed (1.02409270 s).",
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
'data_url' => 'https://raw.githubusercontent.com/CocoaPods/Specs/ce4efe9f986d297008e8c61010a4b0d5881c50d0/Specs/BananaLib/0.96.3/BananaLib.podspec.json',
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
Command::Trunk::Push.any_instance.stubs(:update_master_repo)
|
|
22
|
+
end
|
|
23
|
+
|
|
6
24
|
describe 'CLAide' do
|
|
7
25
|
it 'registers it self' do
|
|
8
|
-
Command.parse(%w(
|
|
26
|
+
Command.parse(%w( trunk push )).should.be.instance_of Command::Trunk::Push
|
|
9
27
|
end
|
|
10
28
|
end
|
|
11
29
|
|
|
@@ -17,8 +35,8 @@ module Pod
|
|
|
17
35
|
end
|
|
18
36
|
|
|
19
37
|
it 'should error when the trunk service returns an error' do
|
|
20
|
-
url = 'https://trunk.cocoapods.org/api/v1/pods'
|
|
21
|
-
|
|
38
|
+
url = 'https://trunk.cocoapods.org/api/v1/pods?allow_warnings=false'
|
|
39
|
+
stub_request(:post, url).to_return(:status => 422, :body => {
|
|
22
40
|
'error' => 'The Pod Specification did not pass validation.',
|
|
23
41
|
'data' => {
|
|
24
42
|
'warnings' => [
|
|
@@ -86,30 +104,196 @@ module Pod
|
|
|
86
104
|
describe 'validation' do
|
|
87
105
|
before do
|
|
88
106
|
Installer.any_instance.stubs(:aggregate_targets).returns([])
|
|
89
|
-
Installer.any_instance.stubs(:
|
|
107
|
+
Installer.any_instance.stubs(:pod_targets).returns([])
|
|
90
108
|
|
|
91
109
|
Validator.any_instance.stubs(:check_file_patterns)
|
|
92
|
-
Validator.any_instance.stubs(:validated?).returns(true)
|
|
93
110
|
Validator.any_instance.stubs(:validate_url)
|
|
94
111
|
Validator.any_instance.stubs(:validate_screenshots)
|
|
95
112
|
Validator.any_instance.stubs(:xcodebuild).returns('')
|
|
113
|
+
Validator.any_instance.stubs(:install_pod)
|
|
114
|
+
Validator.any_instance.stubs(:build_pod)
|
|
115
|
+
Validator.any_instance.stubs(:add_app_project_import)
|
|
116
|
+
Validator.any_instance.stubs(:used_swift_version).returns(nil)
|
|
117
|
+
%i(prepare resolve_dependencies download_dependencies).each do |m|
|
|
118
|
+
Installer.any_instance.stubs(m)
|
|
119
|
+
end
|
|
120
|
+
Command::Trunk::Push.any_instance.stubs(:master_repo_url).
|
|
121
|
+
returns(Pod::TrunkSource::TRUNK_REPO_URL)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'passes the SWIFT_VERSION to the Validator' do
|
|
125
|
+
Validator.any_instance.expects(:swift_version=).with('3.0')
|
|
126
|
+
|
|
127
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --swift-version=3.0))
|
|
128
|
+
cmd.send(:validate_podspec)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'passes a swift version back to command, to handle .swift-version files' do
|
|
132
|
+
Validator.any_instance.stubs(:dot_swift_version).returns('1.2.3')
|
|
133
|
+
Validator.any_instance.stubs(:used_swift_version).returns('1.2.3')
|
|
134
|
+
|
|
135
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --allow-warnings))
|
|
136
|
+
cmd.send(:validate_podspec)
|
|
137
|
+
cmd.instance_variable_get(:@swift_version).should == '1.2.3'
|
|
96
138
|
end
|
|
97
139
|
|
|
98
140
|
it 'validates specs as frameworks by default' do
|
|
99
|
-
Validator.any_instance.expects(:podfile_from_spec).
|
|
100
|
-
|
|
141
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
142
|
+
with(:ios, '8.0', true, [], nil).once.returns(Podfile.new)
|
|
143
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
144
|
+
with(:osx, nil, true, [], nil).once.returns(Podfile.new)
|
|
145
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
146
|
+
with(:tvos, nil, true, [], nil).once.returns(Podfile.new)
|
|
147
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
148
|
+
with(:watchos, nil, true, [], nil).once.returns(Podfile.new)
|
|
101
149
|
|
|
102
150
|
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec))
|
|
103
151
|
cmd.send(:validate_podspec)
|
|
104
152
|
end
|
|
105
153
|
|
|
106
154
|
it 'validates specs as libraries if requested' do
|
|
107
|
-
Validator.any_instance.expects(:podfile_from_spec).
|
|
108
|
-
|
|
155
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
156
|
+
with(:ios, nil, false, [], nil).once.returns(Podfile.new)
|
|
157
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
158
|
+
with(:osx, nil, false, [], nil).once.returns(Podfile.new)
|
|
159
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
160
|
+
with(:tvos, nil, false, [], nil).once.returns(Podfile.new)
|
|
161
|
+
Validator.any_instance.expects(:podfile_from_spec).
|
|
162
|
+
with(:watchos, nil, false, [], nil).once.returns(Podfile.new)
|
|
163
|
+
|
|
164
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --use-libraries))
|
|
165
|
+
cmd.send(:validate_podspec)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it 'prints the failure reason' do
|
|
169
|
+
Validator.any_instance.expects(:validated?).returns(false)
|
|
170
|
+
Validator.any_instance.expects(:validate)
|
|
171
|
+
Validator.any_instance.expects(:failure_reason).returns('failure_reason')
|
|
109
172
|
|
|
110
173
|
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --use-libraries))
|
|
174
|
+
e = should.raise(Informative) { cmd.send(:validate_podspec) }
|
|
175
|
+
e.message.should.include 'The spec did not pass validation, due to failure_reason.'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'passes skip import validation' do
|
|
179
|
+
Validator.any_instance.expects(:skip_import_validation=).with(true)
|
|
180
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --skip-import-validation))
|
|
181
|
+
cmd.send(:validate_podspec)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it 'passes skip test' do
|
|
185
|
+
Validator.any_instance.expects(:skip_tests=).with(true)
|
|
186
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --skip-tests))
|
|
187
|
+
cmd.send(:validate_podspec)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'passes use modular headers' do
|
|
191
|
+
Validator.any_instance.expects(:use_modular_headers=)
|
|
192
|
+
|
|
193
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --use-modular-headers))
|
|
111
194
|
cmd.send(:validate_podspec)
|
|
112
195
|
end
|
|
113
196
|
end
|
|
197
|
+
|
|
198
|
+
describe 'sending the swift version up to trunk' do
|
|
199
|
+
before do
|
|
200
|
+
# This won't get called
|
|
201
|
+
Command::Trunk::Push.any_instance.unstub(:update_master_repo)
|
|
202
|
+
# For faking the networking when sending
|
|
203
|
+
Pod::Command::Trunk.any_instance.expects(:json).returns({})
|
|
204
|
+
Pod::Command::Trunk.any_instance.expects(:auth_headers).returns({})
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'passes the value to trunk' do
|
|
208
|
+
# Fakes for the network response
|
|
209
|
+
response = mock
|
|
210
|
+
response.expects(:headers).returns('location' => ['http://theinternet.com'])
|
|
211
|
+
response.expects(:status_code).returns(200)
|
|
212
|
+
|
|
213
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --swift-version=1.1.2))
|
|
214
|
+
|
|
215
|
+
# Using a blank podspec - JSON should include `"pushed_with_swift_version":"1.1.2"`
|
|
216
|
+
cmd.stubs(:spec).returns(Pod::Specification.new)
|
|
217
|
+
|
|
218
|
+
json = <<-JSON
|
|
219
|
+
{"name":null,"pushed_with_swift_version":"1.1.2","platforms":{"osx":null,"ios":null,"tvos":null,"watchos":null}}
|
|
220
|
+
JSON
|
|
221
|
+
|
|
222
|
+
cmd.stubs(:validate_podspec)
|
|
223
|
+
cmd.stubs(:request_url)
|
|
224
|
+
|
|
225
|
+
api_route = 'pods?allow_warnings=false'
|
|
226
|
+
cmd.expects(:request_path).with(:post, api_route, json, {}).returns(response)
|
|
227
|
+
cmd.send(:push_to_trunk)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
describe 'updating the master repo' do
|
|
232
|
+
before do
|
|
233
|
+
@cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec))
|
|
234
|
+
@cmd.stubs(:validate_podspec)
|
|
235
|
+
@cmd.stubs(:push_to_trunk).returns([200, success_json])
|
|
236
|
+
Command::Trunk::Push.any_instance.unstub(:update_master_repo)
|
|
237
|
+
Command::Trunk::Push.any_instance.stubs(:master_repo_name).
|
|
238
|
+
returns(Pod::TrunkSource::TRUNK_REPO_NAME)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'updates the master repo when it exists' do
|
|
242
|
+
Config.instance.sources_manager.stubs(:source_with_url).
|
|
243
|
+
at_most(2).
|
|
244
|
+
returns(Pod::TrunkSource.new(Pod::TrunkSource::TRUNK_REPO_NAME)).
|
|
245
|
+
returns(Pod::TrunkSource.new(Pod::TrunkSource::TRUNK_REPO_NAME))
|
|
246
|
+
|
|
247
|
+
Config.instance.sources_manager.expects(:update).with(Pod::TrunkSource::TRUNK_REPO_NAME).twice
|
|
248
|
+
Command::Repo::AddCDN.any_instance.expects(:run).never
|
|
249
|
+
|
|
250
|
+
@cmd.run
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it 'sets up the master repo when it does not exist' do
|
|
254
|
+
Config.instance.sources_manager.stubs(:source_with_url).
|
|
255
|
+
at_most(3).
|
|
256
|
+
returns(nil).
|
|
257
|
+
returns(Pod::TrunkSource.new(Pod::TrunkSource::TRUNK_REPO_NAME))
|
|
258
|
+
Config.instance.sources_manager.expects(:update).with(Pod::TrunkSource::TRUNK_REPO_NAME).twice
|
|
259
|
+
Command::Repo::AddCDN.any_instance.expects(:run)
|
|
260
|
+
|
|
261
|
+
@cmd.run
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
describe 'Presenting Responses to the user' do
|
|
266
|
+
before do
|
|
267
|
+
Command::Trunk::Push.any_instance.stubs(:update_master_repo)
|
|
268
|
+
Config.instance.sources_manager.stubs(:master_repo_functional?).returns(true)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it 'shows full logs when verbose' do
|
|
272
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --verbose))
|
|
273
|
+
cmd.stubs(:validate_podspec)
|
|
274
|
+
cmd.stubs(:push_to_trunk).returns([200, success_json])
|
|
275
|
+
|
|
276
|
+
cmd.run
|
|
277
|
+
UI.output.should.match %r{- Data URL: https://raw.githubusercontent.com/CocoaPods/Specs}
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it 'shows full logs when errored' do
|
|
281
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec --verbose))
|
|
282
|
+
cmd.stubs(:validate_podspec)
|
|
283
|
+
cmd.stubs(:push_to_trunk).returns([400, success_json])
|
|
284
|
+
|
|
285
|
+
cmd.run
|
|
286
|
+
UI.output.should.match %r{- Data URL: https://raw.githubusercontent.com/CocoaPods/Specs}
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it 'shows thanks emojis when success' do
|
|
290
|
+
cmd = Command.parse(%w(trunk push spec/fixtures/BananaLib.podspec))
|
|
291
|
+
cmd.stubs(:validate_podspec)
|
|
292
|
+
cmd.stubs(:push_to_trunk).returns([200, success_json])
|
|
293
|
+
cmd.run
|
|
294
|
+
|
|
295
|
+
UI.output.should.match %r{https://cocoapods.org/pods/BananaLib}
|
|
296
|
+
end
|
|
297
|
+
end
|
|
114
298
|
end
|
|
115
299
|
end
|
|
@@ -17,8 +17,8 @@ module Pod
|
|
|
17
17
|
|
|
18
18
|
it 'should register user' do
|
|
19
19
|
url = 'https://trunk.cocoapods.org/api/v1/sessions'
|
|
20
|
-
|
|
21
|
-
with(:body =>
|
|
20
|
+
stub_request(:post, url).
|
|
21
|
+
with(:body => hash_including('email' => 'kyle@cocoapods.org')).
|
|
22
22
|
to_return(:status => 200, :body => '{"token": "acct"}')
|
|
23
23
|
Netrc.any_instance.stubs(:[]).returns(nil)
|
|
24
24
|
Netrc.any_instance.expects(:[]=).with('trunk.cocoapods.org', ['kyle@cocoapods.org', 'acct'])
|
|
@@ -39,7 +39,7 @@ module Pod
|
|
|
39
39
|
|
|
40
40
|
it 'should successfully remove an owner' do
|
|
41
41
|
url = 'https://trunk.cocoapods.org/api/v1/pods/QueryKit/owners/kyle@cocoapods.org'
|
|
42
|
-
|
|
42
|
+
stub_request(:delete, url).
|
|
43
43
|
with(:headers => { 'Authorization' => 'Token 527d11fe429f3426cb8dbeba183a0d80' }).
|
|
44
44
|
to_return(:status => 200, :body => '[]', :headers => {})
|
|
45
45
|
|
data/spec/command/trunk_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -22,7 +22,10 @@ require 'bacon'
|
|
|
22
22
|
require 'mocha-on-bacon'
|
|
23
23
|
require 'pretty_bacon'
|
|
24
24
|
require 'webmock'
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
include WebMock::API
|
|
27
|
+
WebMock.enable!
|
|
28
|
+
WebMock.disable_net_connect!(:allow => ['codeclimate.com', 'cdn.cocoapods.org'])
|
|
26
29
|
|
|
27
30
|
require 'cocoapods'
|
|
28
31
|
|
|
@@ -45,6 +48,11 @@ module Pod
|
|
|
45
48
|
class << self
|
|
46
49
|
attr_accessor :output
|
|
47
50
|
attr_accessor :warnings
|
|
51
|
+
attr_accessor :inputs
|
|
52
|
+
|
|
53
|
+
def gets
|
|
54
|
+
inputs.shift
|
|
55
|
+
end
|
|
48
56
|
|
|
49
57
|
def puts(message = '')
|
|
50
58
|
@output << "#{message}\n"
|
|
@@ -59,16 +67,31 @@ module Pod
|
|
|
59
67
|
end
|
|
60
68
|
end
|
|
61
69
|
end
|
|
70
|
+
|
|
71
|
+
class Command::Trunk
|
|
72
|
+
def time_zone
|
|
73
|
+
'UTC'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
62
76
|
end
|
|
63
77
|
|
|
64
78
|
module Bacon
|
|
65
79
|
class Context
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
old_run_requirement = instance_method(:run_requirement)
|
|
81
|
+
define_method(:run_requirement) do |description, spec|
|
|
82
|
+
::Pod::Config.instance = nil
|
|
83
|
+
::Pod::UI.output = ''
|
|
84
|
+
::Pod::UI.warnings = ''
|
|
85
|
+
::Pod::UI.inputs = []
|
|
86
|
+
# The following prevents a nasty behaviour where the increments are not
|
|
87
|
+
# balanced when testing informative which might lead to sections not
|
|
88
|
+
# being printed to the output as they are too nested.
|
|
89
|
+
::Pod::UI.indentation_level = 0
|
|
90
|
+
::Pod::UI.title_level = 0
|
|
91
|
+
|
|
92
|
+
WebMock.reset!
|
|
93
|
+
|
|
94
|
+
old_run_requirement.bind(self).call(description, spec)
|
|
72
95
|
end
|
|
73
96
|
end
|
|
74
97
|
end
|