bundler 4.0.0.beta1 → 4.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ea78831fde425df537d3ff1df353f5a3aca9f487ce4afa9e46299fa9dc97156
4
- data.tar.gz: 6a00156d2407d372ee1e53ea9e8410a47c3ab253f022316001781e051c9cdb48
3
+ metadata.gz: 0b538a3abc5f8651616cf8883d701149ee50457172c532fe11e3c5f0849dca2d
4
+ data.tar.gz: 610279b2dd9c3601d1c9cbf64ccd9a536f3ab5f7871a135014156352932b032e
5
5
  SHA512:
6
- metadata.gz: b019a26c02b28e3f2e9d09dc52651549395248978130e40413800ebd738140bc3451639a112a0475a4cfa43818798aaff4d88b0105633e035133f7cc985d3003
7
- data.tar.gz: dead007ff8a70c1bde02642b9c22c4eeb038cddb9751d175c4106ad030284ed2a71b84f4861e23e83d9be48e47bf3c5085e0ba0e80d9a10902ce042b6a78939b
6
+ metadata.gz: 12b40ef7ba38861f20330914c5f6473f7bf6396a6cba0bcae2eef51d4e5c48fbfa1ab8f7a3071ca999f4e1d56a424b42b486f12704fe409fc0e4f2362e1f6552
7
+ data.tar.gz: 8e2fa626c039857ab573a7213732d3a40e7de05d813bc3b197b1466d17fa5d835bb2141e7a74a445ba2fc4f6d48cba2a959373681cdc0bc47fa4dcaa184e3c8d
data/CHANGELOG.md CHANGED
@@ -1,6 +1,95 @@
1
1
  # Changelog
2
2
 
3
- ## 4.0.0.beta1 (2025-11-20)
3
+ ## 4.0.3 (2025-12-23)
4
+
5
+ ### Enhancements:
6
+
7
+ - Fall back to ruby platform gem when precompiled variant is incompatible [#9211](https://github.com/ruby/rubygems/pull/9211)
8
+
9
+ ## 4.0.2 (2025-12-17)
10
+
11
+ ### Enhancements:
12
+
13
+ - Support single quotes in mise format ruby version [#9183](https://github.com/ruby/rubygems/pull/9183)
14
+ - Tweak the Bundler's "X gems now installed message": [#9194](https://github.com/ruby/rubygems/pull/9194)
15
+
16
+ ### Bug fixes:
17
+
18
+ - Allow to show cli_help with `bundler` executable [#9198](https://github.com/ruby/rubygems/pull/9198)
19
+ - Allow bundle pristine to work for git gems in the same repo [#9196](https://github.com/ruby/rubygems/pull/9196)
20
+
21
+ ## 4.0.1 (2025-12-09)
22
+
23
+ ### Performance:
24
+
25
+ - Increase connection pool to allow for up to 70% speed increase on `bundle install` [#9087](https://github.com/ruby/rubygems/pull/9087)
26
+
27
+ ### Enhancements:
28
+
29
+ - Fix the config suggestion in the warning for `$ bundle` [#9164](https://github.com/ruby/rubygems/pull/9164)
30
+ - Fix native extension loading in newgem template for RHEL-based systems [#9156](https://github.com/ruby/rubygems/pull/9156)
31
+
32
+ ### Bug fixes:
33
+
34
+ - Fix Bundler removing executables after creating them [#9169](https://github.com/ruby/rubygems/pull/9169)
35
+
36
+ ## 4.0.0 (2025-12-03)
37
+
38
+ ### Features:
39
+
40
+ - Support bundle install --lockfile option [#9111](https://github.com/ruby/rubygems/pull/9111)
41
+ - Add support for lockfile in Gemfile and bundle install --no-lock [#9059](https://github.com/ruby/rubygems/pull/9059)
42
+ - Add `--ext=go` to `bundle gem` [#8183](https://github.com/ruby/rubygems/pull/8183)
43
+ - Update Bundler::CurrentRuby::ALL_RUBY_VERSIONS [#9058](https://github.com/ruby/rubygems/pull/9058)
44
+ - Introduce `bundle list --format=json` [#8728](https://github.com/ruby/rubygems/pull/8728)
45
+
46
+ ### Performance:
47
+
48
+ - Run git operations in parallel to speed things up: [#9100](https://github.com/ruby/rubygems/pull/9100)
49
+ - Replace instance method look up in plugin installer [#9094](https://github.com/ruby/rubygems/pull/9094)
50
+ - Adjust the API_REQUEST_LIMIT to make less network roundtrip [#9071](https://github.com/ruby/rubygems/pull/9071)
51
+
52
+ ### Enhancements:
53
+
54
+ - Make BUNDLE_LOCKFILE environment variable have precedence over lockfile method in Gemfile [#9146](https://github.com/ruby/rubygems/pull/9146)
55
+ - Improve banner message for the default command [#9145](https://github.com/ruby/rubygems/pull/9145)
56
+ - Introduce `install_or_cli_help` and use it default `bundle` command [#9136](https://github.com/ruby/rubygems/pull/9136)
57
+ - Add go_gem/rake_task for Go native extension gem skeleton [#9105](https://github.com/ruby/rubygems/pull/9105)
58
+ - Warn users that `bundle` now display the help: [#9092](https://github.com/ruby/rubygems/pull/9092)
59
+ - Use DidYouMean::SpellChecker for gem suggestions in Bundler [#3857](https://github.com/ruby/rubygems/pull/3857)
60
+ - Update all vendored libraries to latest version [#9089](https://github.com/ruby/rubygems/pull/9089)
61
+ - We don't need to allow some warning now [#9074](https://github.com/ruby/rubygems/pull/9074)
62
+ - Support to embedded Pathname [#9056](https://github.com/ruby/rubygems/pull/9056)
63
+ - Enforce activation of irb when running with bundle console [#9033](https://github.com/ruby/rubygems/pull/9033)
64
+ - Update Magnus version in Rust extension gem template [#9025](https://github.com/ruby/rubygems/pull/9025)
65
+ - Add checksum of gems hosted on private servers: [#9004](https://github.com/ruby/rubygems/pull/9004)
66
+ - Loading support on Windows [#8254](https://github.com/ruby/rubygems/pull/8254)
67
+ - Improve error message when the same source is specified through `gemspec` and `path` [#8460](https://github.com/ruby/rubygems/pull/8460)
68
+ - Raise an error in frozen mode if some registry gems have empty checksums [#8888](https://github.com/ruby/rubygems/pull/8888)
69
+ - Bump vendored thor to 1.4.0 [#8883](https://github.com/ruby/rubygems/pull/8883)
70
+ - Delay default path and global cache changes to Bundler 5 [#8867](https://github.com/ruby/rubygems/pull/8867)
71
+ - Fix spacing in bundle gem newgem.gemspec.tt [#8865](https://github.com/ruby/rubygems/pull/8865)
72
+ - Add some missing deprecation messages [#8844](https://github.com/ruby/rubygems/pull/8844)
73
+
74
+ ### Bug fixes:
75
+
76
+ - Fixed checksums generation issue when no source is specified [#9133](https://github.com/ruby/rubygems/pull/9133)
77
+ - Check for file existence before deletion from cache [#9095](https://github.com/ruby/rubygems/pull/9095)
78
+ - Use method_defined?(:method, false) [#9098](https://github.com/ruby/rubygems/pull/9098)
79
+ - Handle BUNDLER_VERSION being set to an empty string [#6928](https://github.com/ruby/rubygems/pull/6928)
80
+ - Fix `bundle install` when the Gemfile contains "install_if" git gems: [#8992](https://github.com/ruby/rubygems/pull/8992)
81
+ - Fix installation issue related to path sources and precompiled gems [#8973](https://github.com/ruby/rubygems/pull/8973)
82
+ - Fix outdated lockfile during `bundle lock` when source changes [#8962](https://github.com/ruby/rubygems/pull/8962)
83
+ - Raise error on missing version file [#8963](https://github.com/ruby/rubygems/pull/8963)
84
+ - Fix `bundle cache --frozen` and `bundle cache --no-prune` not printing a deprecation message [#8926](https://github.com/ruby/rubygems/pull/8926)
85
+ - Fix local installation incorrectly forced if there's a `vendor/cache` directory and frozen mode is set [#8925](https://github.com/ruby/rubygems/pull/8925)
86
+ - Fix `bundle lock --update <gem>` with `--lockfile` flag updating all gems [#8922](https://github.com/ruby/rubygems/pull/8922)
87
+ - Fix `bundle show --verbose` and recommend it as an alternative to `bundle show --outdated` [#8915](https://github.com/ruby/rubygems/pull/8915)
88
+ - Fix `bundle cache --no-all` not printing a deprecation warning [#8912](https://github.com/ruby/rubygems/pull/8912)
89
+ - Fix `bundle update foo` unable to update foo in an edge case [#8897](https://github.com/ruby/rubygems/pull/8897)
90
+ - Fix Bundler printing more flags than actually passed in verbose mode [#8914](https://github.com/ruby/rubygems/pull/8914)
91
+ - Fix bundler failing to install sorbet-static in truffleruby when there's no lockfile [#8872](https://github.com/ruby/rubygems/pull/8872)
92
+ - Cancel deprecation of `--force` flag to `bundle install` and `bundle update` [#8843](https://github.com/ruby/rubygems/pull/8843)
4
93
 
5
94
  ### Security:
6
95
 
@@ -14,14 +103,12 @@
14
103
  - Pick and add extra changes for 4.0.0 version [#9018](https://github.com/ruby/rubygems/pull/9018)
15
104
  - Replaced Bundler::SharedHelpers.major_deprecation to feature_removed! or feature_deprecated! [#9016](https://github.com/ruby/rubygems/pull/9016)
16
105
  - Removed legacy_check option from SpecSet#for [#9015](https://github.com/ruby/rubygems/pull/9015)
17
- - Removed deprecated legacy windows platform support [#9013](https://github.com/ruby/rubygems/pull/9013)
18
106
  - Make update_requires_all_flag to settings [#9011](https://github.com/ruby/rubygems/pull/9011)
19
107
  - Make default cli command settings [#9010](https://github.com/ruby/rubygems/pull/9010)
20
108
  - Make global_gem_cache flag to settings [#9009](https://github.com/ruby/rubygems/pull/9009)
21
109
  - Consolidate removal of `Bundler.rubygems.all_specs` [#9008](https://github.com/ruby/rubygems/pull/9008)
22
110
  - Consolidate removal of `Bundler::SpecSet#-` and `Bundler::SpecSet#<<` [#9007](https://github.com/ruby/rubygems/pull/9007)
23
111
  - Replaced Bundler.feature_flag.plugins? to Bundler.settings [#9006](https://github.com/ruby/rubygems/pull/9006)
24
- - Switch to 4.0.0.dev in development version [#9002](https://github.com/ruby/rubygems/pull/9002)
25
112
  - Make `bundle show --outdated` raise an error [#8980](https://github.com/ruby/rubygems/pull/8980)
26
113
  - Make `--local-git` flag to `bundle plugin install` raise an error [#8979](https://github.com/ruby/rubygems/pull/8979)
27
114
  - Switch `cache_all` to be `true` by default [#8975](https://github.com/ruby/rubygems/pull/8975)
@@ -38,40 +125,17 @@
38
125
  - Remove deprecated `bundle viz` and `bundle inject` commands [#8923](https://github.com/ruby/rubygems/pull/8923)
39
126
  - Removed to workaround for Bundler 2.2 [#8903](https://github.com/ruby/rubygems/pull/8903)
40
127
 
41
- ### Features:
42
-
43
- - Update Bundler::CurrentRuby::ALL_RUBY_VERSIONS [#9058](https://github.com/ruby/rubygems/pull/9058)
44
- - Introduce `bundle list --format=json` [#8728](https://github.com/ruby/rubygems/pull/8728)
45
-
46
- ### Performance:
47
-
48
- - Replace instance method look up in plugin installer [#9094](https://github.com/ruby/rubygems/pull/9094)
49
- - Adjust the API_REQUEST_LIMIT to make less network roundtrip [#9071](https://github.com/ruby/rubygems/pull/9071)
50
-
51
- ### Enhancements:
52
-
53
- - Use DidYouMean::SpellChecker for gem suggestions in Bundler [#3857](https://github.com/ruby/rubygems/pull/3857)
54
- - Update all vendored libraries to latest version [#9089](https://github.com/ruby/rubygems/pull/9089)
55
- - We don't need to allow some warning now [#9074](https://github.com/ruby/rubygems/pull/9074)
56
- - Shell out fewer times [#9068](https://github.com/ruby/rubygems/pull/9068)
57
- - Build gems directly instead of shelling out [#9053](https://github.com/ruby/rubygems/pull/9053)
58
- - Support to embedded Pathname [#9056](https://github.com/ruby/rubygems/pull/9056)
59
- - Forcely activate irb when running with bundle console [#9033](https://github.com/ruby/rubygems/pull/9033)
60
- - Update Magnus version in Rust extension gem template [#9025](https://github.com/ruby/rubygems/pull/9025)
61
- - Postpone to remove legacy mingw platform [#9023](https://github.com/ruby/rubygems/pull/9023)
62
- - Add checksum of gems hosted on private servers: [#9004](https://github.com/ruby/rubygems/pull/9004)
63
- - Loading support on Windows [#8254](https://github.com/ruby/rubygems/pull/8254)
64
-
65
- ### Bug fixes:
66
-
67
- - Fix `bundle install` when the Gemfile contains "install_if" git gems: [#8992](https://github.com/ruby/rubygems/pull/8992)
68
- - Fix installation issue related to path sources and precompiled gems [#8973](https://github.com/ruby/rubygems/pull/8973)
69
- - Fix outdated lockfile during `bundle lock` when source changes [#8962](https://github.com/ruby/rubygems/pull/8962)
70
- - Raise error on missing version file [#8963](https://github.com/ruby/rubygems/pull/8963)
71
-
72
128
  ### Documentation:
73
129
 
130
+ - Unified UPGRADING.md and extract blog.rubygems.org [#9148](https://github.com/ruby/rubygems/pull/9148)
131
+ - Remove italic formatting from changelog section headers [#9128](https://github.com/ruby/rubygems/pull/9128)
74
132
  - Small clarifications to Bundler 4 upgrade docs [#8964](https://github.com/ruby/rubygems/pull/8964)
133
+ - Improve documentation of `bundle doctor`, `bundle plugin`, and `bundle config` [#8919](https://github.com/ruby/rubygems/pull/8919)
134
+ - Make sure all CLI flags and subcommands are documented [#8861](https://github.com/ruby/rubygems/pull/8861)
135
+ - Clarify documentation about new default gem installation directory in Bundler 4 [#8857](https://github.com/ruby/rubygems/pull/8857)
136
+ - Use mailto link in Code of Conduct [#8849](https://github.com/ruby/rubygems/pull/8849)
137
+ - Update Code of Conduct email to conduct@rubygems.org [#8848](https://github.com/ruby/rubygems/pull/8848)
138
+ - Add missing link to `irb` repo in DEBUGGING.md [#8842](https://github.com/ruby/rubygems/pull/8842)
75
139
 
76
140
  ## 2.7.2 (2025-09-09)
77
141
 
@@ -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 = "2025-11-20".freeze
8
- @git_commit_sha = "9be811c01a".freeze
7
+ @built_at = "2025-12-23".freeze
8
+ @git_commit_sha = "28c66ecc1e".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -44,6 +44,8 @@ module Bundler
44
44
  # (rather than some optimizations we perform at app runtime).
45
45
  definition = Bundler.definition(strict: true)
46
46
  definition.validate_runtime!
47
+ definition.lockfile = options["lockfile"] if options["lockfile"]
48
+ definition.lockfile = false if options["no-lock"]
47
49
 
48
50
  installer = Installer.install(Bundler.root, definition, options)
49
51
 
@@ -88,7 +90,7 @@ module Bundler
88
90
  end
89
91
 
90
92
  def gems_installed_for(definition)
91
- count = definition.specs.count
93
+ count = definition.specs.count {|spec| spec.name != "bundler" }
92
94
  "#{count} #{count == 1 ? "gem" : "gems"} now installed"
93
95
  end
94
96
 
@@ -11,6 +11,7 @@ module Bundler
11
11
  definition = Bundler.definition
12
12
  definition.validate_runtime!
13
13
  installer = Bundler::Installer.new(Bundler.root, definition)
14
+ git_sources = []
14
15
 
15
16
  ProcessLock.lock do
16
17
  installed_specs = definition.specs.reject do |spec|
@@ -41,6 +42,9 @@ module Bundler
41
42
  end
42
43
  FileUtils.rm_rf spec.extension_dir
43
44
  FileUtils.rm_rf spec.full_gem_path
45
+
46
+ next if git_sources.include?(source)
47
+ git_sources << source
44
48
  else
45
49
  Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
46
50
  next
data/lib/bundler/cli.rb CHANGED
@@ -59,17 +59,29 @@ module Bundler
59
59
  def initialize(*args)
60
60
  super
61
61
 
62
+ current_cmd = args.last[:current_command].name
63
+
62
64
  custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
63
65
  if custom_gemfile && !custom_gemfile.empty?
64
66
  Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
65
- Bundler.reset_settings_and_root!
67
+ reset_settings = true
68
+ end
69
+
70
+ # lock --lockfile works differently than install --lockfile
71
+ unless current_cmd == "lock"
72
+ custom_lockfile = options[:lockfile] || ENV["BUNDLE_LOCKFILE"] || Bundler.settings[:lockfile]
73
+ if custom_lockfile && !custom_lockfile.empty?
74
+ Bundler::SharedHelpers.set_env "BUNDLE_LOCKFILE", File.expand_path(custom_lockfile)
75
+ reset_settings = true
76
+ end
66
77
  end
67
78
 
79
+ Bundler.reset_settings_and_root! if reset_settings
80
+
68
81
  Bundler.auto_switch
69
82
 
70
83
  Bundler.settings.set_command_option_if_given :retry, options[:retry]
71
84
 
72
- current_cmd = args.last[:current_command].name
73
85
  Bundler.auto_install if AUTO_INSTALL_CMDS.include?(current_cmd)
74
86
  rescue UnknownArgumentError => e
75
87
  raise InvalidOption, e.message
@@ -92,7 +104,7 @@ module Bundler
92
104
  primary_commands = ["install", "update", "cache", "exec", "config", "help"]
93
105
 
94
106
  list = self.class.printable_commands(true)
95
- by_name = list.group_by {|name, _message| name.match(/^bundle (\w+)/)[1] }
107
+ by_name = list.group_by {|name, _message| name.match(/^bundler? (\w+)/)[1] }
96
108
  utilities = by_name.keys.sort - primary_commands
97
109
  primary_commands.map! {|name| (by_name[name] || raise("no primary command #{name}")).first }
98
110
  utilities.map! {|name| by_name[name].first }
@@ -108,20 +120,31 @@ module Bundler
108
120
  self.class.send(:class_options_help, shell)
109
121
  end
110
122
 
123
+ desc "install_or_cli_help", "Deprecated alias of install", hide: true
124
+ def install_or_cli_help
125
+ Bundler.ui.warn <<~MSG
126
+ `bundle install_or_cli_help` is a deprecated alias of `bundle install`.
127
+ It might be called due to the 'default_cli_command' being set to 'install_or_cli_help',
128
+ if so fix that by running `bundle config set default_cli_command install --global`.
129
+ MSG
130
+ invoke_other_command("install")
131
+ end
132
+
111
133
  def self.default_command(meth = nil)
112
134
  return super if meth
113
135
 
114
- default_cli_command = Bundler.settings[:default_cli_command]
115
- return default_cli_command if default_cli_command
136
+ unless Bundler.settings[:default_cli_command]
137
+ Bundler.ui.info <<~MSG
138
+ In a future version of Bundler, running `bundle` without argument will no longer run `bundle install`.
139
+ Instead, the `cli_help` command will be displayed. Please use `bundle install` explicitly for scripts like CI/CD.
140
+ You can use the future behavior now with `bundle config set default_cli_command cli_help --global`,
141
+ or you can continue to use the current behavior with `bundle config set default_cli_command install --global`.
142
+ This message will be removed after a default_cli_command value is set.
116
143
 
117
- Bundler.ui.warn(<<~MSG)
118
- In the next version of Bundler, running `bundle` without argument will no longer run `bundle install`.
119
- Instead, the `help` command will be displayed.
120
-
121
- If you'd like to keep the previous behaviour please run `bundle config set default_cli_command install --global`.
122
- MSG
144
+ MSG
145
+ end
123
146
 
124
- "install"
147
+ Bundler.settings[:default_cli_command] || "install"
125
148
  end
126
149
 
127
150
  class_option "no-color", type: :boolean, desc: "Disable colorization in output"
@@ -232,8 +255,10 @@ module Bundler
232
255
  method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
233
256
  method_option "jobs", aliases: "-j", type: :numeric, banner: "Specify the number of jobs to run in parallel"
234
257
  method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
258
+ method_option "lockfile", type: :string, banner: "Use the specified lockfile instead of the default."
235
259
  method_option "prefer-local", type: :boolean, banner: "Only attempt to fetch gems remotely if not present locally, even if newer versions are available remotely"
236
260
  method_option "no-cache", type: :boolean, banner: "Don't update the existing gem cache."
261
+ method_option "no-lock", type: :boolean, banner: "Don't create a lockfile."
237
262
  method_option "force", type: :boolean, aliases: "--redownload", banner: "Force reinstalling every gem, even if already installed"
238
263
  method_option "no-prune", type: :boolean, banner: "Don't remove stale gems from the cache (removed)."
239
264
  method_option "path", type: :string, banner: "Specify a different path than the system default, namely, $BUNDLE_PATH or $GEM_HOME (removed)."
@@ -260,9 +285,14 @@ module Bundler
260
285
  end
261
286
 
262
287
  require_relative "cli/install"
288
+ options = self.options.dup
289
+ options["lockfile"] ||= ENV["BUNDLE_LOCKFILE"]
263
290
  Bundler.settings.temporary(no_install: false) do
264
- Install.new(options.dup).run
291
+ Install.new(options).run
265
292
  end
293
+ rescue GemfileNotFound => error
294
+ invoke_other_command("cli_help")
295
+ raise error # re-raise to show the error and get a failing exit status
266
296
  end
267
297
 
268
298
  map aliases_for("install")
@@ -709,6 +739,19 @@ module Bundler
709
739
  config[:current_command]
710
740
  end
711
741
 
742
+ def invoke_other_command(name)
743
+ _, _, config = @_initializer
744
+ original_command = config[:current_command]
745
+ command = self.class.all_commands[name]
746
+ config[:current_command] = command
747
+ send(name)
748
+ ensure
749
+ config[:current_command] = original_command
750
+ end
751
+
752
+ def current_command=(command)
753
+ end
754
+
712
755
  def print_command
713
756
  return unless Bundler.ui.debug?
714
757
  cmd = current_command
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "lockfile_parser"
4
+ require_relative "worker"
4
5
 
5
6
  module Bundler
6
7
  class Definition
@@ -9,6 +10,8 @@ module Bundler
9
10
  attr_accessor :no_lock
10
11
  end
11
12
 
13
+ attr_writer :lockfile
14
+
12
15
  attr_reader(
13
16
  :dependencies,
14
17
  :locked_checksums,
@@ -379,7 +382,7 @@ module Bundler
379
382
  end
380
383
 
381
384
  def write_lock(file, preserve_unknown_sections)
382
- return if Definition.no_lock || file.nil?
385
+ return if Definition.no_lock || !lockfile || file.nil?
383
386
 
384
387
  contents = to_lock
385
388
 
@@ -536,6 +539,8 @@ module Bundler
536
539
  end
537
540
 
538
541
  def add_checksums
542
+ require "rubygems/package"
543
+
539
544
  @locked_checksums = true
540
545
 
541
546
  setup_domain!(add_checksums: true)
@@ -1100,7 +1105,23 @@ module Bundler
1100
1105
  @source_requirements ||= find_source_requirements
1101
1106
  end
1102
1107
 
1108
+ def preload_git_source_worker
1109
+ @preload_git_source_worker ||= Bundler::Worker.new(5, "Git source preloading", ->(source, _) { source.specs })
1110
+ end
1111
+
1112
+ def preload_git_sources
1113
+ sources.git_sources.each {|source| preload_git_source_worker.enq(source) }
1114
+ ensure
1115
+ preload_git_source_worker.stop
1116
+ end
1117
+
1103
1118
  def find_source_requirements
1119
+ if Gem.ruby_version >= Gem::Version.new("3.3")
1120
+ # Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
1121
+ # fetch git repositories one by one.
1122
+ preload_git_sources
1123
+ end
1124
+
1104
1125
  # Record the specs available in each gem's source, so that those
1105
1126
  # specs will be available later when the resolver knows where to
1106
1127
  # look for that gemspec (or its dependencies)
data/lib/bundler/dsl.rb CHANGED
@@ -9,8 +9,9 @@ module Bundler
9
9
 
10
10
  def self.evaluate(gemfile, lockfile, unlock)
11
11
  builder = new
12
+ builder.lockfile(lockfile)
12
13
  builder.eval_gemfile(gemfile)
13
- builder.to_definition(lockfile, unlock)
14
+ builder.to_definition(builder.lockfile_path, unlock)
14
15
  end
15
16
 
16
17
  VALID_PLATFORMS = Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
@@ -38,6 +39,7 @@ module Bundler
38
39
  @gemspecs = []
39
40
  @gemfile = nil
40
41
  @gemfiles = []
42
+ @lockfile = nil
41
43
  add_git_sources
42
44
  end
43
45
 
@@ -101,6 +103,15 @@ module Bundler
101
103
  add_dependency(name, version, options)
102
104
  end
103
105
 
106
+ # For usage in Dsl.evaluate, since lockfile is used as part of the Gemfile.
107
+ def lockfile_path
108
+ @lockfile
109
+ end
110
+
111
+ def lockfile(file)
112
+ @lockfile = file
113
+ end
114
+
104
115
  def source(source, *args, &blk)
105
116
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
106
117
  options = normalize_hash(options)
@@ -175,6 +186,7 @@ module Bundler
175
186
 
176
187
  def to_definition(lockfile, unlock)
177
188
  check_primary_source_safety
189
+ lockfile = @lockfile unless @lockfile.nil?
178
190
  Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
179
191
  end
180
192
 
@@ -415,8 +427,8 @@ module Bundler
415
427
  windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
416
428
  if windows_platforms.any?
417
429
  windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
418
- removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
419
- Bundler::SharedHelpers.feature_removed! removed_message
430
+ deprecated_message = "Platform #{windows_platforms} will be removed in the future. Please use platform :windows instead."
431
+ Bundler::SharedHelpers.feature_deprecated! deprecated_message
420
432
  end
421
433
 
422
434
  # Save sources passed in a key
@@ -60,6 +60,28 @@ module Bundler
60
60
  end
61
61
  end
62
62
 
63
+ # needed for binstubs
64
+ def executables
65
+ if @remote_specification
66
+ @remote_specification.executables
67
+ elsif _local_specification
68
+ _local_specification.executables
69
+ else
70
+ super
71
+ end
72
+ end
73
+
74
+ # needed for bundle clean
75
+ def bindir
76
+ if @remote_specification
77
+ @remote_specification.bindir
78
+ elsif _local_specification
79
+ _local_specification.bindir
80
+ else
81
+ super
82
+ end
83
+ end
84
+
63
85
  # needed for post_install_messages during install
64
86
  def post_install_message
65
87
  if @remote_specification
@@ -6,6 +6,7 @@ module Bundler
6
6
  BUNDLER_KEYS = %w[
7
7
  BUNDLE_BIN_PATH
8
8
  BUNDLE_GEMFILE
9
+ BUNDLE_LOCKFILE
9
10
  BUNDLER_VERSION
10
11
  BUNDLER_SETUP
11
12
  GEM_HOME
@@ -5,6 +5,12 @@ require "rubygems/remote_fetcher"
5
5
  module Bundler
6
6
  class Fetcher
7
7
  class GemRemoteFetcher < Gem::RemoteFetcher
8
+ def initialize(*)
9
+ super
10
+
11
+ @pool_size = 5
12
+ end
13
+
8
14
  def request(*args)
9
15
  super do |req|
10
16
  req.delete("User-Agent") if headers["User-Agent"]
@@ -44,12 +44,14 @@ def gemfile(force_latest_compatible = false, options = {}, &gemfile)
44
44
  raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
45
45
 
46
46
  old_gemfile = ENV["BUNDLE_GEMFILE"]
47
+ old_lockfile = ENV["BUNDLE_LOCKFILE"]
47
48
 
48
49
  Bundler.unbundle_env!
49
50
 
50
51
  begin
51
52
  Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir))
52
53
  Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
54
+ Bundler::SharedHelpers.set_env "BUNDLE_LOCKFILE", "Gemfile.lock"
53
55
 
54
56
  Bundler::Plugin.gemfile_install(&gemfile) if Bundler.settings[:plugins]
55
57
  builder = Bundler::Dsl.new
@@ -94,5 +96,11 @@ def gemfile(force_latest_compatible = false, options = {}, &gemfile)
94
96
  else
95
97
  ENV["BUNDLE_GEMFILE"] = ""
96
98
  end
99
+
100
+ if old_lockfile
101
+ ENV["BUNDLE_LOCKFILE"] = old_lockfile
102
+ else
103
+ ENV["BUNDLE_LOCKFILE"] = ""
104
+ end
97
105
  end
98
106
  end
@@ -138,24 +138,16 @@ module Bundler
138
138
  source.local!
139
139
 
140
140
  if use_exact_resolved_specifications?
141
- materialize(self) do |matching_specs|
142
- choose_compatible(matching_specs)
143
- end
144
- else
145
- materialize([name, version]) do |matching_specs|
146
- target_platform = source.is_a?(Source::Path) ? platform : Bundler.local_platform
147
-
148
- installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, target_platform)
149
-
150
- specification = choose_compatible(installable_candidates, fallback_to_non_installable: false)
151
- return specification unless specification.nil?
141
+ spec = materialize(self) {|specs| choose_compatible(specs, fallback_to_non_installable: false) }
142
+ return spec if spec
152
143
 
153
- if target_platform != platform
154
- installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, platform)
155
- end
156
-
157
- choose_compatible(installable_candidates)
144
+ # Exact spec is incompatible; in frozen mode, try to find a compatible platform variant
145
+ # In non-frozen mode, return nil to trigger re-resolution and lockfile update
146
+ if Bundler.frozen_bundle?
147
+ materialize([name, version]) {|specs| resolve_best_platform(specs) }
158
148
  end
149
+ else
150
+ materialize([name, version]) {|specs| resolve_best_platform(specs) }
159
151
  end
160
152
  end
161
153
 
@@ -190,6 +182,39 @@ module Bundler
190
182
  !source.is_a?(Source::Path) && ruby_platform_materializes_to_ruby_platform?
191
183
  end
192
184
 
185
+ # Try platforms in order of preference until finding a compatible spec.
186
+ # Used for legacy lockfiles and as a fallback when the exact locked spec
187
+ # is incompatible. Falls back to frozen bundle behavior if none match.
188
+ def resolve_best_platform(specs)
189
+ find_compatible_platform_spec(specs) || frozen_bundle_fallback(specs)
190
+ end
191
+
192
+ def find_compatible_platform_spec(specs)
193
+ candidate_platforms.each do |plat|
194
+ candidates = MatchPlatform.select_best_platform_match(specs, plat)
195
+ spec = choose_compatible(candidates, fallback_to_non_installable: false)
196
+ return spec if spec
197
+ end
198
+ nil
199
+ end
200
+
201
+ # Platforms to try in order of preference. Ruby platform is last since it
202
+ # requires compilation, but works when precompiled gems are incompatible.
203
+ def candidate_platforms
204
+ target = source.is_a?(Source::Path) ? platform : Bundler.local_platform
205
+ [target, platform, Gem::Platform::RUBY].uniq
206
+ end
207
+
208
+ # In frozen mode, accept any candidate. Will error at install time.
209
+ # When target differs from locked platform, prefer locked platform's candidates
210
+ # to preserve lockfile integrity.
211
+ def frozen_bundle_fallback(specs)
212
+ target = source.is_a?(Source::Path) ? platform : Bundler.local_platform
213
+ fallback_platform = target == platform ? target : platform
214
+ candidates = MatchPlatform.select_best_platform_match(specs, fallback_platform)
215
+ choose_compatible(candidates)
216
+ end
217
+
193
218
  def ruby_platform_materializes_to_ruby_platform?
194
219
  generic_platform = Bundler.generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY
195
220
 
@@ -145,6 +145,9 @@ Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init
145
145
  \fBjobs\fR (\fBBUNDLE_JOBS\fR)
146
146
  The number of gems Bundler can install in parallel\. Defaults to the number of available processors\.
147
147
  .TP
148
+ \fBlockfile\fR (\fBBUNDLE_LOCKFILE\fR)
149
+ The path to the lockfile that bundler should use\. By default, Bundler adds \fB\.lock\fR to the end of the \fBgemfile\fR entry\. Can be set to \fBfalse\fR in the Gemfile to disable lockfile creation entirely (see gemfile(5))\.
150
+ .TP
148
151
  \fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR)
149
152
  Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. Defaults to true\.
150
153
  .TP
@@ -189,6 +189,10 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
189
189
  * `jobs` (`BUNDLE_JOBS`):
190
190
  The number of gems Bundler can install in parallel. Defaults to the number of
191
191
  available processors.
192
+ * `lockfile` (`BUNDLE_LOCKFILE`):
193
+ The path to the lockfile that bundler should use. By default, Bundler adds
194
+ `.lock` to the end of the `gemfile` entry. Can be set to `false` in the
195
+ Gemfile to disable lockfile creation entirely (see gemfile(5)).
192
196
  * `lockfile_checksums` (`BUNDLE_LOCKFILE_CHECKSUMS`):
193
197
  Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources. Defaults to true.
194
198
  * `no_install` (`BUNDLE_NO_INSTALL`):
@@ -4,7 +4,7 @@
4
4
  .SH "NAME"
5
5
  \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
6
6
  .SH "SYNOPSIS"
7
- \fBbundle install\fR [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-no\-cache] [\-\-prefer\-local] [\-\-quiet] [\-\-retry=NUMBER] [\-\-standalone[=GROUP[ GROUP\|\.\|\.\|\.]]] [\-\-trust\-policy=TRUST\-POLICY] [\-\-target\-rbconfig=TARGET\-RBCONFIG]
7
+ \fBbundle install\fR [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-lockfile=LOCKFILE] [\-\-no\-cache] [\-\-no\-lock] [\-\-prefer\-local] [\-\-quiet] [\-\-retry=NUMBER] [\-\-standalone[=GROUP[ GROUP\|\.\|\.\|\.]]] [\-\-trust\-policy=TRUST\-POLICY] [\-\-target\-rbconfig=TARGET\-RBCONFIG]
8
8
  .SH "DESCRIPTION"
9
9
  Install the gems specified in your Gemfile(5)\. If this is the first time you run bundle install (and a \fBGemfile\.lock\fR does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems\.
10
10
  .P
@@ -28,12 +28,20 @@ The maximum number of parallel download and install jobs\. The default is the nu
28
28
  \fB\-\-local\fR
29
29
  Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
30
30
  .TP
31
+ \fB\-\-lockfile=LOCKFILE\fR
32
+ The location of the lockfile which Bundler should use\. This defaults to the Gemfile location with \fB\.lock\fR appended\.
33
+ .TP
31
34
  \fB\-\-prefer\-local\fR
32
35
  Force using locally installed gems, or gems already present in Rubygems' cache or in \fBvendor/cache\fR, when resolving, even if newer versions are available remotely\. Only attempt to connect to \fBrubygems\.org\fR for gems that are not present locally\.
33
36
  .TP
34
37
  \fB\-\-no\-cache\fR
35
38
  Do not update the cache in \fBvendor/cache\fR with the newly bundled gems\. This does not remove any gems in the cache but keeps the newly bundled gems from being cached during the install\.
36
39
  .TP
40
+ \fB\-\-no\-lock\fR
41
+ Do not create a lockfile\. Useful if you want to install dependencies but not lock versions of gems\. Recommended for library development, and other situations where the code is expected to work with a range of dependency versions\.
42
+ .IP
43
+ This has the same effect as using \fBlockfile false\fR in the Gemfile\. See gemfile(5) for more information\.
44
+ .TP
37
45
  \fB\-\-quiet\fR
38
46
  Do not print progress information to the standard output\.
39
47
  .TP
@@ -8,7 +8,9 @@ bundle-install(1) -- Install the dependencies specified in your Gemfile
8
8
  [--gemfile=GEMFILE]
9
9
  [--jobs=NUMBER]
10
10
  [--local]
11
+ [--lockfile=LOCKFILE]
11
12
  [--no-cache]
13
+ [--no-lock]
12
14
  [--prefer-local]
13
15
  [--quiet]
14
16
  [--retry=NUMBER]
@@ -60,6 +62,10 @@ update process below under [CONSERVATIVE UPDATING][].
60
62
  appropriate platform-specific gem exists on `rubygems.org` it will not be
61
63
  found.
62
64
 
65
+ * `--lockfile=LOCKFILE`:
66
+ The location of the lockfile which Bundler should use. This defaults
67
+ to the Gemfile location with `.lock` appended.
68
+
63
69
  * `--prefer-local`:
64
70
  Force using locally installed gems, or gems already present in Rubygems' cache
65
71
  or in `vendor/cache`, when resolving, even if newer versions are available
@@ -71,6 +77,15 @@ update process below under [CONSERVATIVE UPDATING][].
71
77
  does not remove any gems in the cache but keeps the newly bundled gems from
72
78
  being cached during the install.
73
79
 
80
+ * `--no-lock`:
81
+ Do not create a lockfile. Useful if you want to install dependencies but not
82
+ lock versions of gems. Recommended for library development, and other
83
+ situations where the code is expected to work with a range of dependency
84
+ versions.
85
+
86
+ This has the same effect as using `lockfile false` in the Gemfile.
87
+ See gemfile(5) for more information.
88
+
74
89
  * `--quiet`:
75
90
  Do not print progress information to the standard output.
76
91
 
@@ -469,4 +469,35 @@ For implicit gems (dependencies of explicit gems), any source, git, or path repo
469
469
  .IP "3." 4
470
470
  If neither of the above conditions are met, the global source will be used\. If multiple global sources are specified, they will be prioritized from last to first, but this is deprecated since Bundler 1\.13, so Bundler prints a warning and will abort with an error in the future\.
471
471
  .IP "" 0
472
+ .SH "LOCKFILE"
473
+ By default, Bundler will create a lockfile by adding \fB\.lock\fR to the end of the Gemfile name\. To change this, use the \fBlockfile\fR method:
474
+ .IP "" 4
475
+ .nf
476
+ lockfile "/path/to/lockfile\.lock"
477
+ .fi
478
+ .IP "" 0
479
+ .P
480
+ This is useful when you want to use different lockfiles per ruby version or platform\.
481
+ .P
482
+ To avoid writing a lock file, use \fBfalse\fR as the argument:
483
+ .IP "" 4
484
+ .nf
485
+ lockfile false
486
+ .fi
487
+ .IP "" 0
488
+ .P
489
+ This is useful for library development and other situations where the code is expected to work with a range of dependency versions\.
490
+ .SS "LOCKFILE PRECEDENCE"
491
+ When determining path to the lockfile or whether to create a lockfile, the following precedence is used:
492
+ .IP "1." 4
493
+ The \fBbundle install\fR \fB\-\-no\-lock\fR option (which disables lockfile creation)\.
494
+ .IP "2." 4
495
+ The \fBbundle install\fR \fB\-\-lockfile\fR option\.
496
+ .IP "3." 4
497
+ The \fBBUNDLE_LOCKFILE\fR environment variable\.
498
+ .IP "4." 4
499
+ The \fBlockfile\fR method in the Gemfile\.
500
+ .IP "5." 4
501
+ The default behavior of adding \fB\.lock\fR to the end of the Gemfile name\.
502
+ .IP "" 0
472
503
 
@@ -556,3 +556,31 @@ bundler uses the following priority order:
556
556
  If multiple global sources are specified, they will be prioritized from
557
557
  last to first, but this is deprecated since Bundler 1.13, so Bundler prints
558
558
  a warning and will abort with an error in the future.
559
+
560
+ ## LOCKFILE
561
+
562
+ By default, Bundler will create a lockfile by adding `.lock` to the end of the
563
+ Gemfile name. To change this, use the `lockfile` method:
564
+
565
+ lockfile "/path/to/lockfile.lock"
566
+
567
+ This is useful when you want to use different lockfiles per ruby version or
568
+ platform.
569
+
570
+ To avoid writing a lock file, use `false` as the argument:
571
+
572
+ lockfile false
573
+
574
+ This is useful for library development and other situations where the code is
575
+ expected to work with a range of dependency versions.
576
+
577
+ ### LOCKFILE PRECEDENCE
578
+
579
+ When determining path to the lockfile or whether to create a lockfile, the
580
+ following precedence is used:
581
+
582
+ 1. The `bundle install` `--no-lock` option (which disables lockfile creation).
583
+ 1. The `bundle install` `--lockfile` option.
584
+ 1. The `BUNDLE_LOCKFILE` environment variable.
585
+ 1. The `lockfile` method in the Gemfile.
586
+ 1. The default behavior of adding `.lock` to the end of the Gemfile name.
@@ -42,18 +42,21 @@ module Bundler
42
42
  # Loads the file relative to the dirname of the Gemfile itself.
43
43
  def normalize_ruby_file(filename)
44
44
  file_content = Bundler.read_file(gemfile.dirname.join(filename))
45
- # match "ruby-3.2.2", ruby = "3.2.2" or "ruby 3.2.2" capturing version string up to the first space or comment
46
- if /^ # Start of line
47
- ruby # Literal "ruby"
48
- [\s-]* # Optional whitespace or hyphens (for "ruby-3.2.2" format)
49
- (?:=\s*)? # Optional equals sign with whitespace (for ruby = "3.2.2" format)
50
- "? # Optional opening quote
51
- ( # Start capturing group
52
- [^\s#"]+ # One or more chars that aren't spaces, #, or quotes
53
- ) # End capturing group
54
- "? # Optional closing quote
55
- /x.match(file_content)
56
- $1
45
+ # match "ruby-3.2.2", ruby = "3.2.2", ruby = '3.2.2' or "ruby 3.2.2" capturing version string up to the first space or comment
46
+ version_match = /^ # Start of line
47
+ ruby # Literal "ruby"
48
+ [\s-]* # Optional whitespace or hyphens (for "ruby-3.2.2" format)
49
+ (?:=\s*)? # Optional equals sign with whitespace (for ruby = "3.2.2" format)
50
+ (?:
51
+ "([^"]+)" # Double quoted version
52
+ |
53
+ '([^']+)' # Single quoted version
54
+ |
55
+ ([^\s#"']+) # Unquoted version
56
+ )
57
+ /x.match(file_content)
58
+ if version_match
59
+ version_match[1] || version_match[2] || version_match[3]
57
60
  else
58
61
  file_content.strip
59
62
  end
@@ -103,6 +103,10 @@ module Bundler
103
103
  end
104
104
  end
105
105
 
106
+ def build_jobs
107
+ Bundler.settings[:jobs] || super
108
+ end
109
+
106
110
  def build_extensions
107
111
  extension_cache_path = options[:bundler_extension_cache_path]
108
112
  extension_dir = spec.extension_dir
@@ -240,7 +240,11 @@ module Bundler
240
240
 
241
241
  cached.each do |path|
242
242
  Bundler.ui.info " * #{File.basename(path)}"
243
- File.delete(path)
243
+
244
+ begin
245
+ File.delete(path)
246
+ rescue Errno::ENOENT
247
+ end
244
248
  end
245
249
  end
246
250
  end
@@ -65,6 +65,7 @@ module Bundler
65
65
  gem.rubocop
66
66
  gem.test
67
67
  gemfile
68
+ lockfile
68
69
  path
69
70
  shebang
70
71
  simulate_version
@@ -23,6 +23,9 @@ module Bundler
23
23
  end
24
24
 
25
25
  def default_lockfile
26
+ given = ENV["BUNDLE_LOCKFILE"]
27
+ return Pathname.new(given) if given && !given.empty?
28
+
26
29
  gemfile = default_gemfile
27
30
 
28
31
  case gemfile.basename.to_s
@@ -297,6 +300,7 @@ module Bundler
297
300
  def set_bundle_variables
298
301
  Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", bundle_bin_path
299
302
  Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
303
+ Bundler::SharedHelpers.set_env "BUNDLE_LOCKFILE", default_lockfile.to_s
300
304
  Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
301
305
  Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__)
302
306
  end
@@ -59,6 +59,11 @@ Rake::ExtensionTask.new("<%= config[:underscored_name] %>", GEMSPEC) do |ext|
59
59
  end
60
60
  <% end -%>
61
61
 
62
+ <% if config[:ext] == "go" -%>
63
+ require "go_gem/rake_task"
64
+
65
+ GoGem::RakeTask.new("<%= config[:underscored_name] %>")
66
+ <% end -%>
62
67
  <% end -%>
63
68
  <% if default_task_names.size == 1 -%>
64
69
  task default: <%= default_task_names.first.inspect %>
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative "<%= File.basename(config[:namespaced_path]) %>/version"
4
4
  <%- if config[:ext] -%>
5
- require_relative "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
5
+ require "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
6
6
  <%- end -%>
7
7
 
8
8
  <%- config[:constant_array].each_with_index do |c, i| -%>
@@ -17,6 +17,7 @@ module Bundler
17
17
  @level = ENV["DEBUG"] ? "debug" : "info"
18
18
  @warning_history = []
19
19
  @output_stream = :stdout
20
+ @thread_safe_logger_key = "logger_level_#{object_id}"
20
21
  end
21
22
 
22
23
  def add_color(string, *color)
@@ -97,11 +98,13 @@ module Bundler
97
98
  end
98
99
 
99
100
  def level(name = nil)
100
- return @level unless name
101
+ current_level = Thread.current.thread_variable_get(@thread_safe_logger_key) || @level
102
+ return current_level unless name
103
+
101
104
  unless index = LEVELS.index(name)
102
105
  raise "#{name.inspect} is not a valid level"
103
106
  end
104
- index <= LEVELS.index(@level)
107
+ index <= LEVELS.index(current_level)
105
108
  end
106
109
 
107
110
  def output_stream=(symbol)
@@ -167,12 +170,13 @@ module Bundler
167
170
  end * "\n"
168
171
  end
169
172
 
170
- def with_level(level)
171
- original = @level
172
- @level = level
173
+ def with_level(desired_level)
174
+ old_level = level
175
+ Thread.current.thread_variable_set(@thread_safe_logger_key, desired_level)
176
+
173
177
  yield
174
178
  ensure
175
- @level = original
179
+ Thread.current.thread_variable_set(@thread_safe_logger_key, old_level)
176
180
  end
177
181
 
178
182
  def with_output_stream(symbol)
@@ -625,7 +625,7 @@ class Bundler::Thor
625
625
  # alias name.
626
626
  def find_command_possibilities(meth)
627
627
  len = meth.to_s.length
628
- possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
628
+ possibilities = all_commands.reject { |_k, c| c.hidden? }.merge(map).keys.select { |n| meth == n[0, len] }.sort
629
629
  unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
630
630
 
631
631
  if possibilities.include?(meth)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "4.0.0.beta1".freeze
4
+ VERSION = "4.0.3".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= gem_version.segments.first
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta1
4
+ version: 4.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko