bundler 4.0.9 → 4.0.18

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +147 -0
  3. data/bundler.gemspec +2 -2
  4. data/lib/bundler/build_metadata.rb +1 -1
  5. data/lib/bundler/cli/add.rb +3 -0
  6. data/lib/bundler/cli/check.rb +1 -3
  7. data/lib/bundler/cli/common.rb +6 -0
  8. data/lib/bundler/cli/config.rb +8 -3
  9. data/lib/bundler/cli/gem.rb +2 -3
  10. data/lib/bundler/cli/install.rb +3 -0
  11. data/lib/bundler/cli/issue.rb +2 -2
  12. data/lib/bundler/cli/lock.rb +3 -0
  13. data/lib/bundler/cli/open.rb +12 -2
  14. data/lib/bundler/cli/outdated.rb +42 -2
  15. data/lib/bundler/cli/update.rb +2 -0
  16. data/lib/bundler/cli.rb +18 -12
  17. data/lib/bundler/compact_index_client/cache.rb +11 -0
  18. data/lib/bundler/compact_index_client/cache_file.rb +1 -1
  19. data/lib/bundler/compact_index_client/parser.rb +4 -1
  20. data/lib/bundler/definition.rb +51 -12
  21. data/lib/bundler/dsl.rb +10 -3
  22. data/lib/bundler/endpoint_specification.rb +17 -2
  23. data/lib/bundler/fetcher/base.rb +3 -0
  24. data/lib/bundler/fetcher/compact_index.rb +13 -0
  25. data/lib/bundler/fetcher/gem_remote_fetcher.rb +2 -0
  26. data/lib/bundler/fetcher.rb +12 -2
  27. data/lib/bundler/injector.rb +1 -2
  28. data/lib/bundler/installer/parallel_installer.rb +68 -23
  29. data/lib/bundler/installer.rb +12 -1
  30. data/lib/bundler/lockfile_generator.rb +39 -1
  31. data/lib/bundler/lockfile_parser.rb +23 -1
  32. data/lib/bundler/man/bundle-add.1 +6 -3
  33. data/lib/bundler/man/bundle-add.1.ronn +7 -2
  34. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  35. data/lib/bundler/man/bundle-cache.1 +4 -1
  36. data/lib/bundler/man/bundle-cache.1.ronn +6 -0
  37. data/lib/bundler/man/bundle-check.1 +1 -1
  38. data/lib/bundler/man/bundle-clean.1 +1 -1
  39. data/lib/bundler/man/bundle-config.1 +121 -157
  40. data/lib/bundler/man/bundle-config.1.ronn +33 -1
  41. data/lib/bundler/man/bundle-console.1 +3 -3
  42. data/lib/bundler/man/bundle-console.1.ronn +2 -2
  43. data/lib/bundler/man/bundle-doctor.1 +1 -1
  44. data/lib/bundler/man/bundle-env.1 +1 -1
  45. data/lib/bundler/man/bundle-exec.1 +1 -1
  46. data/lib/bundler/man/bundle-fund.1 +1 -1
  47. data/lib/bundler/man/bundle-gem.1 +1 -1
  48. data/lib/bundler/man/bundle-help.1 +1 -1
  49. data/lib/bundler/man/bundle-info.1 +1 -1
  50. data/lib/bundler/man/bundle-init.1 +2 -2
  51. data/lib/bundler/man/bundle-init.1.ronn +1 -1
  52. data/lib/bundler/man/bundle-install.1 +5 -2
  53. data/lib/bundler/man/bundle-install.1.ronn +9 -1
  54. data/lib/bundler/man/bundle-issue.1 +1 -1
  55. data/lib/bundler/man/bundle-licenses.1 +1 -1
  56. data/lib/bundler/man/bundle-list.1 +1 -1
  57. data/lib/bundler/man/bundle-lock.1 +5 -2
  58. data/lib/bundler/man/bundle-lock.1.ronn +6 -0
  59. data/lib/bundler/man/bundle-open.1 +1 -1
  60. data/lib/bundler/man/bundle-outdated.1 +17 -14
  61. data/lib/bundler/man/bundle-outdated.1.ronn +19 -12
  62. data/lib/bundler/man/bundle-platform.1 +1 -1
  63. data/lib/bundler/man/bundle-plugin.1 +2 -2
  64. data/lib/bundler/man/bundle-plugin.1.ronn +1 -1
  65. data/lib/bundler/man/bundle-pristine.1 +1 -1
  66. data/lib/bundler/man/bundle-remove.1 +1 -1
  67. data/lib/bundler/man/bundle-show.1 +1 -1
  68. data/lib/bundler/man/bundle-update.1 +5 -2
  69. data/lib/bundler/man/bundle-update.1.ronn +8 -0
  70. data/lib/bundler/man/bundle-version.1 +1 -1
  71. data/lib/bundler/man/bundle.1 +23 -2
  72. data/lib/bundler/man/bundle.1.ronn +22 -1
  73. data/lib/bundler/man/gemfile.5 +13 -2
  74. data/lib/bundler/man/gemfile.5.ronn +20 -1
  75. data/lib/bundler/mirror.rb +7 -7
  76. data/lib/bundler/plugin/unloaded_source.rb +25 -0
  77. data/lib/bundler/plugin.rb +12 -6
  78. data/lib/bundler/remote_specification.rb +1 -1
  79. data/lib/bundler/resolver/base.rb +9 -0
  80. data/lib/bundler/resolver/strategy.rb +6 -3
  81. data/lib/bundler/resolver.rb +80 -1
  82. data/lib/bundler/rubygems_ext.rb +22 -0
  83. data/lib/bundler/rubygems_gem_installer.rb +35 -2
  84. data/lib/bundler/runtime.rb +11 -11
  85. data/lib/bundler/self_manager.rb +6 -1
  86. data/lib/bundler/settings/validator.rb +7 -0
  87. data/lib/bundler/settings.rb +2 -0
  88. data/lib/bundler/shared_helpers.rb +6 -1
  89. data/lib/bundler/source/git/git_proxy.rb +13 -2
  90. data/lib/bundler/source/git.rb +1 -1
  91. data/lib/bundler/source/metadata.rb +4 -0
  92. data/lib/bundler/source/path.rb +3 -2
  93. data/lib/bundler/source/rubygems/remote.rb +12 -2
  94. data/lib/bundler/source/rubygems.rb +81 -13
  95. data/lib/bundler/source_list.rb +44 -3
  96. data/lib/bundler/spec_set.rb +2 -2
  97. data/lib/bundler/stub_specification.rb +1 -0
  98. data/lib/bundler/templates/newgem/newgem.gemspec.tt +10 -1
  99. data/lib/bundler/vendored_tsort.rb +19 -2
  100. data/lib/bundler/version.rb +1 -1
  101. data/lib/bundler.rb +11 -1
  102. metadata +5 -6
  103. data/lib/bundler/vendor/tsort/LICENSE.txt +0 -22
  104. data/lib/bundler/vendor/tsort/lib/tsort.rb +0 -455
@@ -1,10 +1,10 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-LOCK" "1" "March 2026" ""
3
+ .TH "BUNDLE\-LOCK" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
6
6
  .SH "SYNOPSIS"
7
- \fBbundle lock\fR [\-\-update] [\-\-bundler[=BUNDLER]] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-add\-checksums] [\-\-add\-platform] [\-\-remove\-platform] [\-\-normalize\-platforms] [\-\-patch] [\-\-minor] [\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
7
+ \fBbundle lock\fR [\-\-update] [\-\-bundler[=BUNDLER]] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-add\-checksums] [\-\-add\-platform] [\-\-remove\-platform] [\-\-normalize\-platforms] [\-\-patch] [\-\-minor] [\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative] [\-\-cooldown=NUMBER]
8
8
  .SH "DESCRIPTION"
9
9
  Lock the gems specified in Gemfile\.
10
10
  .SH "OPTIONS"
@@ -59,6 +59,9 @@ If updating, do not allow any gem to be updated past latest \-\-patch | \-\-mino
59
59
  .TP
60
60
  \fB\-\-conservative\fR
61
61
  If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated\.
62
+ .TP
63
+ \fB\-\-cooldown=<number>\fR
64
+ Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1)\.
62
65
  .SH "UPDATING ALL GEMS"
63
66
  If you run \fBbundle lock\fR with \fB\-\-update\fR option without list of gems, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
64
67
  .SH "UPDATING A LIST OF GEMS"
@@ -20,6 +20,7 @@ bundle-lock(1) -- Creates / Updates a lockfile without installing
20
20
  [--pre]
21
21
  [--strict]
22
22
  [--conservative]
23
+ [--cooldown=NUMBER]
23
24
 
24
25
  ## DESCRIPTION
25
26
 
@@ -84,6 +85,11 @@ Lock the gems specified in Gemfile.
84
85
  * `--conservative`:
85
86
  If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated.
86
87
 
88
+ * `--cooldown=<number>`:
89
+ Only consider gem versions published at least <number> days ago when
90
+ resolving. Pass `0` to disable cooldown for this run, overriding any
91
+ per-source or global configuration. See `cooldown` in bundle-config(1).
92
+
87
93
  ## UPDATING ALL GEMS
88
94
 
89
95
  If you run `bundle lock` with `--update` option without list of gems, bundler will
@@ -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\-OPEN" "1" "March 2026" ""
3
+ .TH "BUNDLE\-OPEN" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
6
6
  .SH "SYNOPSIS"
@@ -1,10 +1,10 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-OUTDATED" "1" "March 2026" ""
3
+ .TH "BUNDLE\-OUTDATED" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-outdated\fR \- List installed gems with newer versions available
6
6
  .SH "SYNOPSIS"
7
- \fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-filter\-strict | \-\-strict] [\-\-update\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit]
7
+ \fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-filter\-strict | \-\-strict] [\-\-update\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit] [\-\-cooldown=NUMBER]
8
8
  .SH "DESCRIPTION"
9
9
  Outdated lists the names and versions of gems that have a newer version available in the given source\. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems\. Prerelease gems are ignored by default\. If your gems are up to date, Bundler will exit with a status of 0\. Otherwise, it will exit 1\.
10
10
  .SH "OPTIONS"
@@ -53,6 +53,9 @@ Only list patch newer versions\.
53
53
  .TP
54
54
  \fB\-\-only\-explicit\fR
55
55
  Only list gems specified in your Gemfile, not their dependencies\.
56
+ .TP
57
+ \fB\-\-cooldown=<number>\fR
58
+ Annotate (rather than hide) versions that are still inside the cooldown window of \fInumber\fR days\. The prose output appends "in cooldown for Nd more days" and the table form adds "(cooldown Nd)" to the Latest column\. See \fBcooldown\fR in bundle\-config(1)\.
56
59
  .SH "PATCH LEVEL OPTIONS"
57
60
  See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
58
61
  .SH "FILTERING OUTPUT"
@@ -61,42 +64,42 @@ The 3 filtering options do not affect the resolution of versions, merely what ve
61
64
  If the regular output shows the following:
62
65
  .IP "" 4
63
66
  .nf
64
- * Gem Current Latest Requested Groups
65
- * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
66
- * hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
67
- * headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
67
+ * Gem Current Latest Requested Groups Release Date
68
+ * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
69
+ * hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default 2023\-11\-10
70
+ * headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test 2022\-08\-19
68
71
  .fi
69
72
  .IP "" 0
70
73
  .P
71
74
  \fB\-\-filter\-major\fR would only show:
72
75
  .IP "" 4
73
76
  .nf
74
- * Gem Current Latest Requested Groups
75
- * hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
77
+ * Gem Current Latest Requested Groups Release Date
78
+ * hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default 2023\-11\-10
76
79
  .fi
77
80
  .IP "" 0
78
81
  .P
79
82
  \fB\-\-filter\-minor\fR would only show:
80
83
  .IP "" 4
81
84
  .nf
82
- * Gem Current Latest Requested Groups
83
- * headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
85
+ * Gem Current Latest Requested Groups Release Date
86
+ * headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test 2022\-08\-19
84
87
  .fi
85
88
  .IP "" 0
86
89
  .P
87
90
  \fB\-\-filter\-patch\fR would only show:
88
91
  .IP "" 4
89
92
  .nf
90
- * Gem Current Latest Requested Groups
91
- * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
93
+ * Gem Current Latest Requested Groups Release Date
94
+ * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
92
95
  .fi
93
96
  .IP "" 0
94
97
  .P
95
98
  Filter options can be combined\. \fB\-\-filter\-minor\fR and \fB\-\-filter\-patch\fR would show:
96
99
  .IP "" 4
97
100
  .nf
98
- * Gem Current Latest Requested Groups
99
- * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
101
+ * Gem Current Latest Requested Groups Release Date
102
+ * faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
100
103
  .fi
101
104
  .IP "" 0
102
105
  .P
@@ -16,6 +16,7 @@ bundle-outdated(1) -- List installed gems with newer versions available
16
16
  [--filter-minor]
17
17
  [--filter-patch]
18
18
  [--only-explicit]
19
+ [--cooldown=NUMBER]
19
20
 
20
21
  ## DESCRIPTION
21
22
 
@@ -71,6 +72,12 @@ are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1.
71
72
  * `--only-explicit`:
72
73
  Only list gems specified in your Gemfile, not their dependencies.
73
74
 
75
+ * `--cooldown=<number>`:
76
+ Annotate (rather than hide) versions that are still inside the
77
+ cooldown window of <number> days. The prose output appends "in
78
+ cooldown for Nd more days" and the table form adds "(cooldown Nd)" to
79
+ the Latest column. See `cooldown` in bundle-config(1).
80
+
74
81
  ## PATCH LEVEL OPTIONS
75
82
 
76
83
  See [bundle update(1)](bundle-update.1.html) for details.
@@ -82,29 +89,29 @@ in the output.
82
89
 
83
90
  If the regular output shows the following:
84
91
 
85
- * Gem Current Latest Requested Groups
86
- * faker 1.6.5 1.6.6 ~> 1.4 development, test
87
- * hashie 1.2.0 3.4.6 = 1.2.0 default
88
- * headless 2.2.3 2.3.1 = 2.2.3 test
92
+ * Gem Current Latest Requested Groups Release Date
93
+ * faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
94
+ * hashie 1.2.0 3.4.6 = 1.2.0 default 2023-11-10
95
+ * headless 2.2.3 2.3.1 = 2.2.3 test 2022-08-19
89
96
 
90
97
  `--filter-major` would only show:
91
98
 
92
- * Gem Current Latest Requested Groups
93
- * hashie 1.2.0 3.4.6 = 1.2.0 default
99
+ * Gem Current Latest Requested Groups Release Date
100
+ * hashie 1.2.0 3.4.6 = 1.2.0 default 2023-11-10
94
101
 
95
102
  `--filter-minor` would only show:
96
103
 
97
- * Gem Current Latest Requested Groups
98
- * headless 2.2.3 2.3.1 = 2.2.3 test
104
+ * Gem Current Latest Requested Groups Release Date
105
+ * headless 2.2.3 2.3.1 = 2.2.3 test 2022-08-19
99
106
 
100
107
  `--filter-patch` would only show:
101
108
 
102
- * Gem Current Latest Requested Groups
103
- * faker 1.6.5 1.6.6 ~> 1.4 development, test
109
+ * Gem Current Latest Requested Groups Release Date
110
+ * faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
104
111
 
105
112
  Filter options can be combined. `--filter-minor` and `--filter-patch` would show:
106
113
 
107
- * Gem Current Latest Requested Groups
108
- * faker 1.6.5 1.6.6 ~> 1.4 development, test
114
+ * Gem Current Latest Requested Groups Release Date
115
+ * faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
109
116
 
110
117
  Combining all three `filter` options would be the same result as providing none of them.
@@ -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\-PLATFORM" "1" "March 2026" ""
3
+ .TH "BUNDLE\-PLATFORM" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-platform\fR \- Displays platform compatibility information
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\-PLUGIN" "1" "March 2026" ""
3
+ .TH "BUNDLE\-PLUGIN" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-plugin\fR \- Manage Bundler plugins
6
6
  .SH "SYNOPSIS"
@@ -71,6 +71,6 @@ Describe subcommands or one specific subcommand\.
71
71
  No options\.
72
72
  .SH "SEE ALSO"
73
73
  .IP "\(bu" 4
74
- How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR
74
+ How to write a Bundler plugin \fIhttps://guides\.rubygems\.org/bundler_plugins/\fR
75
75
  .IP "" 0
76
76
 
@@ -81,4 +81,4 @@ No options.
81
81
 
82
82
  ## SEE ALSO
83
83
 
84
- * [How to write a Bundler plugin](https://bundler.io/guides/bundler_plugins.html)
84
+ * [How to write a Bundler plugin](https://guides.rubygems.org/bundler_plugins/)
@@ -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\-PRISTINE" "1" "March 2026" ""
3
+ .TH "BUNDLE\-PRISTINE" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
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\-REMOVE" "1" "March 2026" ""
3
+ .TH "BUNDLE\-REMOVE" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-remove\fR \- Removes gems from the Gemfile
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\-SHOW" "1" "March 2026" ""
3
+ .TH "BUNDLE\-SHOW" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
6
6
  .SH "SYNOPSIS"
@@ -1,10 +1,10 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-UPDATE" "1" "March 2026" ""
3
+ .TH "BUNDLE\-UPDATE" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-update\fR \- Update your gems to the latest available versions
6
6
  .SH "SYNOPSIS"
7
- \fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
7
+ \fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-cooldown=NUMBER] [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
8
8
  .SH "DESCRIPTION"
9
9
  Update the gems specified (all gems, if \fB\-\-all\fR flag is used), ignoring the previously installed gems specified in the \fBGemfile\.lock\fR\. In general, you should use bundle install(1) \fIbundle\-install\.1\.html\fR to install the same exact gems and versions across machines\.
10
10
  .P
@@ -64,6 +64,9 @@ Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR
64
64
  .TP
65
65
  \fB\-\-conservative\fR
66
66
  Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\.
67
+ .TP
68
+ \fB\-\-cooldown=<number>\fR
69
+ Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. Combine with \fB\-\-conservative\fR to minimize transitive churn when bypassing cooldown for an urgent update\. See \fBcooldown\fR in bundle\-config(1)\.
67
70
  .SH "UPDATING ALL GEMS"
68
71
  If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
69
72
  .P
@@ -9,6 +9,7 @@ bundle-update(1) -- Update your gems to the latest available versions
9
9
  [--local]
10
10
  [--ruby]
11
11
  [--bundler[=VERSION]]
12
+ [--cooldown=NUMBER]
12
13
  [--force]
13
14
  [--full-index]
14
15
  [--gemfile=GEMFILE]
@@ -91,6 +92,13 @@ gem.
91
92
  * `--conservative`:
92
93
  Use bundle install conservative update behavior and do not allow indirect dependencies to be updated.
93
94
 
95
+ * `--cooldown=<number>`:
96
+ Only consider gem versions published at least <number> days ago when
97
+ resolving. Pass `0` to disable cooldown for this run, overriding any
98
+ per-source or global configuration. Combine with `--conservative` to
99
+ minimize transitive churn when bypassing cooldown for an urgent
100
+ update. See `cooldown` in bundle-config(1).
101
+
94
102
  ## UPDATING ALL GEMS
95
103
 
96
104
  If you run `bundle update --all`, bundler will ignore
@@ -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\-VERSION" "1" "March 2026" ""
3
+ .TH "BUNDLE\-VERSION" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-version\fR \- Prints Bundler version information
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" "1" "March 2026" ""
3
+ .TH "BUNDLE" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\fR \- Ruby Dependency Management
6
6
  .SH "SYNOPSIS"
@@ -8,7 +8,7 @@
8
8
  .SH "DESCRIPTION"
9
9
  Bundler manages an \fBapplication's dependencies\fR through its entire life across many machines systematically and repeatably\.
10
10
  .P
11
- See the bundler website \fIhttps://bundler\.io\fR for information on getting started, and Gemfile(5) for more information on the \fBGemfile\fR format\.
11
+ See the RubyGems guides \fIhttps://guides\.rubygems\.org/\fR for information on getting started, and Gemfile(5) for more information on the \fBGemfile\fR format\.
12
12
  .SH "OPTIONS"
13
13
  .TP
14
14
  \fB\-\-no\-color\fR
@@ -54,6 +54,18 @@ Determine whether the requirements for your application are installed and availa
54
54
  \fBbundle show(1)\fR \fIbundle\-show\.1\.html\fR
55
55
  Show the source location of a particular gem in the bundle
56
56
  .TP
57
+ \fBbundle info(1)\fR \fIbundle\-info\.1\.html\fR
58
+ Show information for the given gem in your bundle
59
+ .TP
60
+ \fBbundle list(1)\fR \fIbundle\-list\.1\.html\fR
61
+ List all the gems in the bundle
62
+ .TP
63
+ \fBbundle licenses(1)\fR \fIbundle\-licenses\.1\.html\fR
64
+ Print the license of all gems in the bundle
65
+ .TP
66
+ \fBbundle fund(1)\fR \fIbundle\-fund\.1\.html\fR
67
+ Lists information about gems seeking funding assistance
68
+ .TP
57
69
  \fBbundle outdated(1)\fR \fIbundle\-outdated\.1\.html\fR
58
70
  Show all of the outdated gems in the current bundle
59
71
  .TP
@@ -78,9 +90,18 @@ Display platform compatibility information
78
90
  \fBbundle clean(1)\fR \fIbundle\-clean\.1\.html\fR
79
91
  Clean up unused gems in your Bundler directory
80
92
  .TP
93
+ \fBbundle pristine(1)\fR \fIbundle\-pristine\.1\.html\fR
94
+ Restores installed gems to their pristine condition
95
+ .TP
81
96
  \fBbundle doctor(1)\fR \fIbundle\-doctor\.1\.html\fR
82
97
  Display warnings about common problems
83
98
  .TP
99
+ \fBbundle env(1)\fR \fIbundle\-env\.1\.html\fR
100
+ Print information about the environment Bundler is running under
101
+ .TP
102
+ \fBbundle issue(1)\fR \fIbundle\-issue\.1\.html\fR
103
+ Get help reporting Bundler issues
104
+ .TP
84
105
  \fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
85
106
  Removes gems from the Gemfile
86
107
  .TP
@@ -10,7 +10,7 @@ bundle(1) -- Ruby Dependency Management
10
10
  Bundler manages an `application's dependencies` through its entire life
11
11
  across many machines systematically and repeatably.
12
12
 
13
- See [the bundler website](https://bundler.io) for information on getting
13
+ See [the RubyGems guides](https://guides.rubygems.org/) for information on getting
14
14
  started, and Gemfile(5) for more information on the `Gemfile` format.
15
15
 
16
16
  ## OPTIONS
@@ -64,6 +64,18 @@ We divide `bundle` subcommands into primary commands and utilities:
64
64
  * [`bundle show(1)`](bundle-show.1.html):
65
65
  Show the source location of a particular gem in the bundle
66
66
 
67
+ * [`bundle info(1)`](bundle-info.1.html):
68
+ Show information for the given gem in your bundle
69
+
70
+ * [`bundle list(1)`](bundle-list.1.html):
71
+ List all the gems in the bundle
72
+
73
+ * [`bundle licenses(1)`](bundle-licenses.1.html):
74
+ Print the license of all gems in the bundle
75
+
76
+ * [`bundle fund(1)`](bundle-fund.1.html):
77
+ Lists information about gems seeking funding assistance
78
+
67
79
  * [`bundle outdated(1)`](bundle-outdated.1.html):
68
80
  Show all of the outdated gems in the current bundle
69
81
 
@@ -88,9 +100,18 @@ We divide `bundle` subcommands into primary commands and utilities:
88
100
  * [`bundle clean(1)`](bundle-clean.1.html):
89
101
  Clean up unused gems in your Bundler directory
90
102
 
103
+ * [`bundle pristine(1)`](bundle-pristine.1.html):
104
+ Restores installed gems to their pristine condition
105
+
91
106
  * [`bundle doctor(1)`](bundle-doctor.1.html):
92
107
  Display warnings about common problems
93
108
 
109
+ * [`bundle env(1)`](bundle-env.1.html):
110
+ Print information about the environment Bundler is running under
111
+
112
+ * [`bundle issue(1)`](bundle-issue.1.html):
113
+ Get help reporting Bundler issues
114
+
94
115
  * [`bundle remove(1)`](bundle-remove.1.html):
95
116
  Removes gems from the Gemfile
96
117
 
@@ -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 "GEMFILE" "5" "March 2026" ""
3
+ .TH "GEMFILE" "5" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
6
6
  .SH "SYNOPSIS"
@@ -107,6 +107,8 @@ gem "nokogiri", ">= 1\.4\.2"
107
107
  gem "RedCloth", ">= 4\.1\.0", "< 4\.2\.0"
108
108
  .fi
109
109
  .IP "" 0
110
+ .P
111
+ Most version specifiers, like \fB>= 1\.0\fR, are self\-explanatory\. The pessimistic specifier \fB~>\fR constrains both a lower and an upper bound: \fB~> 2\.0\.3\fR is identical to \fB>= 2\.0\.3\fR and \fB< 2\.1\fR, and \fB~> 2\.1\fR is identical to \fB>= 2\.1\fR and \fB< 3\.0\fR\. A pessimistic specifier with a prerelease component, like \fB~> 2\.2\.beta\fR, will match prerelease versions like \fB2\.2\.beta\.12\fR\. \fB~> 0\fR is identical to \fB>= 0\.0\fR and \fB< 1\.0\fR\.
110
112
  .SS "REQUIRE AS"
111
113
  Each \fIgem\fR \fBMAY\fR specify files that should be used when autorequiring via \fBBundler\.require\fR\. You may pass an array with multiple files or \fBtrue\fR if the file you want \fBrequired\fR has the same name as \fIgem\fR or \fBfalse\fR to prevent any file from being autorequired\.
112
114
  .IP "" 4
@@ -164,7 +166,7 @@ bundle config set \-\-local without development test
164
166
  .P
165
167
  Also, calling \fBBundler\.setup\fR with no parameters, or calling \fBrequire "bundler/setup"\fR will setup all groups except for the ones you excluded via \fB\-\-without\fR (since they are not available)\.
166
168
  .P
167
- Note that on \fBbundle install\fR, bundler downloads and evaluates all gems, in order to create a single canonical list of all of the required gems and their dependencies\. This means that you cannot list different versions of the same gems in different groups\. For more details, see Understanding Bundler \fIhttps://bundler\.io/rationale\.html\fR\.
169
+ Note that on \fBbundle install\fR, bundler downloads and evaluates all gems, in order to create a single canonical list of all of the required gems and their dependencies\. This means that you cannot list different versions of the same gems in different groups\. For more details, see Dependency management \fIhttps://guides\.rubygems\.org/dependency_management/\fR\.
168
170
  .SS "PLATFORMS"
169
171
  If a gem should only be used in a particular platform or set of platforms, you can specify them\. Platforms are essentially identical to groups, except that you do not need to use the \fB\-\-without\fR install\-time flag to exclude groups of gems for other platforms\.
170
172
  .P
@@ -460,6 +462,15 @@ The \fBgemspec\fR method adds any runtime dependencies as gem requirements in th
460
462
  The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: \fB{,*,*/*}\.gemspec\fR), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\.
461
463
  .P
462
464
  When a \fBgemspec\fR dependency encounters version conflicts during resolution, the local version under development will always be selected \-\- even if there are remote versions that better match other requirements for the \fBgemspec\fR gem\.
465
+ .SH "EVAL_GEMFILE"
466
+ A Gemfile \fBMAY\fR be split across multiple files\. The \fBeval_gemfile\fR method reads the contents of another file as if they appeared in the current Gemfile\. A relative path is resolved against the directory of the file containing the call\.
467
+ .IP "" 4
468
+ .nf
469
+ eval_gemfile "another\.gemfile"
470
+ .fi
471
+ .IP "" 0
472
+ .P
473
+ This can be useful to run tests against multiple combinations of dependencies, or to load per\-developer gems from an untracked gemfile\.
463
474
  .SH "SOURCE PRIORITY"
464
475
  When attempting to locate a gem to satisfy a gem requirement, bundler uses the following priority order:
465
476
  .IP "1." 4
@@ -137,6 +137,13 @@ Each _gem_ `MAY` have one or more version specifiers.
137
137
  gem "nokogiri", ">= 1.4.2"
138
138
  gem "RedCloth", ">= 4.1.0", "< 4.2.0"
139
139
 
140
+ Most version specifiers, like `>= 1.0`, are self-explanatory. The pessimistic
141
+ specifier `~>` constrains both a lower and an upper bound: `~> 2.0.3` is
142
+ identical to `>= 2.0.3` and `< 2.1`, and `~> 2.1` is identical to `>= 2.1` and
143
+ `< 3.0`. A pessimistic specifier with a prerelease component, like
144
+ `~> 2.2.beta`, will match prerelease versions like `2.2.beta.12`. `~> 0` is
145
+ identical to `>= 0.0` and `< 1.0`.
146
+
140
147
  ### REQUIRE AS
141
148
 
142
149
  Each _gem_ `MAY` specify files that should be used when autorequiring via
@@ -193,7 +200,7 @@ are not available).
193
200
  Note that on `bundle install`, bundler downloads and evaluates all gems, in order to
194
201
  create a single canonical list of all of the required gems and their dependencies.
195
202
  This means that you cannot list different versions of the same gems in different
196
- groups. For more details, see [Understanding Bundler](https://bundler.io/rationale.html).
203
+ groups. For more details, see [Dependency management](https://guides.rubygems.org/dependency_management/).
197
204
 
198
205
  ### PLATFORMS
199
206
 
@@ -541,6 +548,18 @@ When a `gemspec` dependency encounters version conflicts during resolution, the
541
548
  local version under development will always be selected -- even if there are
542
549
  remote versions that better match other requirements for the `gemspec` gem.
543
550
 
551
+ ## EVAL_GEMFILE
552
+
553
+ A Gemfile `MAY` be split across multiple files. The `eval_gemfile` method reads
554
+ the contents of another file as if they appeared in the current Gemfile. A
555
+ relative path is resolved against the directory of the file containing the
556
+ call.
557
+
558
+ eval_gemfile "another.gemfile"
559
+
560
+ This can be useful to run tests against multiple combinations of dependencies,
561
+ or to load per-developer gems from an untracked gemfile.
562
+
544
563
  ## SOURCE PRIORITY
545
564
 
546
565
  When attempting to locate a gem to satisfy a gem requirement,
@@ -160,18 +160,18 @@ module Bundler
160
160
 
161
161
  def wait_for_writtable_socket(socket, address, timeout)
162
162
  if IO.select(nil, [socket], nil, timeout)
163
- probe_writtable_socket(socket, address)
163
+ probe_writtable_socket(socket)
164
164
  else # TCP Handshake timed out, or there is something dropping packets
165
165
  false
166
166
  end
167
167
  end
168
168
 
169
- def probe_writtable_socket(socket, address)
170
- socket.connect_nonblock(address)
171
- rescue Errno::EISCONN
172
- true
173
- rescue StandardError # Connection failed
174
- false
169
+ def probe_writtable_socket(socket)
170
+ # Check the pending error on the socket rather than calling
171
+ # +connect_nonblock+ a second time. On BSD-based systems such as macOS a
172
+ # second connect returns +EISCONN+ even when the asynchronous connect
173
+ # failed, which would make a down mirror look reachable.
174
+ socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR).int == 0
175
175
  end
176
176
  end
177
177
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ module Plugin
5
+ # Stands in for a source handled by a plugin that is not loaded yet, so
6
+ # that the lockfile can still be parsed during the plugin install pass,
7
+ # and by external tools reading a lockfile without the plugin installed.
8
+ class UnloadedSource
9
+ include API::Source
10
+
11
+ # Unlike real plugin sources, where the handling class encodes the
12
+ # source type, all unloaded sources share this class, so the type must
13
+ # be compared explicitly.
14
+ def ==(other)
15
+ super && options["type"] == other.options["type"]
16
+ end
17
+
18
+ alias_method :eql?, :==
19
+
20
+ def hash
21
+ [super, options["type"]].hash
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,11 +4,12 @@ require_relative "plugin/api"
4
4
 
5
5
  module Bundler
6
6
  module Plugin
7
- autoload :DSL, File.expand_path("plugin/dsl", __dir__)
8
- autoload :Events, File.expand_path("plugin/events", __dir__)
9
- autoload :Index, File.expand_path("plugin/index", __dir__)
10
- autoload :Installer, File.expand_path("plugin/installer", __dir__)
11
- autoload :SourceList, File.expand_path("plugin/source_list", __dir__)
7
+ autoload :DSL, File.expand_path("plugin/dsl", __dir__)
8
+ autoload :Events, File.expand_path("plugin/events", __dir__)
9
+ autoload :Index, File.expand_path("plugin/index", __dir__)
10
+ autoload :Installer, File.expand_path("plugin/installer", __dir__)
11
+ autoload :SourceList, File.expand_path("plugin/source_list", __dir__)
12
+ autoload :UnloadedSource, File.expand_path("plugin/unloaded_source", __dir__)
12
13
 
13
14
  class MalformattedPlugin < PluginError; end
14
15
  class UndefinedCommandError < PluginError; end
@@ -199,9 +200,14 @@ module Bundler
199
200
  # @return [API::Source] the instance of the class that handles the source
200
201
  # type passed in locked_opts
201
202
  def from_lock(locked_opts)
203
+ opts = locked_opts.merge("uri" => locked_opts["remote"])
204
+ # use an inert placeholder when the plugin handling this source is not
205
+ # installed, so that the lockfile can still be parsed
206
+ return UnloadedSource.new(opts) unless source?(locked_opts["type"])
207
+
202
208
  src = source(locked_opts["type"])
203
209
 
204
- src.new(locked_opts.merge("uri" => locked_opts["remote"]))
210
+ src.new(opts)
205
211
  end
206
212
 
207
213
  # To be called via the API to register a hooks and corresponding block that
@@ -12,7 +12,7 @@ module Bundler
12
12
 
13
13
  attr_reader :name, :version, :platform
14
14
  attr_writer :dependencies
15
- attr_accessor :source, :remote, :locked_platform
15
+ attr_accessor :source, :remote, :locked_platform, :created_at
16
16
 
17
17
  def initialize(name, version, platform, spec_fetcher)
18
18
  @name = name
@@ -8,6 +8,7 @@ module Bundler
8
8
  attr_reader :packages, :requirements, :source_requirements, :locked_specs
9
9
 
10
10
  def initialize(source_requirements, dependencies, base, platforms, options)
11
+ @explicit_unlocks = options.delete(:explicit_unlocks) || []
11
12
  @source_requirements = source_requirements
12
13
  @locked_specs = options[:locked_specs]
13
14
 
@@ -43,6 +44,14 @@ module Bundler
43
44
  @packages[name]
44
45
  end
45
46
 
47
+ # Gems the user named on a `bundle update GEM` / `bundle lock --update GEM`
48
+ # command line. These are the only ones meant to move off their locked
49
+ # version, so cooldown keeps applying to them while every other locked gem
50
+ # stays exempt.
51
+ def explicitly_unlocked?(name)
52
+ @explicit_unlocks.include?(name)
53
+ end
54
+
46
55
  def base_requirements
47
56
  @base_requirements ||= build_base_requirements
48
57
  end
@@ -5,6 +5,7 @@ module Bundler
5
5
  class Strategy
6
6
  def initialize(source)
7
7
  @source = source
8
+ @package_priority_cache = {}
8
9
  end
9
10
 
10
11
  def next_package_and_version(unsatisfied)
@@ -17,10 +18,12 @@ module Bundler
17
18
 
18
19
  def next_term_to_try_from(unsatisfied)
19
20
  unsatisfied.min_by do |package, range|
20
- matching_versions = @source.versions_for(package, range)
21
- higher_versions = @source.versions_for(package, range.upper_invert)
21
+ @package_priority_cache[[package, range]] ||= begin
22
+ matching_versions = @source.versions_for(package, range)
23
+ higher_versions = @source.versions_for(package, range.upper_invert)
22
24
 
23
- [matching_versions.count <= 1 ? 0 : 1, higher_versions.count]
25
+ [matching_versions.count <= 1 ? 0 : 1, higher_versions.count]
26
+ end
24
27
  end
25
28
  end
26
29