Skip to content

Conversation

@hsbt
Copy link
Member

@hsbt hsbt commented Mar 3, 2023

What was the end-user or developer problem that led to this PR?

When we try to install local gem like pkg/bigdecimal-3.1.4.gem with Ruby 3.3.0-dev(ruby/ruby master version). RubyGems always fail with the following error.

https://github.com/ruby/bigdecimal/actions/runs/4269574995/jobs/7432842358

ERROR:  Error installing pkg/bigdecimal-3.1.4.gem:
	ERROR: Failed to build gem native extension.

    No such file or directory @ dir_s_mkdir - /home/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/gems/bigdecimal-3.1.4/ext/bigdecimal/.gem.2023022[5](https://github.com/ruby/bigdecimal/actions/runs/4269574995/jobs/7432842358#step:8:6)-1814-[6](https://github.com/ruby/bigdecimal/actions/runs/4269574995/jobs/7432842358#step:8:7)gtm34

Gem files will remain installed in /home/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/gems/bigdecimal-3.1.4 for inspection.
Results logged to /home/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/extensions/x[8](https://github.com/ruby/bigdecimal/actions/runs/4269574995/jobs/7432842358#step:8:9)6_64-linux/3.3.0+0/bigdecimal-3.1.4/gem_make.out

What is your fix for the problem, implemented in this PR?

This is too complex condition. The assumption is that json is default gems(bigdecimal-3.1.4 didn't release yet, I showed same example with json),
https://github.com/rubygems/rubygems/blob/master/lib/rubygems/request_set.rb#L183 is always true when it's given same name and same version.

When we try to install via rubygems.org like gem i json -v 2.6.3, It's working fine. When we use remote installation, gemspec is APISpecification in https://github.com/rubygems/rubygems/blob/master/lib/rubygems/request_set.rb#L184 like:

[Activation request
  [APISpecification name: json version: 2.6.3 platform: ruby dependencies: [] set uri: https://index.rubygems.org/info/]
   for [Dependency request  json (= 2.6.3)  requested by nil]]

This gemspec don't have Gem::Specificaiton#extensions like:

Gem::Specification.new do |s|
  s.name = "json"
  s.version = Gem::Version.new("2.6.3")
  s.installed_by_version = Gem::Version.new("0")
  s.authors = ["Florian Frank"]
  s.date = Time.utc(2022, 12, 5)
  s.description = "This is a JSON implementation as a Ruby extension in C."
  s.email = "flori@ping.de"
  s.homepage = "http://flori.github.com/json"
  s.metadata = {"bug_tracker_uri"=>"https://github.com/flori/json/issues",
   "changelog_uri"=>"https://github.com/flori/json/blob/master/CHANGES.md",
   "documentation_uri"=>"http://flori.github.io/json/doc/index.html",
   "homepage_uri"=>"http://flori.github.io/json/",
   "source_code_uri"=>"https://github.com/flori/json",
   "wiki_uri"=>"https://github.com/flori/json/wiki"}
  s.require_paths = ["lib"]
  s.required_ruby_version = Gem::Requirement.new([">= 2.3"])
  s.rubygems_version = "3.4.0.dev"
  s.specification_version = 4
  s.summary = "JSON Implementation for Ruby"
  end

Because https://github.com/rubygems/rubygems/blob/master/lib/rubygems/specification.rb#L1607 is skip to this Gem::Specification#build_extensions and download, build, install after that.

But when we invoke gem i pkg/json-2.6.3.gem, we have LocalSpecification like:

[Activation request
  [LocalSpecification name: json version: 2.6.3 platform: ruby dependencies: [] source: /Users/hsbt/Documents/github.com/flori/json/pkg/json-2.6.3.gem]
   for [Dependency request  json (= 2.6.3)  requested by nil]]

This gemspec have full spec of Gem::Specification:

Gem::Specification.new do |s|
  s.name = "json"
  s.version = Gem::Version.new("2.6.3")
  s.installed_by_version = Gem::Version.new("0")
  s.authors = ["Florian Frank"]
  s.date = Time.utc(2023, 3, 3)
  s.description = "This is a JSON implementation as a Ruby extension in C."
  s.email = "flori@ping.de"
  s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb", "ext/json/extconf.rb"]
  s.extra_rdoc_files = ["README.md"]
  s.files = ["CHANGES.md",
   "LICENSE",
  # (snip)
   "lib/json/pure/parser.rb",
   "lib/json/version.rb"]
  s.homepage = "https://flori.github.io/json"
  s.licenses = ["Ruby"]
  s.metadata = {"bug_tracker_uri"=>"https://github.com/flori/json/issues",
   "changelog_uri"=>"https://github.com/flori/json/blob/master/CHANGES.md",
   "documentation_uri"=>"https://flori.github.io/json/doc/index.html",
   "homepage_uri"=>"https://flori.github.io/json",
   "source_code_uri"=>"https://github.com/flori/json",
   "wiki_uri"=>"https://github.com/flori/json/wiki"}
  s.rdoc_options = ["--title", "JSON implementation for Ruby", "--main", "README.md"]
  s.require_paths = ["/Users/hsbt/.local/share/gem/extensions/arm64-darwin-22/3.3.0+0-static/json-2.6.3", "lib"]
  s.required_ruby_version = Gem::Requirement.new([">= 2.3"])
  s.rubygems_version = "3.5.0.dev"
  s.specification_version = 4
  s.summary = "JSON Implementation for Ruby"
end

So, Gem::Specification#build_extensions try to build this spec despite there is no files of json-2.6.3.


I added guard condition to Gem::Specification#build_extensions for fullname of default gems.

Make sure the following tasks are checked

@hsbt hsbt force-pushed the fix-default-gems-installation branch 2 times, most recently from 56d6c85 to abe5ac8 Compare March 3, 2023 09:58
  Current implementation tried to build installation artifact. But default gems
  didn't provide normal gem files. So, It's always build failure.

  https://github.com/ruby/bigdecimal/actions/runs/4269574995/jobs/7432842788

    ERROR:  Error installing pkg/bigdecimal-3.1.4.gem:
    ERROR: Failed to build gem native extension.

    No such file or directory @ dir_s_mkdir - /Users/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/gems/bigdecimal-3.1.4/ext/bigdecimal/.gem.20230225-2301-2mul99

    Gem files will remain installed in /Users/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/gems/bigdecimal-3.1.4 for inspection.
    Results logged to /Users/runner/.rubies/ruby-head/lib/ruby/gems/3.3.0+0/extensions/x86_64-darwin-19/3.3.0+0/bigdecimal-3.1.4/gem_make.out
@hsbt hsbt force-pushed the fix-default-gems-installation branch from abe5ac8 to 2157aa8 Compare March 3, 2023 10:09
@deivid-rodriguez
Copy link
Contributor

Is this related to #6429?

@hsbt
Copy link
Member Author

hsbt commented Mar 3, 2023

Yes. But I think #6429 is correct behavior with current implementation. I fixed only broken behavior of C-ext gem and local installation. So, pure ruby gem, C-ext gem and remote installation are working fine.

We can consider skipping all of gem installation with same default gems version after this.

@hsbt
Copy link
Member Author

hsbt commented Mar 3, 2023

Ah, I only said a target gem like foo of gem install foo. If #6429 said "Do not fetch dependencies that are default gems", It may be bug of rubygems.

I'm not sure this PR fix #6429 yet.

@hsbt hsbt added this pull request to the merge queue Mar 5, 2023
Merged via the queue into master with commit 03a074e Mar 5, 2023
@hsbt hsbt deleted the fix-default-gems-installation branch March 5, 2023 23:52
hsbt added a commit to ruby/json that referenced this pull request Mar 8, 2023
hsbt added a commit to ruby/json that referenced this pull request Mar 8, 2023
hsbt added a commit to ruby/json that referenced this pull request Mar 8, 2023
deivid-rodriguez pushed a commit that referenced this pull request Mar 8, 2023
Fix installation error of same version of default gems with local installation

(cherry picked from commit 03a074e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants