lib/bundler/definition.rb in bundler-2.4.14 vs lib/bundler/definition.rb in bundler-2.4.15
- old
+ new
@@ -74,12 +74,15 @@
@ruby_version = ruby_version
@gemfiles = gemfiles
@lockfile = lockfile
@lockfile_contents = String.new
+
@locked_bundler_version = nil
- @locked_ruby_version = nil
+ @resolved_bundler_version = nil
+
+ @locked_ruby_version = nil
@new_platform = nil
@removed_platform = nil
if lockfile && File.exist?(lockfile)
@lockfile_contents = Bundler.read_file(lockfile)
@@ -144,11 +147,11 @@
end
@dependency_changes = converge_dependencies
@local_changes = converge_locals
- @incomplete_lockfile = check_missing_lockfile_specs
+ @missing_lockfile_dep = check_missing_lockfile_dep
end
def gem_version_promoter
@gem_version_promoter ||= GemVersionPromoter.new
end
@@ -232,10 +235,18 @@
def requested_dependencies
dependencies_for(requested_groups)
end
def current_dependencies
+ filter_relevant(dependencies)
+ end
+
+ def current_locked_dependencies
+ filter_relevant(locked_dependencies)
+ end
+
+ def filter_relevant(dependencies)
dependencies.select do |d|
d.should_include? && !d.gem_platforms([generic_local_platform]).empty?
end
end
@@ -271,11 +282,11 @@
# @return [SpecSet] resolved dependencies
def resolve
@resolve ||= if Bundler.frozen_bundle?
Bundler.ui.debug "Frozen, using resolution from the lockfile"
@locked_specs
- elsif !unlocking? && nothing_changed?
+ elsif no_resolve_needed?
if deleted_deps.any?
Bundler.ui.debug "Some dependencies were deleted, using a subset of the resolution from the lockfile"
SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
else
Bundler.ui.debug "Found no changes, using resolution from the lockfile"
@@ -308,11 +319,11 @@
# i.e., Windows with `git config core.autocrlf=true`
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
if @locked_bundler_version
locked_major = @locked_bundler_version.segments.first
- current_major = Bundler.gem_version.segments.first
+ current_major = bundler_version_to_lock.segments.first
updating_major = locked_major < current_major
end
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
@@ -348,29 +359,20 @@
end
version
end
end
+ def bundler_version_to_lock
+ @resolved_bundler_version || Bundler.gem_version
+ end
+
def to_lock
require_relative "lockfile_generator"
LockfileGenerator.generate(self)
end
def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
- msg = String.new
- msg << "You are trying to install in deployment mode after changing\n" \
- "your Gemfile. Run `bundle install` elsewhere and add the\n" \
- "updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
-
- unless explicit_flag
- suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
- "bundle config set frozen false"
- end
- msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
- "freeze \nby running `#{suggested_command}`." if suggested_command
- end
-
added = []
deleted = []
changed = []
new_platforms = @platforms - @locked_platforms
@@ -380,18 +382,13 @@
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
both_sources = Hash.new {|h, k| h[k] = [] }
- @dependencies.each {|d| both_sources[d.name][0] = d }
+ current_dependencies.each {|d| both_sources[d.name][0] = d }
+ current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
- locked_dependencies.each do |d|
- next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty?
-
- both_sources[d.name][1] = d
- end
-
both_sources.each do |name, (dep, lock_dep)|
next if dep.nil? || lock_dep.nil?
gemfile_source = dep.source || sources.default_source
lock_source = lock_dep.source || sources.default_source
@@ -401,16 +398,25 @@
lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
end
reason = change_reason
- msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty?
+ msg = String.new
+ msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
- msg << "\n"
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control.\n"
+ unless explicit_flag
+ suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
+ "bundle config set frozen false"
+ end
+ msg << "If this is a development machine, remove the #{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)} " \
+ "freeze by running `#{suggested_command}`." if suggested_command
+ end
+
raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed?
end
def validate_runtime!
validate_ruby!
@@ -470,13 +476,17 @@
attr_reader :sources
private :sources
def nothing_changed?
- !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@incomplete_lockfile
+ !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@missing_lockfile_dep && !@unlocking_bundler
end
+ def no_resolve_needed?
+ !unlocking? && nothing_changed?
+ end
+
def unlocking?
@unlocking
end
private
@@ -484,13 +494,20 @@
def resolver
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
end
def expanded_dependencies
- dependencies + metadata_dependencies
+ dependencies_with_bundler + metadata_dependencies
end
+ def dependencies_with_bundler
+ return dependencies unless @unlocking_bundler
+ return dependencies if dependencies.map(&:name).include?("bundler")
+
+ [Dependency.new("bundler", @unlocking_bundler)] + dependencies
+ end
+
def resolution_packages
@resolution_packages ||= begin
last_resolve = converge_locked_specs
remove_ruby_from_platforms_if_necessary!(current_dependencies)
packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, :locked_specs => @originally_locked_specs, :unlock => @unlock[:gems], :prerelease => gem_version_promoter.pre?)
@@ -550,10 +567,12 @@
end
def start_resolution
result = resolver.start
+ @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
+
SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
end
def precompute_source_requirements_for_indirect_dependencies?
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
@@ -607,11 +626,12 @@
[@source_changes, "the list of sources changed"],
[@dependency_changes, "the dependencies in your gemfile changed"],
[@new_platform, "you added a new platform to your gemfile"],
[@path_changes, "the gemspecs for path gems changed"],
[@local_changes, "the gemspecs for git local gems changed"],
- [@incomplete_lockfile, "your lock file is missing some gems"],
+ [@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""],
+ [@unlocking_bundler, "an update to the version of Bundler itself was requested"],
].select(&:first).map(&:last).join(", ")
end
def pretty_dep(dep)
SharedHelpers.pretty_dependency(dep)
@@ -662,24 +682,28 @@
changed || specs_changed?(source)
end.map(&:first)
!sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
end
- def check_missing_lockfile_specs
+ def check_missing_lockfile_dep
all_locked_specs = @locked_specs.map(&:name) << "bundler"
missing = @locked_specs.select do |s|
s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) }
end
if missing.any?
@locked_specs.delete(missing)
- true
- else
- false
+ return missing.first.name
end
+
+ return if @dependency_changes
+
+ current_dependencies.find do |d|
+ @locked_specs[d.name].empty?
+ end&.name
end
def converge_paths
sources.path_sources.any? do |source|
specs_changed?(source)
@@ -859,11 +883,19 @@
end
source_requirements.merge!(source_map.locked_requirements) unless @remote
metadata_dependencies.each do |dep|
source_requirements[dep.name] = sources.metadata_source
end
- source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
- source_requirements["bundler"] = sources.metadata_source # needs to come last to override
+
+ default_bundler_source = source_requirements["bundler"] || sources.default_source
+
+ if @unlocking_bundler
+ default_bundler_source.add_dependency_names("bundler")
+ else
+ source_requirements[:default_bundler] = default_bundler_source
+ source_requirements["bundler"] = sources.metadata_source # needs to come last to override
+ end
+
verify_changed_sources!
source_requirements
end
def verify_changed_sources!