lib/chef/provider/package/rubygems.rb in chef-11.4.4 vs lib/chef/provider/package/rubygems.rb in chef-11.6.0.hotfix.1
- old
+ new
@@ -29,11 +29,18 @@
# list
require 'rubygems/version'
require 'rubygems/dependency'
require 'rubygems/spec_fetcher'
require 'rubygems/platform'
-require 'rubygems/format'
+
+# Compatibility note: Rubygems 2.0 removes rubygems/format in favor of
+# rubygems/package.
+begin
+ require 'rubygems/format'
+rescue LoadError
+ require 'rubygems/package'
+end
require 'rubygems/dependency_installer'
require 'rubygems/uninstaller'
require 'rubygems/specification'
class Chef
@@ -104,19 +111,35 @@
ensure
Gem.sources = original_sources
end
##
+ # Extracts the gemspec from a (on-disk) gem package.
+ # === Returns
+ # Gem::Specification
+ #
+ #--
+ # Compatibility note: Rubygems 1.x uses Gem::Format, 2.0 moved this
+ # code into Gem::Package.
+ def spec_from_file(file)
+ if defined?(Gem::Format) and Gem::Package.respond_to?(:open)
+ Gem::Format.from_file_by_path(file).spec
+ else
+ Gem::Package.new(file).spec
+ end
+ end
+
+ ##
# Determines the candidate version for a gem from a .gem file on disk
# and checks if it matches the version contraints in +gem_dependency+
# === Returns
# Gem::Version a singular gem version object is returned if the gem
# is available
# nil returns nil if the gem on disk doesn't match the
# version constraints for +gem_dependency+
def candidate_version_from_file(gem_dependency, source)
- spec = Gem::Format.from_file_by_path(source).spec
+ spec = spec_from_file(source)
if spec.satisfies_requirement?(gem_dependency)
logger.debug {"#{@new_resource} found candidate gem version #{spec.version} from local gem package #{source}"}
spec.version
else
# This is probably going to end badly...
@@ -140,21 +163,30 @@
##
# Find the newest gem version available from Gem.sources that satisfies
# the constraints of +gem_dependency+
def find_newest_remote_version(gem_dependency, *sources)
- # DependencyInstaller sorts the results such that the last one is
- # always the one it considers best.
- spec_with_source = dependency_installer.find_gems_with_sources(gem_dependency).last
+ available_gems = dependency_installer.find_gems_with_sources(gem_dependency)
+ spec, source = if available_gems.respond_to?(:last)
+ # DependencyInstaller sorts the results such that the last one is
+ # always the one it considers best.
+ spec_with_source = available_gems.last
+ spec_with_source && spec_with_source
+ else
+ # Rubygems 2.0 returns a Gem::Available set, which is a
+ # collection of AvailableSet::Tuple structs
+ available_gems.pick_best!
+ best_gem = available_gems.set.first
+ best_gem && [best_gem.spec, best_gem.source]
+ end
- spec = spec_with_source && spec_with_source[0]
- version = spec && spec_with_source[0].version
+ version = spec && spec.version
if version
- logger.debug { "#{@new_resource} found gem #{spec.name} version #{version} for platform #{spec.platform} from #{spec_with_source[1]}" }
+ logger.debug { "#{@new_resource} found gem #{spec.name} version #{version} for platform #{spec.platform} from #{source}" }
version
else
- source_list = sources.compact.empty? ? "[#{Gem.sources.join(', ')}]" : "[#{sources.join(', ')}]"
+ source_list = sources.compact.empty? ? "[#{Gem.sources.to_a.join(', ')}]" : "[#{sources.join(', ')}]"
logger.warn { "#{@new_resource} failed to find gem #{gem_dependency} from #{source_list}" }
nil
end
end
@@ -391,10 +423,13 @@
return true if @new_resource.source.nil?
scheme = URI.parse(@new_resource.source).scheme
# URI.parse gets confused by MS Windows paths with forward slashes.
scheme = nil if scheme =~ /^[a-z]$/
%w{http https}.include?(scheme)
+ rescue URI::InvalidURIError
+ Chef::Log.debug("#{@new_resource} failed to parse source '#{@new_resource.source}' as a URI, assuming a local path")
+ false
end
def current_version
#raise 'todo'
# If one or more matching versions are installed, the newest of them
@@ -500,10 +535,10 @@
src = @new_resource.source && " --source=#{@new_resource.source} --source=http://rubygems.org"
end
if version
shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
else
- shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri #{src}#{opts}", :env=>nil)
+ shell_out!("#{gem_binary_path} install \"#{name}\" -q --no-rdoc --no-ri #{src}#{opts}", :env=>nil)
end
end
def upgrade_package(name, version)
install_package(name, version)