Skip to content

Commit 246a62e

Browse files
committed
Create utility method to clean up temporary directory that this created
1 parent 0977588 commit 246a62e

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

lib/octocatalog-diff/util/util.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,27 @@ def self.temp_dir(prefix = 'ocd-', basedir = ENV['OCTOCATALOG_DIFF_TEMPDIR'])
6868
# If the base directory was not specified, then create a temporary directory, and
6969
# send the `at_exit` to clean it up at the conclusion.
7070
the_dir = Dir.mktmpdir(prefix)
71-
at_exit do
71+
at_exit { remove_temp_dir(the_dir) }
72+
the_dir
73+
end
74+
75+
# Utility method!
76+
# Remove a directory recursively that has been used as a temporary directory. This
77+
# should be called within an `at_exit` handler, and is only intended to be called via the
78+
# `temp_dir` method above.
79+
#
80+
# dir - A String with the directory to remove.
81+
def self.remove_temp_dir(dir)
82+
retries = 0
83+
while File.directory?(dir) && retries < 10
84+
retries += 1
7285
begin
73-
FileUtils.remove_entry_secure(the_dir) if File.directory?(the_dir)
74-
rescue Errno::ENOENT # rubocop:disable Lint/HandleExceptions
75-
# OK if the directory doesn't exist since we're trying to remove it anyway
86+
FileUtils.remove_entry_secure(dir)
87+
rescue Errno::ENOTEMPTY, Errno::ENOENT # rubocop:disable Lint/HandleExceptions
88+
# Errno::ENOTEMPTY will trigger a retry because the directory exists
89+
# Errno::ENOENT will break the loop because the directory won't exist next time it's checked
7690
end
7791
end
78-
the_dir
7992
end
8093
end
8194
end

spec/octocatalog-diff/tests/util/util_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,37 @@
109109
expect { described_class.temp_dir }.to raise_error(Errno::ENOENT, /temp_dir: Base dir/)
110110
end
111111
end
112+
113+
describe '#remove_temp_dir' do
114+
let(:dir) { '/var/tmp/abcd/efgh/ijkl' }
115+
116+
it 'should do nothing if the directory does not exist' do
117+
allow(File).to receive(:directory?).and_call_original
118+
allow(File).to receive(:directory?).with(dir).and_return(false)
119+
expect(FileUtils).not_to receive(:remove_entry_secure).with(dir)
120+
described_class.remove_temp_dir(dir)
121+
end
122+
123+
it 'should do nothing if Errno::ENOENT is raised due to race conditions' do
124+
allow(File).to receive(:directory?).and_call_original
125+
allow(File).to receive(:directory?).with(dir).and_return(true, false)
126+
expect(FileUtils).to receive(:remove_entry_secure).with(dir).exactly(1).times.and_raise(Errno::ENOENT)
127+
described_class.remove_temp_dir(dir)
128+
end
129+
130+
it 'should retry if Errno::ENOTEMPTY is raised' do
131+
allow(File).to receive(:directory?).and_call_original
132+
allow(File).to receive(:directory?).with(dir).and_return(true, false)
133+
134+
call_count = 0
135+
allow(FileUtils).to receive(:remove_entry_secure).with(dir) do
136+
call_count += 1
137+
raise Errno::ENOTEMPTY if call_count == 1
138+
raise 'This should not occur' unless call_count == 2
139+
true
140+
end
141+
142+
described_class.remove_temp_dir(dir)
143+
end
144+
end
112145
end

0 commit comments

Comments
 (0)