[rubygems/rubygems] Undeprecate Gemfiles without a global source

After having a second look at this deprecation, the explanation that
we're giving does not make a lot of sense. When working only with local
gems, Bundler will indeed generate a different lockfile depending on
the latest installed version of each gem is at `bundle install` time.

That's the same situation that happens with remote sources: Bundler will
generate a different lockfile depending on the latest version of each
gem available remotely.

So, I don't think "a consistent lockfile not getting generated" is a
good motivation for deprecating this.

Also, this deprecation brings additional challenges, since for example,
it should arguably not get printed when using `bundle install --local`?

The original problem when this deprecation was introduced was an
incorrect message about a missing gem having been yanked.

So, I think a better solution is to, as long as we give proper error
messages when things go wrong, let users do what's best for them and
undo the deprecation.

https://github.com/rubygems/rubygems/commit/17499cb83f
This commit is contained in:
David Rodríguez 2024-11-05 17:55:41 +01:00 коммит произвёл git
Родитель df3395f2e3
Коммит ffcfaf4ce4
4 изменённых файлов: 41 добавлений и 38 удалений

Просмотреть файл

@ -608,10 +608,20 @@ module Bundler
missing_specs.each do |s|
locked_gem = @locked_specs[s.name].last
next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
message = if sources.implicit_global_source?
"Because your Gemfile specifies no global remote source, your bundle is locked to " \
"#{locked_gem} from #{locked_gem.source}. However, #{locked_gem} is not installed. You'll " \
"need to either add a global remote source to your Gemfile or make sure #{locked_gem} is " \
"available locally before rerunning Bundler."
else
"Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end
raise GemNotFound, message
end
missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|

Просмотреть файл

@ -503,18 +503,7 @@ module Bundler
end
def check_rubygems_source_safety
if @sources.implicit_global_source?
implicit_global_source_warning
elsif @sources.aggregate_global_source?
multiple_global_source_warning
end
end
def implicit_global_source_warning
Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
"Not using an explicit global source may result in a different lockfile being generated depending on " \
"the gems you have installed locally before bundler is run. " \
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
multiple_global_source_warning if @sources.aggregate_global_source?
end
def multiple_global_source_warning

Просмотреть файл

@ -350,21 +350,4 @@ RSpec.describe Bundler::Dsl do
end
end
end
describe "#check_primary_source_safety" do
context "when a global source is not defined implicitly" do
it "will raise a major deprecation warning" do
not_a_global_source = double("not-a-global-source", no_remotes?: true)
allow(Bundler::Source::Rubygems).to receive(:new).and_return(not_a_global_source)
warning = "This Gemfile does not include an explicit global source. " \
"Not using an explicit global source may result in a different lockfile being generated depending on " \
"the gems you have installed locally before bundler is run. " \
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
expect(Bundler::SharedHelpers).to receive(:major_deprecation).with(2, warning)
subject.check_primary_source_safety
end
end
end
end

Просмотреть файл

@ -340,15 +340,36 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "myrack 1.2", "activesupport 1.2.3"
end
it "gives a useful error if no sources are set" do
it "gives useful errors if no global sources are set, and gems not installed locally, with and without a lockfile" do
install_gemfile <<-G, raise_on_error: false
gem "myrack"
G
expect(err).to include("This Gemfile does not include an explicit global source. " \
"Not using an explicit global source may result in a different lockfile being generated depending on " \
"the gems you have installed locally before bundler is run. " \
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\".")
expect(err).to eq("Could not find gem 'myrack' in locally installed gems.")
lockfile <<~L
GEM
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install", raise_on_error: false
expect(err).to include(
"Because your Gemfile specifies no global remote source, your bundle is locked to " \
"myrack (1.0.0) from locally installed gems. However, myrack (1.0.0) is not installed. " \
"You'll need to either add a global remote source to your Gemfile or make sure myrack (1.0.0) " \
"is available locally before rerunning Bundler."
)
end
it "creates a Gemfile.lock on a blank Gemfile" do