Skip to content

Commit

Permalink
Merge pull request rubygems#8519 from rubygems/deivid-rodriguez/bette…
Browse files Browse the repository at this point in the history
…r-permission-errors

Allow noop `bundle install` to work on read-only or protected folders
  • Loading branch information
deivid-rodriguez authored Feb 20, 2025
2 parents 4d5e7f3 + 794b0ec commit 1ea5c46
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
18 changes: 18 additions & 0 deletions bundler/lib/bundler/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,24 @@ def message
status_code(31)
end

class ReadOnlyFileSystemError < PermissionError
def message
"There was an error while trying to #{action} `#{@path}`. " \
"File system is read-only."
end

status_code(42)
end

class OperationNotPermittedError < PermissionError
def message
"There was an error while trying to #{action} `#{@path}`. " \
"Underlying OS system call raised an EPERM error."
end

status_code(43)
end

class GenericSystemCallError < BundlerError
attr_reader :underlying_error

Expand Down
2 changes: 1 addition & 1 deletion bundler/lib/bundler/plugin/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def initialize

begin
load_index(global_index_file, true)
rescue GenericSystemCallError
rescue PermissionError
# no need to fail when on a read-only FS, for example
nil
rescue ArgumentError => e
Expand Down
4 changes: 4 additions & 0 deletions bundler/lib/bundler/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def filesystem_access(path, action = :write, &block)
raise NoSpaceOnDeviceError.new(path, action)
rescue Errno::ENOTSUP
raise OperationNotSupportedError.new(path, action)
rescue Errno::EPERM
raise OperationNotPermittedError.new(path, action)
rescue Errno::EROFS
raise ReadOnlyFileSystemError.new(path, action)
rescue Errno::EEXIST, Errno::ENOENT
raise
rescue SystemCallError => e
Expand Down
25 changes: 21 additions & 4 deletions bundler/spec/install/process_lock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,36 @@
expect(the_bundle).to include_gems "myrack 1.0"
end

context "when creating a lock raises Errno::ENOTSUP" do
before { allow(File).to receive(:open).and_raise(Errno::ENOTSUP) }

it "skips creating the lock file and yields" do
processed = false
Bundler::ProcessLock.lock(default_bundle_path) { processed = true }

expect(processed).to eq true
end
end

context "when creating a lock raises Errno::EPERM" do
before { allow(File).to receive(:open).and_raise(Errno::EPERM) }

it "raises a friendly error" do
expect { Bundler::ProcessLock.lock(default_bundle_path) }.to raise_error(Bundler::GenericSystemCallError)
it "skips creating the lock file and yields" do
processed = false
Bundler::ProcessLock.lock(default_bundle_path) { processed = true }

expect(processed).to eq true
end
end

context "when creating a lock raises Errno::EROFS" do
before { allow(File).to receive(:open).and_raise(Errno::EROFS) }

it "raises a friendly error" do
expect { Bundler::ProcessLock.lock(default_bundle_path) }.to raise_error(Bundler::GenericSystemCallError)
it "skips creating the lock file and yields" do
processed = false
Bundler::ProcessLock.lock(default_bundle_path) { processed = true }

expect(processed).to eq true
end
end
end
Expand Down

0 comments on commit 1ea5c46

Please sign in to comment.