ruby-changes:60573
From: David <ko1@a...>
Date: Mon, 30 Mar 2020 13:00:59 +0900 (JST)
Subject: [ruby-changes:60573] 9d5e7d6c67 (master): [rubygems/rubygems] Revert "Remove Gem::DependencyInstaller#find_gems_with_sources"
https://git.ruby-lang.org/ruby.git/commit/?id=9d5e7d6c67 From 9d5e7d6c67b084649a6966c69032dd35b1e16b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...> Date: Sun, 22 Mar 2020 12:50:56 +0100 Subject: [rubygems/rubygems] Revert "Remove Gem::DependencyInstaller#find_gems_with_sources" This reverts commit 04c79d3eb9d9803d9fae78575b125b325b97206e. Final removal is postponed until next year until we find a better way to manage deprecations. https://github.com/rubygems/rubygems/commit/3e1cf918a5 diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index 14ff8be..fe89b00 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -7,6 +7,7 @@ require 'rubygems/spec_fetcher' https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L7 require 'rubygems/user_interaction' require 'rubygems/source' require 'rubygems/available_set' +require 'rubygems/deprecate' ## # Installs a gem along with all its dependencies from local and remote gems. @@ -14,6 +15,7 @@ require 'rubygems/available_set' https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L15 class Gem::DependencyInstaller include Gem::UserInteraction + extend Gem::Deprecate DEFAULT_OPTIONS = { # :nodoc: :env_shebang => false, @@ -120,6 +122,81 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L122 @domain == :both or @domain == :remote end + ## + # Returns a list of pairs of gemspecs and source_uris that match + # Gem::Dependency +dep+ from both local (Dir.pwd) and remote (Gem.sources) + # sources. Gems are sorted with newer gems preferred over older gems, and + # local gems preferred over remote gems. + + def find_gems_with_sources(dep, best_only=false) # :nodoc: + set = Gem::AvailableSet.new + + if consider_local? + sl = Gem::Source::Local.new + + if spec = sl.find_gem(dep.name) + if dep.matches_spec? spec + set.add spec, sl + end + end + end + + if consider_remote? + begin + # This is pulled from #spec_for_dependency to allow + # us to filter tuples before fetching specs. + tuples, errors = Gem::SpecFetcher.fetcher.search_for_dependency dep + + if best_only && !tuples.empty? + tuples.sort! do |a,b| + if b[0].version == a[0].version + if b[0].platform != Gem::Platform::RUBY + 1 + else + -1 + end + else + b[0].version <=> a[0].version + end + end + tuples = [tuples.first] + end + + specs = [] + tuples.each do |tup, source| + begin + spec = source.fetch_spec(tup) + rescue Gem::RemoteFetcher::FetchError => e + errors << Gem::SourceFetchProblem.new(source, e) + else + specs << [spec, source] + end + end + + if @errors + @errors += errors + else + @errors = errors + end + + set << specs + + rescue Gem::RemoteFetcher::FetchError => e + # FIX if there is a problem talking to the network, we either need to always tell + # the user (no really_verbose) or fail hard, not silently tell them that we just + # couldn't find their requested gem. + verbose do + "Error fetching remote data:\t\t#{e.message}\n" \ + "Falling back to local-only install" + end + @domain = :local + end + end + + set + end + deprecate :find_gems_with_sources, :none, 2020, 12 + def in_background(what) # :nodoc: fork_happened = false if @build_docs_in_background and Process.respond_to?(:fork) diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 50ae3f0..e7a72c1 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -911,6 +911,117 @@ class TestGemDependencyInstaller < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_dependency_installer.rb#L911 assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name } end + def test_find_gems_gems_with_sources + util_setup_gems + + inst = Gem::DependencyInstaller.new + dep = Gem::Dependency.new 'b', '>= 0' + + Gem::Specification.reset + + set = Gem::Deprecate.skip_during do + inst.find_gems_with_sources(dep) + end + + assert_kind_of Gem::AvailableSet, set + + s = set.set.first + + assert_equal @b1, s.spec + assert_equal Gem::Source.new(@gem_repo), s.source + end + + def test_find_gems_with_sources_local + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + inst = Gem::DependencyInstaller.new + dep = Gem::Dependency.new 'a', '>= 0' + set = nil + + Dir.chdir @tempdir do + set = Gem::Deprecate.skip_during do + inst.find_gems_with_sources dep + end + end + + gems = set.sorted + + assert_equal 2, gems.length + + remote, local = gems + + assert_equal 'a-1', local.spec.full_name, 'local spec' + assert_equal File.join(@tempdir, @a1.file_name), + local.source.download(local.spec), 'local path' + + assert_equal 'a-1', remote.spec.full_name, 'remote spec' + assert_equal Gem::Source.new(@gem_repo), remote.source, 'remote path' + end + + def test_find_gems_with_sources_prerelease + util_setup_gems + + installer = Gem::DependencyInstaller.new + + dependency = Gem::Dependency.new('a', Gem::Requirement.default) + + set = Gem::Deprecate.skip_during do + installer.find_gems_with_sources(dependency) + end + + releases = set.all_specs + + assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' } + refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' } + + dependency.prerelease = true + + set = Gem::Deprecate.skip_during do + installer.find_gems_with_sources(dependency) + end + + prereleases = set.all_specs + + assert_equal [@a1_pre, @a1], prereleases + end + + def test_find_gems_with_sources_with_best_only_and_platform + util_setup_gems + a1_x86_mingw32, = util_gem 'a', '1' do |s| + s.platform = 'x86-mingw32' + end + util_setup_spec_fetcher @a1, a1_x86_mingw32 + Gem.platforms << Gem::Platform.new('x86-mingw32') + + installer = Gem::DependencyInstaller.new + + dependency = Gem::Dependency.new('a', Gem::Requirement.default) + + set = Gem::Deprecate.skip_during do + installer.find_gems_with_sources(dependency, true) + end + + releases = set.all_specs + + assert_equal [a1_x86_mingw32], releases + end + + def test_find_gems_with_sources_with_bad_source + Gem.sources.replace ["http://not-there.nothing"] + + installer = Gem::DependencyInstaller.new + + dep = Gem::Dependency.new('a') + + out = Gem::Deprecate.skip_during do + installer.find_gems_with_sources(dep) + end + + assert out.empty? + assert_kind_of Gem::SourceFetchProblem, installer.errors.first + end + def test_resolve_dependencies util_setup_gems -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/