gemcutter 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/commands/abstract_command.rb +6 -2
- data/lib/commands/migrate.rb +17 -5
- data/lib/commands/push.rb +1 -1
- data/lib/rubygems_plugin.rb +0 -11
- data/test/command_helper.rb +1 -1
- metadata +6 -10
- data/README.textile +0 -27
- data/test/commands/abstract_command_test.rb +0 -113
- data/test/commands/migrate_command_test.rb +0 -141
- data/test/commands/push_command_test.rb +0 -41
- data/test/commands/tumble_command_test.rb +0 -58
@@ -3,6 +3,8 @@ require 'rubygems/local_remote_options'
|
|
3
3
|
class Gem::AbstractCommand < Gem::Command
|
4
4
|
include Gem::LocalRemoteOptions
|
5
5
|
|
6
|
+
URL = "http://gemcutter.org"
|
7
|
+
|
6
8
|
def api_key
|
7
9
|
Gem.configuration[:gemcutter_key]
|
8
10
|
end
|
@@ -80,13 +82,15 @@ class Gem::AbstractCommand < Gem::Command
|
|
80
82
|
|
81
83
|
# @return [URI, nil] the HTTP-proxy as a URI if set; +nil+ otherwise
|
82
84
|
def http_proxy
|
83
|
-
proxy = Gem.configuration[:http_proxy]
|
85
|
+
proxy = Gem.configuration[:http_proxy] || ENV['http_proxy'] || ENV['HTTP_PROXY']
|
84
86
|
return nil if proxy.nil? || proxy == :no_proxy
|
85
87
|
URI.parse(proxy)
|
86
88
|
end
|
87
89
|
|
88
90
|
def ask_for_password(message)
|
89
|
-
|
91
|
+
system "stty -echo"
|
92
|
+
password = ask(message)
|
93
|
+
system "stty echo"
|
90
94
|
ui.say("\n")
|
91
95
|
password
|
92
96
|
end
|
data/lib/commands/migrate.rb
CHANGED
@@ -21,6 +21,10 @@ class Gem::Commands::MigrateCommand < Gem::AbstractCommand
|
|
21
21
|
check_for_approved
|
22
22
|
end
|
23
23
|
|
24
|
+
def project_name
|
25
|
+
rubygem['rubyforge_project'] || rubygem['name']
|
26
|
+
end
|
27
|
+
|
24
28
|
def find(name)
|
25
29
|
require 'json'
|
26
30
|
|
@@ -62,10 +66,18 @@ class Gem::Commands::MigrateCommand < Gem::AbstractCommand
|
|
62
66
|
require 'tempfile'
|
63
67
|
require 'net/scp'
|
64
68
|
|
65
|
-
url = "#{
|
66
|
-
say "Uploading the migration token to #{url}.
|
67
|
-
|
68
|
-
|
69
|
+
url = "#{project_name}.rubyforge.org"
|
70
|
+
say "Uploading the migration token to #{url}."
|
71
|
+
|
72
|
+
rf_cfg_path = "#{Gem.user_home}/.rubyforge/user-config.yml"
|
73
|
+
|
74
|
+
login, password = if File.exists?(rf_cfg_path)
|
75
|
+
rcfg = YAML.load_file(rf_cfg_path)
|
76
|
+
rcfg.values_at('username', 'password')
|
77
|
+
else
|
78
|
+
say "Please enter your RubyForge login:"
|
79
|
+
[ask("Login: "), ask_for_password("Password: ")]
|
80
|
+
end
|
69
81
|
|
70
82
|
begin
|
71
83
|
Net::SCP.start(url, login, :password => password) do |scp|
|
@@ -73,7 +85,7 @@ class Gem::Commands::MigrateCommand < Gem::AbstractCommand
|
|
73
85
|
temp_token.chmod 0644
|
74
86
|
temp_token.write(token)
|
75
87
|
temp_token.close
|
76
|
-
scp.upload! temp_token.path, "/var/www/gforge-projects/#{
|
88
|
+
scp.upload! temp_token.path, "/var/www/gforge-projects/#{project_name}/migrate-#{rubygem['name']}.html"
|
77
89
|
end
|
78
90
|
say "Successfully uploaded your token."
|
79
91
|
rescue Exception => e
|
data/lib/commands/push.rb
CHANGED
@@ -27,7 +27,7 @@ class Gem::Commands::PushCommand < Gem::AbstractCommand
|
|
27
27
|
|
28
28
|
name = get_one_gem_name
|
29
29
|
response = make_request(:post, "gems") do |request|
|
30
|
-
request.body = File.open(name).read
|
30
|
+
request.body = File.open(name, 'rb'){|io| io.read }
|
31
31
|
request.add_field("Content-Length", request.body.size)
|
32
32
|
request.add_field("Content-Type", "application/octet-stream")
|
33
33
|
request.add_field("Authorization", api_key)
|
data/lib/rubygems_plugin.rb
CHANGED
@@ -7,14 +7,3 @@ require 'commands/abstract_command'
|
|
7
7
|
require "commands/#{command}"
|
8
8
|
Gem::CommandManager.instance.register_command command.to_sym
|
9
9
|
end
|
10
|
-
|
11
|
-
URL = "http://gemcutter.org" unless defined?(URL)
|
12
|
-
|
13
|
-
class Gem::StreamUI
|
14
|
-
def ask_for_password(message)
|
15
|
-
system "stty -echo"
|
16
|
-
password = ask(message)
|
17
|
-
system "stty echo"
|
18
|
-
password
|
19
|
-
end
|
20
|
-
end
|
data/test/command_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemcutter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Quaranto
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-21 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -38,8 +38,8 @@ executables: []
|
|
38
38
|
|
39
39
|
extensions: []
|
40
40
|
|
41
|
-
extra_rdoc_files:
|
42
|
-
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
43
|
files:
|
44
44
|
- lib/commands/abstract_command.rb
|
45
45
|
- lib/commands/migrate.rb
|
@@ -47,7 +47,6 @@ files:
|
|
47
47
|
- lib/commands/push.rb
|
48
48
|
- lib/commands/tumble.rb
|
49
49
|
- lib/rubygems_plugin.rb
|
50
|
-
- README.textile
|
51
50
|
has_rdoc: true
|
52
51
|
homepage: http://github.com/qrush/gemcutter
|
53
52
|
licenses: []
|
@@ -55,6 +54,7 @@ licenses: []
|
|
55
54
|
post_install_message: |+
|
56
55
|
|
57
56
|
========================================================================
|
57
|
+
|
58
58
|
Thanks for installing Gemcutter! You can now run:
|
59
59
|
|
60
60
|
gem tumble use Gemcutter as your primary RubyGem source
|
@@ -83,13 +83,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
83
|
requirements: []
|
84
84
|
|
85
85
|
rubyforge_project: gemcutter
|
86
|
-
rubygems_version: 1.3.
|
86
|
+
rubygems_version: 1.3.5
|
87
87
|
signing_key:
|
88
88
|
specification_version: 3
|
89
89
|
summary: Commands to interact with gemcutter.org
|
90
90
|
test_files:
|
91
91
|
- test/command_helper.rb
|
92
|
-
- test/commands/migrate_command_test.rb
|
93
|
-
- test/commands/tumble_command_test.rb
|
94
|
-
- test/commands/push_command_test.rb
|
95
|
-
- test/commands/abstract_command_test.rb
|
data/README.textile
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
h1. gemcutter
|
2
|
-
|
3
|
-
Awesome RubyGem hosting.
|
4
|
-
|
5
|
-
h2. Purpose
|
6
|
-
|
7
|
-
* Provide a better API for dealing with gems
|
8
|
-
* Create more transparent and accessible project pages
|
9
|
-
* Enable the community to improve and enhance the site
|
10
|
-
|
11
|
-
h2. Concerns
|
12
|
-
|
13
|
-
These have been moved on to the "FAQ":http://gemcutter.org/pages/faq.
|
14
|
-
|
15
|
-
h2. Contributions
|
16
|
-
|
17
|
-
Gemcutter has a 'commit-bit' policy, much like the Rubinius project. Submit a patch that is accepted, and you'll get full commit access to the project. Please check the wiki for more information.
|
18
|
-
|
19
|
-
If you're looking for things to hack on, please check GitHub Issues. If you've found bugs or have feature ideas don't be afraid to pipe up and ask the mailing list about them.
|
20
|
-
|
21
|
-
h2. Testing
|
22
|
-
|
23
|
-
Make sure you run @rake gemcutter:index:create@ before running the test suite, otherwise it might complain. Better solutions to this are more than welcome.
|
24
|
-
|
25
|
-
h2. License
|
26
|
-
|
27
|
-
Gemcutter uses the MIT license. Please check the LICENSE file for more details.
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../command_helper'
|
2
|
-
|
3
|
-
class Gem::Commands::FakeCommand < Gem::AbstractCommand
|
4
|
-
def description
|
5
|
-
'fake command'
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
super 'fake', description
|
10
|
-
end
|
11
|
-
|
12
|
-
def execute
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class AbstractCommandTest < CommandTest
|
17
|
-
context "with an fake command" do
|
18
|
-
setup do
|
19
|
-
@command = Gem::Commands::FakeCommand.new
|
20
|
-
stub(@command).say
|
21
|
-
end
|
22
|
-
|
23
|
-
context "parsing the proxy" do
|
24
|
-
should "return nil if no proxy is set" do
|
25
|
-
stub(Gem).configuration { { :http_proxy => nil } }
|
26
|
-
assert_equal nil, @command.http_proxy
|
27
|
-
end
|
28
|
-
|
29
|
-
should "return nil if the proxy is set to :no_proxy" do
|
30
|
-
stub(Gem).configuration { { :http_proxy => :no_proxy } }
|
31
|
-
assert_equal nil, @command.http_proxy
|
32
|
-
end
|
33
|
-
|
34
|
-
should "return a proxy as a URI if set" do
|
35
|
-
stub(Gem).configuration { { :http_proxy => 'http://proxy.example.org:9192' } }
|
36
|
-
assert_equal 'proxy.example.org', @command.http_proxy.host
|
37
|
-
assert_equal 9192, @command.http_proxy.port
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# TODO: rewrite all of this junk using spies
|
42
|
-
#should "use a proxy if specified" do
|
43
|
-
# stub(@command).http_proxy { 'http://some.proxy' }
|
44
|
-
# mock(@command).use_proxy!
|
45
|
-
# mock(@command).sign_in
|
46
|
-
# @command.setup
|
47
|
-
#end
|
48
|
-
|
49
|
-
#should "not use a proxy if unspecified" do
|
50
|
-
# stub(@command).http_proxy { nil }
|
51
|
-
# mock(@command).use_proxy!.never
|
52
|
-
# mock(@command).sign_in
|
53
|
-
# @command.setup
|
54
|
-
#end
|
55
|
-
|
56
|
-
should "sign in if no api key" do
|
57
|
-
stub(Gem).configuration { {:gemcutter_key => nil} }
|
58
|
-
mock(@command).sign_in
|
59
|
-
@command.setup
|
60
|
-
end
|
61
|
-
|
62
|
-
should "not sign in if api key exists" do
|
63
|
-
stub(Gem).configuration { {:gemcutter_key => "1234567890"} }
|
64
|
-
mock(@command).sign_in.never
|
65
|
-
@command.setup
|
66
|
-
end
|
67
|
-
|
68
|
-
context "using the proxy" do
|
69
|
-
setup do
|
70
|
-
stub(Gem).configuration { { :http_proxy => "http://gilbert:sekret@proxy.example.org:8081" } }
|
71
|
-
@proxy_class = Object.new
|
72
|
-
mock(Net::HTTP).Proxy('proxy.example.org', 8081, 'gilbert', 'sekret') { @proxy_class }
|
73
|
-
@command.use_proxy!
|
74
|
-
end
|
75
|
-
|
76
|
-
should "replace Net::HTTP with a proxy version" do
|
77
|
-
assert_equal @proxy_class, @command.proxy_class
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context "signing in" do
|
82
|
-
setup do
|
83
|
-
@email = "email"
|
84
|
-
@password = "password"
|
85
|
-
@key = "key"
|
86
|
-
mock(@command).say("Enter your Gemcutter credentials. Don't have an account yet? Create one at #{URL}/sign_up")
|
87
|
-
mock(@command).ask("Email: ") { @email }
|
88
|
-
mock(@command).ask_for_password("Password: ") { @password }
|
89
|
-
FakeWeb.register_uri :get, "https://#{@email}:#{@password}@gemcutter.heroku.com/api_key", :body => @key
|
90
|
-
|
91
|
-
@config = Object.new
|
92
|
-
stub(Gem).configuration { @config }
|
93
|
-
stub(@config)[:gemcutter_key] = @key
|
94
|
-
stub(@config).write
|
95
|
-
end
|
96
|
-
|
97
|
-
should "sign in" do
|
98
|
-
mock(@command).say("Signed in. Your api key has been stored in ~/.gemrc")
|
99
|
-
@command.sign_in
|
100
|
-
end
|
101
|
-
|
102
|
-
should "let the user know if there was a problem" do
|
103
|
-
@problem = "Access Denied"
|
104
|
-
mock(@command).say(@problem)
|
105
|
-
mock(@command).terminate_interaction
|
106
|
-
mock(@config).write.never
|
107
|
-
|
108
|
-
FakeWeb.register_uri :get, "https://#{@email}:#{@password}@gemcutter.heroku.com/api_key", :body => @problem, :status => 401
|
109
|
-
@command.sign_in
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../command_helper'
|
2
|
-
require 'net/scp'
|
3
|
-
|
4
|
-
class MigrateCommandTest < CommandTest
|
5
|
-
context "executing the command" do
|
6
|
-
setup do
|
7
|
-
@command = Gem::Commands::MigrateCommand.new
|
8
|
-
stub(@command).setup
|
9
|
-
stub(@command).migrate
|
10
|
-
end
|
11
|
-
|
12
|
-
should "setup and send the gem" do
|
13
|
-
@command.execute
|
14
|
-
assert_received(@command) { |subject| subject.setup }
|
15
|
-
assert_received(@command) { |subject| subject.migrate }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context "migrating" do
|
20
|
-
setup do
|
21
|
-
@command = Gem::Commands::MigrateCommand.new
|
22
|
-
@token = "deadbeef"
|
23
|
-
stub(@command).say
|
24
|
-
stub(@command).find
|
25
|
-
stub(@command).get_token { @token }
|
26
|
-
stub(@command).upload_token
|
27
|
-
stub(@command).check_for_approved
|
28
|
-
end
|
29
|
-
|
30
|
-
should "raise an error with no arguments" do
|
31
|
-
assert_raise Gem::CommandLineError do
|
32
|
-
@command.migrate
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
should "migrate the gem" do
|
37
|
-
stub(@command).get_one_gem_name { "mygem" }
|
38
|
-
@command.migrate
|
39
|
-
assert_received(@command) { |subject| subject.find("mygem") }
|
40
|
-
assert_received(@command) { |subject| subject.get_token }
|
41
|
-
assert_received(@command) { |subject| subject.upload_token(@token) }
|
42
|
-
assert_received(@command) { |subject| subject.check_for_approved }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context "ask about the gem" do
|
47
|
-
setup do
|
48
|
-
@command = Gem::Commands::MigrateCommand.new
|
49
|
-
stub(@command).say
|
50
|
-
stub(@command).terminate_interaction
|
51
|
-
|
52
|
-
@name = "rails"
|
53
|
-
@json = "{\"downloads\":4,\"name\":\"rails\",\"authors\":\"David Heinemeier Hansson\",\"version\":\"2.3.3\",\"rubyforge_project\":\"rails\",\"info\":\"Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.\"}"
|
54
|
-
end
|
55
|
-
|
56
|
-
should "find gem info if it exists" do
|
57
|
-
FakeWeb.register_uri :get, "https://gemcutter.heroku.com/gems/#{@name}.json", :body => @json
|
58
|
-
@command.find(@name)
|
59
|
-
assert_equal JSON.parse(@json), @command.rubygem
|
60
|
-
end
|
61
|
-
|
62
|
-
should "dump out if the gem couldn't be found" do
|
63
|
-
FakeWeb.register_uri :get, "https://gemcutter.heroku.com/gems/#{@name}.json", :body => "Not hosted here.", :status => 404
|
64
|
-
@command.find(@name)
|
65
|
-
assert_received(@command) { |subject| subject.say(anything) }
|
66
|
-
assert_received(@command) { |subject| subject.terminate_interaction }
|
67
|
-
end
|
68
|
-
|
69
|
-
should "dump out if bad json is returned" do
|
70
|
-
FakeWeb.register_uri :get, "https://gemcutter.heroku.com/gems/#{@name}.json", :body => "bad data is bad"
|
71
|
-
@command.find(@name)
|
72
|
-
assert_received(@command) { |subject| subject.say(anything) }
|
73
|
-
assert_received(@command) { |subject| subject.terminate_interaction }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context "getting the token" do
|
78
|
-
setup do
|
79
|
-
@command = Gem::Commands::MigrateCommand.new
|
80
|
-
@name = "SomeGem"
|
81
|
-
stub(@command).say
|
82
|
-
stub(@command).terminate_interaction
|
83
|
-
stub(@command).rubygem { { "name" => @name } }
|
84
|
-
end
|
85
|
-
|
86
|
-
should "ask gemcutter to start the migration" do
|
87
|
-
token = "SECRET TOKEN"
|
88
|
-
FakeWeb.register_uri :post, "https://gemcutter.heroku.com/gems/#{@name}/migrate", :body => token
|
89
|
-
assert_equal token, @command.get_token
|
90
|
-
end
|
91
|
-
|
92
|
-
should "dump out if gem could not be found" do
|
93
|
-
FakeWeb.register_uri :post, "https://gemcutter.heroku.com/gems/#{@name}/migrate", :status => 404, :body => "not found"
|
94
|
-
@command.get_token
|
95
|
-
assert_received(@command) { |subject| subject.say("not found") }
|
96
|
-
assert_received(@command) { |subject| subject.terminate_interaction }
|
97
|
-
end
|
98
|
-
|
99
|
-
should "dump out if migration has already been completed" do
|
100
|
-
FakeWeb.register_uri :post, "https://gemcutter.heroku.com/gems/#{@name}/migrate", :status => 403, :body => "already migrated"
|
101
|
-
@command.get_token
|
102
|
-
assert_received(@command) { |subject| subject.say("already migrated") }
|
103
|
-
assert_received(@command) { |subject| subject.terminate_interaction }
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context "uploading the token" do
|
108
|
-
setup do
|
109
|
-
@command = Gem::Commands::MigrateCommand.new
|
110
|
-
@token = "deadbeef"
|
111
|
-
stub(@command).say
|
112
|
-
stub(@command).rubygem { { "rubyforge_project" => "bostonrb" } }
|
113
|
-
stub(Net::SCP).start
|
114
|
-
end
|
115
|
-
|
116
|
-
should "connect to rubyforge and upload away" do
|
117
|
-
stub(@command).ask { "user" }
|
118
|
-
stub(@command).ask_for_password { "secret" }
|
119
|
-
@command.upload_token(@token)
|
120
|
-
|
121
|
-
# TODO: figure out how to test the upload! in the block
|
122
|
-
assert_received(Net::SCP) { |subject| subject.start("bostonrb.rubyforge.org", "user", :password => "secret") }
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
context "checking if the rubygem was approved" do
|
127
|
-
setup do
|
128
|
-
@command = Gem::Commands::MigrateCommand.new
|
129
|
-
@name = "rails"
|
130
|
-
|
131
|
-
stub(@command).say
|
132
|
-
stub(@command).rubygem { { "name" => @name } }
|
133
|
-
end
|
134
|
-
|
135
|
-
should "let the server decide the status" do
|
136
|
-
FakeWeb.register_uri :put, "https://gemcutter.heroku.com/gems/#{@name}/migrate", :body => "Success!", :status => 400
|
137
|
-
@command.check_for_approved
|
138
|
-
assert_received(@command) { |subject| subject.say("Success!") }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../command_helper'
|
2
|
-
|
3
|
-
class PushCommandTest < CommandTest
|
4
|
-
context "pushing" do
|
5
|
-
setup do
|
6
|
-
@command = Gem::Commands::PushCommand.new
|
7
|
-
stub(@command).say
|
8
|
-
end
|
9
|
-
|
10
|
-
should "setup and send the gem" do
|
11
|
-
mock(@command).setup
|
12
|
-
mock(@command).send_gem
|
13
|
-
@command.execute
|
14
|
-
end
|
15
|
-
|
16
|
-
should "raise an error with no arguments" do
|
17
|
-
assert_raise Gem::CommandLineError do
|
18
|
-
@command.send_gem
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
should "push a gem" do
|
23
|
-
mock(@command).say("Pushing gem to Gemcutter...")
|
24
|
-
@response = "success"
|
25
|
-
FakeWeb.register_uri :post, "https://gemcutter.heroku.com/gems", :body => @response
|
26
|
-
|
27
|
-
@gem = "test"
|
28
|
-
@io = "io"
|
29
|
-
@config = { :gemcutter_key => "key" }
|
30
|
-
|
31
|
-
stub(File).open(@gem) { @io }
|
32
|
-
stub(@io).read.stub!.size
|
33
|
-
|
34
|
-
stub(@command).options { {:args => [@gem]} }
|
35
|
-
stub(Gem).configuration { @config }
|
36
|
-
|
37
|
-
mock(@command).say(@response)
|
38
|
-
@command.send_gem
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../command_helper'
|
2
|
-
|
3
|
-
class TumbleCommandTest < CommandTest
|
4
|
-
context "with a tumbler and some sources" do
|
5
|
-
setup do
|
6
|
-
@sources = ["gems.rubyforge.org", URL]
|
7
|
-
stub(Gem).sources { @sources }
|
8
|
-
@command = Gem::Commands::TumbleCommand.new
|
9
|
-
end
|
10
|
-
|
11
|
-
should "show sources" do
|
12
|
-
mock(@command).say("Your gem sources are now:")
|
13
|
-
mock(@command).say("- #{@sources.first}")
|
14
|
-
mock(@command).say("- #{URL}")
|
15
|
-
@command.show_sources
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context "tumbling the gem sources" do
|
20
|
-
setup do
|
21
|
-
@sources = ["http://rubyforge.org"]
|
22
|
-
stub(Gem).sources { @sources }
|
23
|
-
@config = Object.new
|
24
|
-
stub(Gem).configuration { @config }
|
25
|
-
|
26
|
-
@command = Gem::Commands::TumbleCommand.new
|
27
|
-
end
|
28
|
-
|
29
|
-
should "add gemcutter as first source" do
|
30
|
-
mock(@sources).unshift(URL)
|
31
|
-
mock(@config).write
|
32
|
-
|
33
|
-
@command.tumble
|
34
|
-
end
|
35
|
-
|
36
|
-
should "remove gemcutter if it's in the sources" do
|
37
|
-
mock(@sources).include?(URL) { true }
|
38
|
-
mock(@config).write
|
39
|
-
mock(@sources).delete(URL)
|
40
|
-
|
41
|
-
@command.tumble
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "executing the tumbler" do
|
46
|
-
setup do
|
47
|
-
@command = Gem::Commands::TumbleCommand.new
|
48
|
-
end
|
49
|
-
|
50
|
-
should "say thanks, tumble and show the sources" do
|
51
|
-
mock(@command).say(anything)
|
52
|
-
mock(@command).tumble
|
53
|
-
mock(@command).show_sources
|
54
|
-
|
55
|
-
@command.execute
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|