mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
3434676e9e
Added missing require for `gem uninstall --format-executable`. The correct name of the executable being uninstalled is now displayed with --format-executable. Fixed `gem unpack uninstalled_gem` default version picker. RubyGems no longer claims a nonexistent gem can be uninstalled. `gem which` no longer claims directories are requirable files. `gem cleanup` continues cleaning up gems if one can't be uninstalled due to permissions. Issue #82. Gem repository directories are no longer created world-writable. Patch by Sakuro OZAWA. [Ruby 1.9 - Bug #4930] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32852 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
160 lines
3.5 KiB
Ruby
160 lines
3.5 KiB
Ruby
require 'tempfile'
|
|
require 'rubygems'
|
|
require 'rubygems/remote_fetcher'
|
|
|
|
##
|
|
# A fake Gem::RemoteFetcher for use in tests or to avoid real live HTTP
|
|
# requests when testing code that uses RubyGems.
|
|
#
|
|
# Example:
|
|
#
|
|
# @fetcher = Gem::FakeFetcher.new
|
|
# @fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml
|
|
# Gem::RemoteFetcher.fetcher = @fetcher
|
|
#
|
|
# # invoke RubyGems code
|
|
#
|
|
# paths = @fetcher.paths
|
|
# assert_equal 'http://gems.example.com/yaml', paths.shift
|
|
# assert paths.empty?, paths.join(', ')
|
|
#
|
|
# See RubyGems' tests for more examples of FakeFetcher.
|
|
|
|
class Gem::FakeFetcher
|
|
|
|
attr_reader :data
|
|
attr_reader :last_request
|
|
attr_accessor :paths
|
|
|
|
def initialize
|
|
@data = {}
|
|
@paths = []
|
|
end
|
|
|
|
def find_data(path)
|
|
path = path.to_s
|
|
@paths << path
|
|
raise ArgumentError, 'need full URI' unless path =~ %r'^https?://'
|
|
|
|
unless @data.key? path then
|
|
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
|
|
end
|
|
|
|
@data[path]
|
|
end
|
|
|
|
def fetch_path path, mtime = nil
|
|
data = find_data(path)
|
|
|
|
if data.respond_to?(:call) then
|
|
data.call
|
|
else
|
|
if path.to_s =~ /gz$/ and not data.nil? and not data.empty? then
|
|
data = Gem.gunzip data
|
|
end
|
|
|
|
data
|
|
end
|
|
end
|
|
|
|
# Thanks, FakeWeb!
|
|
def open_uri_or_path(path)
|
|
data = find_data(path)
|
|
body, code, msg = data
|
|
|
|
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
|
|
response.instance_variable_set(:@body, body)
|
|
response.instance_variable_set(:@read, true)
|
|
response
|
|
end
|
|
|
|
def request(uri, request_class, last_modified = nil)
|
|
data = find_data(uri)
|
|
body, code, msg = data
|
|
|
|
@last_request = request_class.new uri.request_uri
|
|
yield @last_request if block_given?
|
|
|
|
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
|
|
response.instance_variable_set(:@body, body)
|
|
response.instance_variable_set(:@read, true)
|
|
response
|
|
end
|
|
|
|
def fetch_size(path)
|
|
path = path.to_s
|
|
@paths << path
|
|
|
|
raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
|
|
|
|
unless @data.key? path then
|
|
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
|
|
end
|
|
|
|
data = @data[path]
|
|
|
|
data.respond_to?(:call) ? data.call : data.length
|
|
end
|
|
|
|
def download spec, source_uri, install_dir = Gem.dir
|
|
name = File.basename spec.cache_file
|
|
path = File.join install_dir, "cache", name
|
|
|
|
Gem.ensure_gem_subdirectories install_dir
|
|
|
|
if source_uri =~ /^http/ then
|
|
File.open(path, "wb") do |f|
|
|
f.write fetch_path(File.join(source_uri, "gems", name))
|
|
end
|
|
else
|
|
FileUtils.cp source_uri, path
|
|
end
|
|
|
|
path
|
|
end
|
|
|
|
def download_to_cache dependency
|
|
found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
|
|
dependency.prerelease?
|
|
|
|
return if found.empty?
|
|
|
|
spec, source_uri = found.first
|
|
|
|
download spec, source_uri
|
|
end
|
|
|
|
end
|
|
|
|
# :stopdoc:
|
|
class Gem::RemoteFetcher
|
|
|
|
def self.fetcher=(fetcher)
|
|
@fetcher = fetcher
|
|
end
|
|
|
|
end
|
|
# :startdoc:
|
|
|
|
##
|
|
# A StringIO duck-typed class that uses Tempfile instead of String as the
|
|
# backing store.
|
|
#
|
|
# This is available when rubygems/test_utilities is required.
|
|
#--
|
|
# This class was added to flush out problems in Rubinius' IO implementation.
|
|
|
|
class TempIO < Tempfile
|
|
def initialize(string = '')
|
|
super "TempIO"
|
|
binmode
|
|
write string
|
|
rewind
|
|
end
|
|
|
|
def string
|
|
flush
|
|
Gem.read_binary path
|
|
end
|
|
end
|
|
|