Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First pass at getting bundler to play well when $GEM_HOME is owned by…

… root
  • Loading branch information...
commit 32a2eb2699a89eaf98200c7a00ce4def25feca22 1 parent 86240f5
Carl Lerche authored
View
17 lib/bundler.rb
@@ -134,6 +134,10 @@ def app_cache
root.join("vendor/cache")
end
+ def tmp
+ "#{Gem.user_home}/.bundler/tmp"
+ end
+
def settings
@settings ||= Settings.new(root)
end
@@ -150,6 +154,19 @@ def default_gemfile
SharedHelpers.default_gemfile
end
+ def requires_sudo?
+ case
+ when File.writable?(bundle_path) ||
+ `which sudo 2>NUL`.empty? ||
+ File.owned?(bundle_path)
+ false
+ else
+ true
+ end
+ rescue Errno::ENOENT
+ false
+ end
+
private
def configure_gem_home_and_path
View
1  lib/bundler/installer.rb
@@ -48,6 +48,7 @@ def run(options)
spec.source.install(spec)
generate_bundler_executable_stubs(spec)
+ FileUtils.rm_rf(Bundler.tmp)
end
lock
View
28 lib/bundler/source.rb
@@ -68,15 +68,24 @@ def install(spec)
return if @installed[spec.full_name]
+ install_path = Bundler.requires_sudo? ? Bundler.tmp : Gem.dir
+
installer = Gem::Installer.new path,
- :install_dir => Gem.dir,
+ :install_dir => install_path,
:ignore_dependencies => true,
:wrappers => true,
:env_shebang => true,
- :bin_dir => "#{Gem.dir}/bin"
+ :bin_dir => "#{install_path}/bin"
installer.install
+ # SUDO HAX
+ if Bundler.requires_sudo?
+ `sudo mkdir -p #{Gem.dir}/gems #{Gem.dir}/specifications`
+ `sudo mv #{Bundler.tmp}/gems/#{spec.full_name} #{Gem.dir}/gems/`
+ `sudo mv #{Bundler.tmp}/specifications/#{spec.full_name}.gemspec #{Gem.dir}/specifications/`
+ end
+
spec.loaded_from = "#{Gem.dir}/specifications/#{spec.full_name}.gemspec"
end
@@ -184,8 +193,19 @@ def fetch_all_remote_specs(&blk)
def download_gem_from_uri(spec, uri)
spec.fetch_platform
- Gem::RemoteFetcher.fetcher.download(spec, uri, Gem.dir)
- "#{Gem.dir}/cache/#{spec.full_name}.gem"
+
+ download_path = Bundler.requires_sudo? ? Bundler.tmp : Gem.dir
+ gem_path = "#{Gem.dir}/cache/#{spec.full_name}.gem"
+
+ FileUtils.mkdir_p("#{download_path}/cache")
+ Gem::RemoteFetcher.fetcher.download(spec, uri, download_path)
+
+ if Bundler.requires_sudo?
+ `sudo mkdir -p #{Gem.dir}/cache`
+ `sudo mv #{Bundler.tmp}/cache/#{spec.full_name}.gem #{gem_path}`
+ end
+
+ gem_path
end
end
View
10 spec/install/gems/simple_case_spec.rb
@@ -469,4 +469,14 @@
end
end
+ describe_sudo "it working when $GEM_HOME is owned by root" do
+ it "installs gems" do
+ install_gemfile <<-G
+ source "file://#{gem_repo1}"
+ gem 'rack'
+ G
+
+ should_be_installed("rack 1.0.0")
+ end
+ end
end
View
1  spec/spec_helper.rb
@@ -32,6 +32,7 @@
config.include Spec::Path
config.include Spec::Rubygems
config.include Spec::Platforms
+ config.include Spec::Sudo
original_wd = Dir.pwd
original_path = ENV['PATH']
View
6 spec/support/helpers.rb
@@ -3,7 +3,11 @@ module Helpers
def reset!
Dir["#{tmp}/{gems/*,*}"].each do |dir|
next if %(base remote1 gems rubygems_1_3_5 rubygems_1_3_6 rubygems_master).include?(File.basename(dir))
- FileUtils.rm_rf(dir)
+ if File.owned?(dir)
+ FileUtils.rm_rf(dir)
+ else
+ `sudo rm -rf #{dir}`
+ end
end
FileUtils.mkdir_p(tmp)
FileUtils.mkdir_p(home)
View
38 spec/support/sudo.rb
@@ -0,0 +1,38 @@
+module Spec
+ module Sudo
+ def self.sudo?
+ @which_sudo ||= `which sudo`.strip
+ @which_sudo.any?
+ end
+
+ module Describe
+ def describe_sudo(*args, &blk)
+ return unless Sudo.sudo?
+ describe(*args) do
+ before :each do
+ chown_system_gems
+ end
+
+ instance_eval(&blk)
+ end
+ end
+ end
+
+ def self.included(klass)
+ klass.extend Describe
+ end
+
+ def sudo?
+ Sudo.sudo?
+ end
+
+ def sudo(cmd)
+ cmd = "sudo #{cmd}" if sudo?
+ sys_exec(cmd)
+ end
+
+ def chown_system_gems
+ sudo "chown -R root #{system_gem_path}"
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.