lib/bundler/source.rb in bundler-1.1.pre.4 vs lib/bundler/source.rb in bundler-1.1.pre.5
- old
+ new
@@ -9,10 +9,11 @@
module Bundler
module Source
# TODO: Refactor this class
class Rubygems
attr_reader :remotes, :caches
+ attr_accessor :dependencies
def initialize(options = {})
@options = options
@remotes = (options["remotes"] || []).map { |r| normalize_uri(r) }
@fetchers = {}
@@ -63,55 +64,49 @@
remote_names = self.remotes.map { |r| r.to_s }.join(', ')
"rubygems repository #{remote_names}"
end
alias_method :name, :to_s
- def specs(dependencies = nil)
- @specs ||= fetch_specs(dependencies)
+ def specs
+ @specs ||= fetch_specs
end
def fetch(spec)
spec, uri = @spec_fetch_map[spec.full_name]
if spec
path = download_gem_from_uri(spec, uri)
s = Bundler.rubygems.spec_from_gem(path)
- spec.__swap__(s)
+ spec.__swap__(s) if spec.is_a?(RemoteSpecification)
end
end
- def outdated(spec)
- installed_spec = installed_specs[spec.name]
- installed_spec = installed_spec.first
-
- if installed_spec && spec.version == installed_spec.version
- Bundler.ui.debug "Up to date: #{spec.name} (#{installed_spec.version}) "
- return
- end
-
- Bundler.ui.info "#{spec.name} (#{spec.version} > #{installed_spec.version}) "
- end
-
def install(spec)
- path = cached_gem(spec)
-
if installed_specs[spec].any?
Bundler.ui.info "Using #{spec.name} (#{spec.version}) "
return
end
Bundler.ui.info "Installing #{spec.name} (#{spec.version}) "
+ path = cached_gem(spec)
- install_path = Bundler.requires_sudo? ? Bundler.tmp : Bundler.rubygems.gem_dir
- options = { :install_dir => install_path,
- :ignore_dependencies => true,
- :wrappers => true,
- :env_shebang => true }
- options.merge!(:bin_dir => "#{install_path}/bin") unless spec.executables.nil? || spec.executables.empty?
+ Bundler.rubygems.preserve_paths do
- installer = Gem::Installer.new path, options
- installer.install
+ install_path = Bundler.requires_sudo? ? Bundler.tmp : Bundler.rubygems.gem_dir
+ options = { :install_dir => install_path,
+ :ignore_dependencies => true,
+ :wrappers => true,
+ :env_shebang => true }
+ options.merge!(:bin_dir => "#{install_path}/bin") unless spec.executables.nil? || spec.executables.empty?
+ installer = Gem::Installer.new path, options
+ installer.install
+ end
+
+ if spec.post_install_message
+ Installer.post_install_messages[spec.name] = spec.post_install_message
+ end
+
# SUDO HAX
if Bundler.requires_sudo?
sudo "mkdir -p #{Bundler.rubygems.gem_dir}/gems #{Bundler.rubygems.gem_dir}/specifications"
sudo "cp -R #{Bundler.tmp}/gems/#{spec.full_name} #{Bundler.rubygems.gem_dir}/gems/"
sudo "cp -R #{Bundler.tmp}/specifications/#{spec.full_name}.gemspec #{Bundler.rubygems.gem_dir}/specifications/"
@@ -149,26 +144,30 @@
private
def cached_gem(spec)
possibilities = @caches.map { |p| "#{p}/#{spec.file_name}" }
- possibilities.find { |p| File.exist?(p) }
+ cached_gem = possibilities.find { |p| File.exist?(p) }
+ unless cached_gem
+ raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
+ end
+ cached_gem
end
def normalize_uri(uri)
uri = uri.to_s
uri = "#{uri}/" unless uri =~ %r'/$'
uri = URI(uri)
raise ArgumentError, "The source must be an absolute URI" unless uri.absolute?
uri
end
- def fetch_specs(dependencies = nil)
+ def fetch_specs
Index.build do |idx|
idx.use installed_specs
idx.use cached_specs if @allow_cached || @allow_remote
- idx.use remote_specs(dependencies) if @allow_remote
+ idx.use remote_specs if @allow_remote
end
end
def installed_specs
@installed_specs ||= begin
@@ -204,11 +203,11 @@
@cached_specs ||= begin
idx = installed_specs.dup
path = Bundler.app_cache
Dir["#{path}/*.gem"].each do |gemfile|
- next if gemfile =~ /bundler\-[\d\.]+?\.gem/
+ next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
begin
s ||= Bundler.rubygems.spec_from_gem(gemfile)
rescue Gem::Package::FormatError
raise GemspecError, "Could not read gem at #{gemfile}. It may be corrupted."
@@ -220,32 +219,21 @@
end
idx
end
- def remote_specs(dependencies = nil)
+ def remote_specs
@remote_specs ||= begin
idx = Index.new
old = Bundler.rubygems.sources
remotes.each do |uri|
- Bundler.ui.info "Fetching source index for #{uri}"
@fetchers[uri] = Bundler::Fetcher.new(uri)
- gem_names =
- if dependencies
- dependencies.map {|d| d.name }
- end
- @fetchers[uri].fetch_remote_specs(gem_names) do |n,v|
- v.each do |name, version, platform|
- next if name == 'bundler'
- spec = RemoteSpecification.new(name, version, platform, @fetchers[uri])
- spec.source = self
- @spec_fetch_map[spec.full_name] = [spec, uri]
- idx << spec
- end
- end
+ gem_names = dependencies && dependencies.map{|d| d.name }
+
+ idx.use @fetchers[uri].specs(gem_names, self, @spec_fetch_map)
end
idx
ensure
Bundler.rubygems.sources = old
end
@@ -601,10 +589,23 @@
input = uri
end
Digest::SHA1.hexdigest(input)
end
+ # Escape the URI for git commands
+ def uri_escaped
+ if Bundler::WINDOWS
+ # Windows quoting requires double quotes only, with double quotes
+ # inside the string escaped by being doubled.
+ '"' + uri.gsub('"') {|s| '""'} + '"'
+ else
+ # Bash requires single quoted strings, with the single quotes escaped
+ # by ending the string, escaping the quote, and restarting the string.
+ "'" + uri.gsub("'") {|s| "'\\''"} + "'"
+ end
+ end
+
def cache_path
@cache_path ||= begin
git_scope = "#{base_name}-#{uri_hash}"
if Bundler.requires_sudo?
@@ -618,23 +619,24 @@
def cache
if cached?
return if has_revision_cached?
Bundler.ui.info "Updating #{uri}"
in_cache do
- git %|fetch --force --quiet --tags "#{uri}" "refs/heads/*:refs/heads/*"|
+ git %|fetch --force --quiet --tags #{uri_escaped} "refs/heads/*:refs/heads/*"|
end
else
Bundler.ui.info "Fetching #{uri}"
FileUtils.mkdir_p(cache_path.dirname)
- git %|clone "#{uri}" "#{cache_path}" --bare --no-hardlinks|
+ git %|clone #{uri_escaped} "#{cache_path}" --bare --no-hardlinks|
end
end
def checkout
unless File.exist?(path.join(".git"))
FileUtils.mkdir_p(path.dirname)
FileUtils.rm_rf(path)
git %|clone --no-checkout "#{cache_path}" "#{path}"|
+ File.chmod((0777 & ~File.umask), path)
end
Dir.chdir(path) do
git %|fetch --force --quiet --tags "#{cache_path}"|
git "reset --hard #{revision}"