rubygems-update 3.5.15 → 3.5.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -1
  3. data/bundler/CHANGELOG.md +31 -1
  4. data/bundler/lib/bundler/build_metadata.rb +2 -2
  5. data/bundler/lib/bundler/cli/check.rb +1 -1
  6. data/bundler/lib/bundler/cli/gem.rb +1 -1
  7. data/bundler/lib/bundler/cli.rb +18 -18
  8. data/bundler/lib/bundler/definition.rb +33 -22
  9. data/bundler/lib/bundler/env.rb +1 -1
  10. data/bundler/lib/bundler/force_platform.rb +0 -2
  11. data/bundler/lib/bundler/gem_helpers.rb +14 -7
  12. data/bundler/lib/bundler/injector.rb +1 -4
  13. data/bundler/lib/bundler/installer/standalone.rb +0 -3
  14. data/bundler/lib/bundler/installer.rb +1 -3
  15. data/bundler/lib/bundler/lazy_specification.rb +1 -0
  16. data/bundler/lib/bundler/plugin/api/source.rb +1 -0
  17. data/bundler/lib/bundler/resolver/base.rb +4 -0
  18. data/bundler/lib/bundler/resolver/candidate.rb +4 -16
  19. data/bundler/lib/bundler/resolver/package.rb +4 -0
  20. data/bundler/lib/bundler/resolver/spec_group.rb +20 -2
  21. data/bundler/lib/bundler/resolver.rb +18 -9
  22. data/bundler/lib/bundler/rubygems_ext.rb +37 -13
  23. data/bundler/lib/bundler/rubygems_integration.rb +1 -1
  24. data/bundler/lib/bundler/runtime.rb +1 -6
  25. data/bundler/lib/bundler/source/git.rb +29 -16
  26. data/bundler/lib/bundler/source/rubygems.rb +1 -0
  27. data/bundler/lib/bundler/spec_set.rb +15 -13
  28. data/bundler/lib/bundler/stub_specification.rb +8 -0
  29. data/bundler/lib/bundler/version.rb +1 -1
  30. data/bundler/lib/bundler/yaml_serializer.rb +1 -1
  31. data/lib/rubygems/config_file.rb +13 -8
  32. data/lib/rubygems/dependency.rb +8 -0
  33. data/lib/rubygems/query_utils.rb +1 -1
  34. data/lib/rubygems/specification.rb +2 -2
  35. data/lib/rubygems/uninstaller.rb +15 -1
  36. data/lib/rubygems/yaml_serializer.rb +1 -1
  37. data/lib/rubygems.rb +1 -1
  38. data/rubygems-update.gemspec +1 -1
  39. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28cfb831008b4e410b548da95cb6d13d1ce5bf6e8fa627d7b9b68054a8d9986a
4
- data.tar.gz: 56a3282f366046b58dc95dd26ff68a1654f4020cebc24ec47ba9161aab5c66d3
3
+ metadata.gz: 4de10b4ef4790d15ab080c077f5373aa81c8173d79c92b7114abb206892bac14
4
+ data.tar.gz: a4f077e4f6133d34807d56da7441a6913a431842d0a25df6a1fc675885d7ae6d
5
5
  SHA512:
6
- metadata.gz: bae4267616d578f691e583b6bdea0d8022a42cee9f7be5e46e09962a766624900e059f295647f83d0d621df32b4637165d96c92bfe66ff222d943b161f67e93b
7
- data.tar.gz: 44d6c04d7f8531f3154a901b98a9f707941e0d8955bc02bd5a5b0cc2f8c01702fcb00ad2955886d89f4fece3ce6cb85c9a4bc412f756308ca9ada5b3a6b700e0
6
+ metadata.gz: e5a60f2a2906d32a151b741a5a0b7a10f3ce771e67c442f4a2c1d6bd32aaecfc5df0f4df01e1daa388e2eedcb523bebbd6a1eac96d5d9b96badc0e2feb2980a3
7
+ data.tar.gz: 4b70512b9ea90529d0493fc06e52d905ad4bd52379584828045604c4113f11f3a9728362d86f182f7b69487651b2cdcfaa303134dfc68204a0254ebf75c9e63e
data/CHANGELOG.md CHANGED
@@ -1,4 +1,43 @@
1
- # 3.5.15 / 2024-07-08
1
+ # 3.5.17 / 2024-08-01
2
+
3
+ ## Enhancements:
4
+
5
+ * Explicitly encode `Gem::Dependency` to yaml. Pull request
6
+ [#7867](https://github.com/rubygems/rubygems/pull/7867) by segiddins
7
+ * Installs bundler 2.5.17 as a default gem.
8
+
9
+ ## Bug fixes:
10
+
11
+ * Fix `gem list` regression when a regular gem shadows a default one. Pull
12
+ request [#7892](https://github.com/rubygems/rubygems/pull/7892) by
13
+ deivid-rodriguez
14
+ * Always leave default gem executables around. Pull request
15
+ [#7879](https://github.com/rubygems/rubygems/pull/7879) by
16
+ deivid-rodriguez
17
+ * Fix line comment issue for hash when loading gemrc. Pull request
18
+ [#7857](https://github.com/rubygems/rubygems/pull/7857) by leetking
19
+
20
+ # 3.5.16 / 2024-07-18
21
+
22
+ ## Enhancements:
23
+
24
+ * Installs bundler 2.5.16 as a default gem.
25
+
26
+ ## Bug fixes:
27
+
28
+ * Fix gemspec `require_paths` validation. Pull request
29
+ [#7866](https://github.com/rubygems/rubygems/pull/7866) by
30
+ deivid-rodriguez
31
+ * Fix loading of nested `gemrc` config keys when specified as symbols.
32
+ Pull request [#7851](https://github.com/rubygems/rubygems/pull/7851) by
33
+ moofkit
34
+
35
+ ## Performance:
36
+
37
+ * Use `caller_locations` instead of splitting `caller`. Pull request
38
+ [#7708](https://github.com/rubygems/rubygems/pull/7708) by nobu
39
+
40
+ # 3.5.15 / 2024-07-09
2
41
 
3
42
  ## Enhancements:
4
43
 
data/bundler/CHANGELOG.md CHANGED
@@ -1,4 +1,34 @@
1
- # 2.5.15 (July 8, 2024)
1
+ # 2.5.17 (August 1, 2024)
2
+
3
+ ## Enhancements:
4
+
5
+ - Print better log message when current platform is not present in the lockfile [#7891](https://github.com/rubygems/rubygems/pull/7891)
6
+ - Explicitly encode `Gem::Dependency` to yaml [#7867](https://github.com/rubygems/rubygems/pull/7867)
7
+ - Enable lockfile checksums on future Bundler 3 when there's no previous lockfile [#7805](https://github.com/rubygems/rubygems/pull/7805)
8
+
9
+ ## Bug fixes:
10
+
11
+ - Fix truffleruby removing gems from lockfile [#7795](https://github.com/rubygems/rubygems/pull/7795)
12
+ - Fix `bundle check` exit code when gem git source is not checked out [#7894](https://github.com/rubygems/rubygems/pull/7894)
13
+ - Generate gems.rb from Gemfile.tt template for `bundle-gem` [#7853](https://github.com/rubygems/rubygems/pull/7853)
14
+ - Fix git source cache being used as the install location [#4469](https://github.com/rubygems/rubygems/pull/4469)
15
+ - Fix `bundle exec gem uninstall` [#7886](https://github.com/rubygems/rubygems/pull/7886)
16
+
17
+ # 2.5.16 (July 18, 2024)
18
+
19
+ ## Bug fixes:
20
+
21
+ - Fix platform removal regression when `platforms:` used in the Gemfile [#7864](https://github.com/rubygems/rubygems/pull/7864)
22
+ - Fix standalone script when default gems with extensions are used [#7870](https://github.com/rubygems/rubygems/pull/7870)
23
+ - Fix another case of `bundle lock --add-platform` doing nothing [#7848](https://github.com/rubygems/rubygems/pull/7848)
24
+ - Fix bad error messages when using `bundle add` with frozen mode set [#7845](https://github.com/rubygems/rubygems/pull/7845)
25
+ - Fix generic platform gems getting incorrectly removed from lockfile [#7833](https://github.com/rubygems/rubygems/pull/7833)
26
+
27
+ ## Performance:
28
+
29
+ - Use `caller_locations` instead of splitting `caller` [#7708](https://github.com/rubygems/rubygems/pull/7708)
30
+
31
+ # 2.5.15 (July 9, 2024)
2
32
 
3
33
  ## Enhancements:
4
34
 
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2024-07-09".freeze
8
- @git_commit_sha = "ee7468dc1a".freeze
7
+ @built_at = "2024-08-01".freeze
8
+ @git_commit_sha = "74d92b2502".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -17,7 +17,7 @@ module Bundler
17
17
  begin
18
18
  definition.resolve_only_locally!
19
19
  not_installed = definition.missing_specs
20
- rescue GemNotFound, SolveFailure
20
+ rescue GemNotFound, GitError, SolveFailure
21
21
  Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
22
22
  Bundler.ui.warn "Install missing gems with `bundle install`."
23
23
  exit 1
@@ -79,7 +79,7 @@ module Bundler
79
79
  ensure_safe_gem_name(name, constant_array)
80
80
 
81
81
  templates = {
82
- "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name,
82
+ "Gemfile.tt" => Bundler.preferred_gemfile_name,
83
83
  "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
84
84
  "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
85
85
  "sig/newgem.rbs.tt" => "sig/#{namespaced_path}.rbs",
@@ -110,8 +110,8 @@ module Bundler
110
110
  default_task(Bundler.feature_flag.default_cli_command)
111
111
 
112
112
  class_option "no-color", type: :boolean, desc: "Disable colorization in output"
113
- class_option "retry", type: :numeric, aliases: "-r", banner: "NUM",
114
- desc: "Specify the number of times you wish to attempt network commands"
113
+ class_option "retry", type: :numeric, aliases: "-r", banner: "NUM",
114
+ desc: "Specify the number of times you wish to attempt network commands"
115
115
  class_option "verbose", type: :boolean, desc: "Enable verbose output mode", aliases: "-V"
116
116
 
117
117
  def help(cli = nil)
@@ -260,15 +260,15 @@ module Bundler
260
260
  method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
261
261
  method_option "group", aliases: "-g", type: :array, banner: "Update a specific group"
262
262
  method_option "jobs", aliases: "-j", type: :numeric, banner: "Specify the number of jobs to run in parallel"
263
- method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
264
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
263
+ method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
264
+ method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
265
265
  method_option "source", type: :array, banner: "Update a specific source (and all gems associated with it)"
266
266
  method_option "redownload", type: :boolean, aliases: "--force", banner: "Force downloading every gem."
267
267
  method_option "ruby", type: :boolean, banner: "Update ruby specified in Gemfile.lock"
268
268
  method_option "bundler", type: :string, lazy_default: "> 0.a", banner: "Update the locked version of bundler"
269
- method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
270
- method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
271
- method_option "major", type: :boolean, banner: "Prefer updating to next major version (default)"
269
+ method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
270
+ method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
271
+ method_option "major", type: :boolean, banner: "Prefer updating to next major version (default)"
272
272
  method_option "pre", type: :boolean, banner: "Always choose the highest allowed version when updating gems, regardless of prerelease status"
273
273
  method_option "strict", type: :boolean, banner: "Do not allow any gem to be updated past latest --patch | --minor | --major"
274
274
  method_option "conservative", type: :boolean, banner: "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
@@ -397,11 +397,11 @@ module Bundler
397
397
  end
398
398
 
399
399
  desc "cache [OPTIONS]", "Locks and then caches all of the gems into vendor/cache"
400
- method_option "all", type: :boolean,
401
- default: Bundler.feature_flag.cache_all?,
402
- banner: "Include all sources (including path and git)."
400
+ method_option "all", type: :boolean,
401
+ default: Bundler.feature_flag.cache_all?,
402
+ banner: "Include all sources (including path and git)."
403
403
  method_option "all-platforms", type: :boolean, banner: "Include gems for all platforms present in the lockfile, not only the current one"
404
- method_option "cache-path", type: :string, banner: "Specify a different cache path than the default (vendor/cache)."
404
+ method_option "cache-path", type: :string, banner: "Specify a different cache path than the default (vendor/cache)."
405
405
  method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
406
406
  method_option "no-install", type: :boolean, banner: "Don't install the gems, only update the cache."
407
407
  method_option "no-prune", type: :boolean, banner: "Don't remove stale gems from the cache."
@@ -605,7 +605,7 @@ module Bundler
605
605
  end
606
606
 
607
607
  desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", hide: true
608
- method_option "source", type: :string, banner: "Install gem from the given source"
608
+ method_option "source", type: :string, banner: "Install gem from the given source"
609
609
  method_option "group", type: :string, banner: "Install gem into a bundler group"
610
610
  def inject(name, version)
611
611
  SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command"
@@ -615,16 +615,16 @@ module Bundler
615
615
 
616
616
  desc "lock", "Creates a lockfile without installing"
617
617
  method_option "update", type: :array, lazy_default: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
618
- method_option "local", type: :boolean, default: false, banner: "do not attempt to fetch remote gemspecs and use the local gem cache only"
619
- method_option "print", type: :boolean, default: false, banner: "print the lockfile to STDOUT instead of writing to the file system"
618
+ method_option "local", type: :boolean, default: false, banner: "do not attempt to fetch remote gemspecs and use the local gem cache only"
619
+ method_option "print", type: :boolean, default: false, banner: "print the lockfile to STDOUT instead of writing to the file system"
620
620
  method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
621
621
  method_option "lockfile", type: :string, default: nil, banner: "the path the lockfile should be written to"
622
622
  method_option "full-index", type: :boolean, default: false, banner: "Fall back to using the single-file index of all gems"
623
623
  method_option "add-platform", type: :array, default: [], banner: "Add a new platform to the lockfile"
624
- method_option "remove-platform", type: :array, default: [], banner: "Remove a platform from the lockfile"
625
- method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
626
- method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
627
- method_option "major", type: :boolean, banner: "If updating, prefer updating to next major version (default)"
624
+ method_option "remove-platform", type: :array, default: [], banner: "Remove a platform from the lockfile"
625
+ method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
626
+ method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
627
+ method_option "major", type: :boolean, banner: "If updating, prefer updating to next major version (default)"
628
628
  method_option "pre", type: :boolean, banner: "If updating, always choose the highest allowed version, regardless of prerelease status"
629
629
  method_option "strict", type: :boolean, banner: "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
630
630
  method_option "conservative", type: :boolean, banner: "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
@@ -81,7 +81,7 @@ module Bundler
81
81
  @resolved_bundler_version = nil
82
82
 
83
83
  @locked_ruby_version = nil
84
- @new_platform = nil
84
+ @new_platforms = []
85
85
  @removed_platform = nil
86
86
 
87
87
  if lockfile_exists?
@@ -115,7 +115,7 @@ module Bundler
115
115
  @originally_locked_specs = @locked_specs
116
116
  @locked_sources = []
117
117
  @locked_platforms = []
118
- @locked_checksums = nil
118
+ @locked_checksums = Bundler.feature_flag.bundler_3_mode?
119
119
  end
120
120
 
121
121
  locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@@ -137,7 +137,7 @@ module Bundler
137
137
  end
138
138
  @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
139
139
 
140
- add_current_platform unless Bundler.frozen_bundle?
140
+ @current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
141
141
 
142
142
  converge_path_sources_to_gemspec_sources
143
143
  @path_changes = converge_paths
@@ -367,6 +367,10 @@ module Bundler
367
367
  end
368
368
 
369
369
  def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
370
+ return unless Bundler.frozen_bundle?
371
+
372
+ raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
373
+
370
374
  added = []
371
375
  deleted = []
372
376
  changed = []
@@ -395,7 +399,7 @@ module Bundler
395
399
  changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
396
400
  end
397
401
 
398
- reason = change_reason
402
+ reason = nothing_changed? ? "some dependencies were deleted from your gemfile" : change_reason
399
403
  msg = String.new
400
404
  msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
401
405
  msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
@@ -453,8 +457,10 @@ module Bundler
453
457
  end
454
458
 
455
459
  def add_platform(platform)
456
- @new_platform ||= !@platforms.include?(platform)
457
- @platforms |= [platform]
460
+ return if @platforms.include?(platform)
461
+
462
+ @new_platforms << platform
463
+ @platforms << platform
458
464
  end
459
465
 
460
466
  def remove_platform(platform)
@@ -478,7 +484,8 @@ module Bundler
478
484
 
479
485
  !@source_changes &&
480
486
  !@dependency_changes &&
481
- !@new_platform &&
487
+ !@current_platform_missing &&
488
+ @new_platforms.empty? &&
482
489
  !@path_changes &&
483
490
  !@local_changes &&
484
491
  !@missing_lockfile_dep &&
@@ -561,7 +568,7 @@ module Bundler
561
568
  def resolution_packages
562
569
  @resolution_packages ||= begin
563
570
  last_resolve = converge_locked_specs
564
- remove_invalid_platforms!(current_dependencies)
571
+ remove_invalid_platforms!
565
572
  packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre?)
566
573
  packages = additional_base_requirements_to_prevent_downgrades(packages, last_resolve)
567
574
  packages = additional_base_requirements_to_force_updates(packages)
@@ -623,13 +630,14 @@ module Bundler
623
630
  def start_resolution
624
631
  local_platform_needed_for_resolvability = @most_specific_non_local_locked_ruby_platform && !@platforms.include?(local_platform)
625
632
  @platforms << local_platform if local_platform_needed_for_resolvability
633
+ add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
626
634
 
627
635
  result = SpecSet.new(resolver.start)
628
636
 
629
637
  @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
630
638
 
631
639
  if @most_specific_non_local_locked_ruby_platform
632
- if result.incomplete_for_platform?(dependencies, @most_specific_non_local_locked_ruby_platform)
640
+ if spec_set_incomplete_for_platform?(result, @most_specific_non_local_locked_ruby_platform)
633
641
  @platforms.delete(@most_specific_non_local_locked_ruby_platform)
634
642
  elsif local_platform_needed_for_resolvability
635
643
  @platforms.delete(local_platform)
@@ -638,8 +646,6 @@ module Bundler
638
646
 
639
647
  @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
640
648
 
641
- result.complete_platforms!(platforms)
642
-
643
649
  SpecSet.new(result.for(dependencies, false, @platforms))
644
650
  end
645
651
 
@@ -667,19 +673,19 @@ module Bundler
667
673
  end
668
674
 
669
675
  def add_current_platform
670
- @most_specific_non_local_locked_ruby_platform = find_most_specific_non_local_locked_ruby_platform
676
+ return if @platforms.include?(local_platform)
677
+
678
+ @most_specific_non_local_locked_ruby_platform = find_most_specific_locked_ruby_platform
671
679
  return if @most_specific_non_local_locked_ruby_platform
672
680
 
673
- add_platform(local_platform)
681
+ @platforms << local_platform
682
+ true
674
683
  end
675
684
 
676
- def find_most_specific_non_local_locked_ruby_platform
685
+ def find_most_specific_locked_ruby_platform
677
686
  return unless generic_local_platform_is_ruby? && current_platform_locked?
678
687
 
679
- most_specific_locked_ruby_platform = most_specific_locked_platform
680
- return unless most_specific_locked_ruby_platform != local_platform
681
-
682
- most_specific_locked_ruby_platform
688
+ most_specific_locked_platform
683
689
  end
684
690
 
685
691
  def change_reason
@@ -701,7 +707,8 @@ module Bundler
701
707
  [
702
708
  [@source_changes, "the list of sources changed"],
703
709
  [@dependency_changes, "the dependencies in your gemfile changed"],
704
- [@new_platform, "you added a new platform to your gemfile"],
710
+ [@current_platform_missing, "your lockfile does not include the current platform"],
711
+ [@new_platforms.any?, "you added a new platform to your gemfile"],
705
712
  [@path_changes, "the gemspecs for path gems changed"],
706
713
  [@local_changes, "the gemspecs for git local gems changed"],
707
714
  [@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""],
@@ -1054,21 +1061,25 @@ module Bundler
1054
1061
  unlocked_definition
1055
1062
  end
1056
1063
 
1057
- def remove_invalid_platforms!(dependencies)
1064
+ def remove_invalid_platforms!
1058
1065
  return if Bundler.frozen_bundle?
1059
1066
 
1060
1067
  platforms.reverse_each do |platform|
1061
1068
  next if local_platform == platform ||
1062
- (@new_platform && platforms.last == platform) ||
1069
+ @new_platforms.include?(platform) ||
1063
1070
  @path_changes ||
1064
1071
  @dependency_changes ||
1065
1072
  @locked_spec_with_invalid_deps ||
1066
- !@originally_locked_specs.incomplete_for_platform?(dependencies, platform)
1073
+ !spec_set_incomplete_for_platform?(@originally_locked_specs, platform)
1067
1074
 
1068
1075
  remove_platform(platform)
1069
1076
  end
1070
1077
  end
1071
1078
 
1079
+ def spec_set_incomplete_for_platform?(spec_set, platform)
1080
+ spec_set.incomplete_for_platform?(current_dependencies, platform)
1081
+ end
1082
+
1072
1083
  def source_map
1073
1084
  @source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
1074
1085
  end
@@ -120,7 +120,7 @@ module Bundler
120
120
  specs = Bundler.rubygems.find_name(name)
121
121
  out << [" #{name}", "(#{specs.map(&:version).join(",")})"] unless specs.empty?
122
122
  end
123
- if (exe = caller.last.split(":").first)&.match? %r{(exe|bin)/bundler?\z}
123
+ if (exe = caller_locations.last.absolute_path)&.match? %r{(exe|bin)/bundler?\z}
124
124
  shebang = File.read(exe).lines.first
125
125
  shebang.sub!(/^#!\s*/, "")
126
126
  unless shebang.start_with?(Gem.ruby, "/usr/bin/env ruby")
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Bundler
4
4
  module ForcePlatform
5
- private
6
-
7
5
  # The `:force_ruby_platform` value used by dependencies for resolution, and
8
6
  # by locked specifications for materialization is `false` by default, except
9
7
  # for TruffleRuby. TruffleRuby generally needs to force the RUBY platform
@@ -46,19 +46,26 @@ module Bundler
46
46
  end
47
47
  module_function :platform_specificity_match
48
48
 
49
- def select_best_platform_match(specs, platform)
50
- matching = specs.select {|spec| spec.match_platform(platform) }
49
+ def select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
50
+ matching = if force_ruby
51
+ specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! }
52
+ else
53
+ specs.select {|spec| spec.match_platform(platform) }
54
+ end
55
+
56
+ if prefer_locked
57
+ locked_originally = matching.select {|spec| spec.is_a?(LazySpecification) }
58
+ return locked_originally if locked_originally.any?
59
+ end
51
60
 
52
61
  sort_best_platform_match(matching, platform)
53
62
  end
54
63
  module_function :select_best_platform_match
55
64
 
56
- def force_ruby_platform(specs)
57
- matching = specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! }
58
-
59
- sort_best_platform_match(matching, Gem::Platform::RUBY)
65
+ def select_best_local_platform_match(specs, force_ruby: false)
66
+ select_best_platform_match(specs, local_platform, force_ruby: force_ruby).map(&:materialize_for_installation).compact
60
67
  end
61
- module_function :force_ruby_platform
68
+ module_function :select_best_local_platform_match
62
69
 
63
70
  def sort_best_platform_match(matching, platform)
64
71
  exact = matching.select {|spec| spec.platform == platform }
@@ -23,10 +23,7 @@ module Bundler
23
23
  # @param [Pathname] lockfile_path The lockfile in which to inject the new dependency.
24
24
  # @return [Array]
25
25
  def inject(gemfile_path, lockfile_path)
26
- if Bundler.frozen_bundle?
27
- # ensure the lock and Gemfile are synced
28
- Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
29
- end
26
+ Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
30
27
 
31
28
  # temporarily unfreeze
32
29
  Bundler.settings.temporary(deployment: false, frozen: false) do
@@ -58,9 +58,6 @@ module Bundler
58
58
  else
59
59
  SharedHelpers.relative_path_to(full_path, from: Bundler.root.join(bundler_path))
60
60
  end
61
- rescue TypeError
62
- error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
63
- raise Gem::InvalidSpecificationException.new(error_message)
64
61
  end
65
62
 
66
63
  def prevent_gem_activation
@@ -69,9 +69,7 @@ module Bundler
69
69
  Bundler.create_bundle_path
70
70
 
71
71
  ProcessLock.lock do
72
- if Bundler.frozen_bundle?
73
- @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
74
- end
72
+ @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
75
73
 
76
74
  if @definition.dependencies.empty?
77
75
  Bundler.ui.warn "The Gemfile specifies no dependencies"
@@ -4,6 +4,7 @@ require_relative "force_platform"
4
4
 
5
5
  module Bundler
6
6
  class LazySpecification
7
+ include MatchMetadata
7
8
  include MatchPlatform
8
9
  include ForcePlatform
9
10
 
@@ -196,6 +196,7 @@ module Bundler
196
196
 
197
197
  FileUtils.rm_rf(new_cache_path)
198
198
  FileUtils.cp_r(install_path, new_cache_path)
199
+ FileUtils.rm_rf(app_cache_path.join(".git"))
199
200
  FileUtils.touch(app_cache_path.join(".bundlecache"))
200
201
  end
201
202
 
@@ -30,6 +30,10 @@ module Bundler
30
30
  end.compact
31
31
  end
32
32
 
33
+ def specs_compatible_with(result)
34
+ @base.specs_compatible_with(result)
35
+ end
36
+
33
37
  def [](name)
34
38
  @base[name]
35
39
  end
@@ -24,10 +24,10 @@ module Bundler
24
24
 
25
25
  attr_reader :version
26
26
 
27
- def initialize(version, specs: [])
28
- @spec_group = Resolver::SpecGroup.new(specs)
27
+ def initialize(version, group: nil, priority: -1)
28
+ @spec_group = group || SpecGroup.new([])
29
29
  @version = Gem::Version.new(version)
30
- @ruby_only = specs.map(&:platform).uniq == [Gem::Platform::RUBY]
30
+ @priority = priority
31
31
  end
32
32
 
33
33
  def dependencies
@@ -40,18 +40,6 @@ module Bundler
40
40
  @spec_group.to_specs(package.force_ruby_platform?)
41
41
  end
42
42
 
43
- def generic!
44
- @ruby_only = true
45
-
46
- self
47
- end
48
-
49
- def platform_specific!
50
- @ruby_only = false
51
-
52
- self
53
- end
54
-
55
43
  def prerelease?
56
44
  @version.prerelease?
57
45
  end
@@ -61,7 +49,7 @@ module Bundler
61
49
  end
62
50
 
63
51
  def sort_obj
64
- [@version, @ruby_only ? -1 : 1]
52
+ [@version, @priority]
65
53
  end
66
54
 
67
55
  def <=>(other)
@@ -25,6 +25,10 @@ module Bundler
25
25
  @prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore
26
26
  end
27
27
 
28
+ def platform_specs(specs)
29
+ platforms.map {|platform| GemHelpers.select_best_platform_match(specs, platform, prefer_locked: !unlock?) }
30
+ end
31
+
28
32
  def to_s
29
33
  @name.delete("\0")
30
34
  end
@@ -3,6 +3,8 @@
3
3
  module Bundler
4
4
  class Resolver
5
5
  class SpecGroup
6
+ attr_reader :specs
7
+
6
8
  def initialize(specs)
7
9
  @specs = specs
8
10
  end
@@ -38,17 +40,33 @@ module Bundler
38
40
  def dependencies
39
41
  @dependencies ||= @specs.map do |spec|
40
42
  __dependencies(spec) + metadata_dependencies(spec)
41
- end.flatten.uniq
43
+ end.flatten.uniq.sort
44
+ end
45
+
46
+ def ==(other)
47
+ sorted_spec_names == other.sorted_spec_names
48
+ end
49
+
50
+ def merge(other)
51
+ return false unless equivalent?(other)
52
+
53
+ @specs |= other.specs
54
+
55
+ true
42
56
  end
43
57
 
44
58
  protected
45
59
 
46
60
  def sorted_spec_names
47
- @sorted_spec_names ||= @specs.map(&:full_name).sort
61
+ @specs.map(&:full_name).sort
48
62
  end
49
63
 
50
64
  private
51
65
 
66
+ def equivalent?(other)
67
+ name == other.name && version == other.version && source == other.source && dependencies == other.dependencies
68
+ end
69
+
52
70
  def exemplary_spec
53
71
  @specs.first
54
72
  end
@@ -79,7 +79,8 @@ module Bundler
79
79
  def solve_versions(root:, logger:)
80
80
  solver = PubGrub::VersionSolver.new(source: self, root: root, logger: logger)
81
81
  result = solver.solve
82
- result.map {|package, version| version.to_specs(package) }.flatten.uniq
82
+ resolved_specs = result.map {|package, version| version.to_specs(package) }.flatten
83
+ resolved_specs |= @base.specs_compatible_with(SpecSet.new(resolved_specs))
83
84
  rescue PubGrub::SolveFailure => e
84
85
  incompatibility = e.incompatibility
85
86
 
@@ -254,7 +255,7 @@ module Bundler
254
255
  results = filter_matching_specs(results, locked_requirement) if locked_requirement
255
256
 
256
257
  results.group_by(&:version).reduce([]) do |groups, (version, specs)|
257
- platform_specs = package.platforms.map {|platform| select_best_platform_match(specs, platform) }
258
+ platform_specs = package.platform_specs(specs)
258
259
 
259
260
  # If package is a top-level dependency,
260
261
  # candidate is only valid if there are matching versions for all resolution platforms.
@@ -269,14 +270,22 @@ module Bundler
269
270
  next groups if platform_specs.all?(&:empty?)
270
271
  end
271
272
 
272
- platform_specs.flatten!
273
-
274
273
  ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
275
- groups << Resolver::Candidate.new(version, specs: ruby_specs) if ruby_specs.any?
274
+ ruby_group = Resolver::SpecGroup.new(ruby_specs)
275
+
276
+ unless ruby_group.empty?
277
+ platform_specs.each do |specs|
278
+ ruby_group.merge(Resolver::SpecGroup.new(specs))
279
+ end
280
+
281
+ groups << Resolver::Candidate.new(version, group: ruby_group, priority: -1)
282
+ next groups if package.force_ruby_platform?
283
+ end
276
284
 
277
- next groups if platform_specs == ruby_specs || package.force_ruby_platform?
285
+ platform_group = Resolver::SpecGroup.new(platform_specs.flatten.uniq)
286
+ next groups if platform_group == ruby_group
278
287
 
279
- groups << Resolver::Candidate.new(version, specs: platform_specs)
288
+ groups << Resolver::Candidate.new(version, group: platform_group, priority: 1)
280
289
 
281
290
  groups
282
291
  end
@@ -431,8 +440,8 @@ module Bundler
431
440
 
432
441
  def requirement_to_range(requirement)
433
442
  ranges = requirement.requirements.map do |(op, version)|
434
- ver = Resolver::Candidate.new(version).generic!
435
- platform_ver = Resolver::Candidate.new(version).platform_specific!
443
+ ver = Resolver::Candidate.new(version, priority: -1)
444
+ platform_ver = Resolver::Candidate.new(version, priority: 1)
436
445
 
437
446
  case op
438
447
  when "~>"
@@ -56,7 +56,16 @@ module Gem
56
56
  # Can be removed once RubyGems 3.5.14 support is dropped
57
57
  VALIDATES_FOR_RESOLUTION = Specification.new.respond_to?(:validate_for_resolution).freeze
58
58
 
59
+ # Can be removed once RubyGems 3.3.15 support is dropped
60
+ FLATTENS_REQUIRED_PATHS = Specification.new.respond_to?(:flatten_require_paths).freeze
61
+
59
62
  class Specification
63
+ # Can be removed once RubyGems 3.5.15 support is dropped
64
+ correct_array_attributes = @@default_value.select {|_k,v| v.is_a?(Array) }.keys
65
+ unless @@array_attributes == correct_array_attributes
66
+ @@array_attributes = correct_array_attributes # rubocop:disable Style/ClassVars
67
+ end
68
+
60
69
  require_relative "match_metadata"
61
70
  require_relative "match_platform"
62
71
 
@@ -161,6 +170,27 @@ module Gem
161
170
  end
162
171
  end
163
172
 
173
+ unless FLATTENS_REQUIRED_PATHS
174
+ def flatten_require_paths
175
+ return unless raw_require_paths.first.is_a?(Array)
176
+
177
+ warn "#{name} #{version} includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this"
178
+ raw_require_paths.flatten!
179
+ end
180
+
181
+ class << self
182
+ module RequirePathFlattener
183
+ def from_yaml(input)
184
+ spec = super(input)
185
+ spec.flatten_require_paths
186
+ spec
187
+ end
188
+ end
189
+
190
+ prepend RequirePathFlattener
191
+ end
192
+ end
193
+
164
194
  private
165
195
 
166
196
  def dependencies_to_gemfile(dependencies, group = nil)
@@ -207,26 +237,20 @@ module Gem
207
237
 
208
238
  include ::Bundler::ForcePlatform
209
239
 
240
+ attr_reader :force_ruby_platform
241
+
210
242
  attr_accessor :source, :groups
211
243
 
212
244
  alias_method :eql?, :==
213
245
 
214
- def force_ruby_platform
215
- return @force_ruby_platform if defined?(@force_ruby_platform) && !@force_ruby_platform.nil?
216
-
217
- @force_ruby_platform = default_force_ruby_platform
218
- end
219
-
220
- def encode_with(coder)
221
- to_yaml_properties.each do |ivar|
222
- coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar)
246
+ unless method_defined?(:encode_with, false)
247
+ def encode_with(coder)
248
+ [:@name, :@requirement, :@type, :@prerelease, :@version_requirements].each do |ivar|
249
+ coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar)
250
+ end
223
251
  end
224
252
  end
225
253
 
226
- def to_yaml_properties
227
- instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
228
- end
229
-
230
254
  def to_lock
231
255
  out = String.new(" #{name}")
232
256
  unless requirement.none?
@@ -204,7 +204,7 @@ module Bundler
204
204
 
205
205
  [::Kernel.singleton_class, ::Kernel].each do |kernel_class|
206
206
  redefine_method(kernel_class, :gem) do |dep, *reqs|
207
- if executables&.include?(File.basename(caller.first.split(":").first))
207
+ if executables&.include?(File.basename(caller_locations(1, 1).first.path))
208
208
  break
209
209
  end
210
210
 
@@ -10,7 +10,7 @@ module Bundler
10
10
  end
11
11
 
12
12
  def setup(*groups)
13
- @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
13
+ @definition.ensure_equivalent_gemfile_and_lockfile
14
14
 
15
15
  # Has to happen first
16
16
  clean_load_path
@@ -128,11 +128,6 @@ module Bundler
128
128
  spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
129
129
  end
130
130
 
131
- Dir[cache_path.join("*/.git")].each do |git_dir|
132
- FileUtils.rm_rf(git_dir)
133
- FileUtils.touch(File.expand_path("../.bundlecache", git_dir))
134
- end
135
-
136
131
  prune_cache(cache_path) unless Bundler.settings[:no_prune]
137
132
  end
138
133
 
@@ -164,7 +164,8 @@ module Bundler
164
164
  "does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override"
165
165
  end
166
166
 
167
- set_local!(path)
167
+ @local = true
168
+ set_paths!(path)
168
169
 
169
170
  # Create a new git proxy without the cached revision
170
171
  # so the Gemfile.lock always picks up the new revision.
@@ -187,13 +188,11 @@ module Bundler
187
188
  end
188
189
 
189
190
  def specs(*)
190
- set_local!(app_cache_path) if has_app_cache? && !local?
191
+ set_cache_path!(app_cache_path) if has_app_cache? && !local?
191
192
 
192
193
  if requires_checkout? && !@copied
193
194
  fetch
194
- git_proxy.copy_to(install_path, submodules)
195
- serialize_gemspecs_in(install_path)
196
- @copied = true
195
+ checkout
197
196
  end
198
197
 
199
198
  local_specs
@@ -206,10 +205,7 @@ module Bundler
206
205
  print_using_message "Using #{version_message(spec, options[:previous_spec])} from #{self}"
207
206
 
208
207
  if (requires_checkout? && !@copied) || force
209
- Bundler.ui.debug " * Checking out revision: #{ref}"
210
- git_proxy.copy_to(install_path, submodules)
211
- serialize_gemspecs_in(install_path)
212
- @copied = true
208
+ checkout
213
209
  end
214
210
 
215
211
  generate_bin_options = { disable_extensions: !Bundler.rubygems.spec_missing_extensions?(spec), build_args: options[:build_args] }
@@ -221,12 +217,13 @@ module Bundler
221
217
  def cache(spec, custom_path = nil)
222
218
  app_cache_path = app_cache_path(custom_path)
223
219
  return unless Bundler.feature_flag.cache_all?
224
- return if path == app_cache_path
220
+ return if install_path == app_cache_path
221
+ return if cache_path == app_cache_path
225
222
  cached!
226
223
  FileUtils.rm_rf(app_cache_path)
227
224
  git_proxy.checkout if requires_checkout?
228
- git_proxy.copy_to(app_cache_path, @submodules)
229
- serialize_gemspecs_in(app_cache_path)
225
+ FileUtils.cp_r("#{cache_path}/.", app_cache_path)
226
+ FileUtils.touch(app_cache_path.join(".bundlecache"))
230
227
  end
231
228
 
232
229
  def load_spec_files
@@ -270,6 +267,13 @@ module Bundler
270
267
 
271
268
  private
272
269
 
270
+ def checkout
271
+ Bundler.ui.debug " * Checking out revision: #{ref}"
272
+ git_proxy.copy_to(install_path, submodules)
273
+ serialize_gemspecs_in(install_path)
274
+ @copied = true
275
+ end
276
+
273
277
  def humanized_ref
274
278
  if local?
275
279
  path
@@ -298,10 +302,19 @@ module Bundler
298
302
  end
299
303
  end
300
304
 
301
- def set_local!(path)
302
- @local = true
303
- @local_specs = @git_proxy = nil
304
- @cache_path = @install_path = path
305
+ def set_paths!(path)
306
+ set_cache_path!(path)
307
+ set_install_path!(path)
308
+ end
309
+
310
+ def set_cache_path!(path)
311
+ @git_proxy = nil
312
+ @cache_path = path
313
+ end
314
+
315
+ def set_install_path!(path)
316
+ @local_specs = nil
317
+ @install_path = path
305
318
  end
306
319
 
307
320
  def has_app_cache?
@@ -206,6 +206,7 @@ module Bundler
206
206
 
207
207
  spec.full_gem_path = installed_spec.full_gem_path
208
208
  spec.loaded_from = installed_spec.loaded_from
209
+ spec.base_dir = installed_spec.base_dir
209
210
 
210
211
  spec.post_install_message
211
212
  end
@@ -71,12 +71,6 @@ module Bundler
71
71
  platforms
72
72
  end
73
73
 
74
- def complete_platforms!(platforms)
75
- platforms.each do |platform|
76
- complete_platform(platform)
77
- end
78
- end
79
-
80
74
  def validate_deps(s)
81
75
  s.runtime_dependencies.each do |dep|
82
76
  next if dep.name == "bundler"
@@ -100,7 +94,7 @@ module Bundler
100
94
  end
101
95
 
102
96
  def delete(specs)
103
- specs.each {|spec| @specs.delete(spec) }
97
+ Array(specs).each {|spec| @specs.delete(spec) }
104
98
 
105
99
  reset!
106
100
  end
@@ -158,6 +152,12 @@ module Bundler
158
152
  @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
159
153
  end
160
154
 
155
+ def specs_compatible_with(other)
156
+ select do |spec|
157
+ other.valid?(spec)
158
+ end
159
+ end
160
+
161
161
  def delete_by_name(name)
162
162
  @specs.reject! {|spec| spec.name == name }
163
163
 
@@ -195,6 +195,10 @@ module Bundler
195
195
  lookup.keys
196
196
  end
197
197
 
198
+ def valid?(s)
199
+ s.matches_current_metadata? && valid_dependencies?(s)
200
+ end
201
+
198
202
  private
199
203
 
200
204
  def reset!
@@ -209,7 +213,7 @@ module Bundler
209
213
  spec = specs.first
210
214
  matching_specs = spec.source.specs.search([spec.name, spec.version])
211
215
  platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).find do |s|
212
- s.matches_current_metadata? && valid_dependencies?(s)
216
+ valid?(s)
213
217
  end
214
218
 
215
219
  if platform_spec
@@ -273,13 +277,11 @@ module Bundler
273
277
  specs_for_name = lookup[dep.name]
274
278
  return [] unless specs_for_name
275
279
 
276
- matching_specs = if dep.force_ruby_platform
277
- GemHelpers.force_ruby_platform(specs_for_name)
280
+ if platform
281
+ GemHelpers.select_best_platform_match(specs_for_name, platform, force_ruby: dep.force_ruby_platform)
278
282
  else
279
- GemHelpers.select_best_platform_match(specs_for_name, platform || Bundler.local_platform)
283
+ GemHelpers.select_best_local_platform_match(specs_for_name, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform)
280
284
  end
281
- matching_specs.map!(&:materialize_for_installation).compact! if platform.nil?
282
- matching_specs
283
285
  end
284
286
 
285
287
  def tsort_each_child(s)
@@ -77,6 +77,14 @@ module Bundler
77
77
  stub.full_require_paths
78
78
  end
79
79
 
80
+ def require_paths
81
+ stub.require_paths
82
+ end
83
+
84
+ def base_dir=(path)
85
+ stub.base_dir = path
86
+ end
87
+
80
88
  def load_paths
81
89
  full_require_paths
82
90
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.5.15".freeze
4
+ VERSION = "2.5.17".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
@@ -41,7 +41,7 @@ module Bundler
41
41
  HASH_REGEX = /
42
42
  ^
43
43
  ([ ]*) # indentations
44
- (.+) # key
44
+ ([^#]+) # key excludes comment char '#'
45
45
  (?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
46
46
  [ ]?
47
47
  (['"]?) # optional opening quote
@@ -510,12 +510,12 @@ if you believe they were disclosed to a third party.
510
510
 
511
511
  # Return the configuration information for +key+.
512
512
  def [](key)
513
- @hash[key.to_s]
513
+ @hash[key] || @hash[key.to_s]
514
514
  end
515
515
 
516
516
  # Set configuration option +key+ to +value+.
517
517
  def []=(key, value)
518
- @hash[key.to_s] = value
518
+ @hash[key] = value
519
519
  end
520
520
 
521
521
  def ==(other) # :nodoc:
@@ -543,8 +543,13 @@ if you believe they were disclosed to a third party.
543
543
  require_relative "yaml_serializer"
544
544
 
545
545
  content = Gem::YAMLSerializer.load(yaml)
546
+ deep_transform_config_keys!(content)
547
+ end
546
548
 
547
- content.transform_keys! do |k|
549
+ private
550
+
551
+ def self.deep_transform_config_keys!(config)
552
+ config.transform_keys! do |k|
548
553
  if k.match?(/\A:(.*)\Z/)
549
554
  k[1..-1].to_sym
550
555
  elsif k.include?("__") || k.match?(%r{/\Z})
@@ -558,7 +563,7 @@ if you believe they were disclosed to a third party.
558
563
  end
559
564
  end
560
565
 
561
- content.transform_values! do |v|
566
+ config.transform_values! do |v|
562
567
  if v.is_a?(String)
563
568
  if v.match?(/\A:(.*)\Z/)
564
569
  v[1..-1].to_sym
@@ -571,18 +576,18 @@ if you believe they were disclosed to a third party.
571
576
  else
572
577
  v
573
578
  end
574
- elsif v.is_a?(Hash) && v.empty?
579
+ elsif v.empty?
575
580
  nil
581
+ elsif v.is_a?(Hash)
582
+ deep_transform_config_keys!(v)
576
583
  else
577
584
  v
578
585
  end
579
586
  end
580
587
 
581
- content
588
+ config
582
589
  end
583
590
 
584
- private
585
-
586
591
  def set_config_file_name(args)
587
592
  @config_file_name = ENV["GEMRC"]
588
593
  need_config_file_name = false
@@ -337,4 +337,12 @@ class Gem::Dependency
337
337
  :released
338
338
  end
339
339
  end
340
+
341
+ def encode_with(coder) # :nodoc:
342
+ coder.add "name", @name
343
+ coder.add "requirement", @requirement
344
+ coder.add "type", @type
345
+ coder.add "prerelease", @prerelease
346
+ coder.add "version_requirements", @version_requirements
347
+ end
340
348
  end
@@ -132,7 +132,7 @@ module Gem::QueryUtils
132
132
  version_matches = show_prereleases? || !s.version.prerelease?
133
133
 
134
134
  name_matches && version_matches
135
- end
135
+ end.uniq(&:full_name)
136
136
 
137
137
  spec_tuples = specs.map do |spec|
138
138
  [spec.name_tuple, spec]
@@ -175,7 +175,7 @@ class Gem::Specification < Gem::BasicSpecification
175
175
  end
176
176
 
177
177
  @@attributes = @@default_value.keys.sort_by(&:to_s)
178
- @@array_attributes = @@default_value.reject {|_k,v| v != [] }.keys
178
+ @@array_attributes = @@default_value.select {|_k,v| v.is_a?(Array) }.keys
179
179
  @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition do |k|
180
180
  @@default_value[k].nil?
181
181
  end
@@ -874,7 +874,7 @@ class Gem::Specification < Gem::BasicSpecification
874
874
  # You probably want to use one of the Enumerable methods instead.
875
875
 
876
876
  def self.all
877
- warn "NOTE: Specification.all called from #{caller.first}" unless
877
+ warn "NOTE: Specification.all called from #{caller(1, 1).first}" unless
878
878
  Gem::Deprecate.skip
879
879
  _all
880
880
  end
@@ -251,7 +251,15 @@ class Gem::Uninstaller
251
251
  raise Gem::FilePermissionError, spec.base_dir unless
252
252
  File.writable?(spec.base_dir)
253
253
 
254
- safe_delete { FileUtils.rm_r spec.full_gem_path }
254
+ full_gem_path = spec.full_gem_path
255
+ exclusions = []
256
+
257
+ if default_spec_matches?(spec) && spec.executables.any?
258
+ exclusions = spec.executables.map {|exe| File.join(spec.bin_dir, exe) }
259
+ exclusions << File.dirname(exclusions.last) until exclusions.last == full_gem_path
260
+ end
261
+
262
+ safe_delete { rm_r full_gem_path, exclusions: exclusions }
255
263
  safe_delete { FileUtils.rm_r spec.extension_dir }
256
264
 
257
265
  old_platform_name = spec.original_name
@@ -378,6 +386,12 @@ class Gem::Uninstaller
378
386
 
379
387
  private
380
388
 
389
+ def rm_r(path, exclusions:)
390
+ FileUtils::Entry_.new(path).postorder_traverse do |ent|
391
+ ent.remove unless exclusions.include?(ent.path)
392
+ end
393
+ end
394
+
381
395
  def specification_record
382
396
  @specification_record ||= @install_dir ? Gem::SpecificationRecord.from_path(@install_dir) : Gem::Specification.specification_record
383
397
  end
@@ -41,7 +41,7 @@ module Gem
41
41
  HASH_REGEX = /
42
42
  ^
43
43
  ([ ]*) # indentations
44
- (.+) # key
44
+ ([^#]+) # key excludes comment char '#'
45
45
  (?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
46
46
  [ ]?
47
47
  (['"]?) # optional opening quote
data/lib/rubygems.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  require "rbconfig"
10
10
 
11
11
  module Gem
12
- VERSION = "3.5.15"
12
+ VERSION = "3.5.17"
13
13
  end
14
14
 
15
15
  # Must be first since it unloads the prelude from 1.9.2
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rubygems-update"
5
- s.version = "3.5.15"
5
+ s.version = "3.5.17"
6
6
  s.authors = ["Jim Weirich", "Chad Fowler", "Eric Hodel", "Luis Lavena", "Aaron Patterson", "Samuel Giddins", "André Arko", "Evan Phoenix", "Hiroshi SHIBATA"]
7
7
  s.email = ["", "", "drbrain@segment7.net", "luislavena@gmail.com", "aaron@tenderlovemaking.com", "segiddins@segiddins.me", "andre@arko.net", "evan@phx.io", "hsbt@ruby-lang.org"]
8
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.15
4
+ version: 3.5.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: exe
18
18
  cert_chain: []
19
- date: 2024-07-09 00:00:00.000000000 Z
19
+ date: 2024-08-01 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: |-
22
22
  A package (also known as a library) contains a set of functionality
@@ -727,7 +727,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
727
727
  - !ruby/object:Gem::Version
728
728
  version: '0'
729
729
  requirements: []
730
- rubygems_version: 3.5.15
730
+ rubygems_version: 3.5.17
731
731
  signing_key:
732
732
  specification_version: 4
733
733
  summary: RubyGems is a package management framework for Ruby. This gem is downloaded