rubygems-update 4.0.12 → 4.0.13

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/bundler/CHANGELOG.md +16 -0
  4. data/bundler/lib/bundler/build_metadata.rb +1 -1
  5. data/bundler/lib/bundler/cli/add.rb +3 -0
  6. data/bundler/lib/bundler/cli/common.rb +6 -0
  7. data/bundler/lib/bundler/cli/install.rb +3 -0
  8. data/bundler/lib/bundler/cli/outdated.rb +42 -2
  9. data/bundler/lib/bundler/cli/update.rb +2 -0
  10. data/bundler/lib/bundler/cli.rb +4 -0
  11. data/bundler/lib/bundler/dsl.rb +6 -2
  12. data/bundler/lib/bundler/endpoint_specification.rb +11 -1
  13. data/bundler/lib/bundler/installer.rb +5 -0
  14. data/bundler/lib/bundler/man/bundle-add.1 +4 -1
  15. data/bundler/lib/bundler/man/bundle-add.1.ronn +6 -1
  16. data/bundler/lib/bundler/man/bundle-config.1 +120 -156
  17. data/bundler/lib/bundler/man/bundle-config.1.ronn +30 -0
  18. data/bundler/lib/bundler/man/bundle-install.1 +4 -1
  19. data/bundler/lib/bundler/man/bundle-install.1.ronn +9 -1
  20. data/bundler/lib/bundler/man/bundle-outdated.1 +16 -13
  21. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +19 -12
  22. data/bundler/lib/bundler/man/bundle-update.1 +4 -1
  23. data/bundler/lib/bundler/man/bundle-update.1.ronn +8 -0
  24. data/bundler/lib/bundler/remote_specification.rb +1 -1
  25. data/bundler/lib/bundler/resolver.rb +42 -1
  26. data/bundler/lib/bundler/rubygems_ext.rb +22 -0
  27. data/bundler/lib/bundler/rubygems_gem_installer.rb +1 -1
  28. data/bundler/lib/bundler/settings.rb +1 -0
  29. data/bundler/lib/bundler/source/git/git_proxy.rb +7 -2
  30. data/bundler/lib/bundler/source/rubygems/remote.rb +12 -2
  31. data/bundler/lib/bundler/source/rubygems.rb +51 -3
  32. data/bundler/lib/bundler/source_list.rb +6 -2
  33. data/bundler/lib/bundler/version.rb +1 -1
  34. data/lib/rubygems/ext/builder.rb +2 -1
  35. data/lib/rubygems/package.rb +21 -1
  36. data/lib/rubygems/resolver/api_set/gem_parser.rb +1 -1
  37. data/lib/rubygems.rb +1 -1
  38. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d207eaa8ea0c17596ba6919cee2053ab7044e1a33c1928e61887a06b2a74700
4
- data.tar.gz: 83258ebcc931736a81fc787b12ea9e8f6ecbc20973230ac542326dff6c8e1ae6
3
+ metadata.gz: 0660c05e56df8027375e8d01d875fc71e9837ed53336eface4ce3caef8463b06
4
+ data.tar.gz: 41fb9134ffe1423a57d10e9c3974c4fd03d02f31aea6da2d8703df407cb720c2
5
5
  SHA512:
6
- metadata.gz: fde24bf1c702d73c532d60c5bedff3e8876b6bf6200779abbdf0a959e96570fb9c8b0c3db27dbd4899a3b1db5f3d011c9255d9ab2c6df4c212a020a2290dcf45
7
- data.tar.gz: 669918da9e6e3552a74057002a34f54a73c5aef7b0043f510578ae46ec6fb4ae40060a437aaed13c7de0e47f2fdc5ab9432315f0954a5c429ffff7381f1f93ee
6
+ metadata.gz: ad34acb0f898943a0a749765234e2ec3abec927d9d6eaffcbd5b33498dc04fe8f0a5477d7569a02a4792fdbaa058c05c14abe38c707c43568f2249c0855c050d
7
+ data.tar.gz: 9bbb91eccb1401d2942b8817734b0130a6c7d33163f4faab4e3204d4f63bbbc317bb78e41a605b494d2224f4954c08d807e75ee3954def54a34e6410d08b85c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.13 / 2026-06-03
4
+
5
+ ### Enhancements:
6
+
7
+ * Prevent extraction from escaping destination_dir via pre-existing symlinks. Pull request [#9493](https://github.com/ruby/rubygems/pull/9493) by thesmartshadow
8
+ * Close stdin immediately when using popen2e. Pull request [#9540](https://github.com/ruby/rubygems/pull/9540) by rwstauner
9
+ * Fallback to copy symlinks on Windows. Pull request [#9296](https://github.com/ruby/rubygems/pull/9296) by larskanis
10
+ * Installs bundler 4.0.13 as a default gem.
11
+
3
12
  ## 4.0.12 / 2026-05-20
4
13
 
5
14
  ### Enhancements:
data/bundler/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.13 / 2026-06-03
4
+
5
+ ### Enhancements:
6
+
7
+ * Do not hard-code permissions for new gem directories during bundle install. Pull request [#9557](https://github.com/ruby/rubygems/pull/9557) by maxfelsher-cgi
8
+ * Clear gem specification cache after acquiring process lock. Pull request [#9310](https://github.com/ruby/rubygems/pull/9310) by ngan
9
+ * Show release date with bundle outdated. Pull request [#9337](https://github.com/ruby/rubygems/pull/9337) by hsbt
10
+
11
+ ### Bug fixes:
12
+
13
+ * Apply cooldown to locally installed gem versions. Pull request [#9582](https://github.com/ruby/rubygems/pull/9582) by hsbt
14
+
15
+ ### Security:
16
+
17
+ * Add `cooldown` to delay newly published gem. Pull request [#9576](https://github.com/ruby/rubygems/pull/9576) by hsbt
18
+
3
19
  ## 4.0.12 / 2026-05-20
4
20
 
5
21
  ### Enhancements:
@@ -5,7 +5,7 @@ module Bundler
5
5
  module BuildMetadata
6
6
  # begin ivars
7
7
  @built_at = nil
8
- @git_commit_sha = "665f998196".freeze
8
+ @git_commit_sha = "003f20f0dc".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -14,6 +14,9 @@ module Bundler
14
14
  def run
15
15
  Bundler.ui.level = "warn" if options[:quiet]
16
16
 
17
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
18
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
19
+
17
20
  validate_options!
18
21
  inject_dependencies
19
22
  perform_bundle_install unless options["skip-install"]
@@ -2,6 +2,12 @@
2
2
 
3
3
  module Bundler
4
4
  module CLI::Common
5
+ def self.validate_cooldown!(value)
6
+ return if value.nil?
7
+ return if value.is_a?(Integer) && value >= 0
8
+ raise InvalidOption, "Expected `--cooldown` to be a non-negative integer, got #{value.inspect}"
9
+ end
10
+
5
11
  def self.output_post_install_messages(messages)
6
12
  return if Bundler.settings["ignore_messages"]
7
13
  messages.to_a.each do |name, msg|
@@ -112,6 +112,9 @@ module Bundler
112
112
 
113
113
  Bundler.settings.set_command_option_if_given :jobs, options["jobs"]
114
114
 
115
+ Bundler::CLI::Common.validate_cooldown!(options["cooldown"])
116
+ Bundler.settings.set_command_option_if_given :cooldown, options["cooldown"]
117
+
115
118
  Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
116
119
 
117
120
  Bundler.settings.set_command_option_if_given :no_install, options["no-install"]
@@ -26,6 +26,9 @@ module Bundler
26
26
  def run
27
27
  check_for_deployment_mode!
28
28
 
29
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
30
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
31
+
29
32
  Bundler.definition.validate_runtime!
30
33
  current_specs = Bundler.ui.silence { Bundler.definition.resolve }
31
34
 
@@ -199,7 +202,15 @@ module Bundler
199
202
  end
200
203
 
201
204
  spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \
202
- "installed #{current_version}#{dependency_version})"
205
+ "installed #{current_version}#{dependency_version}"
206
+
207
+ release_date = release_date_for(active_spec)
208
+ spec_outdated_info += ", released #{release_date}" unless release_date.empty?
209
+
210
+ remaining = cooldown_days_remaining(active_spec)
211
+ spec_outdated_info += ", in cooldown for #{remaining} more day#{"s" if remaining > 1}" if remaining
212
+
213
+ spec_outdated_info += ")"
203
214
 
204
215
  output_message = if options[:parseable]
205
216
  spec_outdated_info.to_s
@@ -215,13 +226,25 @@ module Bundler
215
226
  def gem_column_for(current_spec, active_spec, dependency, groups)
216
227
  current_version = "#{current_spec.version}#{current_spec.git_version}"
217
228
  spec_version = "#{active_spec.version}#{active_spec.git_version}"
229
+ remaining = cooldown_days_remaining(active_spec)
230
+ spec_version += " (cooldown #{remaining}d)" if remaining
218
231
  dependency = dependency.requirement if dependency
219
232
 
220
233
  ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s]
234
+ ret_val << release_date_for(active_spec)
221
235
  ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug?
222
236
  ret_val
223
237
  end
224
238
 
239
+ def cooldown_days_remaining(spec, now = Time.now)
240
+ return nil unless spec.respond_to?(:created_at) && spec.created_at
241
+ return nil unless spec.respond_to?(:remote) && spec.remote
242
+ days = spec.remote.effective_cooldown
243
+ return nil if days.nil? || days <= 0
244
+ remaining = days - ((now - spec.created_at) / 86_400.0)
245
+ remaining > 0 ? remaining.ceil : nil
246
+ end
247
+
225
248
  def check_for_deployment_mode!
226
249
  return unless Bundler.frozen_bundle?
227
250
  suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
@@ -283,11 +306,28 @@ module Bundler
283
306
  end
284
307
 
285
308
  def table_header
286
- header = ["Gem", "Current", "Latest", "Requested", "Groups"]
309
+ header = ["Gem", "Current", "Latest", "Requested", "Groups", "Release Date"]
287
310
  header << "Path" if Bundler.ui.debug?
288
311
  header
289
312
  end
290
313
 
314
+ def release_date_for(spec)
315
+ return "" unless spec.respond_to?(:date)
316
+
317
+ date = spec.date
318
+ return "" unless date
319
+
320
+ return "" unless Gem.const_defined?(:DEFAULT_SOURCE_DATE_EPOCH)
321
+ default_date = Time.at(Gem::DEFAULT_SOURCE_DATE_EPOCH).utc
322
+ default_date = Time.utc(default_date.year, default_date.month, default_date.day)
323
+
324
+ date = date.utc if date.respond_to?(:utc)
325
+
326
+ return "" if date == default_date
327
+
328
+ date.strftime("%Y-%m-%d")
329
+ end
330
+
291
331
  def justify(row, sizes)
292
332
  row.each_with_index.map do |element, index|
293
333
  element.ljust(sizes[index])
@@ -66,6 +66,8 @@ module Bundler
66
66
  opts["force"] = options[:redownload] if options[:redownload]
67
67
 
68
68
  Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
69
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
70
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
69
71
 
70
72
  Bundler.definition.validate_runtime!
71
73
 
@@ -274,6 +274,7 @@ module Bundler
274
274
  method_option "target-rbconfig", type: :string, banner: "Path to rbconfig.rb for the deployment target platform"
275
275
  method_option "without", type: :array, banner: "Exclude gems that are part of the specified named group (removed)."
276
276
  method_option "with", type: :array, banner: "Include gems that are part of the specified named group (removed)."
277
+ method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
277
278
  def install
278
279
  %w[clean deployment frozen no-prune path shebang without with].each do |option|
279
280
  remembered_flag_deprecation(option)
@@ -324,6 +325,7 @@ module Bundler
324
325
  method_option "strict", type: :boolean, banner: "Do not allow any gem to be updated past latest --patch | --minor | --major"
325
326
  method_option "conservative", type: :boolean, banner: "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
326
327
  method_option "all", type: :boolean, banner: "Update everything."
328
+ method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
327
329
  def update(*gems)
328
330
  require_relative "cli/update"
329
331
  Bundler.settings.temporary(no_install: false) do
@@ -405,6 +407,7 @@ module Bundler
405
407
  method_option "skip-install", type: :boolean, banner: "Adds gem to the Gemfile but does not install it"
406
408
  method_option "optimistic", type: :boolean, banner: "Adds optimistic declaration of version to gem"
407
409
  method_option "strict", type: :boolean, banner: "Adds strict declaration of version to gem"
410
+ method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
408
411
  def add(*gems)
409
412
  require_relative "cli/add"
410
413
  Add.new(options.dup, gems).run
@@ -435,6 +438,7 @@ module Bundler
435
438
  method_option "filter-patch", type: :boolean, banner: "Only list patch newer versions"
436
439
  method_option "parseable", aliases: "--porcelain", type: :boolean, banner: "Use minimal formatting for more parseable output"
437
440
  method_option "only-explicit", type: :boolean, banner: "Only list gems specified in your Gemfile, not their dependencies"
441
+ method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
438
442
  def outdated(*gems)
439
443
  require_relative "cli/outdated"
440
444
  Outdated.new(options, gems).run
@@ -116,6 +116,10 @@ module Bundler
116
116
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
117
117
  options = normalize_hash(options)
118
118
  source = normalize_source(source)
119
+ cooldown = options["cooldown"]
120
+ if cooldown && !(cooldown.is_a?(Integer) && cooldown >= 0)
121
+ raise InvalidOption, "Expected `cooldown` to be a non-negative integer, got #{cooldown.inspect}"
122
+ end
119
123
 
120
124
  if options.key?("type")
121
125
  options["type"] = options["type"].to_s
@@ -130,9 +134,9 @@ module Bundler
130
134
  source_opts = options.merge("uri" => source)
131
135
  with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
132
136
  elsif block_given?
133
- with_source(@sources.add_rubygems_source("remotes" => source), &blk)
137
+ with_source(@sources.add_rubygems_source("remotes" => source, "cooldown" => cooldown), &blk)
134
138
  else
135
- @sources.add_global_rubygems_remote(source)
139
+ @sources.add_global_rubygems_remote(source, cooldown: cooldown)
136
140
  end
137
141
  end
138
142
 
@@ -5,7 +5,7 @@ module Bundler
5
5
  class EndpointSpecification < Gem::Specification
6
6
  include MatchRemoteMetadata
7
7
 
8
- attr_reader :name, :version, :platform, :checksum
8
+ attr_reader :name, :version, :platform, :checksum, :created_at
9
9
  attr_writer :dependencies
10
10
  attr_accessor :remote, :locked_platform
11
11
 
@@ -145,6 +145,7 @@ module Bundler
145
145
  unless data
146
146
  @required_ruby_version = nil
147
147
  @required_rubygems_version = nil
148
+ @created_at = nil
148
149
  return
149
150
  end
150
151
 
@@ -161,6 +162,15 @@ module Bundler
161
162
  @required_rubygems_version = Gem::Requirement.new(v)
162
163
  when "ruby"
163
164
  @required_ruby_version = Gem::Requirement.new(v)
165
+ when "created_at"
166
+ value = v.is_a?(Array) ? v.last : v
167
+ if value.is_a?(String)
168
+ @created_at = begin
169
+ Time.new(value)
170
+ rescue ArgumentError
171
+ nil
172
+ end
173
+ end
164
174
  end
165
175
  end
166
176
  rescue StandardError => e
@@ -63,6 +63,11 @@ module Bundler
63
63
  Bundler.create_bundle_path
64
64
 
65
65
  ProcessLock.lock do
66
+ # Invalidate any stale gem specification cache from before we acquired the lock.
67
+ # Another process may have installed gems while we were waiting.
68
+ Gem::Specification.reset
69
+ @definition.sources.clear_cache
70
+
66
71
  @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
67
72
 
68
73
  if @definition.dependencies.empty?
@@ -4,7 +4,7 @@
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"
7
- \fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT|\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-quiet] [\-\-skip\-install] [\-\-strict|\-\-optimistic]
7
+ \fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT|\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-cooldown=NUMBER] [\-\-quiet] [\-\-skip\-install] [\-\-strict|\-\-optimistic]
8
8
  .SH "DESCRIPTION"
9
9
  Adds the named gem to the [\fBGemfile(5)\fR][Gemfile(5)] and run \fBbundle install\fR\. \fBbundle install\fR can be avoided by using the flag \fB\-\-skip\-install\fR\.
10
10
  .SH "OPTIONS"
@@ -50,6 +50,9 @@ Adds optimistic declaration of version\.
50
50
  .TP
51
51
  \fB\-\-strict\fR
52
52
  Adds strict declaration of version\.
53
+ .TP
54
+ \fB\-\-cooldown=<number>\fR
55
+ Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
53
56
  .SH "EXAMPLES"
54
57
  .IP "1." 4
55
58
  You can add the \fBrails\fR gem to the Gemfile without any version restriction\. The source of the gem will be the global source\.
@@ -5,7 +5,7 @@ bundle-add(1) -- Add gem to the Gemfile and run bundle install
5
5
 
6
6
  `bundle add` <GEM_NAME> [--group=GROUP] [--version=VERSION] [--source=SOURCE]
7
7
  [--path=PATH] [--git=GIT|--github=GITHUB] [--branch=BRANCH] [--ref=REF]
8
- [--quiet] [--skip-install] [--strict|--optimistic]
8
+ [--cooldown=NUMBER] [--quiet] [--skip-install] [--strict|--optimistic]
9
9
 
10
10
  ## DESCRIPTION
11
11
 
@@ -56,6 +56,11 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
56
56
  * `--strict`:
57
57
  Adds strict declaration of version.
58
58
 
59
+ * `--cooldown=<number>`:
60
+ Only consider gem versions published at least <number> days ago when
61
+ resolving. Pass `0` to disable cooldown for this run. See `cooldown`
62
+ in bundle-config(1) for precedence rules.
63
+
59
64
  ## EXAMPLES
60
65
 
61
66
  1. You can add the `rails` gem to the Gemfile without any version restriction.