Skip to content

Commit

Permalink
Fix gem pristine etc resetting gem twice sometimes
Browse files Browse the repository at this point in the history
If a default version and a regular version of etc are present at the
same time, RubyGems will end up duplicating work and running pristine
twice.

The `etc` gem is special because it's loaded by RubyGems by default.
When doing this, RubyGems will activate the regularly installed version.
The when `gem pristine` runs, it will find to installed specifications
but materialize both to the already activated specification.

Before:

```
$ gem pristine etc --version 1.4.3
Restoring gems to pristine condition...
Building native extensions. This could take a while...
Restored etc-1.4.3
Building native extensions. This could take a while...
Restored etc-1.4.3
```

After:

```
$ gem pristine etc --version 1.4.3
Restoring gems to pristine condition...
Skipped etc-1.4.3, it is a default gem
Building native extensions. This could take a while...
Restored etc-1.4.3
```
  • Loading branch information
deivid-rodriguez committed Oct 8, 2024
1 parent f61431e commit 1acd494
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/rubygems/basic_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def contains_requirable_file?(file)
end

def default_gem?
loaded_from &&
!loaded_from.nil? &&
File.dirname(loaded_from) == Gem.default_specifications_dir
end

Expand Down
21 changes: 11 additions & 10 deletions lib/rubygems/stub_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,7 @@ def initialize(filename, base_dir, gems_dir, default_gem)
# True when this gem has been activated

def activated?
@activated ||=
begin
loaded = Gem.loaded_specs[name]
loaded && loaded.version == version
end
@activated ||= !loaded_spec.nil?
end

def default_gem?
Expand Down Expand Up @@ -187,11 +183,7 @@ def full_name
# The full Gem::Specification for this gem, loaded from evalling its gemspec

def spec
@spec ||= if @data
loaded = Gem.loaded_specs[name]
loaded if loaded && loaded.version == version
end

@spec ||= loaded_spec if @data
@spec ||= Gem::Specification.load(loaded_from)
end
alias_method :to_spec, :spec
Expand Down Expand Up @@ -231,4 +223,13 @@ def <=>(other) # :nodoc:
def sort_obj # :nodoc:
[name, version, Gem::Platform.sort_priority(platform)]
end

private

def loaded_spec
spec = Gem.loaded_specs[name]
return unless spec && spec.version == version && spec.default_gem? == default_gem?

spec
end
end
10 changes: 10 additions & 0 deletions test/rubygems/specifications/default/bar-0.0.2.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- encoding: utf-8 -*-
# stub: bar 0.0.2 ruby lib

Gem::Specification.new do |s|
s.name = "bar"
s.version = "0.0.2"
s.platform = "ruby"
s.require_paths = ["lib"]
s.summary = "A very bar gem"
end
14 changes: 14 additions & 0 deletions test/rubygems/test_gem_stub_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
class TestStubSpecification < Gem::TestCase
FOO = File.expand_path File.join("specifications", "foo-0.0.1-x86-mswin32.gemspec"), __dir__
BAR = File.expand_path File.join("specifications", "bar-0.0.2.gemspec"), __dir__
BAR_DEFAULT = File.expand_path File.join("specifications", "default", "bar-0.0.2.gemspec"), __dir__

def setup
super
Expand Down Expand Up @@ -173,6 +174,19 @@ def test_to_spec
assert_same real_foo, @foo.to_spec
end

def test_to_spec_default
bar = Gem::StubSpecification.gemspec_stub BAR, @base_dir, @gems_dir
bar_default = Gem::StubSpecification.default_gemspec_stub BAR_DEFAULT, @base_dir, @gems_dir

real_bar = util_spec bar_default.name, bar_default.version
real_bar.activate

assert_equal bar.version, Gem.loaded_specs[bar.name].version,
"sanity check"

refute_same real_bar, bar_default.to_spec
end

def test_to_spec_with_other_specs_loaded_does_not_warn
real_foo = util_spec @foo.name, @foo.version
real_foo.activate
Expand Down

0 comments on commit 1acd494

Please sign in to comment.