diff options
-rw-r--r-- | lib/bundler/rubygems_gem_installer.rb | 14 | ||||
-rw-r--r-- | spec/bundler/commands/install_spec.rb | 30 |
2 files changed, 39 insertions, 5 deletions
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index 098ef0a356..12cc809664 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -66,8 +66,9 @@ module Bundler def build_extensions extension_cache_path = options[:bundler_extension_cache_path] - unless extension_cache_path && extension_dir = spec.extension_dir - prepare_extension_build + extension_dir = spec.extension_dir + unless extension_cache_path && extension_dir + prepare_extension_build(extension_dir) return super end @@ -76,10 +77,10 @@ module Bundler if build_complete && !options[:force] SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath) SharedHelpers.filesystem_access(extension_cache_path) do - FileUtils.cp_r extension_cache_path, spec.extension_dir + FileUtils.cp_r extension_cache_path, extension_dir end else - prepare_extension_build + prepare_extension_build(extension_dir) super SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath) SharedHelpers.filesystem_access(extension_cache_path) do @@ -98,7 +99,10 @@ module Bundler private - def prepare_extension_build + def prepare_extension_build(extension_dir) + SharedHelpers.filesystem_access(extension_dir, :create) do + FileUtils.mkdir_p extension_dir + end require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25") end diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 4a48187db0..57cff4e3b3 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -723,6 +723,36 @@ RSpec.describe "bundle install with gem sources" do end end + describe "when bundle extensions path does not have write access", :permissions do + let(:extensions_path) { bundled_app("vendor/#{Bundler.ruby_scope}/extensions/#{Gem::Platform.local}/#{Gem.extension_api_version}") } + + before do + FileUtils.mkdir_p(extensions_path) + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'simple_binary' + G + end + + it "should display a proper message to explain the problem" do + FileUtils.chmod("-x", extensions_path) + bundle "config set --local path vendor" + + begin + bundle :install, :raise_on_error => false + ensure + FileUtils.chmod("+x", extensions_path) + end + + expect(err).not_to include("ERROR REPORT TEMPLATE") + + expect(err).to include( + "There was an error while trying to create `#{extensions_path.join("simple_binary-1.0")}`. " \ + "It is likely that you need to grant executable permissions for all parent directories and write permissions for `#{extensions_path}`." + ) + end + end + describe "when the path of a specific gem is not writable", :permissions do let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") } let(:foo_path) { gems_path.join("foo-1.0.0") } |