Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
fix fallback when symlink in AbstractAdapter#link_or_copy_file fails
Browse files Browse the repository at this point in the history
  • Loading branch information
mraidel committed Jan 31, 2018
1 parent a99ffec commit 7fd0058
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/paperclip/io_adapters/abstract_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ def copy_to_tempfile(src)

def link_or_copy_file(src, dest)
Paperclip.log("Trying to link #{src} to #{dest}")
FileUtils.ln(src, dest, force: true) # overwrite existing

begin
FileUtils.ln(src, dest, force: true) # overwrite existing
rescue Errno::EXDEV, Errno::EPERM, Errno::ENOENT, Errno::EEXIST => e
Paperclip.log(
"Link failed with #{e.message}; copying link #{src} to #{dest}",
)
FileUtils.cp(src, dest)
end

@destination.close
@destination.open.binmode
rescue Errno::EXDEV, Errno::EPERM, Errno::ENOENT, Errno::EEXIST => e
Paperclip.log("Link failed with #{e.message}; copying link #{src} to #{dest}")
FileUtils.cp(src, dest)
end
end
end
35 changes: 35 additions & 0 deletions spec/paperclip/io_adapters/abstract_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,39 @@ def content_type
expect { subject.original_filename = nil }.not_to raise_error
end
end

context "#link_or_copy_file" do
class TestLinkOrCopyAdapter < Paperclip::AbstractAdapter
public :copy_to_tempfile, :destination
end

subject { TestLinkOrCopyAdapter.new(nil) }
let(:body) { "body" }

let(:file) do
t = Tempfile.new("destination")
t.print(body)
t.rewind
t
end

after do
file.close
file.unlink
end

it "should be able to read the file" do
expect(subject.copy_to_tempfile(file).read).to eq(body)
end

it "should be able to reopen the file after symlink has failed" do
FileUtils.expects(:ln).raises(Errno::EXDEV)
# after the failed symlink the file reports a size of zero
# which makes it necessary to reopen it
# we simulate this condition by closing the file
subject.destination.close

expect(subject.copy_to_tempfile(file).read).to eq(body)
end
end
end

0 comments on commit 7fd0058

Please sign in to comment.