summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-09-30 17:11:17 +0900
committerHomu <homu@barosl.com>2016-09-30 17:11:17 +0900
commitc8991533ff4a6c512e9b18e037c2da581c6d76fb (patch)
tree0704426a5375abcc38125c3b673160874a159a4e
parentdd6aef97a5f2e7173f406267256a8c319d6134ab (diff)
parent2ac0c510a4528d3eeef7fcc1b8e68bb7e053ebac (diff)
downloadbundler-c8991533ff4a6c512e9b18e037c2da581c6d76fb.tar.gz
Auto merge of #4951 - bundler:seg-no-writable-home, r=indirect
Fallback to a temp dir when the home directory is not usable Closes https://github.com/bundler/bundler/issues/4778 This is an alternative to https://github.com/bundler/bundler/pull/4886 \c @allenzhao @indirect
-rw-r--r--lib/bundler.rb38
-rw-r--r--lib/bundler/cli.rb2
-rw-r--r--lib/bundler/fetcher/compact_index.rb2
-rw-r--r--lib/bundler/gem_helper.rb2
-rw-r--r--lib/bundler/shared_helpers.rb13
-rw-r--r--lib/bundler/ui/shell.rb4
-rw-r--r--lib/bundler/ui/silent.rb9
-rw-r--r--spec/bundler/shared_helpers_spec.rb5
-rw-r--r--spec/runtime/inline_spec.rb20
9 files changed, 87 insertions, 8 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 249c4e2dc6..f25d43e001 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -3,6 +3,8 @@ require "fileutils"
require "pathname"
require "rbconfig"
require "thread"
+require "tmpdir"
+
require "bundler/errors"
require "bundler/environment_preserver"
require "bundler/gem_remote_fetcher"
@@ -143,8 +145,41 @@ module Bundler
"#{Bundler.rubygems.ruby_engine}/#{Bundler.rubygems.config_map[:ruby_version]}"
end
+ def user_home
+ @user_home ||= begin
+ home = Bundler.rubygems.user_home
+ warning = "Your home directory is not set properly:"
+ if home.nil?
+ warning += "\n * It is not set at all"
+ elsif !File.directory?(home)
+ warning += "\n * `#{home}` is not a directory"
+ elsif !File.writable?(home)
+ warning += "\n * `#{home}` is not writable"
+ else
+ return @user_home = Pathname.new(home)
+ end
+
+ login = Etc.getlogin || "unknown"
+
+ tmp_home = Pathname.new(Dir.tmpdir).join("bundler", "home", login)
+ begin
+ SharedHelpers.filesystem_access(tmp_home, :write) do |p|
+ FileUtils.mkdir_p(p)
+ end
+ rescue => e
+ warning += "\n\nBundler also failed to create a temporary home directory at `#{tmp_home}`:\n#{e}"
+ raise warning
+ end
+
+ warning += "\n\nBundler will use `#{tmp_home}` as your home directory temporarily"
+
+ Bundler.ui.warn(warning)
+ tmp_home
+ end
+ end
+
def user_bundle_path
- Pathname.new(Bundler.rubygems.user_home).join(".bundle")
+ Pathname.new(user_home).join(".bundle")
end
def home
@@ -409,6 +444,7 @@ EOF
@locked_gems = nil
@bundle_path = nil
@bin_path = nil
+ @user_home = nil
Plugin.reset!
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index ee18767a73..8aa4a0e576 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -36,8 +36,10 @@ module Bundler
ensure
self.options ||= {}
Bundler.settings.cli_flags_given = !options.empty?
+ unprinted_warnings = Bundler.ui.unprinted_warnings
Bundler.ui = UI::Shell.new(options)
Bundler.ui.level = "debug" if options["verbose"]
+ unprinted_warnings.each {|w| Bundler.ui.warn(w) }
if ENV["RUBYGEMS_GEMDEPS"] && !ENV["RUBYGEMS_GEMDEPS"].empty?
Bundler.ui.warn(
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
index 9461368df5..63b5c8371d 100644
--- a/lib/bundler/fetcher/compact_index.rb
+++ b/lib/bundler/fetcher/compact_index.rb
@@ -61,7 +61,7 @@ module Bundler
compact_index_request :fetch_spec
def available?
- user_home = Pathname.new(Bundler.rubygems.user_home)
+ user_home = Bundler.user_home
return nil unless user_home.directory? && user_home.writable?
# Read info file checksums out of /versions, so we can know if gems are up to date
fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
index fdb2db7dbf..73cbf9e0d1 100644
--- a/lib/bundler/gem_helper.rb
+++ b/lib/bundler/gem_helper.rb
@@ -98,7 +98,7 @@ module Bundler
allowed_push_host = @gemspec.metadata["allowed_push_host"]
gem_command += " --host #{allowed_push_host}" if allowed_push_host
end
- unless allowed_push_host || Pathname.new("~/.gem/credentials").expand_path.file?
+ unless allowed_push_host || Bundler.user_home.join(".gem/credentials").file?
raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
end
sh(gem_command)
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index ca4eafd623..0ddcea1ca5 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -39,10 +39,12 @@ module Bundler
bundle_dir = find_directory(".bundle")
return nil unless bundle_dir
- global_bundle_dir = File.join(Bundler.rubygems.user_home, ".bundle")
+ bundle_dir = Pathname.new(bundle_dir)
+
+ global_bundle_dir = Bundler.user_home.join(".bundle")
return nil if bundle_dir == global_bundle_dir
- Pathname.new(bundle_dir)
+ bundle_dir
end
def in_bundle?
@@ -202,10 +204,15 @@ module Bundler
def set_rubylib
rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR)
- rubylib.unshift File.expand_path("../..", __FILE__)
+ rubylib.unshift bundler_ruby_lib
ENV["RUBYLIB"] = rubylib.uniq.join(File::PATH_SEPARATOR)
end
+ def bundler_ruby_lib
+ File.expand_path("../..", __FILE__)
+ end
+ private :bundler_ruby_lib
+
def clean_load_path
# handle 1.9 where system gems are always on the load path
if defined?(::Gem)
diff --git a/lib/bundler/ui/shell.rb b/lib/bundler/ui/shell.rb
index 5c1fa61568..697290f795 100644
--- a/lib/bundler/ui/shell.rb
+++ b/lib/bundler/ui/shell.rb
@@ -83,6 +83,10 @@ module Bundler
with_level("silent", &blk)
end
+ def unprinted_warnings
+ []
+ end
+
private
# valimism
diff --git a/lib/bundler/ui/silent.rb b/lib/bundler/ui/silent.rb
index 367eaa58c2..5e0037f488 100644
--- a/lib/bundler/ui/silent.rb
+++ b/lib/bundler/ui/silent.rb
@@ -2,6 +2,10 @@
module Bundler
module UI
class Silent
+ def initialize
+ @warnings = []
+ end
+
def add_color(string, color)
string
end
@@ -13,6 +17,7 @@ module Bundler
end
def warn(message, newline = nil)
+ @warnings |= [message]
end
def error(message, newline = nil)
@@ -44,6 +49,10 @@ module Bundler
def silence
yield
end
+
+ def unprinted_warnings
+ @warnings
+ end
end
end
end
diff --git a/spec/bundler/shared_helpers_spec.rb b/spec/bundler/shared_helpers_spec.rb
index 4c0d61cf0a..8826dcd4dd 100644
--- a/spec/bundler/shared_helpers_spec.rb
+++ b/spec/bundler/shared_helpers_spec.rb
@@ -234,7 +234,9 @@ describe Bundler::SharedHelpers do
shared_examples_for "ENV['RUBYLIB'] gets set correctly" do
let(:ruby_lib_path) { "stubbed_ruby_lib_dir" }
- before { allow(File).to receive(:expand_path).and_return(ruby_lib_path) }
+ before do
+ allow(Bundler::SharedHelpers).to receive(:bundler_ruby_lib).and_return(ruby_lib_path)
+ end
it "ensures bundler's ruby version lib path is in ENV['RUBYLIB']" do
subject.set_bundle_environment
@@ -324,7 +326,6 @@ describe Bundler::SharedHelpers do
let(:ruby_lib_path) { "stubbed_ruby_lib_dir" }
before do
- allow(File).to receive(:expand_path).and_return(ruby_lib_path)
ENV["RUBYLIB"] = ruby_lib_path
end
diff --git a/spec/runtime/inline_spec.rb b/spec/runtime/inline_spec.rb
index 3119045be4..4d9a1f7fe4 100644
--- a/spec/runtime/inline_spec.rb
+++ b/spec/runtime/inline_spec.rb
@@ -173,4 +173,24 @@ describe "bundler/inline#gemfile" do
expect(err).to be_empty
expect(exitstatus).to be_zero if exitstatus
end
+
+ it "allows calling gemfile twice" do
+ script <<-RUBY
+ gemfile do
+ path "#{lib_path}" do
+ gem "two"
+ end
+ end
+
+ gemfile do
+ path "#{lib_path}" do
+ gem "four"
+ end
+ end
+ RUBY
+
+ expect(out).to eq("two\nfour")
+ expect(err).to be_empty
+ expect(exitstatus).to be_zero if exitstatus
+ end
end