Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Feature request/proposal: bundle why gem #5078

Closed
zverok opened this issue Oct 12, 2016 · 13 comments · Fixed by #5336
Closed

Feature request/proposal: bundle why gem #5078

zverok opened this issue Oct 12, 2016 · 13 comments · Fixed by #5336

Comments

@zverok
Copy link
Contributor

zverok commented Oct 12, 2016

Idea is borrowed from newly arrived YARN package manager. Shown, for example, in this twit

Idea is, something like that:

bundle why gemname
# output 1:
gemname 1.14 installed because required explicitly in Gemfile, group :development
# output 2:
gemname 1.14 installed because required by othergemname 2.03 (Gemfile, group :testing)
# more complicated:
gemname 1.14 installed because required by othergemname 2.03 => thirdone 0.19 => fourthgem 0.0.1 (Gemfile, group :runtime)
# and this one
gemname 1.14 installed because required by othergemname 2.03 (Gemfile, group :testing) and thirdone 0.19 (Gemfile, group :runtime)

Utterly naive implementation (not doing all what is proposed, just showing it is possible; also, really quickly dropped in bad Ruby) shown here

If an idea itself is acceptable (and I am not missing it is already possible/done), I can prepare proper PR with good design, specs and stuff.

@segiddins
Copy link
Member

This could also use the raw dependency graph that molinillo gives us at the end of resolution, or by following the graph that SpecSet holds, but at the end of the day this feels more like plugin functionality to me (and I'd personally prefer bundle explain, since it seems more verb-y to me)

@indirect
Copy link
Member

I like bundle explain and the idea of this as a plugin. To be super clear, though, you can already get this effect by opening your Gemfile.lock and then searching for the gem name. It will show up, indented, under any gem that requires it.

@zverok
Copy link
Contributor Author

zverok commented Oct 14, 2016

This could also use the raw dependency graph that molinillo gives us at the end of resolution, or by following the graph that SpecSet holds

Yep, I'll investigate the possibilities, first solution was just really the first way to it I've came up with (just to check there is enough information in internal structures to do it).

but at the end of the day this feels more like plugin functionality to me (and I'd personally prefer bundle explain, since it seems more verb-y to me)

I like bundle explain and the idea of this as a plugin.

Got it. Will do.

To be super clear, though, you can already get this effect by opening your Gemfile.lock and then searching for the gem name. It will show up, indented, under any gem that requires it.

Yep, of course I understand this. Just not geeky enough for me (too much manual work to quickly answer simple question).

@zverok
Copy link
Contributor Author

zverok commented Oct 14, 2016

Fix me if I am wrong: plugin system is still in development, right? Guessing from #3463 and http://bundler.io/whats_new.html#experimental-plugin-system?.. So, there are only some preliminary possibilities for writing plugins, are they documented anywhere?..

@indirect
Copy link
Member

indirect commented Dec 4, 2016

@zverok you can completely ignore the plugin system for now, and create a gem that installs the command bundle-explain. When your gem is installed and a user runs bundle explain foo, Bundler will look for bundle-explain in the $PATH, and exec to bundle-explain foo. 👍

@mjreed-wbd
Copy link

mjreed-wbd commented Dec 12, 2016

You can only use the Gemfile.lock if the bundle install succeeds. Otherwise, no lock, no dependency graph. I want to know why Bundler is even trying to install a given gem in the first place, but if that installation fails, I can't find that out.

If I'm wrong, please tell me so. But as far as I can tell, today, if I get a message from 'bundle install' that it fails because there is no compatible version of gem X, which is not in my Gemfile, the only way I can find out which of the gems in my Gemfile wind up ultimately requiring gem X is to somehow manage to get some permutation of the set of gems in my Gemfile to install successfully so that I can run [bundle exec] gem dependency.

@segiddins
Copy link
Member

If installation fails, the error message for the version conflict should be sufficient to explain why that dependency was included. If it is not, please open up a separate issue.

@indirect
Copy link
Member

@segiddins I believe this request is about gems that fail to install, after a successful resolution. e.g. “what why is it trying to install pgsql?! I don’t depend on that”

@markjreed
Copy link

@indirect exactly. resolution succeeds, but isn't documented in the Gemfile.lock because the actual install fails and aborts the installation. So the resolution is nowhere visible, and there is no way to determine why it was trying to install the gem that failed.

@segiddins
Copy link
Member

Thanks for the clarification! So it's really the "resolution succeeds" but actually installing a gem fails case, and we print "try seeing if gem install ... works", we should print the different gems that caused "foo" to be required in the first place. Is that correct?

@markjreed
Copy link

@segiddins Yes, that would be very helpful.

@segiddins
Copy link
Member

RuntimeError: install failed
An error occurred while installing activesupport (5.0.1), and Bundler cannot continue.
Make sure that `gem install activesupport -v '5.0.1'` succeeds before bundling.

In Gemfile:
  rails was resolved to 5.0.1, which depends on
    actioncable was resolved to 5.0.1, which depends on
      actionpack was resolved to 5.0.1, which depends on
        actionview was resolved to 5.0.1, which depends on
          rails-dom-testing was resolved to 2.0.2, which depends on
            activesupport

Would this sort of output be helpful?
(The example is a gemfile that contains rails, and installing activesupport has failed)

@markjreed
Copy link

Yes, that sort of output would be perfect!

bundlerbot added a commit that referenced this issue Feb 21, 2017
…rect

[ParallelInstaller] Print out why a gem needed to be installed if ins…

…tallation fails

I think this will close #5078 by making it easier to understand why a gem needed to be installed, especially in the case when the user can't just look in the lockfile
bundlerbot added a commit that referenced this issue Mar 11, 2017
…rect

[ParallelInstaller] Print out why a gem needed to be installed if ins…

…tallation fails

I think this will close #5078 by making it easier to understand why a gem needed to be installed, especially in the case when the user can't just look in the lockfile
philipefarias added a commit to dleemoo/rc-images that referenced this issue Jun 12, 2017
Changes since last version used (1.14.6):

== 1.15.1 (2017-06-02)

Bugfixes:

  - `bundle lock --update GEM` will fail gracefully when the gem is not in the lockfile (rubygems/bundler#5693, @segiddins)
  - `bundle init --gemspec` will fail gracefully when the gemspec is invalid (@colby-swandale)
  - `bundle install --force` works when the gemfile contains git gems (rubygems/bundler#5678, @segiddins)
  - `bundle env` will print well-formed markdown when there are no settings (rubygems/bundler#5677, @segiddins)

== 1.15.0 (2017-05-19)

This space intentionally left blank.

== 1.15.0.pre.4 (2017-05-10)

Bugfixes:

  - avoid conflicts when `Gem.finish_resolve` is called after the bundle has been set up (@segiddins)
  - ensure that `Gem::Specification.find_by_name` always returns an object that can have `#to_spec` called on it (rubygems/bundler#5592, @jules2689)

== 1.15.0.pre.3 (2017-04-30)

Bugfixes:

  - avoid redundant blank lines in the readme generated by `bundle gem` (@koic)
  - ensure that `open-uri` is not loaded after `bundle exec` (@segiddins)
  - print a helpful error message when an activated default gem conflicts with
    a gem in the gemfile (@segiddins)
  - only shorten `ref` option for git gems when it is a SHA (rubygems/bundler#5620, @segiddins)

== 1.15.0.pre.2 (2017-04-23)

Bugfixes:

  - ensure pre-existing fit caches are updated from remote sources (rubygems/bundler#5423, @alextaylor000)
  - avoid duplicating specs in the lockfile after updating with the gem uninstalled (rubygems/bundler#5599, @segiddins)
  - ensure git gems have their extensions available at runtime (rubygems/bundler#5594, @jules2689, @segiddins)

== 1.15.0.pre.1 (2017-04-16)

Features:

  - print a notification when a newer version of bundler is available (rubygems/bundler#4683, @segiddins)
  - add man pages for all bundler commands (rubygems/bundler#4988, @feministy)
  - add the `bundle info` command (@fredrb, @colby-swandale)
  - all files created with `bundle gem` comply with the bundler style guide (@zachahn)
  - if installing a gem fails, print out the reason the gem needed to be installed (rubygems/bundler#5078, @segiddins)
  - allow setting `gem.push_key` to set the key used when running `rake release` (@DTrierweiler)
  - print gem versions that are regressing during `bundle update` in yellow (rubygems/bundler#5506, @brchristian)
  - avoid printing extraneous dependencies when the resolver encounters a conflict (@segiddins)
  - add the `bundle issue` command that prints instructions for reporting issues (rubygems/bundler#4871, @jonathanpike)
  - add `--source` and `--group` options to the `bundle inject` command (rubygems/bundler#5452, @Shekharrajak)
  - add the `bundle add` command to add a gem to the gemfile (@denniss)
  - add the `bundle pristine` command to re-install gems from cached `.gem` files (rubygems/bundler#4509, @denniss)
  - add a `--parseable` option for `bundle config` (@JuanitoFatas, @colby-swandale)

Performance:

  - speed up gemfile initialization by storing locked dependencies as a hash (@jules2689)
  - speed up gemfile initialization by making locked dependency comparison lazy, avoiding object allocation (@jules2689)
  - only validate git gems when they are downloaded, instead of every time `Bundler.setup` is run (@segiddins)
  - avoid regenerating the lockfile when nothing has changed (@segiddins)
  - avoid diffing large arrays when no sources in the gemfile have changed (@segiddins)
  - avoid evaluating full gemspecs when running with RubyGems 2.5+ (@segiddins)

Bugfixes:

  - fix cases where `bundle update` would print a resolver conflict instead of updating the selected gems (rubygems/bundler#5031, rubygems/bundler#5095, @segiddins)
  - print out a stack trace after an interrupt when running in debug mode (@segiddins)
  - print out when bundler starts fetching a gem from a remote server (@segiddins)
  - fix `bundle gem` failing when `git` is unavailable (rubygems/bundler#5458, @Shekharrajak, @colby-swandale)
  - suggest the appropriate command to unfreeze a bundle (rubygems/bundler#5009, @denniss)
  - ensure nested calls to `bundle exec` resolve default gems correctly (rubygems/bundler#5500, @segiddins)
  - ensure that a plugin failing to install doesn't uninstall other plugins (@kerrizor, @roseaboveit)
  - ensure `socket` is required before being referenced (rubygems/bundler#5533, @rafaelfranca)
  - allow running `bundle outdated` when gems aren't installed locally (rubygems/bundler#5553, @segiddins)
  - print a helpful error when `bundle exec`ing to a gem that isn't included in the bundle (rubygems/bundler#5487, @segiddins)
  - print an error message when a non-git gem is given a `branch` option (rubygems/bundler#5530, @colby-swandale)
  - allow interrupts to exit the process after gems have been installed (@segiddins)
  - print the underlying error when downloading gem metadata fails (rubygems/bundler#5579, @segiddins)
  - avoid deadlocking when installing with a lockfile that is missing dependencies (rubygems/bundler#5378, rubygems/bundler#5480, rubygems/bundler#5519, rubygems/bundler#5526, rubygems/bundler#5529, rubygems/bundler#5549, rubygems/bundler#5572, @segiddins)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants