- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.8k
Description
Bundler Plugin System
The Bundler Plugin system allows a developer to integrate into certain points in Bundler's runtime. These include, at the time of writing, before-install, before-install-all, after-install, and after-install-all. There is also an option to add your own bundle commands like bundle viz.
Each of these points allows a plugin to interact with a Bundler::ParallelInstaller::SpecInstallation in the singular install options, and arrays of Bundler::Dependency objects in the -all options.
These provide users with the opportunities to modify the behaviour of bundle install to their heart's content.
I've seen two use cases in practice:
- https://github.com/jules2689/extended_bundler-errors : A bundlerplugin that makes gem installation errors more actionable, educative, and all around easier to understand
- https://github.com/shopify/bootboot: Bootboot is a Bundler plugin meant to help dual boot your ruby application.
The former was created by myself and is intended for a large audience (everyone), while the latter was created by Rafael Franca and Edouard Chin - of the Shopify Rails team - and is intended for an organization or project needing to run two versions of a gem at once.
Distribution
The 2 aforementioned plugins presents two different distribution systems. The first errors handling plugin is intended to be installed using bundler plugin install while the latter is intended to be listed in the Gemfile using the plugin "blah" stanza. Both methods have issues that I'll enumerate in this issue.
bundler plugin install
The issue here is that it assumes users know to run bundle plugin install. This is not muscle memory, particularly since there exists practically no plugin gems available for use.
Gemfile's plugin stanza
Once a Gemfile lists plugin in the stanza, it now has to evaluate every single time. bundle install causes the plugin to be install every single time. Likely because it is not added to the .bundle/plugin/index file.
A Common Problem
What plugins exist? In what ways can I extend Bundler? No one can answer these questions. It is up to the plugin developer to market their plugin gem, to little benefit. Many people have never heard of Plugins.
This is even listed here: https://github.com/bundler/bundler/issues/4682
Issues with the plugin index
- The plugin index lists all gems with a full path (https://github.com/bundler/bundler/issues/6943, partial fix in a Ruby Buildpack for Heroku is here: https://github.com/intercom/heroku-buildpack-ruby/pull/4).
- The plugin index can be located at multiple locations (as is normal with bundler), either in ./.bundle/plugins/indexor~/.bundle/plugin/index- it's not obvious what is where though
- The plugin index has an unbounded growth in the hooks section. Likewise if you install multiple versions of the same plugin, it does not get overwritten, it's simply appended.
commands: hooks: after-install: - "extended_bundler-errors" - "extended_bundler-errors" - "extended_bundler-errors" before-install-all: - "extended_bundler-errors" - "extended_bundler-errors" - "extended_bundler-errors" load_paths: extended_bundler-errors: - "/Users/juliannadeau/.bundle/plugin/gems/extended_bundler-errors-0.3.2/lib" - "/Users/juliannadeau/.bundle/plugin/gems/extended_bundler-errors-0.3.1/lib" plugin_paths: extended_bundler-errors: "/Users/juliannadeau/.bundle/plugin/gems/extended_bundler-errors-0.3.2" sources: 
- I've had users experience plugins being deleted at the path specified in the index, to which Bundler seems to have issues
Developing/Managing Plugins
- Paths do not work in the bundle plugin installcommand, but once installed in another way, it ends up in the index forever and just works (TM)~/src/github.com/jules2689/website(master*) ➜ bundle plugin install /Users/juliannadeau/src/github.com/jules2689/extended_bundler-errors Fetching gem metadata from https://rubygems.org/. Fetching gem metadata from https://rubygems.org/. Could not find gem '/Users/juliannadeau/src/github.com/jules2689/extended_bundler-errors' in any of the gem sources listed in your Gemfile. ~/src/github.com/jules2689/website(master*) ➜ bundle plugin install extended_bundler-errors Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Using bundler 1.17.2 Installing extended_bundler-errors 0.3.2 Installed plugin extended_bundler-errors
- You cannot uninstall plugins once installed (https://github.com/bundler/bundler/issues/5447)
- There are no way to manage or list plugins (Add bundle plugin listcommand rubygems/bundler#5467) despite alistcommand being added (Add plugin list command rubygems/bundler#6120), it does not work.~ ➜ bundle -v Bundler version 2.0.1 ~ ➜ bundle plugin list Could not find command "list".
Summary
There are 3 main categories to focus on:
- Technical Issues
- Distribution
- Management of Plugins
These 3 categories cause plugins to be more difficult to develop than needed (installing local plugins), difficult to use (technical issues and management), and difficult to find (distribution). This section aims to provide a list of requirements to start to remedy these issues.
Technical Issues
- Fix the full path issue in the plugin index
- Implement a more coherent way to handle the pluginindex, that is apparent and evident. Tell the user when a plugin is being installed that a plugin is "Installing globally" or "Installing locally"- pluginstanza goes to- .bundle/plugins/index
- bundle plugin installgoes to- ~/.bundle/plugins/indexunless- --localflag or something is set
 
- Make sure the index is not every growing in the hooks section
- Make sure that upgrading a plugin does not cause 2 entries of the same plugin (de-dupe the plugin paths)
- Make sure that the pluginstanza does not cause abundle installto always evaluate and does not prevent abundle checkfrom succeeding
Distribution
- On Rubygems.org, list a section for plugins. This can be determined by looking for a validplugin.rbfile in the base of the gem.
- Once that is determined, then allow users to search for the plugins and present the gem in a different show page than a standard gem
I don't expect wide adoption of plugins. It is likely to be a fragmented system, so we should be looking to see how a plugin affects the ecosystem and adopt the ones intended for all users into core where it makes sense.
Management of plugins
- Implement a bundle plugin uninstallcommand
- Implement, properly, a bundle plugin listcommand
- Make sure users do not have to touch the indexfile
- Allow path installs in the bundle plugin install(this should be local only, I'd think?)