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

Respect --no-install option for git: sources #6088

Conversation

KJTsanaktsidis
Copy link
Contributor

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

Currently, the --no-install option to bundle package is totally ignored for git sources. This can have very strange effects if you have:

  • a git-sourced gem,
  • with native extensions,
  • whose extconf.rb script depends on another gem,
  • which is installed from Rubygems in the gemfile.

In that circumstance, bundle package --no-install --all will download the Rubygems dependencies to vendor/cache but NOT install them. It will also check out the git gems to vendor/cache (good), and attempt to build their native extensions (bad!).

The native extension build will fail because the extconf.rb script crashes, since the dependency it needs is missing.

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

I implemented a fix for this in source/git.rb as an early return if Bundle.settings[:no_install], since this is analogous to what's happening in source/rubygems.rb.

I do admit though the whole thing is a little strange though - an "install" method that.... proceeds to look at a global flag to not install anything.

At this point, if you think this is the right solution for the problem, I can whip up a test and then get this merged. If you think there's a better way to factor this package functionality though I'm all ears.

Make sure the following tasks are checked

@welcome
Copy link

welcome bot commented Nov 30, 2022

Thanks for opening a pull request and helping make RubyGems and Bundler better! Someone from the RubyGems team will take a look at your pull request shortly and leave any feedback. Please make sure that your pull request has tests for any changes or added functionality.

We use GitHub Actions to test and make sure your change works functionally and uses acceptable conventions, you can review the current progress of GitHub Actions in the PR status window below.

If you have any questions or concerns that you wish to ask, feel free to leave a comment in this PR or join our #rubygems or #bundler channel on Slack.

For more information about contributing to the RubyGems project feel free to review our CONTRIBUTING guide

@deivid-rodriguez
Copy link
Member

I think the underlying root cause of this is related to #3204?

@KJTsanaktsidis
Copy link
Contributor Author

KJTsanaktsidis commented Dec 4, 2022

oof. That issue seems like a lot. Sorry you had to deal with that ❤️

So yeah, @thedanbob already noticed this: #3204 (comment)

I figured out why the test didn't fail: bundle cache --no-install actually does install git gems (and only git gems), and to the correct location of vendor/bundle/ruby/2.5.0/bundler/gems/. So there's no "Fetching' in the later bundle install because it's already installed!

I guess I should open another issue for bundle cache not respecting the --no-install flag for git gems


I think fixing the "the install path is the same as the cache path" is a necessary but not sufficient condition. If my reading of what the rubygems source is doing is correct, this is what I think the expected behaviour should be...

(apologies in advance for my wording here, I'm not too familiar with the correct Rubygems terminology)

For bundle install:

  • Normally: Do a bare clone of the git repo from the remote to the system cache directory
  • If --local is passed in: Assume there is a bare clone in the vendor/cache or system cache directory already
  • git clone the gem from the bare clone to the install path (which will be either the system path or a path from the --path setting). Check out the correct ref.
  • Build native extensions - this is done by cd'ing into the system gem path (or --path setting) and doing the ruby extconf.rb; make dance. (but see below!). Native extensions (that weren't precompiled) should never wind up in vendor/cache
  • The .git directory is then deleted (not sure about this - but it seems like we could, because we know for sure the ref that was checked out from the directory name, and apparently from that issue I take it people don't want to copy large .git directories in situations where they're building gems on one machine and copying them to another)

For bundle exec:

  • The installed path of the gem, either from the system directory of from the --path setting, should be added to $LOAD_PATH. The vendor/cache or system cache directory should NOT be added there.

For bundle cache:

  • Nothing should happen unless the --all setting is present.
  • The bare clone should be copied from the system cache dir to vendor/cache (or cloned there, if it wasn't already in the system cache dir).
  • If --no-install is present, stop here
  • Otherwise, proceed with the install steps - git clone the gem from vendor/cache to the --path setting or system gem dir, and build native extensions in that location as for bundle install.

Sound about right?


Question about native gems:

AFAICT native extensions installed by bundler wind up in two places - both in ruby/x.y.0/gems/$GEM_NAME/lib/ and ruby/x.y.0/extensions/$PLATFORM/x.y.0/$GEM_NAME/. Both seem to get added to $LOAD_PATH:

kj@kj-thinkpad p % find vendor/ -iname '*.so'
vendor/bundle/ruby/3.0.0/gems/puma-6.0.0/ext/puma_http11/puma_http11.so
vendor/bundle/ruby/3.0.0/gems/puma-6.0.0/lib/puma/puma_http11.so
vendor/bundle/ruby/3.0.0/gems/nio4r-2.5.8/ext/nio4r/nio4r_ext.so
vendor/bundle/ruby/3.0.0/gems/nio4r-2.5.8/lib/nio4r_ext.so
vendor/bundle/ruby/3.0.0/extensions/x86_64-linux/3.0.0/puma-6.0.0/puma/puma_http11.so
vendor/bundle/ruby/3.0.0/extensions/x86_64-linux/3.0.0/nio4r-2.5.8/nio4r_ext.so

irb(main):005:0> $LOAD_PATH
=>
["/home/kj/.rbenv/rbenv.d/exec/gem-rehash",
 "/home/kj/p/vendor/bundle/ruby/3.0.0/gems/puma-6.0.0/lib",
 "/home/kj/p/vendor/bundle/ruby/3.0.0/extensions/x86_64-linux/3.0.0/puma-6.0.0",
 "/home/kj/p/vendor/bundle/ruby/3.0.0/gems/nio4r-2.5.8/lib",
 "/home/kj/p/vendor/bundle/ruby/3.0.0/extensions/x86_64-linux/3.0.0/nio4r-2.5.8",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/gems/3.0.0/gems/bundler-2.2.33/lib",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/site_ruby/3.0.0",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/site_ruby/3.0.0/x86_64-linux",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/site_ruby",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/vendor_ruby/3.0.0",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/vendor_ruby/3.0.0/x86_64-linux",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/vendor_ruby",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/3.0.0",
 "/home/kj/.rbenv/versions/3.0.4/lib/ruby/3.0.0/x86_64-linux"]

Should they actually wind up in both places? Any idea what's going on here?


Question about --deployment:

Does the --deployment mode do anything other than imply --local --path vendor/bundle? That's my reading of the doc, but I'm not 100% sure (we don't use this at $DAYJOB because we ship docker images...)

@KJTsanaktsidis
Copy link
Contributor Author

@deivid-rodriguez - any thoughts on the above? If I'm on the right track there I'll definitely try and contribute a patch.

@deivid-rodriguez
Copy link
Member

@KJTsanaktsidis Sorry for the lack of feedback! Let's start with this patch, which seems correct and indeed a related but separate issue.

More issues with caching git sources should get fixed by #4469. Once we introduced the fix here and that PR we can reevaluate if there's still anything missing/incorrect.

Can you add a test for this patch? You can find related specs at bundler/spec/commands/cache_spec.rb.

@KJTsanaktsidis KJTsanaktsidis force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch 3 times, most recently from a944145 to 90b75ef Compare January 4, 2023 06:06
@KJTsanaktsidis
Copy link
Contributor Author

Hey @deivid-rodriguez, @Julzerator and I put our heads together in the new year and put together a test for this fix. PTAL - thanks!

@deivid-rodriguez deivid-rodriguez force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch from 90b75ef to 7812ec7 Compare January 5, 2023 15:43
@deivid-rodriguez
Copy link
Member

Hei @KJTsanaktsidis, thanks for working on this.

That spec seems to also pass without the fix in this PR. Can you write it so that it fails without this change, and passes with it?

@deivid-rodriguez
Copy link
Member

@KJTsanaktsidis still interested?

@KJTsanaktsidis KJTsanaktsidis force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch 2 times, most recently from 8330086 to 90ffe4b Compare March 3, 2023 01:47
@KJTsanaktsidis
Copy link
Contributor Author

Sorry @deivid-rodriguez - this totally fell off my radar. I think I wrote a much better test now, WDYT?

@KJTsanaktsidis KJTsanaktsidis force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch from 90ffe4b to 2e7b677 Compare March 3, 2023 01:52
@deivid-rodriguez deivid-rodriguez force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch 2 times, most recently from a70919d to e720646 Compare March 3, 2023 10:58
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.

Looks great! Thanks for the thorough comments and test, hopefully we can remove the second comment block once #4469 is out!

@deivid-rodriguez
Copy link
Member

Ooops, unfortunately the spec needs to be adapted to also work in "bundler 3" mode, where Bundler will install to .bundle by default, not to the default GEM_HOME. I think you can use the default_bundle_path helper for this.

auto-merge was automatically disabled March 5, 2023 23:01

Head branch was pushed to by a user without write access

@KJTsanaktsidis KJTsanaktsidis force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch from e720646 to 2c7c8d1 Compare March 5, 2023 23:01
@KJTsanaktsidis
Copy link
Contributor Author

OK, think I got it working - should be good to go when you run the workflow. Thanks!

@deivid-rodriguez deivid-rodriguez force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch from 2c7c8d1 to 5bb9bfa Compare March 7, 2023 18:33
Currently, the --no-install option to `bundle package` is totally
ignored for git sources. This can have very strange effects if you have:

- a git-sourced gem,
- with native extensions,
- whose extconf.rb script depends on another gem,
- which is installed from Rubygems in the gemfile.

In that circumstance, `bundle package --no-install --all` will download
the Rubygems dependencies to `vendor/cache` but NOT install them. It
will also check out the git gems to `vendor/cache` (good), and attempt
to build their native extensions (bad!).

The native extension build will fail because the extconf.rb script crashes,
since the dependency it needs is missing.

I implemented a fix for this in `source/git.rb`, since this is analogous
to what's happening in `source/rubygems.rb`. I do admit though the whole
thing is a little strange though - an "install" method that.... proceeds
to look at a global flag to not install anything.

Add test to confirm cache respects the --no-install flag

Co-authored-by: KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au>
@deivid-rodriguez deivid-rodriguez force-pushed the ktsanaktsidis/dont_install_git_gems_with_noinstall branch from 5bb9bfa to 5a77d1c Compare March 7, 2023 18:35
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.

It seems good now. There were two lint issues but I fixed them myself to not delay this fix anymore!

@deivid-rodriguez deivid-rodriguez added this pull request to the merge queue Mar 7, 2023
Merged via the queue into rubygems:master with commit 5272c1e Mar 7, 2023
@KJTsanaktsidis
Copy link
Contributor Author

Great, thanks for your help, sorry it took me so long!

@deivid-rodriguez
Copy link
Member

Thanks to you for the fix!

deivid-rodriguez added a commit that referenced this pull request Mar 8, 2023
…ll_git_gems_with_noinstall

Respect --no-install option for git: sources

(cherry picked from commit 5272c1e)
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.

None yet

3 participants