diff options
Diffstat (limited to 'lib/bundler/source_list.rb')
| -rw-r--r-- | lib/bundler/source_list.rb | 198 |
1 files changed, 122 insertions, 76 deletions
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb index ac2adacb3d..ab7002d6e5 100644 --- a/lib/bundler/source_list.rb +++ b/lib/bundler/source_list.rb @@ -5,24 +5,40 @@ module Bundler attr_reader :path_sources, :git_sources, :plugin_sources, - :global_rubygems_source, + :global_path_source, :metadata_source + def global_rubygems_source + @global_rubygems_source ||= source_class.new("allow_local" => true) + end + def initialize @path_sources = [] @git_sources = [] @plugin_sources = [] @global_rubygems_source = nil - @rubygems_aggregate = rubygems_aggregate_class.new + @global_path_source = nil @rubygems_sources = [] @metadata_source = Source::Metadata.new + + @local_mode = true + end + + def aggregate_global_source? + global_rubygems_source.multiple_remotes? + end + + def implicit_global_source? + global_rubygems_source.no_remotes? end def add_path_source(options = {}) if options["gemspec"] add_source_to_list Source::Gemspec.new(options), path_sources else - add_source_to_list Source::Path.new(options), path_sources + path_source = add_source_to_list Source::Path.new(options), path_sources + @global_path_source ||= path_source if options["global"] + path_source end end @@ -33,78 +49,81 @@ module Bundler end def add_rubygems_source(options = {}) - add_source_to_list Source::Rubygems.new(options), @rubygems_sources + new_source = Source::Rubygems.new(options) + return @global_rubygems_source if @global_rubygems_source == new_source + + add_source_to_list new_source, @rubygems_sources end def add_plugin_source(source, options = {}) add_source_to_list Plugin.source(source).new(options), @plugin_sources end - def global_rubygems_source=(uri) - if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? - @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri) - end - add_rubygems_remote(uri) + def add_global_rubygems_remote(uri, cooldown: nil) + global_rubygems_source.add_remote(uri, cooldown: cooldown) + global_rubygems_source end - def add_rubygems_remote(uri) - if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? - return if Bundler.feature_flag.disable_multisource? - raise InvalidOption, "`lockfile_uses_separate_rubygems_sources` cannot be set without `disable_multisource` being set" - end - @rubygems_aggregate.add_remote(uri) - @rubygems_aggregate + def local_mode? + @local_mode end def default_source - global_rubygems_source || @rubygems_aggregate + global_path_source || global_rubygems_source end def rubygems_sources - @rubygems_sources + [default_source] + non_global_rubygems_sources + [global_rubygems_source] end - def rubygems_remotes - rubygems_sources.map(&:remotes).flatten.uniq + def non_global_rubygems_sources + @rubygems_sources end def all_sources path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source] end + def non_default_explicit_sources + all_sources - [default_source, metadata_source] + end + def get(source) - source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) } + source_list_for(source).find {|s| s.include?(source) } end def lock_sources - if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? - [[default_source], @rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources| - sources.sort_by(&:to_s) - end.flatten(1) - else - lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s) - lock_sources << combine_rubygems_sources - end + lock_other_sources + lock_rubygems_sources + end + + def lock_other_sources + (path_sources + git_sources + plugin_sources).sort_by(&:identifier) + end + + def lock_rubygems_sources + rubygems_sources.sort_by(&:identifier) end # Returns true if there are changes def replace_sources!(replacement_sources) - return true if replacement_sources.empty? + return false if replacement_sources.empty? - [path_sources, git_sources, plugin_sources].each do |source_list| - source_list.map! do |source| - replacement_sources.find {|s| s == source } || source - end - end + @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources) + @global_rubygems_source = global_replacement_source(replacement_sources) - replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && - replacement_sources.detect {|s| s.is_a?(Source::Rubygems) } - @rubygems_aggregate = replacement_rubygems if replacement_rubygems + !equivalent_sources?(lock_sources, replacement_sources) + end + + def prefer_local! + all_sources.each(&:prefer_local!) + end - return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources) - return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set + def local_only! + all_sources.each(&:local_only!) + end - false + def local! + all_sources.each(&:local!) end def cached! @@ -112,16 +131,71 @@ module Bundler end def remote! + @local_mode = false + all_sources.each(&:remote!) end - def rubygems_primary_remotes - @rubygems_aggregate.remotes + def clear_cache + rubygems_sources.each(&:clear_cache) + end + + private + + def map_sources(replacement_sources) + rubygems = @rubygems_sources.map do |source| + replace_rubygems_source(replacement_sources, source) + end + + git, plugin = [@git_sources, @plugin_sources].map do |sources| + sources.map do |source| + replace_source(replacement_sources, source) + end + end + + path = @path_sources.map do |source| + replace_path_source(replacement_sources, source) + end + + [rubygems, path, git, plugin] + end + + def global_replacement_source(replacement_sources) + replace_rubygems_source(replacement_sources, global_rubygems_source, &:local!) + end + + def replace_rubygems_source(replacement_sources, gemfile_source) + replace_source(replacement_sources, gemfile_source) do |replacement_source| + # locked sources never include credentials so always prefer remotes from the gemfile + replacement_source.remotes = gemfile_source.remotes + + yield replacement_source if block_given? + + replacement_source + end end - private + def replace_source(replacement_sources, gemfile_source) + replacement_source = replacement_sources.find {|s| s == gemfile_source } + return gemfile_source unless replacement_source + + replacement_source = yield(replacement_source) if block_given? - def rubygems_aggregate_class + replacement_source + end + + def replace_path_source(replacement_sources, gemfile_source) + replace_source(replacement_sources, gemfile_source) do |replacement_source| + if gemfile_source.is_a?(Source::Gemspec) + gemfile_source.checksum_store = replacement_source.checksum_store + gemfile_source + else + replacement_source + end + end + end + + def source_class Source::Rubygems end @@ -140,47 +214,19 @@ module Bundler end end - def combine_rubygems_sources - Source::Rubygems.new("remotes" => rubygems_remotes) - end - def warn_on_git_protocol(source) return if Bundler.settings["git.allow_insecure"] - if source.uri =~ /^git\:/ + if /^git\:/.match?(source.uri) Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \ "which transmits data without encryption. Disable this warning with " \ - "`bundle config git.allow_insecure true`, or switch to the `https` " \ + "`bundle config set --local git.allow_insecure true`, or switch to the `https` " \ "protocol to keep your data secure." end end - def equal_sources?(lock_sources, replacement_sources) - lock_sources.to_set == replacement_sources.to_set - end - - def equal_source?(source, other_source) - source == other_source - end - - def equivalent_source?(source, other_source) - return false unless Bundler.settings[:allow_deployment_source_credential_changes] && source.is_a?(Source::Rubygems) - - equivalent_rubygems_sources?([source], [other_source]) - end - def equivalent_sources?(lock_sources, replacement_sources) - return false unless Bundler.settings[:allow_deployment_source_credential_changes] - - lock_rubygems_sources, lock_other_sources = lock_sources.partition {|s| s.is_a?(Source::Rubygems) } - replacement_rubygems_sources, replacement_other_sources = replacement_sources.partition {|s| s.is_a?(Source::Rubygems) } - - equivalent_rubygems_sources?(lock_rubygems_sources, replacement_rubygems_sources) && equal_sources?(lock_other_sources, replacement_other_sources) - end - - def equivalent_rubygems_sources?(lock_sources, replacement_sources) - actual_remotes = replacement_sources.map(&:remotes).flatten.uniq - lock_sources.all? {|s| s.equivalent_remotes?(actual_remotes) } + lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier) end end end |
