Skip to content

Commit ad0fdef

Browse files
committed
Fix bundle lock regression when using update and lockfile flags:
- Ref #8917 - ### Problem Prior to Bundler 2.5.6, running `bundle lock --update foo --lockfile Gemfile_bumped.lock` would update only the foo gem and write the lockfile to the `Gemfile_bumped.lock`. In Bundler 2.5.6 and above running the same command, updates absolutely all gems. This change is related to #7047 ### Solution We decided to expose the `write_lock` method rather than going through a complex deprecation cycle of the `lock` method. This commit applies the same business logic as prios to 2.5.6 where, we build the definition using the existing lockfile, make changes to the definition and dump it into the desired lockfile.
1 parent e38c8fb commit ad0fdef

File tree

3 files changed

+81
-43
lines changed

3 files changed

+81
-43
lines changed

bundler/lib/bundler/cli/lock.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,8 @@ def run
3535
update = { bundler: bundler }
3636
end
3737

38-
file = options[:lockfile]
39-
file = file ? Pathname.new(file).expand_path : Bundler.default_lockfile
40-
4138
Bundler.settings.temporary(frozen: false) do
42-
definition = Bundler.definition(update, file)
39+
definition = Bundler.definition(update, Bundler.default_lockfile)
4340
definition.add_checksums if options["add-checksums"]
4441

4542
Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
@@ -71,8 +68,11 @@ def run
7168
if print
7269
puts definition.to_lock
7370
else
71+
file = options[:lockfile]
72+
file = file ? Pathname.new(file).expand_path : Bundler.default_lockfile
73+
7474
puts "Writing lockfile to #{file}"
75-
definition.lock
75+
definition.write_lock(file, false)
7676
end
7777
end
7878

bundler/lib/bundler/definition.rb

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,44 @@ def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or
373373
write_lock(target_lockfile, preserve_unknown_sections)
374374
end
375375

376+
def write_lock(file, preserve_unknown_sections)
377+
return if Definition.no_lock || file.nil?
378+
379+
contents = to_lock
380+
381+
# Convert to \r\n if the existing lock has them
382+
# i.e., Windows with `git config core.autocrlf=true`
383+
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
384+
385+
if @locked_bundler_version
386+
locked_major = @locked_bundler_version.segments.first
387+
current_major = bundler_version_to_lock.segments.first
388+
389+
updating_major = locked_major < current_major
390+
end
391+
392+
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
393+
394+
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
395+
return if Bundler.frozen_bundle?
396+
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
397+
return
398+
end
399+
400+
if Bundler.frozen_bundle?
401+
Bundler.ui.error "Cannot write a changed lockfile while frozen."
402+
return
403+
end
404+
405+
begin
406+
SharedHelpers.filesystem_access(file) do |p|
407+
File.open(p, "wb") {|f| f.puts(contents) }
408+
end
409+
rescue ReadOnlyFileSystemError
410+
raise ProductionError, lockfile_changes_summary("file system is read-only")
411+
end
412+
end
413+
376414
def locked_ruby_version
377415
return unless ruby_version
378416
if @unlocking_ruby || !@locked_ruby_version
@@ -573,44 +611,6 @@ def lockfile_exists?
573611
lockfile && File.exist?(lockfile)
574612
end
575613

576-
def write_lock(file, preserve_unknown_sections)
577-
return if Definition.no_lock || file.nil?
578-
579-
contents = to_lock
580-
581-
# Convert to \r\n if the existing lock has them
582-
# i.e., Windows with `git config core.autocrlf=true`
583-
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
584-
585-
if @locked_bundler_version
586-
locked_major = @locked_bundler_version.segments.first
587-
current_major = bundler_version_to_lock.segments.first
588-
589-
updating_major = locked_major < current_major
590-
end
591-
592-
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
593-
594-
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
595-
return if Bundler.frozen_bundle?
596-
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
597-
return
598-
end
599-
600-
if Bundler.frozen_bundle?
601-
Bundler.ui.error "Cannot write a changed lockfile while frozen."
602-
return
603-
end
604-
605-
begin
606-
SharedHelpers.filesystem_access(file) do |p|
607-
File.open(p, "wb") {|f| f.puts(contents) }
608-
end
609-
rescue ReadOnlyFileSystemError
610-
raise ProductionError, lockfile_changes_summary("file system is read-only")
611-
end
612-
end
613-
614614
def resolver
615615
@resolver ||= new_resolver(resolution_base)
616616
end

bundler/spec/commands/lock_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,44 @@
311311
expect { read_lockfile }.to raise_error(Errno::ENOENT)
312312
end
313313

314+
it "updates a specific gem and write to a custom location" do
315+
build_repo4 do
316+
build_gem "uri", %w[1.0.2 1.0.3]
317+
build_gem "warning", %w[1.4.0 1.5.0]
318+
end
319+
320+
gemfile <<~G
321+
source "https://gem.repo4"
322+
323+
gem "uri"
324+
gem "warning"
325+
G
326+
327+
lockfile <<~L
328+
GEM
329+
remote: https://gem.repo4
330+
specs:
331+
uri (1.0.2)
332+
warning (1.4.0)
333+
334+
PLATFORMS
335+
#{lockfile_platforms}
336+
337+
DEPENDENCIES
338+
uri
339+
warning
340+
341+
BUNDLED WITH
342+
#{Bundler::VERSION}
343+
L
344+
345+
bundle "lock --update uri --lockfile=lock"
346+
347+
lockfile_content = read_lockfile("lock")
348+
expect(lockfile_content).to include("uri (1.0.3)")
349+
expect(lockfile_content).to include("warning (1.4.0)")
350+
end
351+
314352
it "writes to custom location using --lockfile when a default lockfile is present" do
315353
gemfile_with_rails_weakling_and_foo_from_repo4
316354

0 commit comments

Comments
 (0)