ruby-prof 0.4.1-mswin32 → 0.5.0-mswin32
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/CHANGES +30 -0
- data/README +65 -25
- data/Rakefile +33 -32
- data/bin/ruby-prof +100 -83
- data/examples/graph.html +65 -69
- data/ext/measure_allocations.h +43 -0
- data/ext/measure_cpu_time.h +138 -0
- data/ext/measure_process_time.h +41 -0
- data/ext/measure_wall_time.h +42 -0
- data/ext/ruby_prof.c +737 -653
- data/lib/ruby-prof.rb +41 -38
- data/lib/ruby-prof/abstract_printer.rb +42 -0
- data/lib/ruby-prof/call_tree_printer.rb +69 -0
- data/lib/ruby-prof/flat_printer.rb +78 -75
- data/lib/ruby-prof/graph_html_printer.rb +241 -228
- data/lib/ruby-prof/graph_printer.rb +160 -141
- data/lib/ruby-prof/profile_test_case.rb +80 -0
- data/lib/ruby-prof/rails_plugin/ruby-prof/init.rb +6 -0
- data/lib/ruby-prof/rails_plugin/ruby-prof/lib/profiling.rb +52 -0
- data/lib/ruby-prof/task.rb +147 -0
- data/lib/ruby_prof.so +0 -0
- data/test/basic_test.rb +65 -35
- data/test/duplicate_names_test.rb +20 -24
- data/test/gc.log +5 -0
- data/test/measure_mode_test.rb +79 -0
- data/test/module_test.rb +31 -18
- data/test/no_method_class_test.rb +14 -0
- data/test/prime1.rb +17 -0
- data/test/prime2.rb +26 -0
- data/test/prime3.rb +17 -0
- data/test/prime_test.rb +10 -10
- data/test/printers_test.rb +14 -12
- data/test/profile_unit_test.rb +24 -0
- data/test/recursive_test.rb +105 -17
- data/test/singleton_test.rb +38 -0
- data/test/start_test.rb +24 -0
- data/test/test_helper.rb +33 -29
- data/test/test_suite.rb +10 -2
- data/test/thread_test.rb +123 -17
- data/test/timing_test.rb +70 -29
- metadata +28 -30
- data/doc/created.rid +0 -1
- data/doc/files/LICENSE.html +0 -0
- data/doc/files/README.html +0 -376
- data/doc/files/bin/ruby-prof.html +0 -143
- data/doc/files/examples/flat_txt.html +0 -179
- data/doc/files/examples/graph_html.html +0 -948
- data/doc/files/examples/graph_txt.html +0 -297
- data/doc/files/ext/ruby_prof_c.html +0 -101
- data/doc/files/lib/ruby-prof/flat_printer_rb.html +0 -101
- data/doc/files/lib/ruby-prof/graph_html_printer_rb.html +0 -108
- data/doc/files/lib/ruby-prof/graph_printer_rb.html +0 -101
- data/doc/files/lib/ruby-prof/profiletask_rb.html +0 -109
- data/doc/files/lib/ruby-prof_rb.html +0 -111
- data/doc/files/lib/unprof_rb.html +0 -108
- data/doc/rdoc-style.css +0 -208
- data/lib/ruby-prof/profiletask.rb +0 -150
- data/test/clock_mode_test.rb +0 -73
@@ -1,141 +1,160 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
1
|
+
require 'ruby-prof/abstract_printer'
|
2
|
+
|
3
|
+
module RubyProf
|
4
|
+
# Generates graph[link:files/examples/graph_txt.html] profile reports as text.
|
5
|
+
# To use the graph printer:
|
6
|
+
#
|
7
|
+
# result = RubyProf.profile do
|
8
|
+
# [code to profile]
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# printer = RubyProf::GraphPrinter.new(result, 5)
|
12
|
+
# printer.print(STDOUT, 0)
|
13
|
+
#
|
14
|
+
# The constructor takes two arguments. The first is
|
15
|
+
# a RubyProf::Result object generated from a profiling
|
16
|
+
# run. The second is the minimum %total (the methods
|
17
|
+
# total time divided by the overall total time) that
|
18
|
+
# a method must take for it to be printed out in
|
19
|
+
# the report. Use this parameter to eliminate methods
|
20
|
+
# that are not important to the overall profiling results.
|
21
|
+
|
22
|
+
class GraphPrinter < AbstractPrinter
|
23
|
+
PERCENTAGE_WIDTH = 8
|
24
|
+
TIME_WIDTH = 10
|
25
|
+
CALL_WIDTH = 17
|
26
|
+
|
27
|
+
# Create a GraphPrinter. Result is a RubyProf::Result
|
28
|
+
# object generated from a profiling run.
|
29
|
+
def initialize(result)
|
30
|
+
super(result)
|
31
|
+
@thread_times = Hash.new
|
32
|
+
calculate_thread_times
|
33
|
+
end
|
34
|
+
|
35
|
+
def calculate_thread_times
|
36
|
+
# Cache thread times since this is an expensive
|
37
|
+
# operation with the required sorting
|
38
|
+
@result.threads.each do |thread_id, methods|
|
39
|
+
top = methods.sort.last
|
40
|
+
|
41
|
+
thread_time = 0.01
|
42
|
+
thread_time = top.total_time if top.total_time > 0
|
43
|
+
|
44
|
+
@thread_times[thread_id] = thread_time
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Print a graph report to the provided output.
|
49
|
+
#
|
50
|
+
# output - Any IO oject, including STDOUT or a file.
|
51
|
+
# The default value is STDOUT.
|
52
|
+
#
|
53
|
+
# options - Hash of print options. See #setup_options
|
54
|
+
# for more information.
|
55
|
+
#
|
56
|
+
def print(output = STDOUT, options = {})
|
57
|
+
@output = output
|
58
|
+
setup_options(options)
|
59
|
+
print_threads
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def print_threads
|
64
|
+
# sort assumes that spawned threads have higher object_ids
|
65
|
+
@result.threads.sort.each do |thread_id, methods|
|
66
|
+
print_methods(thread_id, methods)
|
67
|
+
@output << "\n" * 2
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def print_methods(thread_id, methods)
|
72
|
+
# Sort methods from longest to shortest total time
|
73
|
+
methods = methods.sort
|
74
|
+
|
75
|
+
toplevel = methods.last
|
76
|
+
total_time = toplevel.total_time
|
77
|
+
if total_time == 0
|
78
|
+
total_time = 0.01
|
79
|
+
end
|
80
|
+
|
81
|
+
print_heading(thread_id)
|
82
|
+
|
83
|
+
# Print each method in total time order
|
84
|
+
methods.reverse_each do |method|
|
85
|
+
total_percentage = (method.total_time/total_time) * 100
|
86
|
+
self_percentage = (method.self_time/total_time) * 100
|
87
|
+
|
88
|
+
next if total_percentage < min_percent
|
89
|
+
|
90
|
+
@output << "-" * 80 << "\n"
|
91
|
+
|
92
|
+
print_parents(thread_id, method)
|
93
|
+
|
94
|
+
# 1 is for % sign
|
95
|
+
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
|
96
|
+
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
|
97
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", method.total_time)
|
98
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", method.self_time)
|
99
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", method.wait_time)
|
100
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", method.children_time)
|
101
|
+
@output << sprintf("%#{CALL_WIDTH}i", method.called)
|
102
|
+
@output << sprintf(" %s", method_name(method))
|
103
|
+
@output << "\n"
|
104
|
+
|
105
|
+
print_children(method)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def print_heading(thread_id)
|
110
|
+
@output << "Thread ID: #{thread_id}\n"
|
111
|
+
@output << "Total Time: #{@thread_times[thread_id]}\n"
|
112
|
+
@output << "\n"
|
113
|
+
|
114
|
+
# 1 is for % sign
|
115
|
+
@output << sprintf("%#{PERCENTAGE_WIDTH}s", "%total")
|
116
|
+
@output << sprintf("%#{PERCENTAGE_WIDTH}s", "%self")
|
117
|
+
@output << sprintf("%#{TIME_WIDTH}s", "total")
|
118
|
+
@output << sprintf("%#{TIME_WIDTH}s", "self")
|
119
|
+
@output << sprintf("%#{TIME_WIDTH}s", "wait")
|
120
|
+
@output << sprintf("%#{TIME_WIDTH}s", "child")
|
121
|
+
@output << sprintf("%#{CALL_WIDTH}s", "calls")
|
122
|
+
@output << " Name"
|
123
|
+
@output << "\n"
|
124
|
+
end
|
125
|
+
|
126
|
+
def print_parents(thread_id, method)
|
127
|
+
method.parents.each do |caller|
|
128
|
+
@output << " " * 2 * PERCENTAGE_WIDTH
|
129
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", caller.total_time)
|
130
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", caller.self_time)
|
131
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", caller.wait_time)
|
132
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", caller.children_time)
|
133
|
+
|
134
|
+
call_called = "#{caller.called}/#{method.called}"
|
135
|
+
@output << sprintf("%#{CALL_WIDTH}s", call_called)
|
136
|
+
@output << sprintf(" %s", caller.target.full_name)
|
137
|
+
@output << "\n"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def print_children(method)
|
142
|
+
method.children.each do |child|
|
143
|
+
# Get children method
|
144
|
+
|
145
|
+
@output << " " * 2 * PERCENTAGE_WIDTH
|
146
|
+
|
147
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", child.total_time)
|
148
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", child.self_time)
|
149
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", child.wait_time)
|
150
|
+
@output << sprintf("%#{TIME_WIDTH}.2f", child.children_time)
|
151
|
+
|
152
|
+
call_called = "#{child.called}/#{child.target.called}"
|
153
|
+
@output << sprintf("%#{CALL_WIDTH}s", call_called)
|
154
|
+
@output << sprintf(" %s", child.target.full_name)
|
155
|
+
@output << "\n"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Make sure to first load the libraries we will override
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ruby-prof'
|
4
|
+
|
5
|
+
module Test
|
6
|
+
module Unit
|
7
|
+
class TestCase
|
8
|
+
|
9
|
+
alias :run__profile__ :run
|
10
|
+
|
11
|
+
def run(result, &block)
|
12
|
+
test_name = @method_name.to_sym
|
13
|
+
alias_test_name = (@method_name + '__profile__').to_sym
|
14
|
+
|
15
|
+
self.class.class_eval("alias :#{alias_test_name} :#{test_name}")
|
16
|
+
|
17
|
+
self.class.send(:define_method, test_name) do
|
18
|
+
# Run the profiler
|
19
|
+
RubyProf.start
|
20
|
+
__send__(alias_test_name)
|
21
|
+
result = RubyProf.stop
|
22
|
+
|
23
|
+
create_output_directory
|
24
|
+
|
25
|
+
# Get the result file name
|
26
|
+
file_name = name.gsub(/\(/, '_').gsub(/\)/, '')
|
27
|
+
file_name = self.underscore(file_name)
|
28
|
+
file_path = File.join(output_directory, file_name)
|
29
|
+
file_path += file_extension
|
30
|
+
|
31
|
+
# Create a printer
|
32
|
+
printer = self.printer.new(result)
|
33
|
+
|
34
|
+
# Write the results
|
35
|
+
File.open(file_path, 'w') do |file|
|
36
|
+
printer.print(file, min_percent)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
self.run__profile__(result, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Taken from rails
|
44
|
+
def underscore(camel_cased_word)
|
45
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
46
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
47
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
48
|
+
tr("-", "_").downcase
|
49
|
+
end
|
50
|
+
|
51
|
+
# Add some additional methods
|
52
|
+
def min_percent
|
53
|
+
1
|
54
|
+
end
|
55
|
+
|
56
|
+
def output_directory
|
57
|
+
# Put results in subdirectory called profile
|
58
|
+
File.join(Dir.getwd, 'profile')
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_output_directory
|
62
|
+
if not File.exist?(output_directory)
|
63
|
+
Dir.mkdir(output_directory)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def file_extension
|
68
|
+
if printer == RubyProf::FlatPrinter
|
69
|
+
'.html'
|
70
|
+
else
|
71
|
+
'.txt'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def printer
|
76
|
+
RubyProf::GraphHtmlPrinter
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'ruby-prof'
|
2
|
+
|
3
|
+
module ActionController #:nodoc:
|
4
|
+
# The ruby-prof module times the performance of actions and reports to the logger. If the Active Record
|
5
|
+
# package has been included, a separate timing section for database calls will be added as well.
|
6
|
+
module Profiling #:nodoc:
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
alias_method_chain :perform_action, :profiling
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform_action_with_profiling
|
14
|
+
if not logger or
|
15
|
+
not logger.level == Logger::DEBUG
|
16
|
+
perform_action_without_profiling
|
17
|
+
else
|
18
|
+
result = RubyProf.profile do
|
19
|
+
perform_action_without_profiling
|
20
|
+
end
|
21
|
+
|
22
|
+
output = StringIO.new
|
23
|
+
output << " [#{complete_request_uri rescue "unknown"}]"
|
24
|
+
output << "\n\n"
|
25
|
+
|
26
|
+
# Create a flat printer
|
27
|
+
printer = RubyProf::FlatPrinter.new(result)
|
28
|
+
|
29
|
+
# Skip anything less than 1% - which is a lot of
|
30
|
+
# stuff in Rails. Don't print the source file
|
31
|
+
# its too noisy.
|
32
|
+
printer.print(output, {:min_percent => 1,
|
33
|
+
:print_file => false})
|
34
|
+
logger.info(output.string)
|
35
|
+
|
36
|
+
## Example for Graph html printer
|
37
|
+
#printer = RubyProf::GraphHtmlPrinter.new(result)
|
38
|
+
#File.open('c:/temp/request.html', 'w') do |file|
|
39
|
+
#printer.print(file, {:min_percent => 1,
|
40
|
+
#:print_file => true})
|
41
|
+
#end
|
42
|
+
|
43
|
+
## Used for KCacheGrind visualizations
|
44
|
+
#printer = RubyProf::CallTreePrinter.new(result)
|
45
|
+
#File.open('c:/temp/callgrind.out', 'w') do |file|
|
46
|
+
#printer.print(file, {:min_percent => 1,
|
47
|
+
#:print_file => true})
|
48
|
+
#end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module RubyProf
|
8
|
+
|
9
|
+
# Define a task library for profiling unit tests with ruby-prof.
|
10
|
+
#
|
11
|
+
# All of the options provided by
|
12
|
+
# the Rake:TestTask are supported except the loader
|
13
|
+
# which is set to ruby-prof. For detailed information
|
14
|
+
# please refer to the Rake:TestTask documentation.
|
15
|
+
#
|
16
|
+
# ruby-prof specific options include:
|
17
|
+
#
|
18
|
+
# output_dir - For each file specified an output
|
19
|
+
# file with profile information will be
|
20
|
+
# written to the output directory.
|
21
|
+
# By default, the output directory is
|
22
|
+
# called "profile" and is created underneath
|
23
|
+
# the current working directory.
|
24
|
+
#
|
25
|
+
# printer - Specifies the output printer. Valid values include
|
26
|
+
# :flat, :graph, :graph_html and :call_tree.
|
27
|
+
#
|
28
|
+
# min_percent - Methods that take less than the specified percent
|
29
|
+
# will not be written out.
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
#
|
33
|
+
# require 'ruby-prof/task'
|
34
|
+
#
|
35
|
+
# RubyProf::ProfileTask.new do |t|
|
36
|
+
# t.test_files = FileList['test/test*.rb']
|
37
|
+
# t.output_dir = "c:/temp"
|
38
|
+
# t.printer = :graph
|
39
|
+
# t.min_percent = 10
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# If rake is invoked with a "TEST=filename" command line option,
|
43
|
+
# then the list of test files will be overridden to include only the
|
44
|
+
# filename specified on the command line. This provides an easy way
|
45
|
+
# to run just one test.
|
46
|
+
#
|
47
|
+
# If rake is invoked with a "TESTOPTS=options" command line option,
|
48
|
+
# then the given options are passed to the test process after a
|
49
|
+
# '--'. This allows Test::Unit options to be passed to the test
|
50
|
+
# suite.
|
51
|
+
#
|
52
|
+
# Examples:
|
53
|
+
#
|
54
|
+
# rake profile # run tests normally
|
55
|
+
# rake profile TEST=just_one_file.rb # run just one test file.
|
56
|
+
# rake profile TESTOPTS="-v" # run in verbose mode
|
57
|
+
# rake profile TESTOPTS="--runner=fox" # use the fox test runner
|
58
|
+
|
59
|
+
class ProfileTask < Rake::TestTask
|
60
|
+
attr_accessor :output_dir
|
61
|
+
attr_accessor :min_percent
|
62
|
+
attr_accessor :printer
|
63
|
+
|
64
|
+
def initialize(name = :profile)
|
65
|
+
super(name)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create the tasks defined by this task lib.
|
69
|
+
def define
|
70
|
+
lib_path = @libs.join(File::PATH_SEPARATOR)
|
71
|
+
desc "Profile" + (@name==:profile ? "" : " for #{@name}")
|
72
|
+
|
73
|
+
task @name do
|
74
|
+
create_output_directory
|
75
|
+
|
76
|
+
@ruby_opts.unshift( "-I#{lib_path}" )
|
77
|
+
@ruby_opts.unshift( "-w" ) if @warning
|
78
|
+
@ruby_opts.push("-S ruby-prof")
|
79
|
+
@ruby_opts.push("--printer #{@printer}")
|
80
|
+
@ruby_opts.push("--min_percent #{@min_percent}")
|
81
|
+
|
82
|
+
file_list.each do |file_path|
|
83
|
+
run_script(file_path)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Run script
|
90
|
+
def run_script(script_path)
|
91
|
+
run_code = ''
|
92
|
+
RakeFileUtils.verbose(@verbose) do
|
93
|
+
file_name = File.basename(script_path, File.extname(script_path))
|
94
|
+
case @printer
|
95
|
+
when :flat, :graph, :call_tree
|
96
|
+
file_name += ".txt"
|
97
|
+
when :graph_html
|
98
|
+
file_name += ".html"
|
99
|
+
else
|
100
|
+
file_name += ".txt"
|
101
|
+
end
|
102
|
+
|
103
|
+
output_file_path = File.join(output_directory, file_name)
|
104
|
+
|
105
|
+
command_line = @ruby_opts.join(" ") +
|
106
|
+
" --file=" + output_file_path +
|
107
|
+
" " + script_path
|
108
|
+
|
109
|
+
puts "ruby " + command_line
|
110
|
+
# We have to catch the exeption to continue on. However,
|
111
|
+
# the error message will have been output to STDERR
|
112
|
+
# already by the time we get here so we don't have to
|
113
|
+
# do that again
|
114
|
+
begin
|
115
|
+
ruby command_line
|
116
|
+
rescue => e
|
117
|
+
STDOUT << e << "\n"
|
118
|
+
STDOUT.flush
|
119
|
+
end
|
120
|
+
puts ""
|
121
|
+
puts ""
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def output_directory
|
126
|
+
File.expand_path(@output_dir)
|
127
|
+
end
|
128
|
+
|
129
|
+
def create_output_directory
|
130
|
+
if not File.exist?(output_directory)
|
131
|
+
Dir.mkdir(output_directory)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def clean_output_directory
|
136
|
+
if File.exist?(output_directory)
|
137
|
+
files = Dir.glob(output_directory + '/*')
|
138
|
+
FileUtils.rm(files)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def option_list # :nodoc:
|
143
|
+
ENV['OPTIONS'] || @options.join(" ") || ""
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|