Support for Factor programming language http://factorcode.org
[ohcount] / lib / ohcount / scratch_dir.rb
1 require 'fileutils'
2 require 'tmpdir'
3
4 # A utility class to manage the creation and automatic cleanup of temporary directories.
5 class ScratchDir
6         attr_reader :path
7
8         # Creates a uniquely named directory in the system tmp directory.
9         #
10         # If a block is passed to the constructor, the path to the created directory
11         # will be yielded to the block. The directory will then be deleted
12         # when this block returns.
13         #
14         # Sample usage:
15         #
16         #   ScratchDir.new do |path|
17         #     # Do some work in the new directory
18         #     File.new( path + '/foobaz', 'w' ) do
19         #       # ...
20         #     end
21         #   end # Scratch directory is deleted here
22         #
23         def initialize
24                 until @path
25                         @path = File.join(Dir.tmpdir, Time.now.utc.strftime("ohloh_%Y%H%m%S#{rand(900) + 100}"))
26                         begin
27                                 Dir.mkdir(@path)
28                         rescue Errno::EEXIST
29                                 @path = nil
30                         end
31                 end
32                 if block_given?
33                         begin
34                                 yield @path
35                         ensure
36                                 FileUtils.rm_rf(@path)
37                         end
38                 end
39         end
40 end
41
42 if $0 == __FILE__
43         path = nil
44
45         ScratchDir.new do |d|
46                 path = d
47                 STDOUT.puts "Created scratch direcory #{d}"
48                 File.open(File.join(d, "test"), "w") do |io|
49                         io.write "test"
50                 end
51         end
52         raise RuntimeError.new("Directory wasn't cleaned up") if FileTest.directory?(path)
53
54         begin
55                 ScratchDir.new do |d|
56                         path = d
57                         STDOUT.puts "Created scratch direcory #{d}"
58                         raise RuntimeError.new("This error should not prevent cleanup")
59                 end
60         rescue
61         end
62         raise RuntimeError.new("Directory wasn't cleaned up") if FileTest.directory?(path)
63
64         STDOUT.puts "Tests passed."
65 end