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

Commit

Permalink
Add Bundler.system_bindir, defaulted to Gem.bindir
Browse files Browse the repository at this point in the history
This allows users to tell Bundler where to put the binstubs for system gems, much like the -n option in ~/.gemrc for Rubygems. If you set one, it probably makes sense to set the other. If you don't set system_bindir, though, Bundler will install system binstubs into Gem.bindir, regardless of what Rubygems does.

refs #1417
  • Loading branch information
indirect committed Sep 24, 2011
1 parent d02fa27 commit af6badf
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 17 deletions.
11 changes: 10 additions & 1 deletion lib/bundler.rb
Expand Up @@ -219,13 +219,22 @@ def default_lockfile
SharedHelpers.default_lockfile
end

def system_bindir
# Gem.bindir doesn't always return the location that Rubygems will install
# system binaries. If you add a '-n foo' option to your .gemrc, Rubygems will
# install binstubs there instead. Unfortunately, Rubygems doesn't expose
# that directory at all, so rather than parse .gemrc ourselves, we allow
# the directory to be set as well, via `bundle config bindir foo`.
Bundler.settings[:system_bindir] || Gem.bindir
end

def requires_sudo?
return @requires_sudo if defined?(@checked_for_sudo)

path = bundle_path
path = path.parent until path.exist?
sudo_present = !(`which sudo` rescue '').empty?
bin_dir = Pathname.new(Bundler.rubygems.gem_bindir)
bin_dir = Pathname.new(Bundler.system_bindir)
bin_dir = bin_dir.parent until bin_dir.exist?

@checked_for_sudo = true
Expand Down
7 changes: 1 addition & 6 deletions lib/bundler/rubygems_integration.rb
Expand Up @@ -50,12 +50,7 @@ def gem_dir
end

def gem_bindir
# We use Gem.dir/bin because on OS X, Gem.bindir is hardcoded to return
# /usr/bin, a directory owned by root. Users who chown Gem.dir need bins
# to be installed where they have permissions. Furthermore, the official
# solution to change the bindir is adding -n to .gemrc, but Rubygems does
# not honor the -n option in either Gem.bindir or Installer.new.bindir.
File.join Gem.dir, "bin"
Gem.bindir
end

def user_home
Expand Down
6 changes: 3 additions & 3 deletions lib/bundler/source.rb
Expand Up @@ -86,7 +86,7 @@ def install(spec)
:ignore_dependencies => true,
:wrappers => true,
:env_shebang => true,
:bin_dir => "#{install_path}/bin"
:bin_dir => Bundler.system_bindir
).install
end

Expand All @@ -100,8 +100,8 @@ def install(spec)
Bundler.sudo "cp -R #{Bundler.tmp}/gems/#{spec.full_name} #{Bundler.rubygems.gem_dir}/gems/"
Bundler.sudo "cp -R #{Bundler.tmp}/specifications/#{spec.full_name}.gemspec #{Bundler.rubygems.gem_dir}/specifications/"
spec.executables.each do |exe|
Bundler.sudo "mkdir -p #{Bundler.rubygems.gem_bindir}"
Bundler.sudo "cp -R #{Bundler.tmp}/bin/#{exe} #{Bundler.rubygems.gem_bindir}"
Bundler.sudo "mkdir -p #{Bundler.system_bindir}"
Bundler.sudo "cp -R #{Bundler.tmp}/bin/#{exe} #{Bundler.system_bindir}"
end
end

Expand Down
14 changes: 7 additions & 7 deletions spec/install/gems/simple_case_spec.rb
Expand Up @@ -733,22 +733,22 @@ def set_bundle_path(type, location)
end
end

describe "when Gem.bindir is hardcoded to a root-owned directory" do
# On OS X, Gem.bindir is hardcoded to /usr/bin. :(
it "installs binstubs into Gem.dir+'/bin' instead" do
describe "when system_bindir is set" do
# On OS X, Gem.bindir defaults to /usr/bin, so system_bindir is useful if
# you want to avoid sudo installs for system gems with OS X's default ruby
it "overrides Gem.bindir" do
Pathname.new("/usr/bin").should_not be_writable

gemfile <<-G
require 'rubygems'
def Gem.bindir(dir=Gem.dir); "/usr/bin"; end
def Gem.bindir; "/usr/bin"; end
source "file://#{gem_repo1}"
gem "rack"
G

config "BUNDLE_SYSTEM_BINDIR" => system_gem_path('altbin').to_s
bundle :install
should_be_installed "rack 1.0.0"
system_gem_path("bin/rackup").should exist
system_gem_path("altbin/rackup").should exist
end
end

Expand Down

0 comments on commit af6badf

Please sign in to comment.