ruby-prof 0.17.0 → 0.18.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.
Files changed (185) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +500 -482
  3. data/LICENSE +24 -24
  4. data/README.rdoc +487 -485
  5. data/Rakefile +113 -113
  6. data/bin/ruby-prof +345 -345
  7. data/bin/ruby-prof-check-trace +45 -45
  8. data/examples/flat.txt +50 -50
  9. data/examples/graph.dot +84 -84
  10. data/examples/graph.html +823 -823
  11. data/examples/graph.txt +139 -139
  12. data/examples/multi.flat.txt +23 -23
  13. data/examples/multi.graph.html +760 -760
  14. data/examples/multi.grind.dat +114 -114
  15. data/examples/multi.stack.html +547 -547
  16. data/examples/stack.html +547 -547
  17. data/ext/ruby_prof/extconf.rb +68 -68
  18. data/ext/ruby_prof/rp_call_info.c +425 -425
  19. data/ext/ruby_prof/rp_call_info.h +53 -53
  20. data/ext/ruby_prof/rp_measure.c +40 -40
  21. data/ext/ruby_prof/rp_measure.h +45 -45
  22. data/ext/ruby_prof/rp_measure_allocations.c +76 -76
  23. data/ext/ruby_prof/rp_measure_cpu_time.c +136 -136
  24. data/ext/ruby_prof/rp_measure_gc_runs.c +73 -73
  25. data/ext/ruby_prof/rp_measure_gc_time.c +60 -60
  26. data/ext/ruby_prof/rp_measure_memory.c +77 -77
  27. data/ext/ruby_prof/rp_measure_process_time.c +71 -71
  28. data/ext/ruby_prof/rp_measure_wall_time.c +45 -45
  29. data/ext/ruby_prof/rp_method.c +630 -636
  30. data/ext/ruby_prof/rp_method.h +75 -75
  31. data/ext/ruby_prof/rp_stack.c +173 -173
  32. data/ext/ruby_prof/rp_stack.h +63 -63
  33. data/ext/ruby_prof/rp_thread.c +277 -276
  34. data/ext/ruby_prof/rp_thread.h +27 -27
  35. data/ext/ruby_prof/ruby_prof.c +794 -774
  36. data/ext/ruby_prof/ruby_prof.h +60 -59
  37. data/ext/ruby_prof/vc/ruby_prof.sln +20 -21
  38. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +31 -0
  39. data/lib/ruby-prof.rb +68 -68
  40. data/lib/ruby-prof/aggregate_call_info.rb +76 -76
  41. data/lib/ruby-prof/assets/call_stack_printer.css.html +116 -116
  42. data/lib/ruby-prof/assets/call_stack_printer.js.html +384 -384
  43. data/lib/ruby-prof/call_info.rb +115 -115
  44. data/lib/ruby-prof/call_info_visitor.rb +40 -40
  45. data/lib/ruby-prof/compatibility.rb +179 -178
  46. data/lib/ruby-prof/method_info.rb +121 -121
  47. data/lib/ruby-prof/printers/abstract_printer.rb +104 -103
  48. data/lib/ruby-prof/printers/call_info_printer.rb +41 -41
  49. data/lib/ruby-prof/printers/call_stack_printer.rb +265 -265
  50. data/lib/ruby-prof/printers/call_tree_printer.rb +143 -143
  51. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  52. data/lib/ruby-prof/printers/flat_printer.rb +70 -70
  53. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -83
  54. data/lib/ruby-prof/printers/graph_html_printer.rb +249 -249
  55. data/lib/ruby-prof/printers/graph_printer.rb +116 -116
  56. data/lib/ruby-prof/printers/multi_printer.rb +84 -84
  57. data/lib/ruby-prof/profile.rb +26 -26
  58. data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -201
  59. data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -49
  60. data/lib/ruby-prof/rack.rb +174 -174
  61. data/lib/ruby-prof/task.rb +147 -147
  62. data/lib/ruby-prof/thread.rb +35 -35
  63. data/lib/ruby-prof/version.rb +3 -3
  64. data/lib/unprof.rb +10 -10
  65. data/ruby-prof.gemspec +58 -58
  66. data/test/abstract_printer_test.rb +53 -0
  67. data/test/aggregate_test.rb +136 -136
  68. data/test/basic_test.rb +128 -128
  69. data/test/block_test.rb +74 -74
  70. data/test/call_info_test.rb +78 -78
  71. data/test/call_info_visitor_test.rb +31 -31
  72. data/test/duplicate_names_test.rb +32 -32
  73. data/test/dynamic_method_test.rb +55 -55
  74. data/test/enumerable_test.rb +21 -21
  75. data/test/exceptions_test.rb +24 -16
  76. data/test/exclude_methods_test.rb +146 -146
  77. data/test/exclude_threads_test.rb +53 -53
  78. data/test/fiber_test.rb +79 -79
  79. data/test/issue137_test.rb +63 -63
  80. data/test/line_number_test.rb +80 -80
  81. data/test/measure_allocations_test.rb +26 -26
  82. data/test/measure_cpu_time_test.rb +212 -213
  83. data/test/measure_gc_runs_test.rb +32 -32
  84. data/test/measure_gc_time_test.rb +36 -36
  85. data/test/measure_memory_test.rb +33 -33
  86. data/test/measure_process_time_test.rb +61 -63
  87. data/test/measure_wall_time_test.rb +255 -255
  88. data/test/method_elimination_test.rb +84 -84
  89. data/test/module_test.rb +45 -45
  90. data/test/multi_printer_test.rb +104 -104
  91. data/test/no_method_class_test.rb +15 -15
  92. data/test/pause_resume_test.rb +166 -166
  93. data/test/prime.rb +54 -54
  94. data/test/printers_test.rb +275 -275
  95. data/test/printing_recursive_graph_test.rb +127 -127
  96. data/test/rack_test.rb +157 -157
  97. data/test/recursive_test.rb +215 -215
  98. data/test/singleton_test.rb +38 -38
  99. data/test/stack_printer_test.rb +77 -78
  100. data/test/stack_test.rb +138 -138
  101. data/test/start_stop_test.rb +112 -112
  102. data/test/test_helper.rb +267 -275
  103. data/test/thread_test.rb +187 -187
  104. data/test/unique_call_path_test.rb +202 -202
  105. data/test/yarv_test.rb +55 -55
  106. metadata +17 -96
  107. data/doc/LICENSE.html +0 -115
  108. data/doc/README_rdoc.html +0 -637
  109. data/doc/Rack.html +0 -96
  110. data/doc/Rack/RubyProf.html +0 -233
  111. data/doc/Rack/RubyProf/RackProfiler.html +0 -343
  112. data/doc/RubyProf.html +0 -974
  113. data/doc/RubyProf/AbstractPrinter.html +0 -625
  114. data/doc/RubyProf/AggregateCallInfo.html +0 -552
  115. data/doc/RubyProf/CallInfo.html +0 -579
  116. data/doc/RubyProf/CallInfoPrinter.html +0 -121
  117. data/doc/RubyProf/CallInfoVisitor.html +0 -199
  118. data/doc/RubyProf/CallStackPrinter.html +0 -1127
  119. data/doc/RubyProf/CallTreePrinter.html +0 -725
  120. data/doc/RubyProf/Cmd.html +0 -637
  121. data/doc/RubyProf/DeprecationWarnings.html +0 -148
  122. data/doc/RubyProf/DotPrinter.html +0 -258
  123. data/doc/RubyProf/FlatPrinter.html +0 -164
  124. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -210
  125. data/doc/RubyProf/GraphHtmlPrinter.html +0 -558
  126. data/doc/RubyProf/GraphPrinter.html +0 -140
  127. data/doc/RubyProf/MethodInfo.html +0 -676
  128. data/doc/RubyProf/MultiPrinter.html +0 -574
  129. data/doc/RubyProf/Profile.html +0 -908
  130. data/doc/RubyProf/Profile/ExcludeCommonMethods.html +0 -411
  131. data/doc/RubyProf/Profile/LegacyMethodElimination.html +0 -158
  132. data/doc/RubyProf/ProfileTask.html +0 -491
  133. data/doc/RubyProf/Thread.html +0 -275
  134. data/doc/created.rid +0 -33
  135. data/doc/css/fonts.css +0 -167
  136. data/doc/css/rdoc.css +0 -590
  137. data/doc/examples/flat_txt.html +0 -139
  138. data/doc/examples/graph_html.html +0 -910
  139. data/doc/examples/graph_txt.html +0 -248
  140. data/doc/fonts/Lato-Light.ttf +0 -0
  141. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  142. data/doc/fonts/Lato-Regular.ttf +0 -0
  143. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  144. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  145. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  146. data/doc/images/add.png +0 -0
  147. data/doc/images/arrow_up.png +0 -0
  148. data/doc/images/brick.png +0 -0
  149. data/doc/images/brick_link.png +0 -0
  150. data/doc/images/bug.png +0 -0
  151. data/doc/images/bullet_black.png +0 -0
  152. data/doc/images/bullet_toggle_minus.png +0 -0
  153. data/doc/images/bullet_toggle_plus.png +0 -0
  154. data/doc/images/date.png +0 -0
  155. data/doc/images/delete.png +0 -0
  156. data/doc/images/find.png +0 -0
  157. data/doc/images/loadingAnimation.gif +0 -0
  158. data/doc/images/macFFBgHack.png +0 -0
  159. data/doc/images/package.png +0 -0
  160. data/doc/images/page_green.png +0 -0
  161. data/doc/images/page_white_text.png +0 -0
  162. data/doc/images/page_white_width.png +0 -0
  163. data/doc/images/plugin.png +0 -0
  164. data/doc/images/ruby.png +0 -0
  165. data/doc/images/tag_blue.png +0 -0
  166. data/doc/images/tag_green.png +0 -0
  167. data/doc/images/transparent.png +0 -0
  168. data/doc/images/wrench.png +0 -0
  169. data/doc/images/wrench_orange.png +0 -0
  170. data/doc/images/zoom.png +0 -0
  171. data/doc/index.html +0 -666
  172. data/doc/js/darkfish.js +0 -161
  173. data/doc/js/jquery.js +0 -4
  174. data/doc/js/navigation.js +0 -142
  175. data/doc/js/navigation.js.gz +0 -0
  176. data/doc/js/search.js +0 -109
  177. data/doc/js/search_index.js +0 -1
  178. data/doc/js/search_index.js.gz +0 -0
  179. data/doc/js/searcher.js +0 -229
  180. data/doc/js/searcher.js.gz +0 -0
  181. data/doc/table_of_contents.html +0 -1052
  182. data/examples/cachegrind.out.1 +0 -114
  183. data/examples/cachegrind.out.1.32313213 +0 -114
  184. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
  185. data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
@@ -1,174 +1,174 @@
1
- # encoding: utf-8
2
- require 'tmpdir'
3
-
4
- module Rack
5
- class RubyProf
6
- def initialize(app, options = {})
7
- @app = app
8
-
9
- options[:min_percent] ||= 1
10
-
11
- options[:path] ||= Dir.tmpdir
12
- FileUtils.mkdir_p(options[:path])
13
-
14
- @skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.(css|js|png|jpeg|jpg|gif)$}]
15
- @only_paths = options[:only_paths]
16
-
17
- @max_requests = options[:max_requests]
18
-
19
- @options = options
20
- end
21
-
22
- def call(env)
23
- request = Rack::Request.new(env)
24
-
25
- if should_profile?(request.path)
26
- profiler.resume
27
- begin
28
- result = @app.call(env)
29
- ensure
30
- profiler.pause
31
- end
32
-
33
- if profiler.max_requests_reached?
34
- prefix = if aggregate_requests?
35
- nil
36
- else
37
- request.path.gsub('/', '-')[1..-1]
38
- end
39
-
40
- profiler.print!(prefix)
41
- delete_profiler!
42
- end
43
-
44
- result
45
- else
46
- @app.call(env)
47
- end
48
- end
49
-
50
- private
51
-
52
- class RackProfiler
53
- def initialize(options)
54
- @options = options
55
-
56
- @profile = ::RubyProf::Profile.new(profiling_options)
57
- @profile.start
58
- @profile.pause
59
-
60
- @printer_klasses = options[:printers] || default_printers
61
-
62
- @tmpdir = options[:path]
63
-
64
- @max_requests = options[:max_requests] || 1
65
- @requests_count = 0
66
-
67
- @printed = false
68
- # if running across multiple requests, we want to make sure that the
69
- # ongoing profile is not lost if the process shuts down before the
70
- # max request count is reached
71
- ObjectSpace.define_finalizer(self, proc { print! })
72
- end
73
-
74
- def resume
75
- @profile.resume
76
- end
77
-
78
- def pause
79
- @profile.pause
80
- @requests_count += 1
81
- end
82
-
83
- def max_requests_reached?
84
- @requests_count >= @max_requests
85
- end
86
-
87
- def print!(prefix = nil)
88
- return false if @printed || @requests_count == 0
89
-
90
- data = @profile.stop
91
-
92
- prefix ||= "multi-requests-#{@requests_count}"
93
-
94
- @printer_klasses.each do |printer_klass, base_name|
95
- printer = printer_klass.new(data)
96
-
97
- if base_name.respond_to?(:call)
98
- base_name = base_name.call
99
- end
100
-
101
- if printer_klass == ::RubyProf::MultiPrinter \
102
- || printer_klass == ::RubyProf::CallTreePrinter
103
- printer.print(@options.merge(:profile => "#{prefix}-#{base_name}"))
104
- else
105
- file_name = ::File.join(@tmpdir, "#{prefix}-#{base_name}")
106
- ::File.open(file_name, 'wb') do |file|
107
- printer.print(file, @options)
108
- end
109
- end
110
- end
111
-
112
- @printed = true
113
- end
114
-
115
- private
116
-
117
- def profiling_options
118
- options = {}
119
- options[:measure_mode] = ::RubyProf.measure_mode
120
- options[:exclude_threads] =
121
- if @options[:ignore_existing_threads]
122
- Thread.list.select{|t| t != Thread.current}
123
- else
124
- ::RubyProf.exclude_threads
125
- end
126
- if @options[:request_thread_only]
127
- options[:include_threads] = [Thread.current]
128
- end
129
- if @options[:merge_fibers]
130
- options[:merge_fibers] = true
131
- end
132
- options
133
- end
134
-
135
- def default_printers
136
- {::RubyProf::FlatPrinter => 'flat.txt',
137
- ::RubyProf::GraphPrinter => 'graph.txt',
138
- ::RubyProf::GraphHtmlPrinter => 'graph.html',
139
- ::RubyProf::CallStackPrinter => 'call_stack.html'}
140
- end
141
- end
142
-
143
- def profiler
144
- if aggregate_requests?
145
- @@_shared_profiler ||= RackProfiler.new(@options)
146
- else
147
- @_profiler ||= RackProfiler.new(@options)
148
- end
149
- end
150
-
151
- def delete_profiler!
152
- if aggregate_requests?
153
- @@_shared_profiler.print! if @@_shared_profiler
154
- @@_shared_profiler = nil
155
- else
156
- @_profiler = nil
157
- end
158
- end
159
-
160
- def aggregate_requests?
161
- !@max_requests.nil?
162
- end
163
-
164
- def should_profile?(path)
165
- return false if paths_match?(path, @skip_paths)
166
-
167
- @only_paths ? paths_match?(path, @only_paths) : true
168
- end
169
-
170
- def paths_match?(path, paths)
171
- paths.any? { |skip_path| skip_path =~ path }
172
- end
173
- end
174
- end
1
+ # encoding: utf-8
2
+ require 'tmpdir'
3
+
4
+ module Rack
5
+ class RubyProf
6
+ def initialize(app, options = {})
7
+ @app = app
8
+
9
+ options[:min_percent] ||= 1
10
+
11
+ options[:path] ||= Dir.tmpdir
12
+ FileUtils.mkdir_p(options[:path])
13
+
14
+ @skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.(css|js|png|jpeg|jpg|gif)$}]
15
+ @only_paths = options[:only_paths]
16
+
17
+ @max_requests = options[:max_requests]
18
+
19
+ @options = options
20
+ end
21
+
22
+ def call(env)
23
+ request = Rack::Request.new(env)
24
+
25
+ if should_profile?(request.path)
26
+ profiler.resume
27
+ begin
28
+ result = @app.call(env)
29
+ ensure
30
+ profiler.pause
31
+ end
32
+
33
+ if profiler.max_requests_reached?
34
+ prefix = if aggregate_requests?
35
+ nil
36
+ else
37
+ request.path.gsub('/', '-')[1..-1]
38
+ end
39
+
40
+ profiler.print!(prefix)
41
+ delete_profiler!
42
+ end
43
+
44
+ result
45
+ else
46
+ @app.call(env)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ class RackProfiler
53
+ def initialize(options)
54
+ @options = options
55
+
56
+ @profile = ::RubyProf::Profile.new(profiling_options)
57
+ @profile.start
58
+ @profile.pause
59
+
60
+ @printer_klasses = options[:printers] || default_printers
61
+
62
+ @tmpdir = options[:path]
63
+
64
+ @max_requests = options[:max_requests] || 1
65
+ @requests_count = 0
66
+
67
+ @printed = false
68
+ # if running across multiple requests, we want to make sure that the
69
+ # ongoing profile is not lost if the process shuts down before the
70
+ # max request count is reached
71
+ ObjectSpace.define_finalizer(self, proc { print! })
72
+ end
73
+
74
+ def resume
75
+ @profile.resume
76
+ end
77
+
78
+ def pause
79
+ @profile.pause
80
+ @requests_count += 1
81
+ end
82
+
83
+ def max_requests_reached?
84
+ @requests_count >= @max_requests
85
+ end
86
+
87
+ def print!(prefix = nil)
88
+ return false if @printed || @requests_count == 0
89
+
90
+ data = @profile.stop
91
+
92
+ prefix ||= "multi-requests-#{@requests_count}"
93
+
94
+ @printer_klasses.each do |printer_klass, base_name|
95
+ printer = printer_klass.new(data)
96
+
97
+ if base_name.respond_to?(:call)
98
+ base_name = base_name.call
99
+ end
100
+
101
+ if printer_klass == ::RubyProf::MultiPrinter \
102
+ || printer_klass == ::RubyProf::CallTreePrinter
103
+ printer.print(@options.merge(:profile => "#{prefix}-#{base_name}"))
104
+ else
105
+ file_name = ::File.join(@tmpdir, "#{prefix}-#{base_name}")
106
+ ::File.open(file_name, 'wb') do |file|
107
+ printer.print(file, @options)
108
+ end
109
+ end
110
+ end
111
+
112
+ @printed = true
113
+ end
114
+
115
+ private
116
+
117
+ def profiling_options
118
+ options = {}
119
+ options[:measure_mode] = ::RubyProf.measure_mode
120
+ options[:exclude_threads] =
121
+ if @options[:ignore_existing_threads]
122
+ Thread.list.select{|t| t != Thread.current}
123
+ else
124
+ ::RubyProf.exclude_threads
125
+ end
126
+ if @options[:request_thread_only]
127
+ options[:include_threads] = [Thread.current]
128
+ end
129
+ if @options[:merge_fibers]
130
+ options[:merge_fibers] = true
131
+ end
132
+ options
133
+ end
134
+
135
+ def default_printers
136
+ {::RubyProf::FlatPrinter => 'flat.txt',
137
+ ::RubyProf::GraphPrinter => 'graph.txt',
138
+ ::RubyProf::GraphHtmlPrinter => 'graph.html',
139
+ ::RubyProf::CallStackPrinter => 'call_stack.html'}
140
+ end
141
+ end
142
+
143
+ def profiler
144
+ if aggregate_requests?
145
+ @@_shared_profiler ||= RackProfiler.new(@options)
146
+ else
147
+ @_profiler ||= RackProfiler.new(@options)
148
+ end
149
+ end
150
+
151
+ def delete_profiler!
152
+ if aggregate_requests?
153
+ @@_shared_profiler.print! if @@_shared_profiler
154
+ @@_shared_profiler = nil
155
+ else
156
+ @_profiler = nil
157
+ end
158
+ end
159
+
160
+ def aggregate_requests?
161
+ !@max_requests.nil?
162
+ end
163
+
164
+ def should_profile?(path)
165
+ return false if paths_match?(path, @skip_paths)
166
+
167
+ @only_paths ? paths_match?(path, @only_paths) : true
168
+ end
169
+
170
+ def paths_match?(path, paths)
171
+ paths.any? { |skip_path| skip_path =~ path }
172
+ end
173
+ end
174
+ end
@@ -1,147 +1,147 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'rake'
5
- require 'rake/testtask'
6
- require 'fileutils'
7
-
8
- module RubyProf
9
-
10
- # Define a task library for profiling unit tests with ruby-prof.
11
- #
12
- # All of the options provided by
13
- # the Rake:TestTask are supported except the loader
14
- # which is set to ruby-prof. For detailed information
15
- # please refer to the Rake:TestTask documentation.
16
- #
17
- # ruby-prof specific options include:
18
- #
19
- # output_dir - For each file specified an output
20
- # file with profile information will be
21
- # written to the output directory.
22
- # By default, the output directory is
23
- # called "profile" and is created underneath
24
- # the current working directory.
25
- #
26
- # printer - Specifies the output printer. Valid values include
27
- # :flat, :graph, :graph_html and :call_tree.
28
- #
29
- # min_percent - Methods that take less than the specified percent
30
- # will not be written out.
31
- #
32
- # Example:
33
- #
34
- # require 'ruby-prof/task'
35
- #
36
- # RubyProf::ProfileTask.new do |t|
37
- # t.test_files = FileList['test/test*.rb']
38
- # t.output_dir = "c:/temp"
39
- # t.printer = :graph
40
- # t.min_percent = 10
41
- # end
42
- #
43
- # If rake is invoked with a "TEST=filename" command line option,
44
- # then the list of test files will be overridden to include only the
45
- # filename specified on the command line. This provides an easy way
46
- # to run just one test.
47
- #
48
- # If rake is invoked with a "TESTOPTS=options" command line option,
49
- # then the given options are passed to the test process after a
50
- # '--'. This allows Test::Unit options to be passed to the test
51
- # suite.
52
- #
53
- # Examples:
54
- #
55
- # rake profile # run tests normally
56
- # rake profile TEST=just_one_file.rb # run just one test file.
57
- # rake profile TESTOPTS="-v" # run in verbose mode
58
- # rake profile TESTOPTS="--runner=fox" # use the fox test runner
59
-
60
- class ProfileTask < Rake::TestTask
61
- attr_accessor :output_dir
62
- attr_accessor :min_percent
63
- attr_accessor :printer
64
-
65
- def initialize(name = :profile)
66
- super(name)
67
- end
68
-
69
- # Create the tasks defined by this task lib.
70
- def define
71
- lib_path = @libs.join(File::PATH_SEPARATOR)
72
- desc "Profile" + (@name==:profile ? "" : " for #{@name}")
73
-
74
- task @name do
75
- create_output_directory
76
-
77
- @ruby_opts.unshift( "-I#{lib_path}" )
78
- @ruby_opts.unshift( "-w" ) if @warning
79
- @ruby_opts.push("-S ruby-prof")
80
- @ruby_opts.push("--printer #{@printer}")
81
- @ruby_opts.push("--min_percent #{@min_percent}")
82
-
83
- file_list.each do |file_path|
84
- run_script(file_path)
85
- end
86
- end
87
- self
88
- end
89
-
90
- # Run script
91
- def run_script(script_path)
92
- run_code = ''
93
- RakeFileUtils.verbose(@verbose) do
94
- file_name = File.basename(script_path, File.extname(script_path))
95
- case @printer
96
- when :flat, :graph, :call_tree
97
- file_name += ".txt"
98
- when :graph_html
99
- file_name += ".html"
100
- else
101
- file_name += ".txt"
102
- end
103
-
104
- output_file_path = File.join(output_directory, file_name)
105
-
106
- command_line = @ruby_opts.join(" ") +
107
- " --file=" + output_file_path +
108
- " " + script_path
109
-
110
- puts "ruby " + command_line
111
- # We have to catch the exeption to continue on. However,
112
- # the error message will have been output to STDERR
113
- # already by the time we get here so we don't have to
114
- # do that again
115
- begin
116
- ruby command_line
117
- rescue => e
118
- STDOUT << e << "\n"
119
- STDOUT.flush
120
- end
121
- puts ""
122
- puts ""
123
- end
124
- end
125
-
126
- def output_directory
127
- File.expand_path(@output_dir)
128
- end
129
-
130
- def create_output_directory
131
- if not File.exist?(output_directory)
132
- Dir.mkdir(output_directory)
133
- end
134
- end
135
-
136
- def clean_output_directory
137
- if File.exist?(output_directory)
138
- files = Dir.glob(output_directory + '/*')
139
- FileUtils.rm(files)
140
- end
141
- end
142
-
143
- def option_list # :nodoc:
144
- ENV['OPTIONS'] || @options.join(" ") || ""
145
- end
146
- end
147
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'fileutils'
7
+
8
+ module RubyProf
9
+
10
+ # Define a task library for profiling unit tests with ruby-prof.
11
+ #
12
+ # All of the options provided by
13
+ # the Rake:TestTask are supported except the loader
14
+ # which is set to ruby-prof. For detailed information
15
+ # please refer to the Rake:TestTask documentation.
16
+ #
17
+ # ruby-prof specific options include:
18
+ #
19
+ # output_dir - For each file specified an output
20
+ # file with profile information will be
21
+ # written to the output directory.
22
+ # By default, the output directory is
23
+ # called "profile" and is created underneath
24
+ # the current working directory.
25
+ #
26
+ # printer - Specifies the output printer. Valid values include
27
+ # :flat, :graph, :graph_html and :call_tree.
28
+ #
29
+ # min_percent - Methods that take less than the specified percent
30
+ # will not be written out.
31
+ #
32
+ # Example:
33
+ #
34
+ # require 'ruby-prof/task'
35
+ #
36
+ # RubyProf::ProfileTask.new do |t|
37
+ # t.test_files = FileList['test/test*.rb']
38
+ # t.output_dir = "c:/temp"
39
+ # t.printer = :graph
40
+ # t.min_percent = 10
41
+ # end
42
+ #
43
+ # If rake is invoked with a "TEST=filename" command line option,
44
+ # then the list of test files will be overridden to include only the
45
+ # filename specified on the command line. This provides an easy way
46
+ # to run just one test.
47
+ #
48
+ # If rake is invoked with a "TESTOPTS=options" command line option,
49
+ # then the given options are passed to the test process after a
50
+ # '--'. This allows Test::Unit options to be passed to the test
51
+ # suite.
52
+ #
53
+ # Examples:
54
+ #
55
+ # rake profile # run tests normally
56
+ # rake profile TEST=just_one_file.rb # run just one test file.
57
+ # rake profile TESTOPTS="-v" # run in verbose mode
58
+ # rake profile TESTOPTS="--runner=fox" # use the fox test runner
59
+
60
+ class ProfileTask < Rake::TestTask
61
+ attr_accessor :output_dir
62
+ attr_accessor :min_percent
63
+ attr_accessor :printer
64
+
65
+ def initialize(name = :profile)
66
+ super(name)
67
+ end
68
+
69
+ # Create the tasks defined by this task lib.
70
+ def define
71
+ lib_path = @libs.join(File::PATH_SEPARATOR)
72
+ desc "Profile" + (@name==:profile ? "" : " for #{@name}")
73
+
74
+ task @name do
75
+ create_output_directory
76
+
77
+ @ruby_opts.unshift( "-I#{lib_path}" )
78
+ @ruby_opts.unshift( "-w" ) if @warning
79
+ @ruby_opts.push("-S ruby-prof")
80
+ @ruby_opts.push("--printer #{@printer}")
81
+ @ruby_opts.push("--min_percent #{@min_percent}")
82
+
83
+ file_list.each do |file_path|
84
+ run_script(file_path)
85
+ end
86
+ end
87
+ self
88
+ end
89
+
90
+ # Run script
91
+ def run_script(script_path)
92
+ run_code = ''
93
+ RakeFileUtils.verbose(@verbose) do
94
+ file_name = File.basename(script_path, File.extname(script_path))
95
+ case @printer
96
+ when :flat, :graph, :call_tree
97
+ file_name += ".txt"
98
+ when :graph_html
99
+ file_name += ".html"
100
+ else
101
+ file_name += ".txt"
102
+ end
103
+
104
+ output_file_path = File.join(output_directory, file_name)
105
+
106
+ command_line = @ruby_opts.join(" ") +
107
+ " --file=" + output_file_path +
108
+ " " + script_path
109
+
110
+ puts "ruby " + command_line
111
+ # We have to catch the exeption to continue on. However,
112
+ # the error message will have been output to STDERR
113
+ # already by the time we get here so we don't have to
114
+ # do that again
115
+ begin
116
+ ruby command_line
117
+ rescue => e
118
+ STDOUT << e << "\n"
119
+ STDOUT.flush
120
+ end
121
+ puts ""
122
+ puts ""
123
+ end
124
+ end
125
+
126
+ def output_directory
127
+ File.expand_path(@output_dir)
128
+ end
129
+
130
+ def create_output_directory
131
+ if not File.exist?(output_directory)
132
+ Dir.mkdir(output_directory)
133
+ end
134
+ end
135
+
136
+ def clean_output_directory
137
+ if File.exist?(output_directory)
138
+ files = Dir.glob(output_directory + '/*')
139
+ FileUtils.rm(files)
140
+ end
141
+ end
142
+
143
+ def option_list # :nodoc:
144
+ ENV['OPTIONS'] || @options.join(" ") || ""
145
+ end
146
+ end
147
+ end