# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 28
def initialize(uri)
require_relative "uri"
@uri = Gem::Uri.parse!(uri)
@update_cache = nil
end
Creates a new Source
which will use the index located at uri
.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 37
def <=>(other)
case other
when Gem::Source::Installed,
Gem::Source::Local,
Gem::Source::Lock,
Gem::Source::SpecificFile,
Gem::Source::Git,
Gem::Source::Vendor then
-1
when Gem::Source then
unless @uri
return 0 unless other.uri
return 1
end
return -1 unless other.uri
# Returning 1 here ensures that when sorting a list of sources, the
# original ordering of sources supplied by the user is preserved.
return 1 unless @uri.to_s == other.uri.to_s
0
end
end
Sources are ordered by installation preference.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 84
def cache_dir(uri)
# Correct for windows paths
escaped_path = uri.path.sub(%r{^/([a-z]):/}i, '/\\1-/')
File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
end
Returns the local directory to write uri
to.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 73
def dependency_resolver_set(prerelease = false)
new_dependency_resolver_set.tap {|set| set.prerelease = prerelease }
end
Returns a Set
that can fetch specifications from this source.
The set will optionally fetch prereleases if requested.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 193
def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher
fetcher.download spec, uri.to_s, dir
end
Downloads spec
and writes it to dir
. See also Gem::RemoteFetcher#download
.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 243
def enforce_trailing_slash(uri)
uri.merge(uri.path.gsub(%r{/+$}, "") + "/")
end
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 107
def fetch_spec(name_tuple)
fetcher = Gem::RemoteFetcher.fetcher
spec_file_name = name_tuple.spec_name
source_uri = enforce_trailing_slash(uri) + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
cache_dir = cache_dir source_uri
local_spec = File.join cache_dir, spec_file_name
if File.exist? local_spec
spec = Gem.read_binary local_spec
Gem.load_safe_marshal
spec = begin
Gem::SafeMarshal.safe_load(spec)
rescue StandardError
nil
end
return spec if spec
end
source_uri.path << ".rz"
spec = fetcher.fetch_path source_uri
spec = Gem::Util.inflate spec
if update_cache?
require "fileutils"
FileUtils.mkdir_p cache_dir
File.open local_spec, "wb" do |io|
io.write spec
end
end
Gem.load_safe_marshal
# TODO: Investigate setting Gem::Specification#loaded_from to a URI
Gem::SafeMarshal.safe_load spec
end
Fetches a specification for the given name_tuple
.
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 159
def load_specs(type)
file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}"
spec_path = enforce_trailing_slash(uri) + "#{file_name}.gz"
cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name)
retried = false
if update_cache?
require "fileutils"
FileUtils.mkdir_p cache_dir
end
spec_dump = fetcher.cache_update_path spec_path, local_file, update_cache?
Gem.load_safe_marshal
begin
Gem::NameTuple.from_list Gem::SafeMarshal.safe_load(spec_dump)
rescue ArgumentError
if update_cache? && !retried
FileUtils.rm local_file
retried = true
retry
else
raise Gem::Exception.new("Invalid spec cache file in #{local_file}")
end
end
end
Loads type
kind of specs fetching from +@uri+ if the on-disk cache is out of date.
type
is one of the following:
:released => Return the list of all released specs :latest => Return the list of only the highest version of each gem :prerelease => Return the list of all prerelease only specs
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 220
def new_dependency_resolver_set
return Gem::Resolver::IndexSet.new self if uri.scheme == "file"
fetch_uri = if uri.host == "rubygems.org"
index_uri = uri.dup
index_uri.host = "index.rubygems.org"
index_uri
else
uri
end
bundler_api_uri = enforce_trailing_slash(fetch_uri) + "versions"
begin
fetcher = Gem::RemoteFetcher.fetcher
response = fetcher.fetch_path bundler_api_uri, nil, true
rescue Gem::RemoteFetcher::FetchError
Gem::Resolver::IndexSet.new self
else
Gem::Resolver::APISet.new response.uri + "./info/"
end
end
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 213
def typo_squatting?(host, distance_threshold=4)
return if @uri.host.nil?
levenshtein_distance(@uri.host, host).between? 1, distance_threshold
end
# File tmp/rubies/ruby-master/lib/rubygems/source.rb, line 94
def update_cache?
return @update_cache unless @update_cache.nil?
@update_cache =
begin
File.stat(Gem.user_home).uid == Process.uid
rescue Errno::ENOENT
false
end
end
Returns true when it is possible and safe to update the cache directory.