Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix $LOAD_PATH in rake and ext_conf builder #6490

Merged
merged 4 commits into from
Mar 20, 2023
Merged

Fix $LOAD_PATH in rake and ext_conf builder #6490

merged 4 commits into from
Mar 20, 2023

Conversation

ntkme
Copy link
Contributor

@ntkme ntkme commented Mar 16, 2023

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

Installing gem with rake based extension which depends on a native gem (e.g. psych) that has more than one copies on the system (one comes default with ruby installation and one user installation) with the system rubygems can fail in a very strange way.

Reproduction: sinatra/sinatra#1911 (comment)
Explanation: sinatra/sinatra#1911 (comment)

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

Per previous PR related to this issue: #4165

I'm not sure using this -I parameter here is a good idea, so since I'm not sure I'm just keeping things as they are for now and fixing the bug.

Removing this flag caused one of the existing tests to be broken: https://github.com/rubygems/rubygems/actions/runs/4433225457/jobs/7778058872

Therefore, this PR removes it conditionally.

Make sure the following tasks are checked

@ntkme ntkme changed the title Remove rubygems path in rake builder Make sure native extension are loaded correctly in rake builder Mar 16, 2023
@ntkme ntkme changed the title Make sure native extension are loaded correctly in rake builder Make sure native extensions are loaded correctly in rake builder Mar 16, 2023
@deivid-rodriguez
Copy link
Member

Hi! Thanks so much! You could've just moved on by upgrading RubyGems, but you fixed the root cause 😍.

Could you add a test for this?

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

Could you add a test for this?

I'd be happy to. The case is so specific that I'm not sure how to write it / where to put it:

  1. It has to be a default installation of rubygems that comes with ruby, as gem update --system will change the behavior so the bug is no longer reproducible.
  2. It has to install a second copy of a dependency gem (e.g. psych) that already comes with ruby and the version of second installation needs to be different enough so that the linking between the ruby code and native ext could break.
  3. The Rakefile in the gem being installed needs to use that the dependency gem.

@deivid-rodriguez If you can give me some pointer to maybe a similar test case we have currently, I can try come up with a test case.

@deivid-rodriguez
Copy link
Member

I was thinking of something similar to the one added by #4165, but this seems much more specific, indeed.

For this kind tricky tests I normally use realworld testing like the commands run in .github/workflows/install-rubygems.yml. But that requires manually installing RubyGems first, which does not have the same structure as the RubyGems bundled with a pristine version of Ruby.

How are you testing that the fix works? Directly editing the RubyGems copy included with Ruby?

Anyways, yeah, too hard to get this tested, I think it's fine as is.

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

How are you testing that the fix works? Directly editing the RubyGems copy included with Ruby?

Exactly, I start with a ruby 3.0 container which I used in the reproduction, manually apply the patch to the default rubygems, and confirmed that it fixed the problem.

@deivid-rodriguez
Copy link
Member

This is a ruby-core specific thing, not a RubyGems thing, so I found a little discrepancy. On my laptop:

$ find /Users/deivid/.asdf/installs/ruby/3.2.1/lib/ruby/3.2.0/ -type d -depth 1 -name 'arm*'
/Users/deivid/.asdf/installs/ruby/3.2.1/lib/ruby/3.2.0//arm64-darwin22

$ ruby -e 'puts Gem::Platform.local'                               
arm64-darwin-22

$ ruby -e 'puts RUBY_PLATFORM'                                     
arm64-darwin22

So it sounds like we want the latter.

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

Oh wow. On linux it was the same. Let me update the PR.

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

RbConfig::CONFIG['rubyarchdir'] this is it

@ntkme
Copy link
Contributor Author

ntkme commented Mar 16, 2023

@deivid-rodriguez Sorry for lots of back and forth changing the PR. I think now I have the most clean and robust solution:

If rubygems' install location is not present in the default $LOAD_PATH, we add it. - This happens in the rubygems development and test.
If rubygems' install location is present in $LOAD_PATH, just don't add it. - This happens for normal users. The $LOAD_PATH order won't change and we're good.

@ntkme ntkme changed the title Make sure native extensions are loaded correctly in rake builder Make sure native extensions are loaded correctly in rake and ext_conf builder Mar 17, 2023
@hsbt
Copy link
Member

hsbt commented Mar 17, 2023

@ntkme Wait to push for re-run tests. We reached to limit of macOS jobs.

see #6504

@hsbt
Copy link
Member

hsbt commented Mar 17, 2023

Can you rebase this from 7e5fbea? Thanks.

@deivid-rodriguez
Copy link
Member

@ntkme Nice, your solution makes sense to me! Should we move this common logic to the base ext builder?

@ntkme
Copy link
Contributor Author

ntkme commented Mar 17, 2023

@deivid-rodriguez Refactored. I also noticed that there is some inconsistency on the usage of Gem.ruby as it maybe a quoted string. The format of Gem.ruby shall be interpreted as a shell command string instead of a path (the documentation is somewhat misleading)... Therefore, we should shellsplit it. - Today, it already uses shellsplit in ExtConfBuilder but not in RakeBuilder.

rubygems/lib/rubygems.rb

Lines 791 to 802 in 06f8526

##
# The path to the running Ruby interpreter.
def self.ruby
if @ruby.nil?
@ruby = RbConfig.ruby
@ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
end
@ruby
end

@ntkme ntkme changed the title Make sure native extensions are loaded correctly in rake and ext_conf builder Fix $LOAD_PATH in rake and ext_conf builder Mar 17, 2023
Copy link
Member

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for your work!

@deivid-rodriguez deivid-rodriguez added this pull request to the merge queue Mar 17, 2023
@ntkme
Copy link
Contributor Author

ntkme commented Mar 17, 2023

Looks like merge queue check failed due to flakiness of #6512. Not sure if any action is required.

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 17, 2023
@deivid-rodriguez
Copy link
Member

I'm merging the PR fixing the flaky failure and then will merge this one. No action needed @ntkme, thanks for your work!

@deivid-rodriguez deivid-rodriguez added this pull request to the merge queue Mar 20, 2023
@deivid-rodriguez deivid-rodriguez changed the title Fix $LOAD_PATH in rake and ext_conf builder Fix $LOAD_PATH in rake and ext_conf builder Mar 20, 2023
@deivid-rodriguez deivid-rodriguez merged commit 653ee82 into rubygems:master Mar 20, 2023
@ntkme ntkme deleted the remove-rubygems-path-in-rake-builder branch March 20, 2023 16:04
deivid-rodriguez added a commit that referenced this pull request Mar 20, 2023
Fix $LOAD_PATH in rake and ext_conf builder

(cherry picked from commit 653ee82)
yahonda added a commit to yahonda/oracle-enhanced that referenced this pull request Sep 28, 2023
casperisfine pushed a commit to casperisfine/json that referenced this pull request Oct 25, 2024
Ref: ruby#647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20
casperisfine pushed a commit to casperisfine/json that referenced this pull request Oct 25, 2024
Ref: ruby#647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20
byroot added a commit to ruby/json that referenced this pull request Oct 25, 2024
Ref: #647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20
hsbt pushed a commit to hsbt/ruby that referenced this pull request Oct 26, 2024
Ref: ruby/json#647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20

ruby/json@1f5e849fe0
hsbt pushed a commit to hsbt/ruby that referenced this pull request Oct 26, 2024
Ref: ruby/json#647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20

ruby/json@1f5e849fe0
hsbt pushed a commit to ruby/ruby that referenced this pull request Oct 26, 2024
Ref: ruby/json#647
Ref: rubygems/rubygems#6490

Older rubygems are executing `extconf.rb` with a broken `$LOAD_PATH`
causing the `json` gem native extension to be loaded with the stdlib
version of the `.rb` files.

This fails with

```
json/common.rb:82:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
```

Since this is just for `extconf.rb` we can probably just accept that
extra argument and ignore it.

The bug was fixed in rubygems 3.4.9 / 2023-03-20

ruby/json@1f5e849fe0
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