If you force uninstall a dependency but leave other gems depending on
it, those gems will fail to be activated.
In that case, RubyGems prints a rather complicated error:
```
$ rails --version
/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1413:in 'block in Gem::Specification#activate_dependencies': Could not find 'activesupport' (= 8.0.1) among 478 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/deivid/.local/share/gem/ruby/3.4.0:/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/gems/3.4.0' at: /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/specifications/railties-8.0.1.gemspec, execute `gem env` for more information
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1399:in 'Array#each'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1399:in 'Gem::Specification#activate_dependencies'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1381:in 'Gem::Specification#activate'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:283:in 'block in Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Thread::Mutex#synchronize'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/bin/rails:25:in '<main>'
/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/dependency.rb:303:in 'Gem::Dependency#to_specs': Could not find 'activesupport' (= 8.0.1) - did find: [activesupport-7.1.3,activesupport-7.0.8.7] (Gem::MissingSpecVersionError)
Checked in 'GEM_PATH=/Users/deivid/.local/share/gem/ruby/3.4.0:/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/gems/3.4.0' , execute `gem env` for more information
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1411:in 'block in Gem::Specification#activate_dependencies'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1399:in 'Array#each'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1399:in 'Gem::Specification#activate_dependencies'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1381:in 'Gem::Specification#activate'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:283:in 'block in Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Thread::Mutex#synchronize'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/bin/rails:25:in '<main>'
```
With this commit, the error becomes a bit simpler to parse:
```
$ rails --version
/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1421:in 'block in Gem::Specification#activate_dependencies': Could not find 'activesupport' (= 8.0.1) among 478 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/deivid/.local/share/gem/ruby/3.4.0:/Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/gems/3.4.0' at: /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/specifications/railties-8.0.1.gemspec, execute `gem env` for more information
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1407:in 'Array#each'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1407:in 'Gem::Specification#activate_dependencies'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems/specification.rb:1389:in 'Gem::Specification#activate'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:283:in 'block in Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Thread::Mutex#synchronize'
from /Users/deivid/.asdf/installs/ruby/3.4.1/lib/ruby/site_ruby/3.4.0/rubygems.rb:282:in 'Gem.activate_bin_path'
from /Users/deivid/.asdf/installs/ruby/3.4.1/bin/rails:25:in '<main>'
```
And also, we reduce exception based control flow in our code.
https://github.com/rubygems/rubygems/commit/7e48c49f2d
If `Gem::Specification.reset` is used, but there are still unresolved
dependencies, RubyGems prints a warning. There are though, certain cases
where the situation will not cause any issues.
One such case is when the unresolved dependency does not restrict any
versions (>= 0) and there's a default gem matching it.
In this situation, it doesn't matter if Gem paths change, because
default gems are still activatable, so the dependency will be properly
activated if ever needed.
https://github.com/rubygems/rubygems/commit/e5f8a3068e
If a gem package is built from a specification whose platform has been
modified, it will include metadata using the old platform.
This change should fix the problem by making sure `original_platform` is
always properly set.
https://github.com/rubygems/rubygems/commit/ecd5cd4547
If old Bundler versions that unconditionally try to remove this method
are run with RubyGems versions _without_ this method, Bundler crashes
because it tries to remove a method that does not exist.
We need to wait until RubyGems cannot install any Bundler versions that
unconditionally remove this method.
https://github.com/rubygems/rubygems/commit/98804d261d
This method validates only what is required for resolution, skipping any
irrelevant metadata validation. This will be used by Bundler instead of
doing a full validation, allowing gem authors to use `bundle` commands
immediately in newly created gems without first having to fix invalid
metafata fields in the default gemspec.
https://github.com/rubygems/rubygems/commit/da7704cfc0
When `gem uninstall <gem> --install-dir <dir>` is run, if the version
removed had a plugin, and that same version happened to also be
installed globally, then the plugin stub would fail to be removed.
https://github.com/rubygems/rubygems/commit/4e2fa0be77
This class handles all logic to handle the list of specifications, given
a set of GEM_PATH directories. Makes `Gem::Specification` has less
responsibilities and will help with fixing some bugs next.
https://github.com/rubygems/rubygems/commit/df280dbbed
This gets in the middle if we ever start allowing to build as if using a
different RubyGems version than the one being run.
This could be useful to make `gem rebuild` a little more usable, and
it's already done by Bundler specs which already make this method a noop
when they need this.
I'm not sure forcefully setting this, even if user explicitly specified
something else is helpful.
Since this could potentially prevent gems explicitly setting a constant
RubyGems version from building, I changed the error of incorrect
RubyGems version from a hard error to a warning, since it will start
happening in those cases if we stop overwriting the version.
https://github.com/rubygems/rubygems/commit/45676af80d
Nil-value keys in a mapping end with a space or not depending on
libyaml versions, and result metadata are different per platforms.
This commit makes to skip such keys to make metadata reproducible
accross platforms.
https://github.com/rubygems/rubygems/commit/74b4db8d30
I think we can safely assume these days that all RubyGems and Bundler
versions that will ever bundle a new gem created in 2023 support
prereleases.
So this non transparent requirement is not necessary.
In my opinion, it should be the gem author to explicitly add this
constraint, not RubyGems.
https://github.com/rubygems/rubygems/commit/b165e6d725
This gets the specs passing, and handles the fact that we expect
checkums to be pinned only to a particular source
This also avoids reading in .gem files during lockfile generation,
instead allowing us to query the source for each resolved gem to grab
the checksum
Finally, this opens up a route to having user-stored checksum databases,
similar to how other package managers do this!
Add checksums to dev lockfiles
Handle full name conflicts from different original_platforms when adding checksums to store from compact index
Specs passing on Bundler 3
https://github.com/rubygems/rubygems/commit/86c7084e1c
1. Use the checksum provided by the server if provided: provides security
knowing if the gem you downloaded matches the gem on the server
2. Calculate the checksum from the gem on disk: provides security knowing
if the gem has changed between installs
3. In some cases, neither is possible in which case we don't put anything
in the checksum and we maintain functionality as it is today
Add the checksums to specs in the index if we already have them
Prior to checksums, we didn't lose any information when overwriting specs
in the index with stubs. But now when we overwrite EndpointSpecifications
or RemoteSpecifications with more generic specs, we could lose checksum
info. This manually sets checksum info so we keep it in the index.
https://github.com/rubygems/rubygems/commit/de00a4f153
Before this, you would get constant redefinition warnings on Psych::DefaultKey
Additionally, ensure the retries wont continue infinitely in the case of the ArgumentError not being caused by Marshal trying to load the undefined classes
https://github.com/rubygems/rubygems/commit/919e8c2de4