Skip to content

Commit ecf6ae1

Browse files
committed
New task: copy attachments
1 parent 8cab346 commit ecf6ae1

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

lib/tasks/active_storage_db_tasks.rake

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,22 @@ namespace :asdb do
99
puts "#{size_k}K #{date} #{filename}"
1010
end
1111
end
12+
13+
desc 'ActiveStorageDB: download attachment'
14+
task :cp, [:src, :dst] => [:environment] do |_t, args|
15+
src = args[:src]&.strip
16+
dst = args[:dst]&.strip
17+
abort('Required arguments: source file, destination file') if src.blank? || dst.blank?
18+
19+
dst = "#{dst}/#{src}" if Dir.exist?(dst)
20+
abort("Can't write on: #{dst}") unless File.writable?(dst)
21+
22+
blob = ::ActiveStorage::Blob.order(created_at: :desc).find_by(filename: src)
23+
abort('Source file not found') unless blob
24+
25+
ret = File.binwrite(dst, blob.download)
26+
puts "#{ret} bytes written"
27+
rescue StandardError => e
28+
puts e
29+
end
1230
end

spec/tasks/active_storage_db_tasks_spec.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,71 @@
2020
expect(task.split("\n").size).to be 3
2121
end
2222
end
23+
24+
describe 'asdb:cp' do
25+
subject(:task) { execute_task('asdb:cp', options) }
26+
27+
let(:options) {}
28+
29+
it 'exits showing the required arguments' do
30+
with_captured_stderr do
31+
expect { task }.to raise_exception(SystemExit, /Required arguments/)
32+
end
33+
end
34+
35+
context 'with only the source specified' do
36+
let(:options) { { src: 'some_file' } }
37+
38+
it 'exits showing the required arguments' do
39+
with_captured_stderr do
40+
expect { task }.to raise_exception(SystemExit, /Required arguments/)
41+
end
42+
end
43+
end
44+
45+
context 'with an invalid destination' do
46+
let(:options) { { src: 'some_file', dst: 'some_path' } }
47+
48+
before do
49+
allow(File).to receive(:writable?).and_return(false)
50+
end
51+
52+
it 'exits showing a write error' do
53+
with_captured_stderr do
54+
expect { task }.to raise_exception(SystemExit, /Can't write on/)
55+
end
56+
end
57+
end
58+
59+
context 'with a missing source' do
60+
let(:options) { { src: 'some_file', dst: 'some_path' } }
61+
62+
before do
63+
allow(File).to receive(:writable?).and_return(true)
64+
end
65+
66+
it 'exits showing a not found error' do
67+
with_captured_stderr do
68+
expect { task }.to raise_exception(SystemExit, /Source file not found/)
69+
end
70+
end
71+
end
72+
73+
context 'with valid arguments' do
74+
let(:blob) { build_stubbed(:active_storage_blob) }
75+
let(:blobs) { instance_double(ActiveRecord::Relation) }
76+
let(:options) { { src: blob.filename.to_s, dst: 'some_path' } }
77+
78+
before do
79+
allow(File).to receive_messages(binwrite: 1000, writable?: true)
80+
allow(ActiveStorage::Blob).to receive(:order).and_return(blobs)
81+
allow(blobs).to receive(:find_by).and_return(blob)
82+
allow(blob).to receive(:download).and_return('some data')
83+
end
84+
85+
it 'prints the number of bytes written' do
86+
expect(task).to eq "1000 bytes written\n"
87+
end
88+
end
89+
end
2390
end

0 commit comments

Comments
 (0)