bundler 2.6.5 → 2.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -6
  3. data/lib/bundler/build_metadata.rb +2 -2
  4. data/lib/bundler/checksum.rb +22 -12
  5. data/lib/bundler/cli/doctor.rb +14 -14
  6. data/lib/bundler/cli/inject.rb +2 -2
  7. data/lib/bundler/cli/lock.rb +2 -1
  8. data/lib/bundler/compact_index_client/cache.rb +1 -1
  9. data/lib/bundler/compact_index_client/parser.rb +1 -1
  10. data/lib/bundler/compact_index_client/updater.rb +2 -1
  11. data/lib/bundler/definition.rb +108 -91
  12. data/lib/bundler/dsl.rb +2 -3
  13. data/lib/bundler/errors.rb +18 -0
  14. data/lib/bundler/injector.rb +9 -9
  15. data/lib/bundler/lazy_specification.rb +9 -1
  16. data/lib/bundler/lockfile_parser.rb +8 -5
  17. data/lib/bundler/man/bundle-add.1 +1 -1
  18. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  19. data/lib/bundler/man/bundle-cache.1 +1 -1
  20. data/lib/bundler/man/bundle-check.1 +1 -1
  21. data/lib/bundler/man/bundle-clean.1 +1 -1
  22. data/lib/bundler/man/bundle-config.1 +6 -6
  23. data/lib/bundler/man/bundle-config.1.ronn +9 -4
  24. data/lib/bundler/man/bundle-console.1 +1 -1
  25. data/lib/bundler/man/bundle-doctor.1 +1 -1
  26. data/lib/bundler/man/bundle-env.1 +1 -1
  27. data/lib/bundler/man/bundle-exec.1 +3 -3
  28. data/lib/bundler/man/bundle-exec.1.ronn +2 -2
  29. data/lib/bundler/man/bundle-fund.1 +1 -1
  30. data/lib/bundler/man/bundle-gem.1 +1 -1
  31. data/lib/bundler/man/bundle-help.1 +1 -1
  32. data/lib/bundler/man/bundle-info.1 +1 -1
  33. data/lib/bundler/man/bundle-init.1 +1 -1
  34. data/lib/bundler/man/bundle-inject.1 +1 -1
  35. data/lib/bundler/man/bundle-install.1 +1 -1
  36. data/lib/bundler/man/bundle-issue.1 +1 -1
  37. data/lib/bundler/man/bundle-licenses.1 +1 -1
  38. data/lib/bundler/man/bundle-list.1 +1 -1
  39. data/lib/bundler/man/bundle-lock.1 +1 -1
  40. data/lib/bundler/man/bundle-open.1 +1 -1
  41. data/lib/bundler/man/bundle-outdated.1 +1 -1
  42. data/lib/bundler/man/bundle-platform.1 +1 -1
  43. data/lib/bundler/man/bundle-plugin.1 +1 -1
  44. data/lib/bundler/man/bundle-pristine.1 +1 -1
  45. data/lib/bundler/man/bundle-remove.1 +1 -1
  46. data/lib/bundler/man/bundle-show.1 +1 -1
  47. data/lib/bundler/man/bundle-update.1 +1 -1
  48. data/lib/bundler/man/bundle-version.1 +1 -1
  49. data/lib/bundler/man/bundle-viz.1 +1 -1
  50. data/lib/bundler/man/bundle.1 +1 -1
  51. data/lib/bundler/man/gemfile.5 +1 -1
  52. data/lib/bundler/plugin/api/source.rb +1 -1
  53. data/lib/bundler/plugin/index.rb +1 -1
  54. data/lib/bundler/plugin/installer/path.rb +8 -0
  55. data/lib/bundler/plugin.rb +1 -1
  56. data/lib/bundler/resolver/candidate.rb +12 -9
  57. data/lib/bundler/resolver/strategy.rb +40 -0
  58. data/lib/bundler/resolver.rb +11 -22
  59. data/lib/bundler/rubygems_ext.rb +15 -0
  60. data/lib/bundler/runtime.rb +8 -5
  61. data/lib/bundler/shared_helpers.rb +4 -0
  62. data/lib/bundler/source/gemspec.rb +1 -4
  63. data/lib/bundler/source/git/git_proxy.rb +14 -3
  64. data/lib/bundler/source/git.rb +5 -1
  65. data/lib/bundler/source/path.rb +2 -2
  66. data/lib/bundler/source/rubygems/remote.rb +11 -3
  67. data/lib/bundler/source_list.rb +29 -11
  68. data/lib/bundler/spec_set.rb +11 -4
  69. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
  70. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  71. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +11 -0
  72. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
  73. data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
  74. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
  75. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
  76. data/lib/bundler/vendor/uri/lib/uri/common.rb +7 -3
  77. data/lib/bundler/vendor/uri/lib/uri/generic.rb +12 -11
  78. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +6 -6
  79. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  80. data/lib/bundler/version.rb +1 -1
  81. metadata +5 -4
  82. data/lib/bundler/compact_index_client/gem_parser.rb +0 -32
@@ -94,7 +94,8 @@ module Bundler
94
94
 
95
95
  @locked_ruby_version = nil
96
96
  @new_platforms = []
97
- @removed_platform = nil
97
+ @removed_platforms = []
98
+ @originally_invalid_platforms = []
98
99
 
99
100
  if lockfile_exists?
100
101
  @lockfile_contents = Bundler.read_file(lockfile)
@@ -147,9 +148,8 @@ module Bundler
147
148
 
148
149
  @current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
149
150
 
150
- converge_path_sources_to_gemspec_sources
151
- @path_changes = converge_paths
152
151
  @source_changes = converge_sources
152
+ @path_changes = converge_paths
153
153
 
154
154
  if conservative
155
155
  @gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
@@ -330,7 +330,7 @@ module Bundler
330
330
  SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
331
331
  else
332
332
  Bundler.ui.debug "Found no changes, using resolution from the lockfile"
333
- if @removed_platform || @locked_gems.may_include_redundant_platform_specific_gems?
333
+ if @removed_platforms.any? || @locked_gems.may_include_redundant_platform_specific_gems?
334
334
  SpecSet.new(filter_specs(@locked_specs, @dependencies))
335
335
  else
336
336
  @locked_specs
@@ -412,41 +412,8 @@ module Bundler
412
412
 
413
413
  raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
414
414
 
415
- added = []
416
- deleted = []
417
- changed = []
418
-
419
- new_platforms = @platforms - @locked_platforms
420
- deleted_platforms = @locked_platforms - @platforms
421
- added.concat new_platforms.map {|p| "* platform: #{p}" }
422
- deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
423
-
424
- added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
425
- deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
426
-
427
- both_sources = Hash.new {|h, k| h[k] = [] }
428
- current_dependencies.each {|d| both_sources[d.name][0] = d }
429
- current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
430
-
431
- both_sources.each do |name, (dep, lock_dep)|
432
- next if dep.nil? || lock_dep.nil?
433
-
434
- gemfile_source = dep.source || default_source
435
- lock_source = lock_dep.source || default_source
436
- next if lock_source.include?(gemfile_source)
437
-
438
- gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
439
- lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
440
- changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
441
- end
442
-
443
- reason = resolve_needed? ? change_reason : "some dependencies were deleted from your gemfile"
444
- msg = String.new
445
- msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
446
- msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
447
- msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
448
- msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
449
- msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n" unless unlocking?
415
+ msg = lockfile_changes_summary("frozen mode is set")
416
+ return unless msg
450
417
 
451
418
  unless explicit_flag
452
419
  suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
@@ -456,7 +423,7 @@ module Bundler
456
423
  "freeze by running `#{suggested_command}`." if suggested_command
457
424
  end
458
425
 
459
- raise ProductionError, msg if added.any? || deleted.any? || changed.any? || resolve_needed?
426
+ raise ProductionError, msg
460
427
  end
461
428
 
462
429
  def validate_runtime!
@@ -511,10 +478,10 @@ module Bundler
511
478
  end
512
479
 
513
480
  def remove_platform(platform)
514
- removed_platform = @platforms.delete(Gem::Platform.new(platform))
515
- @removed_platform ||= removed_platform
516
- return if removed_platform
517
- raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
481
+ raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" unless @platforms.include?(platform)
482
+
483
+ @removed_platforms << platform
484
+ @platforms.delete(platform)
518
485
  end
519
486
 
520
487
  def nothing_changed?
@@ -541,6 +508,47 @@ module Bundler
541
508
 
542
509
  private
543
510
 
511
+ def lockfile_changes_summary(update_refused_reason)
512
+ added = []
513
+ deleted = []
514
+ changed = []
515
+
516
+ added.concat @new_platforms.map {|p| "* platform: #{p}" }
517
+ deleted.concat @removed_platforms.map {|p| "* platform: #{p}" }
518
+
519
+ added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
520
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
521
+
522
+ both_sources = Hash.new {|h, k| h[k] = [] }
523
+ current_dependencies.each {|d| both_sources[d.name][0] = d }
524
+ current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
525
+
526
+ both_sources.each do |name, (dep, lock_dep)|
527
+ next if dep.nil? || lock_dep.nil?
528
+
529
+ gemfile_source = dep.source || default_source
530
+ lock_source = lock_dep.source || default_source
531
+ next if lock_source.include?(gemfile_source)
532
+
533
+ gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
534
+ lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
535
+ changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
536
+ end
537
+
538
+ return unless added.any? || deleted.any? || changed.any? || resolve_needed?
539
+
540
+ reason = resolve_needed? ? change_reason : "some dependencies were deleted from your gemfile"
541
+
542
+ msg = String.new("#{reason.capitalize.strip}, but ")
543
+ msg << "the lockfile " unless msg.start_with?("Your lockfile")
544
+ msg << "can't be updated because #{update_refused_reason}"
545
+ msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
546
+ msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
547
+ msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
548
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_lockfile_path} to version control.\n" unless unlocking?
549
+ msg
550
+ end
551
+
544
552
  def install_needed?
545
553
  resolve_needed? || missing_specs?
546
554
  end
@@ -556,6 +564,7 @@ module Bundler
556
564
  @local_changes ||
557
565
  @missing_lockfile_dep ||
558
566
  @unlocking_bundler ||
567
+ @locked_spec_with_missing_checksums ||
559
568
  @locked_spec_with_missing_deps ||
560
569
  @locked_spec_with_invalid_deps
561
570
  end
@@ -601,8 +610,12 @@ module Bundler
601
610
  return
602
611
  end
603
612
 
604
- SharedHelpers.filesystem_access(file) do |p|
605
- File.open(p, "wb") {|f| f.puts(contents) }
613
+ begin
614
+ SharedHelpers.filesystem_access(file) do |p|
615
+ File.open(p, "wb") {|f| f.puts(contents) }
616
+ end
617
+ rescue ReadOnlyFileSystemError
618
+ raise ProductionError, lockfile_changes_summary("file system is read-only")
606
619
  end
607
620
  end
608
621
 
@@ -625,7 +638,8 @@ module Bundler
625
638
  @resolution_packages ||= begin
626
639
  last_resolve = converge_locked_specs
627
640
  remove_invalid_platforms!
628
- packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: @new_platforms)
641
+ new_resolution_platforms = @current_platform_missing ? @new_platforms + [local_platform] : @new_platforms
642
+ packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
629
643
  packages = additional_base_requirements_to_prevent_downgrades(packages)
630
644
  packages = additional_base_requirements_to_force_updates(packages)
631
645
  packages
@@ -747,7 +761,11 @@ module Bundler
747
761
  end
748
762
  end
749
763
 
750
- @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
764
+ if should_add_extra_platforms?
765
+ result.add_extra_platforms!(platforms)
766
+ elsif @originally_invalid_platforms.any?
767
+ result.add_originally_invalid_platforms!(platforms, @originally_invalid_platforms)
768
+ end
751
769
 
752
770
  SpecSet.new(result.for(dependencies, @platforms | [Gem::Platform::RUBY]))
753
771
  end
@@ -768,7 +786,6 @@ module Bundler
768
786
  @most_specific_non_local_locked_platform = find_most_specific_locked_platform
769
787
  return if @most_specific_non_local_locked_platform
770
788
 
771
- @new_platforms << local_platform
772
789
  @platforms << local_platform
773
790
  true
774
791
  end
@@ -798,13 +815,14 @@ module Bundler
798
815
  [
799
816
  [@source_changes, "the list of sources changed"],
800
817
  [@dependency_changes, "the dependencies in your gemfile changed"],
801
- [@current_platform_missing, "your lockfile does not include the current platform"],
802
- [@new_platforms.any?, "you added a new platform to your gemfile"],
818
+ [@current_platform_missing, "your lockfile is missing the current platform"],
819
+ [@new_platforms.any?, "you are adding a new platform to your lockfile"],
803
820
  [@path_changes, "the gemspecs for path gems changed"],
804
821
  [@local_changes, "the gemspecs for git local gems changed"],
805
- [@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""],
822
+ [@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
806
823
  [@unlocking_bundler, "an update to the version of Bundler itself was requested"],
807
- [@locked_spec_with_missing_deps, "your lock file includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
824
+ [@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
825
+ [@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
808
826
  [@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
809
827
  ].select(&:first).map(&:last).join(", ")
810
828
  end
@@ -821,8 +839,8 @@ module Bundler
821
839
  !locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
822
840
  end
823
841
 
824
- def dependencies_for_source_changed?(source, locked_source = source)
825
- deps_for_source = @dependencies.select {|s| s.source == source }
842
+ def dependencies_for_source_changed?(source, locked_source)
843
+ deps_for_source = @dependencies.select {|dep| dep.source == source }
826
844
  locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
827
845
 
828
846
  deps_for_source.uniq.sort != locked_deps_for_source.sort
@@ -830,7 +848,7 @@ module Bundler
830
848
 
831
849
  def specs_for_source_changed?(source)
832
850
  locked_index = Index.new
833
- locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
851
+ locked_index.use(@locked_specs.select {|s| s.replace_source_with!(source) })
834
852
 
835
853
  !locked_index.subset?(source.specs)
836
854
  rescue PathError, GitError => e
@@ -862,21 +880,27 @@ module Bundler
862
880
  def check_lockfile
863
881
  @locked_spec_with_invalid_deps = nil
864
882
  @locked_spec_with_missing_deps = nil
883
+ @locked_spec_with_missing_checksums = nil
865
884
 
866
- missing = []
885
+ missing_deps = []
886
+ missing_checksums = []
867
887
  invalid = []
868
888
 
869
889
  @locked_specs.each do |s|
890
+ missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
891
+
870
892
  validation = @locked_specs.validate_deps(s)
871
893
 
872
- missing << s if validation == :missing
894
+ missing_deps << s if validation == :missing
873
895
  invalid << s if validation == :invalid
874
896
  end
875
897
 
876
- if missing.any?
877
- @locked_specs.delete(missing)
898
+ @locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
899
+
900
+ if missing_deps.any?
901
+ @locked_specs.delete(missing_deps)
878
902
 
879
- @locked_spec_with_missing_deps = missing.first.name
903
+ @locked_spec_with_missing_deps = missing_deps.first.name
880
904
  end
881
905
 
882
906
  if invalid.any?
@@ -892,24 +916,6 @@ module Bundler
892
916
  end
893
917
  end
894
918
 
895
- def converge_path_source_to_gemspec_source(source)
896
- return source unless source.instance_of?(Source::Path)
897
- gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source }
898
- gemspec_source || source
899
- end
900
-
901
- def converge_path_sources_to_gemspec_sources
902
- @locked_sources.map! do |source|
903
- converge_path_source_to_gemspec_source(source)
904
- end
905
- @locked_specs.each do |spec|
906
- spec.source &&= converge_path_source_to_gemspec_source(spec.source)
907
- end
908
- @locked_deps.each do |_, dep|
909
- dep.source &&= converge_path_source_to_gemspec_source(dep.source)
910
- end
911
- end
912
-
913
919
  def converge_sources
914
920
  # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
915
921
  # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
@@ -952,11 +958,17 @@ module Bundler
952
958
  unless name == "bundler"
953
959
  locked_specs = @originally_locked_specs[name]
954
960
 
955
- if locked_specs.any? && !dep.matches_spec?(locked_specs.first)
956
- @gems_to_unlock << name
957
- dep_changed = true
958
- elsif locked_specs.empty? && dep_changed == false
959
- @missing_lockfile_dep = name
961
+ if locked_specs.empty?
962
+ @missing_lockfile_dep = name if dep_changed == false
963
+ else
964
+ if locked_specs.map(&:source).uniq.size > 1
965
+ @locked_specs.delete(locked_specs.select {|s| s.source != dep.source })
966
+ end
967
+
968
+ unless dep.matches_spec?(locked_specs.first)
969
+ @gems_to_unlock << name
970
+ dep_changed = true
971
+ end
960
972
  end
961
973
  end
962
974
 
@@ -1130,16 +1142,21 @@ module Bundler
1130
1142
  def remove_invalid_platforms!
1131
1143
  return if Bundler.frozen_bundle?
1132
1144
 
1133
- platforms.reverse_each do |platform|
1145
+ @originally_invalid_platforms = platforms.select do |platform|
1134
1146
  next if local_platform == platform ||
1135
- @new_platforms.include?(platform) ||
1136
- @path_changes ||
1137
- @dependency_changes ||
1138
- @locked_spec_with_invalid_deps ||
1139
- !spec_set_incomplete_for_platform?(@originally_locked_specs, platform)
1147
+ @new_platforms.include?(platform)
1140
1148
 
1141
- remove_platform(platform)
1149
+ # We should probably avoid removing non-ruby platforms, since that means
1150
+ # lockfile will no longer install on those platforms, so a error to give
1151
+ # heads up to the user may be better. However, we have tests expecting
1152
+ # non ruby platform autoremoval to work, so leaving that in place for
1153
+ # now.
1154
+ next if @dependency_changes && platform != Gem::Platform::RUBY
1155
+
1156
+ spec_set_incomplete_for_platform?(@originally_locked_specs, platform)
1142
1157
  end
1158
+
1159
+ @platforms -= @originally_invalid_platforms
1143
1160
  end
1144
1161
 
1145
1162
  def spec_set_incomplete_for_platform?(spec_set, platform)
data/lib/bundler/dsl.rb CHANGED
@@ -77,7 +77,7 @@ module Bundler
77
77
 
78
78
  @gemspecs << spec
79
79
 
80
- path path, "glob" => glob, "name" => spec.name do
80
+ path path, "glob" => glob, "name" => spec.name, "gemspec" => spec do
81
81
  add_dependency spec.name
82
82
  end
83
83
 
@@ -141,8 +141,7 @@ module Bundler
141
141
  def path(path, options = {}, &blk)
142
142
  source_options = normalize_hash(options).merge(
143
143
  "path" => Pathname.new(path),
144
- "root_path" => gemfile_root,
145
- "gemspec" => gemspecs.find {|g| g.name == options["name"] }
144
+ "root_path" => gemfile_root
146
145
  )
147
146
 
148
147
  source_options["global"] = true unless block_given?
@@ -193,6 +193,24 @@ module Bundler
193
193
  status_code(31)
194
194
  end
195
195
 
196
+ class ReadOnlyFileSystemError < PermissionError
197
+ def message
198
+ "There was an error while trying to #{action} `#{@path}`. " \
199
+ "File system is read-only."
200
+ end
201
+
202
+ status_code(42)
203
+ end
204
+
205
+ class OperationNotPermittedError < PermissionError
206
+ def message
207
+ "There was an error while trying to #{action} `#{@path}`. " \
208
+ "Underlying OS system call raised an EPERM error."
209
+ end
210
+
211
+ status_code(43)
212
+ end
213
+
196
214
  class GenericSystemCallError < BundlerError
197
215
  attr_reader :underlying_error
198
216
 
@@ -108,17 +108,17 @@ module Bundler
108
108
  end
109
109
 
110
110
  if d.groups != Array(:default)
111
- group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}"
111
+ group = d.groups.size == 1 ? ", group: #{d.groups.first.inspect}" : ", groups: #{d.groups.inspect}"
112
112
  end
113
113
 
114
- source = ", :source => \"#{d.source}\"" unless d.source.nil?
115
- path = ", :path => \"#{d.path}\"" unless d.path.nil?
116
- git = ", :git => \"#{d.git}\"" unless d.git.nil?
117
- github = ", :github => \"#{d.github}\"" unless d.github.nil?
118
- branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
119
- ref = ", :ref => \"#{d.ref}\"" unless d.ref.nil?
120
- glob = ", :glob => \"#{d.glob}\"" unless d.glob.nil?
121
- require_path = ", :require => #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
114
+ source = ", source: \"#{d.source}\"" unless d.source.nil?
115
+ path = ", path: \"#{d.path}\"" unless d.path.nil?
116
+ git = ", git: \"#{d.git}\"" unless d.git.nil?
117
+ github = ", github: \"#{d.github}\"" unless d.github.nil?
118
+ branch = ", branch: \"#{d.branch}\"" unless d.branch.nil?
119
+ ref = ", ref: \"#{d.ref}\"" unless d.ref.nil?
120
+ glob = ", glob: \"#{d.glob}\"" unless d.glob.nil?
121
+ require_path = ", require: #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
122
122
 
123
123
  %(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{glob}#{require_path})
124
124
  end.join("\n")
@@ -175,6 +175,14 @@ module Bundler
175
175
  @force_ruby_platform = true
176
176
  end
177
177
 
178
+ def replace_source_with!(gemfile_source)
179
+ return unless gemfile_source.can_lock?(self)
180
+
181
+ @source = gemfile_source
182
+
183
+ true
184
+ end
185
+
178
186
  private
179
187
 
180
188
  def use_exact_resolved_specifications?
@@ -196,7 +204,7 @@ module Bundler
196
204
 
197
205
  # If in frozen mode, we fallback to a non-installable candidate because by
198
206
  # doing this we avoid re-resolving and potentially end up changing the
199
- # lock file, which is not allowed. In that case, we will give a proper error
207
+ # lockfile, which is not allowed. In that case, we will give a proper error
200
208
  # about the mismatch higher up the stack, right before trying to install the
201
209
  # bad gem.
202
210
  def choose_compatible(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
@@ -239,7 +239,6 @@ module Bundler
239
239
  spaces = $1
240
240
  return unless spaces.size == 2
241
241
  checksums = $6
242
- return unless checksums
243
242
  name = $2
244
243
  version = $3
245
244
  platform = $4
@@ -249,10 +248,14 @@ module Bundler
249
248
  full_name = Gem::NameTuple.new(name, version, platform).full_name
250
249
  return unless spec = @specs[full_name]
251
250
 
252
- checksums.split(",") do |lock_checksum|
253
- column = line.index(lock_checksum) + 1
254
- checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
255
- spec.source.checksum_store.register(spec, checksum)
251
+ if checksums
252
+ checksums.split(",") do |lock_checksum|
253
+ column = line.index(lock_checksum) + 1
254
+ checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
255
+ spec.source.checksum_store.register(spec, checksum)
256
+ end
257
+ else
258
+ spec.source.checksum_store.register(spec, nil)
256
259
  end
257
260
  end
258
261
 
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-ADD" "1" "January 2025" ""
3
+ .TH "BUNDLE\-ADD" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-BINSTUBS" "1" "January 2025" ""
3
+ .TH "BUNDLE\-BINSTUBS" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CACHE" "1" "January 2025" ""
3
+ .TH "BUNDLE\-CACHE" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CHECK" "1" "January 2025" ""
3
+ .TH "BUNDLE\-CHECK" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CLEAN" "1" "January 2025" ""
3
+ .TH "BUNDLE\-CLEAN" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CONFIG" "1" "January 2025" ""
3
+ .TH "BUNDLE\-CONFIG" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -56,16 +56,16 @@ Creates a directory (defaults to \fB~/bin\fR) and place any executables from the
56
56
  In deployment mode, Bundler will 'roll\-out' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\.
57
57
  .TP
58
58
  \fBonly\fR
59
- A space\-separated list of groups to install only gems of the specified groups\.
59
+ A space\-separated list of groups to install only gems of the specified groups\. Please check carefully if you want to install also gems without a group, cause they get put inside \fBdefault\fR group\. For example \fBonly test:default\fR will install all gems specified in test group and without one\.
60
60
  .TP
61
61
  \fBpath\fR
62
62
  The location to install the specified gems to\. This defaults to Rubygems' setting\. Bundler shares this location with Rubygems, \fBgem install \|\.\|\.\|\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \|\.\|\.\|\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
63
63
  .TP
64
64
  \fBwithout\fR
65
- A space\-separated list of groups referencing gems to skip during installation\.
65
+ A space\-separated or \fB:\fR\-separated list of groups referencing gems to skip during installation\.
66
66
  .TP
67
67
  \fBwith\fR
68
- A space\-separated list of \fBoptional\fR groups referencing gems to include during installation\.
68
+ A space\-separated or \fB:\fR\-separated list of \fBoptional\fR groups referencing gems to include during installation\.
69
69
  .SH "BUILD OPTIONS"
70
70
  You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\.
71
71
  .P
@@ -197,9 +197,9 @@ The following is a list of all configuration keys and their purpose\. You can le
197
197
  .IP "\(bu" 4
198
198
  \fBversion\fR (\fBBUNDLE_VERSION\fR): The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\.
199
199
  .IP "\(bu" 4
200
- \fBwith\fR (\fBBUNDLE_WITH\fR): A \fB:\fR\-separated list of groups whose gems bundler should install\.
200
+ \fBwith\fR (\fBBUNDLE_WITH\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\.
201
201
  .IP "\(bu" 4
202
- \fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A \fB:\fR\-separated list of groups whose gems bundler should not install\.
202
+ \fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\.
203
203
  .IP "" 0
204
204
  .SH "LOCAL GIT REPOS"
205
205
  Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override:
@@ -79,6 +79,9 @@ The options that can be configured are:
79
79
 
80
80
  * `only`:
81
81
  A space-separated list of groups to install only gems of the specified groups.
82
+ Please check carefully if you want to install also gems without a group, cause
83
+ they get put inside `default` group. For example `only test:default` will install
84
+ all gems specified in test group and without one.
82
85
 
83
86
  * `path`:
84
87
  The location to install the specified gems to. This defaults to Rubygems'
@@ -88,10 +91,12 @@ The options that can be configured are:
88
91
  installed to other locations will not get listed.
89
92
 
90
93
  * `without`:
91
- A space-separated list of groups referencing gems to skip during installation.
94
+ A space-separated or `:`-separated list of groups referencing gems to skip during
95
+ installation.
92
96
 
93
97
  * `with`:
94
- A space-separated list of **optional** groups referencing gems to include during installation.
98
+ A space-separated or `:`-separated list of **optional** groups referencing gems to
99
+ include during installation.
95
100
 
96
101
  ## BUILD OPTIONS
97
102
 
@@ -280,9 +285,9 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
280
285
  `system` will use the system version of Bundler, and `x.y.z` will use
281
286
  the specified version of Bundler.
282
287
  * `with` (`BUNDLE_WITH`):
283
- A `:`-separated list of groups whose gems bundler should install.
288
+ A space-separated or `:`-separated list of groups whose gems bundler should install.
284
289
  * `without` (`BUNDLE_WITHOUT`):
285
- A `:`-separated list of groups whose gems bundler should not install.
290
+ A space-separated or `:`-separated list of groups whose gems bundler should not install.
286
291
 
287
292
  ## LOCAL GIT REPOS
288
293
 
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CONSOLE" "1" "January 2025" ""
3
+ .TH "BUNDLE\-CONSOLE" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-console\fR \- Open an IRB session with the bundle pre\-loaded
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-DOCTOR" "1" "January 2025" ""
3
+ .TH "BUNDLE\-DOCTOR" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-doctor\fR \- Checks the bundle for common problems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-ENV" "1" "January 2025" ""
3
+ .TH "BUNDLE\-ENV" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-env\fR \- Print information about the environment Bundler is running under
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-EXEC" "1" "January 2025" ""
3
+ .TH "BUNDLE\-EXEC" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-exec\fR \- Execute a command in the context of the bundle
6
6
  .SH "SYNOPSIS"
@@ -74,8 +74,8 @@ end
74
74
  Bundler provides convenience helpers that wrap \fBsystem\fR and \fBexec\fR, and they can be used like this:
75
75
  .IP "" 4
76
76
  .nf
77
- Bundler\.clean_system('brew install wget')
78
- Bundler\.clean_exec('brew install wget')
77
+ Bundler\.unbundled_system('brew install wget')
78
+ Bundler\.unbundled_exec('brew install wget')
79
79
  .fi
80
80
  .IP "" 0
81
81
  .SH "RUBYGEMS PLUGINS"
@@ -108,8 +108,8 @@ need to use `with_unbundled_env`.
108
108
  Bundler provides convenience helpers that wrap `system` and `exec`, and they
109
109
  can be used like this:
110
110
 
111
- Bundler.clean_system('brew install wget')
112
- Bundler.clean_exec('brew install wget')
111
+ Bundler.unbundled_system('brew install wget')
112
+ Bundler.unbundled_exec('brew install wget')
113
113
 
114
114
 
115
115
  ## RUBYGEMS PLUGINS