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

1.16.0 is intercepting binstub arguments and throwing 'unknown switches' error #6149

Closed
johnmcdowall opened this issue Nov 3, 2017 · 14 comments

Comments

@johnmcdowall
Copy link

I've just created a new Rails project with bundler 1.16.0, and when trying to invoke the webpack binstub with command line arguments for the underlying executable, Bundler is throwing the message 'unknown switches':

$ ./bin/webpack --colors --progress
Unknown switches '--colors, --progress'

This did not / does not happen with 1.15.x Bundler.

I would expect that binstub command line arguments should still be proxied through to the underlying executable? I can find no documentation or issues that would suggest this chnge in behaviour was wanted.

@johnmcdowall
Copy link
Author

It seems this change: https://github.com/bundler/bundler/blob/01fe509b27b317dd4d640beb9140ab31331ea349/lib/bundler/templates/Executable#L11-L12

Is responsible for the change in behaviour? Is this needed?

@johnmcdowall
Copy link
Author

Confirmed, removing those two lines from my binstubs restores the correct behaviour of proxying command line arguments along to the underlying executable.

Removing them also seems to have no detrimental effect?

@colby-swandale
Copy link
Member

I was able to reproduce this, thanks for the report!

@segiddins
Copy link
Member

This shouldn't be happening, since we only old the "real" bundler exe when that file is invoked directly: https://github.com/bundler/bundler/blob/892a637f2d9bf18b9898ea31d4f5bf8d1e8cb8e4/lib/bundler/templates/Executable.bundler#L103-L105

@mattbrictson
Copy link
Contributor

I just ran into this problem as well.

This happens to me in Rails, because out of the box rails new generates the following bin/bundle binstub:

#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')

When I generate a binstub manually, the new binstub doesn't work:

$ bundle binstub unicorn
$ bin/unicorn -E development
Unknown switches '-E'

The fix is to regenerate bundler's binstub:

$ bundle binstub bundler --force
$ bin/unicorn -E development
I, [2017-11-11T14:59:40.867225 #93138]  INFO -- : listening on addr=0.0.0.0:8080 fd=9
I, [2017-11-11T14:59:40.867334 #93138]  INFO -- : worker=0 spawning...
I, [2017-11-11T14:59:40.868225 #93138]  INFO -- : master process ready
I, [2017-11-11T14:59:40.868991 #93151]  INFO -- : worker=0 spawned pid=93151
I, [2017-11-11T14:59:40.869413 #93151]  INFO -- : Refreshing Gem list
I, [2017-11-11T14:59:42.193645 #93151]  INFO -- : worker=0 ready

I suspect that this will commonly be a problem even for non-Rails projects. E.g., if you started the project before bundler 1.16.0 was released, you have the pre-1.16.0 bin/bundle binstub. If you upgrade bundler to 1.16.0 and then generate a new binstub, you will encounter this error.

@guilleiguaran
Copy link

Also reported in Rails issue tracker: rails/rails#31193

Looks like many existing Rails users are going to experience this problem.

idoru added a commit to cloudfoundry/ruby-buildpack that referenced this issue Nov 22, 2017
- Regenerates bundler binstub to account for incompatibility with Rails
generated ones. See:
   * rails/rails#31193
   * rubygems/bundler#6149
- binstubs get correct path via BUNDLE_GEMFILE instead of us rewriting them

[#152452239]

Signed-off-by: Victoria Henry <vhenry@pivotal.io>
@indirect
Copy link
Member

indirect commented Nov 26, 2017

@mattbrictson thanks for the heads up! Just so things are clear, this is not an upgrade issue for Bundler. Bundler 1.15 refused to create a binstub for itself:

$ bundle _1.15.4_ binstubs bundler
Resolving dependencies...
Sorry, Bundler can only be run via Rubygems.

Bundler 1.16 started to support a bundle binstub as a first step towards letting applications quickly load the correct version of Bundler for that application.

I'm not sure how long Rails has been creating a bin/bundle, but it's definitely not a Bundler binstub. To resolve this, we might need to start throwing an informative exception if bin/bundle is the wrong kind of binstub.

@adamof
Copy link

adamof commented Nov 27, 2017

I can confirm that this is a problem with other executables as well. For example sidekiq:

$ gem install bundler
Fetching: bundler-1.16.0.gem (100%)
Successfully installed bundler-1.16.0
1 gem installed
$ bundle version
Bundler version 1.16.0 (2017-10-31 commit 10f20fa33)
$ bundle binstubs sidekiq
$ bin/sidekiq -C config/sidekiq.yml
Unknown switches '-C'

@mattbrictson
Copy link
Contributor

@indirect Understood that the bin/bundle that Rails has been distributing is not a Bundler binstub. The reason I brought this up as an upgrade issue for Bundler is that as @johnmcdowall mentioned, binstubs generated by Bundler 1.16 now contain this code:

bundle_binstub = File.expand_path("../bundle", __FILE__) 
load(bundle_binstub) if File.file?(bundle_binstub)

So before, the binstubs generated by Bundler 1.15 and below would be oblivious to the bin/bundle provided by Rails. But now the binstubs generated by Bundler 1.16 explicitly look for bin/bundle and load it, which leads to the problem.

Perhaps, as you said, Bundler needs to identify this and fail with a helpful error message. For example, it could work like this:

$ bundle binstubs sidekiq
An outdated bin/bundle executable was detected and this command cannot continue.
Run `bundle binstubs bundler --force` to correct this.

@indirect
Copy link
Member

@mattbrictson yep, that's close to what I was imagining. I think we'll probably need to do something like this, to ensure that a bad bin/bundle fails in a predictable way:

def bundle_stub?(path)
    return false unless File.file?(path)
    return true if File.read(path, 150) =~ /This file was generated by Bundler/
    abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end

bundle_binstub = File.expand_path("../bundle", __FILE__)
load(bundle_binstub) if bundle_stub?(bundle_binstub)

@mattbrictson
Copy link
Contributor

@indirect that looks like a good solution 👍

hsbt added a commit to hsbt/bundler that referenced this issue Dec 4, 2017
hsbt added a commit to hsbt/bundler that referenced this issue Dec 5, 2017
camelpunch added a commit to alphagov/paas-admin that referenced this issue Dec 6, 2017
Without this change, bundler generate bad binstubs that don't accept
arguments.

Upstream issue: rubygems/bundler#6149
camelpunch added a commit to alphagov/paas-admin that referenced this issue Dec 6, 2017
Without this change, bundler generate bad binstubs that don't accept
arguments.

Upstream issue: rubygems/bundler#6149
chrisfarms pushed a commit to alphagov/paas-admin that referenced this issue Dec 7, 2017
Without this change, bundler generate bad binstubs that don't accept
arguments.

Upstream issue: rubygems/bundler#6149
bundlerbot added a commit that referenced this issue Dec 11, 2017
Show warning message about binstub outside generation.

/cc @indirect

Fixes #6149.

Originated from #6149 (comment)
hsbt pushed a commit to hsbt/bundler that referenced this issue Dec 11, 2017
Show warning message about binstub outside generation.

/cc @indirect

Fixes rubygems#6149.

Originated from rubygems#6149 (comment)
@hsbt hsbt removed this from the 1.16.1 milestone Dec 12, 2017
zspencer added a commit to cohere-coop/nourish.party that referenced this issue Dec 18, 2017
Apparently, Rails creates a `bin/bundle` file that ensures all the gems
are installed (yay!) but in doing so, intercepts the flags and arguments
improperly (boo :()

This switches us to use the bundler generated bundler binstub, which
works better, per: rubygems/bundler#6149
zspencer added a commit to cohere-coop/nourish.party that referenced this issue Dec 18, 2017
Apparently, Rails creates a `bin/bundle` file that ensures all the gems
are installed (yay!) but in doing so, intercepts the flags and arguments
improperly (boo :()

This switches us to use the bundler generated bundler binstub, which
works better, per: rubygems/bundler#6149
flavorjones added a commit to jbarnette/hoe-debugging that referenced this issue Feb 4, 2018
see rubygems/bundler#6149 for the change that
is breaking our build
atcruice added a commit to thelookoutway/robin that referenced this issue Mar 12, 2018
- Also update to Rails 5 binstubs (except bundler
rubygems/bundler#6149)
atcruice added a commit to thelookoutway/robin that referenced this issue Mar 14, 2018
- Also update to Rails 5 binstubs (except bundler
rubygems/bundler#6149)
atcruice added a commit to thelookoutway/robin that referenced this issue Mar 14, 2018
- Also update to Rails 5 binstubs (except bundler
rubygems/bundler#6149)
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Mar 14, 2018
## 1.16.1 (2017-12-12)

Bugfixes:

  - avoid hanging on complex resolver errors ([#6114](rubygems/bundler#6114), @halfbyte)
  - avoid an error when running `bundle update --group` ([#6156](rubygems/bundler#6156), @mattbrictson)
  - ensure the resolver prefers non-pre-release gems when possible ([#6181](rubygems/bundler#6181), @greysteil)
  - include bundler's gemspec in the built gem ([#6165](rubygems/bundler#6165), @dr-itz)
  - ensure locally installed specs are not overriden by those in remote sources during dependency resolution ([#6072](rubygems/bundler#6072), @indirect)
  - ensure custom gemfiles are respected in generated binstubs (@pftg)
  - fail gracefully when loading a bundler-generated binstub when `bin/bundle` was not generated by bundler ([#6149](rubygems/bundler#6149), @hsbt)
  - allow `bundle init` to be run even when a parent directory contains a gemfile ([#6205](rubygems/bundler#6205), @colby-swandale)

## 1.16.0 (2017-10-31)

Bugfixes:

  - avoid new RubyGems warning about unsafe YAML loading (to keep output consistent) (@segiddins)
  - load digest subclasses in a thread-safe manner (@segiddins, @colby-swandale)
  - avoid unusued variable warnings under ruby 2.5 (@amatsuda)
  - fix printing the same message twice in verbose mode ([#6028](rubygems/bundler#6028), @akhramov)
  - allow `SignalException`s to bubble up to the interpreter during `bundle exec` ([#6090](rubygems/bundler#6090), @dekellum)
  - avoid activating stdlib digest under Ruby 2.5 (@segiddins)
  - prioritise explicitly requested gems in dependency resolution sort order (@segiddins)
  - reduce memory usage during dependency resolution ([#6114](rubygems/bundler#6114), @greysteil)
  - ensure that the default bundler gem is not accidentally activated on ruby 2.5 when using local git overrides (@segiddins)

## 1.16.0.pre.3 (2017-10-04)

Features:

  - the output from `bundle env` includes more information, particularly both the compiled & loaded versions of OpenSSL (@indirect)

Bugfixes:

  - fix a bug where installing on FreeBSD would accidentally raise an error (#6013, @olleolleolle)
  - fix a regression in 1.16 where pre-release gems could accidentally be resolved even when the gemfile contained no pre-release requirements (@greysteil)
  - bundler will avoid making unnecessary network requests to fetch dependency data, fixing a regression introduced in 1.16 (@segiddins)
  - the outdated bundler version message is disabled by default until the message has been fine-tuned (#6004, @segiddins)

## 1.16.0.pre.2 (2017-09-06)

Bugfixes:

  - handle when a connection is missing a socket when warning about OpenSSL version (@greysteil)
  - the description for the `rake release` task now reflects `$RUBYGEMS_HOST` (@wadetandy)
  - fix a bug where `bundle update` would regress transitive dependencies (@greysteil)

## 1.16.0.pre.1 (2017-09-04)

Features:

  - allow using non-branch symbolic refs in a git source (#4845, @segiddins)
  - allow absolute paths in the `cache path` setting (#5627, @mal)
  - gems created via `bundle gem` with rspec have `--require spec_helper` in their `.rspec` file (@koic)
  - `bundle env` includes `Gem.ruby` and the `bundle` binstub shebang when they don't match (#5616, @segiddins)
  - allow passing gem names to `bundle pristine` (@segiddins)
  - `bundle version` and `bundle env` include the commit and build date for the bundler gem (#5049, @segiddins)
  - add the `--shebang` option to `bundle binstubs` (#4070, @segiddins, @zorbash)
  - gemfiles are `eval`ed one fewer time when running `bundle install` (#4952, #3096, #4417, @segiddins)
  - the `fileutils` gem is now vendored so different versions of the gem can be activated (@segiddins)
  - speed up no-op installations (#5842, @segiddins)
  - default to keeping the lockfile in the default gem template (@deivid-rodriguez)
  - add a special bundler binstub that ensures the correct version of bundler is activated (#5876, @segiddins)
  - speed up dependency resolution and ensure that all resolvable gemfiles can be installed (@segiddins, @greysteil)
  - add a `bundle list` command that prints the gems in use (#4754, @colby-swandale)
  - allow adding credentials to a gem source during deployment when `allow_deployment_source_credential_changes` is set (@adrian-gomez)
  - making an outdated (and insecure) TLS connection to rubygems.org will print a warning (@segiddins)

Bugfixes:

  - allow configuring a mirror fallback timeout without a trailing slash (#4830, @segiddins)
  - fix handling of mirrors for file: urls that contain upper-case characters (@segiddins)
  - list the correct gem host for `rake release` when `allowed_push_host` has been set (@mdeering)
  - ensure `Bundler.original_env` preserves all env keys that bundler sets (#5700, @segiddins)
  - ensure `bundle pristine` removes files added to a git gem (@segiddins)
  - load plugin files from path gems before gem installation (#5429, @segiddins)
  - ensure gems containing manpages are properly set up (#5730, @segiddins)
  - avoid fetching remote specs when all effected gems are in groups that are not being installed (@segiddins)
  - allow `BUNDLE_GEMFILE` to be a relative path (#5712, @gxespino)
  - show a more helpful error message when a gem fails to install due to a corrupted lockfile (#5846, @segiddins)
  - add a process lock to allow multiple concurrent `bundle install`s (#5851, @stefansedich)
  - ensure that specifications always return an array for `#extensions` (@greysteil)
  - print a helpful error message when using a gem in the Gemfile with an empty name (@colby-swandale)
  - ensure that all gemfiles are included in `bundle env` (@segiddins)
  - use ssl client cert and ca cert settings from gem configuration as fallbacks (@stan3)
  - avoid global namespace pollution when loading gems (#5958, @shyouhei)
  - avoid running a complete re-resolve on `bundle update --bundler` (@segiddins)
  - allow `bundle binstubs --standalone` to work without `path` being set (@colby-swandale)
  - fix support for bundle paths that include jars or wars on jruby (#5975, @torcido)
@paddor
Copy link

paddor commented Apr 12, 2019

I'm having this issue with Bundler version 2.0.1 (2019-01-04 commit d7ad2192f).
The switches --name-only, --without-group, and --only-group are unknown. Only --paths works.

which bundle just prints /home/p/.gem/ruby/2.6.2/bin/bundle, which is where I installed Ruby using ruby-install. The header in the file itself says it was generated by RubyGems.

Any ideas?

@deivid-rodriguez
Copy link
Member

You mean with bundle list, right? The problem is that the help that documents those options is for the new list command, that it's yet to be released. That has been fixed in #7072, and will be released with the next version.

@paddor
Copy link

paddor commented Apr 14, 2019

Yes, I meant bundle list. Is there another way to just list the gems in a particular group?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants