diff options
author | Sven Schwyn <schwyn@bitcetera.com> | 2017-01-24 23:00:31 +0100 |
---|---|---|
committer | Sven Schwyn <schwyn@bitcetera.com> | 2017-02-08 21:29:26 +0100 |
commit | 2dfb263b0f90a1d30b04cd13263428137e5ef92c (patch) | |
tree | fe22b049d05c4000fbc5d3d180a89ac83c504b9b | |
parent | 6e69db334661fd31f559fb72463e7911b6f9c6a1 (diff) | |
download | bundler-2dfb263b0f90a1d30b04cd13263428137e5ef92c.tar.gz |
Permissive temporary home directory
When falling back to a temporary home directory, make sure the "home" directory has mode 0777 to prevent "permission denied" when this mechanism is used by more than one login.
-rw-r--r-- | lib/bundler.rb | 45 | ||||
-rw-r--r-- | spec/bundler/bundler_spec.rb | 39 |
2 files changed, 63 insertions, 21 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index 2cd8d9916b..c98dece747 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -146,34 +146,37 @@ module Bundler 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" + + warning = if home.nil? + "Your home directory is not set." elsif !File.directory?(home) - warning += "\n * `#{home}` is not a directory" + "`#{home}` is not a directory." elsif !File.writable?(home) - warning += "\n * `#{home}` is not writable" - else - return @user_home = Pathname.new(home) + "`#{home}` is not writable." 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 + if warning + user_home = tmp_home_path(Etc.getlogin, warning) + Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n" + user_home + else + Pathname.new(home) end + end + end - warning += "\n\nBundler will use `#{tmp_home}` as your home directory temporarily" - - Bundler.ui.warn(warning) - tmp_home + def tmp_home_path(login, warning) + login ||= "unknown" + path = Pathname.new(Dir.tmpdir).join("bundler", "home") + SharedHelpers.filesystem_access(path) do |tmp_home_path| + unless tmp_home_path.exist? + tmp_home_path.mkpath + tmp_home_path.chmod(0o777) + end + tmp_home_path.join(login).tap(&:mkpath) end + rescue => e + raise "#{warning}\nBundler also failed to create a temporary home directory at `#{path}':\n#{e}" end def user_bundle_path diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb index 4458efce6a..268c0d99ac 100644 --- a/spec/bundler/bundler_spec.rb +++ b/spec/bundler/bundler_spec.rb @@ -170,4 +170,43 @@ EOF end end end + + describe "#user_home" do + context "home directory is set" do + it "should return the user home" do + path = "/home/oggy" + allow(Bundler.rubygems).to receive(:user_home).and_return(path) + allow(File).to receive(:directory?).with(path).and_return true + allow(File).to receive(:writable?).with(path).and_return true + expect(Bundler.user_home).to eq(Pathname(path)) + end + end + + context "home directory is not set" do + it "should issue warning and return a temporary user home" do + allow(Bundler.rubygems).to receive(:user_home).and_return(nil) + allow(Etc).to receive(:getlogin).and_return("USER") + allow(Dir).to receive(:tmpdir).and_return("/TMP") + allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(true) + expect(FileUtils).to receive(:mkpath).with("/TMP/bundler/home/USER") + message = <<EOF +Your home directory is not set. +Bundler will use `/TMP/bundler/home/USER' as your home directory temporarily. +EOF + expect(Bundler.ui).to receive(:warn).with(message) + expect(Bundler.user_home).to eq(Pathname("/TMP/bundler/home/USER")) + end + end + end + + describe "#tmp_home_path" do + it "should create temporary user home" do + allow(Dir).to receive(:tmpdir).and_return("/TMP") + allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(false) + expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home") + expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home/USER") + expect(File).to receive(:chmod).with(0o777, "/TMP/bundler/home") + expect(Bundler.tmp_home_path("USER", "")).to eq(Pathname("/TMP/bundler/home/USER")) + end + end end |