Skip to content

Commit

Permalink
Implement unyank for local and remote repositories.
Browse files Browse the repository at this point in the history
Fixes: #9
  • Loading branch information
urfolomeus authored and latentflip committed Mar 7, 2013
1 parent ca4c88f commit dcf69fb
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 1 deletion.
50 changes: 50 additions & 0 deletions lib/stickler/client/unyank.rb
@@ -0,0 +1,50 @@
module Stickler
class Client
class Unyank < Stickler::Client
def self.banner
<<-_
Restore a yanked gem to the gemserver's index.
Usage: stickler unyank [options] --gem-version x.y.z gem
Options:
_
end

def parser
unless @parser then
@parser = super
@parser.opt( :gem_version, "The version of the gem to unyank (required)", :type => :string, :required => true )
@parser.opt( :platform, "The platform of the gem to unyank", :type => :string, :default => ::Gem::Platform::RUBY )
end
return @parser
end

def parse( argv )
gem_name = nil
opts = super( argv ) do |p|
raise Trollop::CommandlineError, "At least one gem is required to unyank" if p.leftovers.empty?
gem_name = p.leftovers.shift
end
opts[:gem_name] = gem_name
return opts
end

def run
opts = parse( self.argv )
repo = remote_repo_for( opts )
spec = Stickler::SpecLite.new( opts[:gem_name], opts[:gem_version], opts[:platform] )

$stdout.write "Unyanking gem #{spec.full_name} from #{repo.uri} : "
$stdout.flush
if spec = repo.unyank( spec ) then
$stdout.puts "OK"
else
$stdout.puts "FAILURE"
end
rescue Stickler::Repository::Error => e
$stdout.puts "ERROR: #{e.message}"
end
end
end
end
13 changes: 13 additions & 0 deletions lib/stickler/middleware/gemcutter.rb
Expand Up @@ -41,6 +41,19 @@ def initialize( app = nil, options = {} )
end
end

# gemcutter unyank
post '/api/v1/gems/unyank' do
begin
spec = Stickler::SpecLite.new( params[:spec_name], params[:version] )
@repo.unyank( spec )
logger.info( "Unyanked #{spec.full_name}" )
return spec.to_s
rescue Stickler::Repository::Error => e
logger.error( "Error unyanking #{spec.full_name} to repo : #{e}" )
error( 500, "Error unyanking gem to repo: #{e}" )
end
end

# gemcutter yank
delete '/api/v1/gems/yank' do
spec = Stickler::SpecLite.new( params[:gem_name], params[:version] )
Expand Down
12 changes: 11 additions & 1 deletion lib/stickler/repository/local.rb
Expand Up @@ -162,6 +162,15 @@ def yank( spec )
return uri_for_gem( spec )
end

#
# See Api#unyank
#
def unyank( spec )
return nil if specification_file_exist?( spec )
return nil unless gem_file_exist?( spec )
install_specification( spec )
end


#
# :call-seq:
Expand Down Expand Up @@ -194,7 +203,8 @@ def add( io )
# See Api#push
#
def push( path )
spec = specification_from_gem_file( path )
# is this line needed? Never used.
# spec = specification_from_gem_file( path )
result = nil
File.open( path ) do |io|
result = add( io )
Expand Down
27 changes: 27 additions & 0 deletions lib/stickler/repository/remote.rb
Expand Up @@ -95,6 +95,19 @@ def yank( spec )
raise Stickler::Repository::Error, "Failure yanking: #{e.inspect}"
end

#
# See Api#unyank
#
def unyank( spec )
return nil unless remote_gem_file_exist?( spec )
query = { :spec_name => spec.name, :version => spec.version.to_s }
resp = resource_request( unyank_resource, :query => query )
true
rescue Excon::Errors::Error => e
# raise Stickler::Repository::Error, "Failure unyanking: #{e.inspect}"
[]
end

#
# See Api#delete
#
Expand Down Expand Up @@ -179,6 +192,10 @@ def yank_uri
Addressable::URI.join( uri, "api/v1/gems/yank" )
end

def unyank_uri
Addressable::URI.join( uri, "api/v1/gems/unyank" )
end

def yank_resource
unless @yank_resource then
params = { :method => :delete,
Expand All @@ -188,6 +205,16 @@ def yank_resource
end
return @yank_resource
end

def unyank_resource
unless @unyank_resource then
params = { :method => :post,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
:expects => [200] }
@unyank_resource = Excon.new( unyank_uri.to_s, params )
end
return @unyank_resource
end

def gem_resource( spec )
Excon.new( full_uri_to_gem( spec ), :method => :get, :expects => [200] )
Expand Down
32 changes: 32 additions & 0 deletions spec/repository/api_behavior.rb
Expand Up @@ -104,6 +104,38 @@

end

describe "#unyank" do
before( :each ) do
@repo.search_for( @foo_spec ).should be_empty
@repo.push( @foo_gem_local_path )
end

it "returns nil if the gem to unyank does not exist" do
non_existing_gem = @missing_spec
@repo.unyank( non_existing_gem ).should be_nil
end

#Do we even care about this?
xit "returns nil if the gem to unyank has not been yanked" do
@repo.unyank( @foo_spec ).should be_nil
end

context " when file has been yanked" do
before :each do
@repo.yank( @foo_spec )
end

it "return true if the gem is successfully unyanked" do
@repo.unyank( @foo_spec ).should be_true
end

it "finds the gem in a search" do
@repo.unyank( @foo_spec )
@repo.search_for( @foo_spec ).should_not be_empty
end
end
end

describe "#search_for" do
it "returns specs for items that are found" do
@repo.push( @foo_gem_local_path )
Expand Down

0 comments on commit dcf69fb

Please sign in to comment.