riel 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +0 -0
- data/lib/riel/ansicolor.rb +93 -0
- data/lib/riel/array.rb +20 -0
- data/lib/riel/command.rb +30 -0
- data/lib/riel/date.rb +16 -0
- data/lib/riel/dir.rb +90 -0
- data/lib/riel/enumerable.rb +66 -0
- data/lib/riel/env.rb +49 -0
- data/lib/riel/file.rb +212 -0
- data/lib/riel/filetype.rb +189 -0
- data/lib/riel/hash.rb +12 -0
- data/lib/riel/io.rb +20 -0
- data/lib/riel/log.rb +548 -0
- data/lib/riel/matchdata.rb +13 -0
- data/lib/riel/optproc.rb +369 -0
- data/lib/riel/pathname.rb +16 -0
- data/lib/riel/rcfile.rb +35 -0
- data/lib/riel/regexp.rb +152 -0
- data/lib/riel/setdiff.rb +53 -0
- data/lib/riel/size_converter.rb +62 -0
- data/lib/riel/string.rb +81 -0
- data/lib/riel/tempfile.rb +28 -0
- data/lib/riel/text.rb +408 -0
- data/lib/riel/timer.rb +52 -0
- data/lib/riel.rb +13 -0
- data/test/riel/array_test.rb +22 -0
- data/test/riel/command_test.rb +28 -0
- data/test/riel/date_test.rb +17 -0
- data/test/riel/dir_test.rb +98 -0
- data/test/riel/enumerable_test.rb +27 -0
- data/test/riel/env_test.rb +52 -0
- data/test/riel/file_test.rb +242 -0
- data/test/riel/filetype_test.rb +32 -0
- data/test/riel/hash_test.rb +12 -0
- data/test/riel/io_test.rb +22 -0
- data/test/riel/log_test.rb +184 -0
- data/test/riel/matchdata_test.rb +15 -0
- data/test/riel/optproc_test.rb +233 -0
- data/test/riel/pathname_test.rb +36 -0
- data/test/riel/rcfile_test.rb +44 -0
- data/test/riel/regexp_test.rb +24 -0
- data/test/riel/setdiff_test.rb +26 -0
- data/test/riel/size_converter_test.rb +64 -0
- data/test/riel/string_test.rb +58 -0
- data/test/riel/tempfile_test.rb +16 -0
- data/test/riel/text_test.rb +102 -0
- data/test/riel/timer_test.rb +43 -0
- metadata +134 -0
data/README
ADDED
File without changes
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
# Attribute codes:
|
5
|
+
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
|
6
|
+
# Text color codes:
|
7
|
+
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
|
8
|
+
# Background color codes:
|
9
|
+
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
|
10
|
+
|
11
|
+
module ANSIColor
|
12
|
+
|
13
|
+
ATTRIBUTES = Hash[
|
14
|
+
'none' => '0',
|
15
|
+
'reset' => '0',
|
16
|
+
'bold' => '1',
|
17
|
+
'underscore' => '4',
|
18
|
+
'underline' => '4',
|
19
|
+
'blink' => '5',
|
20
|
+
'reverse' => '7',
|
21
|
+
'concealed' => '8',
|
22
|
+
'black' => '30',
|
23
|
+
'red' => '31',
|
24
|
+
'green' => '32',
|
25
|
+
'yellow' => '33',
|
26
|
+
'blue' => '34',
|
27
|
+
'magenta' => '35',
|
28
|
+
'cyan' => '36',
|
29
|
+
'white' => '37',
|
30
|
+
'on_black' => '40',
|
31
|
+
'on_red' => '41',
|
32
|
+
'on_green' => '42',
|
33
|
+
'on_yellow' => '43',
|
34
|
+
'on_blue' => '44',
|
35
|
+
'on_magenta' => '45',
|
36
|
+
'on_cyan' => '46',
|
37
|
+
'on_white' => '47',
|
38
|
+
]
|
39
|
+
|
40
|
+
ATTRIBUTES.each do |name, val|
|
41
|
+
eval <<-EODEF
|
42
|
+
def ANSIColor.#{name}
|
43
|
+
"\\e[#{val}m"
|
44
|
+
end
|
45
|
+
EODEF
|
46
|
+
end
|
47
|
+
|
48
|
+
def ANSIColor.attributes
|
49
|
+
ATTRIBUTES.collect { |name, val| name }
|
50
|
+
end
|
51
|
+
|
52
|
+
# returns the code for the given color string, which is in the format:
|
53
|
+
# [foreground] on [background]. Note that the foreground and background sections
|
54
|
+
# can have modifiers (attributes). Examples:
|
55
|
+
# black
|
56
|
+
# blue on white
|
57
|
+
# bold green on yellow
|
58
|
+
# underscore bold magenta on cyan
|
59
|
+
# underscore red on bold cyan
|
60
|
+
|
61
|
+
def ANSIColor.code(str)
|
62
|
+
fg, bg = str.split(/\s*\bon_?\s*/)
|
63
|
+
(fg ? foreground(fg) : "") + (bg ? background(bg) : "")
|
64
|
+
end
|
65
|
+
|
66
|
+
# returns the code for the given background color(s)
|
67
|
+
def ANSIColor.background(bgcolor)
|
68
|
+
make_code("on_" + bgcolor)
|
69
|
+
end
|
70
|
+
|
71
|
+
# returns the code for the given foreground color(s)
|
72
|
+
def ANSIColor.foreground(fgcolor)
|
73
|
+
make_code(fgcolor)
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def ANSIColor.make_code(str)
|
79
|
+
if str
|
80
|
+
str.split.collect do |s|
|
81
|
+
if attr = ATTRIBUTES[s]
|
82
|
+
"\e[#{attr}m"
|
83
|
+
else
|
84
|
+
$stderr.puts "WARNING: ANSIColor::make_code(" + str + "): unknown color: " + s
|
85
|
+
return ""
|
86
|
+
end
|
87
|
+
end.join("")
|
88
|
+
else
|
89
|
+
""
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
data/lib/riel/array.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
class Array
|
5
|
+
|
6
|
+
$-w = false
|
7
|
+
|
8
|
+
# Wraps the array with brackets, and inserts a comma and a space between
|
9
|
+
# elements.
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"[ " + collect { |e| e.to_s }.join(", ") + " ]"
|
13
|
+
end
|
14
|
+
$-w = true
|
15
|
+
|
16
|
+
def rand
|
17
|
+
return self[Kernel.rand(length)]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/lib/riel/command.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
#!ruby -w
|
4
|
+
|
5
|
+
class Command
|
6
|
+
|
7
|
+
# Runs the given command and arguments, returning the lines of output. If a
|
8
|
+
# block is provided, then it will be called with each line of output. If the
|
9
|
+
# block takes two arguments, then the line number is also passed to the block.
|
10
|
+
|
11
|
+
def self.run(cmd, *args, &blk)
|
12
|
+
lines = Array.new
|
13
|
+
|
14
|
+
IO.popen("#{cmd} #{args.join(' ')}") do |io|
|
15
|
+
lnum = 0
|
16
|
+
io.each_line do |line|
|
17
|
+
lines << line
|
18
|
+
if blk
|
19
|
+
args = [ line ]
|
20
|
+
args << lnum if blk.arity > 1
|
21
|
+
blk.call(*args)
|
22
|
+
end
|
23
|
+
lnum += 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
lines
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/riel/date.rb
ADDED
data/lib/riel/dir.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
class Dir
|
7
|
+
|
8
|
+
# Returns the home directory, for both Unix and Windows.
|
9
|
+
def self.home
|
10
|
+
ENV["HOME"] || begin
|
11
|
+
hd = ENV["HOMEDRIVE"]
|
12
|
+
hp = ENV["HOMEPATH"]
|
13
|
+
if hd || hp
|
14
|
+
(hd || "") + (hp || "\\")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Removes directories containing no files or files matching only those in
|
20
|
+
# args[:deletable_files], which are basenames.
|
21
|
+
def self.remove_if_empty(dir, args = Hash.new)
|
22
|
+
deletable = args[:deletable] || Array.new
|
23
|
+
verbose = args[:verbose]
|
24
|
+
level = args[:level] || 0
|
25
|
+
|
26
|
+
subargs = args.dup
|
27
|
+
subargs[:level] = level + 1
|
28
|
+
|
29
|
+
dir = Pathname.new(dir) unless dir.kind_of?(Pathname)
|
30
|
+
|
31
|
+
if level <= 1 && verbose
|
32
|
+
puts "dir: #{dir}"
|
33
|
+
end
|
34
|
+
|
35
|
+
if dir.readable?
|
36
|
+
dir.children.sort.each do |child|
|
37
|
+
if child.exist? && child.directory?
|
38
|
+
self.remove_if_empty(child, subargs)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
if dir.expand_path == Pathname.pwd.expand_path
|
43
|
+
puts "skipping current directory: #{dir}" if verbose
|
44
|
+
else
|
45
|
+
can_delete = dir.children.all? do |x|
|
46
|
+
bname = x.basename.to_s
|
47
|
+
deletable.any? do |del|
|
48
|
+
if del.kind_of?(String)
|
49
|
+
bname == del
|
50
|
+
elsif del.kind_of?(Regexp)
|
51
|
+
del.match(bname)
|
52
|
+
else
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if can_delete
|
59
|
+
dir.children.each do |x|
|
60
|
+
puts "removing file: #{x}" if verbose
|
61
|
+
x.delete
|
62
|
+
end
|
63
|
+
|
64
|
+
puts "removing directory: #{dir}" if verbose
|
65
|
+
|
66
|
+
dir.delete
|
67
|
+
else
|
68
|
+
# puts "#{dir} not empty"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
elsif verbose
|
72
|
+
puts "#{dir} not readable"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Moves and copies files to the given directory, creating
|
77
|
+
# it if it does not exist.
|
78
|
+
def self.move_and_copy_files(dir, move_files, copy_files)
|
79
|
+
dir.mkdir unless dir.exist?
|
80
|
+
|
81
|
+
move_files.each do |mfile|
|
82
|
+
File.move(mfile.to_s, dir.to_s)
|
83
|
+
end
|
84
|
+
|
85
|
+
copy_files.each do |cfile|
|
86
|
+
File.copy(cfile.to_s, dir.to_s)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
module Enumerable
|
5
|
+
|
6
|
+
def collect_with_index(&blk)
|
7
|
+
ary = []
|
8
|
+
self.each_with_index do |item, idx|
|
9
|
+
ary << blk.call(item, idx)
|
10
|
+
end
|
11
|
+
ary
|
12
|
+
end
|
13
|
+
|
14
|
+
NOT_NIL = Object.new
|
15
|
+
|
16
|
+
def select_with_index(arg = NOT_NIL, &blk)
|
17
|
+
ary = []
|
18
|
+
self.each_with_index do |item, idx|
|
19
|
+
ary << item if _match?(arg, item, idx, &blk)
|
20
|
+
end
|
21
|
+
ary
|
22
|
+
end
|
23
|
+
|
24
|
+
def detect_with_index(arg = NOT_NIL, &blk)
|
25
|
+
self.each_with_index do |item, idx|
|
26
|
+
return item if _match?(arg, item, idx, &blk)
|
27
|
+
end
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :orig_select :select
|
32
|
+
alias :orig_collect :collect
|
33
|
+
alias :orig_detect :detect
|
34
|
+
alias :orig_reject :reject
|
35
|
+
|
36
|
+
origw = $-w
|
37
|
+
$-w = false
|
38
|
+
def select(arg = NOT_NIL, &blk)
|
39
|
+
ary = []
|
40
|
+
self.each_with_index do |item, idx|
|
41
|
+
ary << item if _match?(arg, item, idx, &blk)
|
42
|
+
end
|
43
|
+
ary
|
44
|
+
end
|
45
|
+
|
46
|
+
def detect(arg = NOT_NIL, &blk)
|
47
|
+
self.each_with_index do |item, idx|
|
48
|
+
return item if _match?(arg, item, idx, &blk)
|
49
|
+
end
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
$-w = origw
|
53
|
+
|
54
|
+
def _match?(arg, item, idx, &blk)
|
55
|
+
if blk
|
56
|
+
args = [ item ]
|
57
|
+
args << idx if idx && blk.arity > 1
|
58
|
+
blk.call(*args)
|
59
|
+
elsif arg == NOT_NIL
|
60
|
+
!item.nil?
|
61
|
+
else
|
62
|
+
arg == item
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/lib/riel/env.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
module Env
|
5
|
+
|
6
|
+
# Returns the home directory, for both Unix and Windows.
|
7
|
+
|
8
|
+
def self.home_directory
|
9
|
+
if hm = ENV["HOME"]
|
10
|
+
hm
|
11
|
+
else
|
12
|
+
hd = ENV["HOMEDRIVE"]
|
13
|
+
hp = ENV["HOMEPATH"]
|
14
|
+
if hd || hp
|
15
|
+
(hd || "") + (hp || "\\")
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# matches single and double quoted strings:
|
23
|
+
REGEXP = / # either:
|
24
|
+
([\"\']) # start with a quote, and save it ($1)
|
25
|
+
( # save this ($2)
|
26
|
+
(?: # either (and don't save this):
|
27
|
+
\\. # any escaped character
|
28
|
+
| # or
|
29
|
+
[^\1\\] # anything that is not a quote ($1), and is not a backslash
|
30
|
+
)*? # only up to the next quote
|
31
|
+
) # end of $2
|
32
|
+
\1 # end with the same quote we started with
|
33
|
+
| # or
|
34
|
+
(:?\S+) # plain old nonwhitespace
|
35
|
+
/x
|
36
|
+
|
37
|
+
# amazing that ruby-mode (Emacs) handled all that.
|
38
|
+
|
39
|
+
# Reads the environment variable, splitting it according to its quoting.
|
40
|
+
|
41
|
+
def self.split(varname)
|
42
|
+
if v = ENV[varname]
|
43
|
+
v.scan(REGEXP).collect { |x| x[1] || x[2] }
|
44
|
+
else
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/riel/file.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'riel/filetype'
|
5
|
+
require 'riel/pathname'
|
6
|
+
require 'riel/tempfile'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
# this eliminates the world-writable warning when running file operations
|
10
|
+
# (opening, finding, executing):
|
11
|
+
|
12
|
+
orig_verbose = $VERBOSE
|
13
|
+
$VERBOSE = nil
|
14
|
+
path = ENV['PATH'].dup
|
15
|
+
$VERBOSE = orig_verbose
|
16
|
+
|
17
|
+
class File
|
18
|
+
|
19
|
+
def self.text?(file)
|
20
|
+
return File.file?(file) && FileType.instance.text?(file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.binary?(file)
|
24
|
+
return !self.text?(file)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns whether the given object is a file. Ignores errors.
|
28
|
+
def self.is_file?(fd)
|
29
|
+
begin
|
30
|
+
return self.stat(fd).file?
|
31
|
+
rescue
|
32
|
+
# ignore files that could not be read, etc.
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns whether the given file is writable. Ignores errors.
|
38
|
+
def self.is_writable?(file)
|
39
|
+
begin
|
40
|
+
return self.stat(file).writable?
|
41
|
+
rescue
|
42
|
+
# ignore files that could not be read, etc.
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns whether the given object is a directory. Ignores errors.
|
48
|
+
def self.is_directory?(fd)
|
49
|
+
begin
|
50
|
+
return self.stat(fd).directory?
|
51
|
+
rescue
|
52
|
+
# ignore files that could not be read, etc.
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns an array of all files under the given directory.
|
58
|
+
def self.find_files(dir)
|
59
|
+
files = Array.new
|
60
|
+
Find.find(dir) { |f| files.push(f) if is_file?(f) }
|
61
|
+
files
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns an array of all directory under the given directory.
|
65
|
+
def self.find_directories(dir)
|
66
|
+
dirs = Array.new
|
67
|
+
Find.find(dir) { |d| dirs.push(d) if is_directory?(d) }
|
68
|
+
dirs
|
69
|
+
end
|
70
|
+
|
71
|
+
# Removes the file/directory, including all subelements. Use with caution!
|
72
|
+
def self.remove_recursively(fd)
|
73
|
+
#$$$ this is rmtree
|
74
|
+
if fd.directory?
|
75
|
+
fd.children.each { |x| remove_recursively(x) }
|
76
|
+
end
|
77
|
+
fd.unlink
|
78
|
+
end
|
79
|
+
|
80
|
+
# Creates the given directory.
|
81
|
+
def self.mkdir(dir)
|
82
|
+
pn = Pathname.new(dir)
|
83
|
+
pn.mkdir unless pn.exist?
|
84
|
+
end
|
85
|
+
|
86
|
+
# Moves the files to the given directory, creating it if it does not exist.
|
87
|
+
def self.move_files(dir, files)
|
88
|
+
mkdir(dir)
|
89
|
+
|
90
|
+
files.each do |file|
|
91
|
+
FileUtils.move(file.to_s, dir.to_s)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Copies the files to the given directory, creating it if it does not exist.
|
96
|
+
def self.copy_files(dir, files)
|
97
|
+
mkdir(dir)
|
98
|
+
|
99
|
+
files.each do |file|
|
100
|
+
FileUtils.copy(file.to_s, dir.to_s)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Converts the argument to a Pathname.
|
105
|
+
def self._to_pathname(file)
|
106
|
+
file.kind_of?(Pathname) ? file : Pathname.new(file.to_s)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Reads a file line by line. Returns the pathname for the file, or nil if it
|
110
|
+
# does not exist.
|
111
|
+
def self.read_file(file, &blk)
|
112
|
+
fpn = _to_pathname(file)
|
113
|
+
if fpn.exist?
|
114
|
+
fpn.open do |f|
|
115
|
+
blk.call f.read
|
116
|
+
end
|
117
|
+
fpn
|
118
|
+
else
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Reads a file line by line, calling the given block. Returns the pathname for
|
124
|
+
# the file, or nil if it does not exist.
|
125
|
+
def self.read_file_lines(file, &blk)
|
126
|
+
fpn = _to_pathname(file)
|
127
|
+
if fpn.exist?
|
128
|
+
fpn.open do |f|
|
129
|
+
f.each_line do |line|
|
130
|
+
blk.call line
|
131
|
+
end
|
132
|
+
fpn
|
133
|
+
end
|
134
|
+
else
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Opens a file for writing and delegates to the given block.
|
140
|
+
def self.open_writable_file(file, &blk)
|
141
|
+
fpn = _to_pathname(file)
|
142
|
+
|
143
|
+
fpn.open(File::WRONLY | File::TRUNC | File::CREAT) do |f|
|
144
|
+
blk.call(f)
|
145
|
+
end
|
146
|
+
|
147
|
+
fpn
|
148
|
+
end
|
149
|
+
|
150
|
+
# Writes a file, using the <code>write</code> method.
|
151
|
+
def self.write_file(file, &blk)
|
152
|
+
open_writable_file(file) do |io|
|
153
|
+
io.write blk.call
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Writes a file, using puts (thus making it better for text files).
|
158
|
+
def self.put_file(file, &blk)
|
159
|
+
open_writable_file(file) do |io|
|
160
|
+
io.puts blk.call
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Opens a tempfile for writing, delegates to the given block, and renames the
|
165
|
+
# temp file to <code>file</code>. If <code>tempfile</code> is specified, it
|
166
|
+
# will be used as the temp file name. Ditto for <code>tempdir</code>, which
|
167
|
+
# defaults to Dir::tmpdir (e.g. "/tmp")
|
168
|
+
|
169
|
+
def self.open_via_temp_file(file, tempfile = nil, tempdir = Dir::tmpdir, &blk)
|
170
|
+
tempname = nil
|
171
|
+
|
172
|
+
fpn = _to_pathname(file)
|
173
|
+
tempfile ||= fpn.rootname
|
174
|
+
|
175
|
+
Tempfile.open(tempfile) do |tf|
|
176
|
+
blk.call(tf)
|
177
|
+
tempname = tf.path
|
178
|
+
end
|
179
|
+
|
180
|
+
FileUtils.mv(tempname, file.to_s)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Writes a file, using write, buffering it via a temp file.
|
184
|
+
def self.write_via_temp_file(file, &blk)
|
185
|
+
open_via_temp_file(file) do |io|
|
186
|
+
io.write blk.call
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Writes a file, using puts, buffering it via a temp file.
|
191
|
+
def self.put_via_temp_file(file, &blk)
|
192
|
+
open_via_temp_file(file) do |io|
|
193
|
+
io.puts blk.call
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns a file for the given basename, sequentially appending an integer
|
198
|
+
# until one is found that does not exist. For example, "foo.3" if "foo",
|
199
|
+
# "foo.1", and "foo.2" already exist.
|
200
|
+
def self.get_unused_file_name(basename)
|
201
|
+
tgt = basename
|
202
|
+
if tgt.exist?
|
203
|
+
i = 1
|
204
|
+
while tgt.exist?
|
205
|
+
tgt = Pathname.new(basename.to_s + "." + i.to_s)
|
206
|
+
i += 1
|
207
|
+
end
|
208
|
+
end
|
209
|
+
tgt
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|