ghazel-fiveruns_tuneup 0.8.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG +33 -0
  2. data/CONTRIBUTORS +5 -0
  3. data/README.rdoc +65 -0
  4. data/assets/images/arrows.gif +0 -0
  5. data/assets/images/edit.png +0 -0
  6. data/assets/images/fade.png +0 -0
  7. data/assets/images/fade_down.png +0 -0
  8. data/assets/images/head.gif +0 -0
  9. data/assets/images/logo.gif +0 -0
  10. data/assets/images/logo_clear.png +0 -0
  11. data/assets/images/magnify.png +0 -0
  12. data/assets/images/pin.png +0 -0
  13. data/assets/images/pip.gif +0 -0
  14. data/assets/images/pointer.gif +0 -0
  15. data/assets/images/pushed_pin.png +0 -0
  16. data/assets/images/schema.png +0 -0
  17. data/assets/images/signin.gif +0 -0
  18. data/assets/images/spinner.gif +0 -0
  19. data/assets/images/warning.gif +0 -0
  20. data/assets/javascripts/init.js +12 -0
  21. data/assets/javascripts/prototype.js +2515 -0
  22. data/assets/javascripts/tuneup.js +115 -0
  23. data/assets/stylesheets/tuneup.css +209 -0
  24. data/init.rb +2 -0
  25. data/install.rb +13 -0
  26. data/lib/bumpspark_helper.rb +52 -0
  27. data/lib/fiveruns/tuneup.rb +154 -0
  28. data/lib/fiveruns/tuneup/asset_tags.rb +54 -0
  29. data/lib/fiveruns/tuneup/configuration.rb +25 -0
  30. data/lib/fiveruns/tuneup/custom_methods.rb +8 -0
  31. data/lib/fiveruns/tuneup/environment.rb +29 -0
  32. data/lib/fiveruns/tuneup/instrumentation/action_controller/base.rb +59 -0
  33. data/lib/fiveruns/tuneup/instrumentation/action_view/base.rb +81 -0
  34. data/lib/fiveruns/tuneup/instrumentation/action_view/partial_template.rb +28 -0
  35. data/lib/fiveruns/tuneup/instrumentation/active_record/base.rb +126 -0
  36. data/lib/fiveruns/tuneup/instrumentation/cgi/session.rb +30 -0
  37. data/lib/fiveruns/tuneup/instrumentation/utilities.rb +187 -0
  38. data/lib/fiveruns/tuneup/multipart.rb +75 -0
  39. data/lib/fiveruns/tuneup/routing.rb +25 -0
  40. data/lib/fiveruns/tuneup/runs.rb +86 -0
  41. data/lib/fiveruns/tuneup/schema.rb +43 -0
  42. data/lib/fiveruns/tuneup/step.rb +221 -0
  43. data/lib/fiveruns/tuneup/version.rb +89 -0
  44. data/lib/fiveruns_tuneup.rb +11 -0
  45. data/lib/tuneup_controller.rb +46 -0
  46. data/lib/tuneup_helper.rb +181 -0
  47. data/rails/init.rb +14 -0
  48. data/tasks/assets.rake +32 -0
  49. data/test/test_helper.rb +3 -0
  50. data/test/tuneup_test.rb +0 -0
  51. data/uninstall.rb +6 -0
  52. data/views/tuneup/_data.html.erb +15 -0
  53. data/views/tuneup/_flash.html.erb +6 -0
  54. data/views/tuneup/_link.html.erb +1 -0
  55. data/views/tuneup/_schema.html.erb +17 -0
  56. data/views/tuneup/_sql.html.erb +23 -0
  57. data/views/tuneup/_step.html.erb +17 -0
  58. data/views/tuneup/panel/_show.html.erb +4 -0
  59. data/views/tuneup/sandbox.html.erb +6 -0
  60. metadata +124 -0
@@ -0,0 +1,89 @@
1
+ # (The MIT License)
2
+ #
3
+ # Copyright (c) 2008 Jamis Buck <jamis@37signals.com>,
4
+ # with modifications by Bruce Williams <bruce@fiveruns.com>
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # 'Software'), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ module Fiveruns
25
+
26
+ module Tuneup
27
+
28
+ # A class for describing the current version of a library. The version
29
+ # consists of three parts: the +major+ number, the +minor+ number, and the
30
+ # +tiny+ (or +patch+) number.
31
+ class Version
32
+
33
+ include Comparable
34
+
35
+ # A convenience method for instantiating a new Version instance with the
36
+ # given +major+, +minor+, and +tiny+ components.
37
+ def self.[](major, minor, tiny)
38
+ new(major, minor, tiny)
39
+ end
40
+
41
+ def self.rails
42
+ @rails ||= begin
43
+ # handle ::Rails::VERSION not being set
44
+ Version.new(::Rails::VERSION::MAJOR, ::Rails::VERSION::MINOR, ::Rails::VERSION::TINY) rescue Version.new(0,0,0)
45
+ end
46
+ end
47
+
48
+ attr_reader :major, :minor, :tiny
49
+
50
+ # Create a new Version object with the given components.
51
+ def initialize(major, minor, tiny)
52
+ @major, @minor, @tiny = major, minor, tiny
53
+ end
54
+
55
+ # Compare this version to the given +version+ object.
56
+ def <=>(version)
57
+ to_i <=> version.to_i
58
+ end
59
+
60
+ # Converts this version object to a string, where each of the three
61
+ # version components are joined by the '.' character. E.g., 2.0.0.
62
+ def to_s
63
+ @to_s ||= [@major, @minor, @tiny].join(".")
64
+ end
65
+
66
+ # Converts this version to a canonical integer that may be compared
67
+ # against other version objects.
68
+ def to_i
69
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
70
+ end
71
+
72
+ def to_a
73
+ [@major, @minor, @tiny]
74
+ end
75
+
76
+ MAJOR = 0
77
+ MINOR = 8
78
+ TINY = 22
79
+
80
+ # The current version as a Version instance
81
+ CURRENT = new(MAJOR, MINOR, TINY)
82
+ # The current version as a String
83
+ STRING = CURRENT.to_s
84
+
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,11 @@
1
+ deps = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : Dependencies
2
+ deps.load_paths.unshift File.dirname(__FILE__)
3
+
4
+ # hack for Rails < 2.3 compatability.
5
+ class String
6
+ if not instance_methods.include?("html_safe!")
7
+ def html_safe!
8
+ self
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ class TuneupController < ActionController::Base
2
+
3
+ def show
4
+ session['fiveruns_tuneup_last_uri'] = params[:uri]
5
+ debug_rjs = response.template.debug_rjs
6
+ response.template.debug_rjs = false
7
+ ActionController::Base.silence do
8
+ render :update do |page|
9
+ page << tuneup_reload_panel
10
+ end
11
+ end
12
+ response.template.debug_rjs = debug_rjs
13
+ end
14
+
15
+ def asset
16
+ filename = File.basename(params[:file])
17
+ if filename =~ /css$/
18
+ response.content_type = 'text/css'
19
+ end
20
+ send_file File.join(File.dirname(__FILE__) << "/../assets/#{filename}")
21
+ end
22
+
23
+ def on
24
+ collect true
25
+ end
26
+
27
+ def off
28
+ collect false
29
+ end
30
+
31
+ def sandbox
32
+
33
+ end
34
+
35
+ #######
36
+ private
37
+ #######
38
+
39
+ def collect(state)
40
+ Fiveruns::Tuneup.collecting = state
41
+ render :update do |page|
42
+ page << %[$('tuneup-panel').update("#{escape_javascript(render(:partial => 'tuneup/panel/show.html.erb'))}")]
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,181 @@
1
+ module TuneupHelper #:nodoc:
2
+
3
+ include BumpsparkHelper
4
+
5
+ def tuneup_collection_link
6
+ state = tuneup_collecting? ? :off : :on
7
+ %|<a onclick="new TuneUpSandbox.Ajax.Request('/tuneup/#{state}', {asynchronous:true, evalScripts:true}); return false;" href="#">Turn #{state.to_s.titleize}</a>|.html_safe!
8
+ end
9
+
10
+ def tuneup_recording?
11
+ Fiveruns::Tuneup.recording?
12
+ end
13
+
14
+ def tuneup_css_class_for_step(step)
15
+ returning [] do |classes|
16
+ if step.children.any?
17
+ classes << 'with-children'
18
+ classes << 'tuneup-opened' if step.depth == 1 || open_step?(step)
19
+ end
20
+ end.join(' ')
21
+ end
22
+
23
+ def tuneup_collecting?
24
+ Fiveruns::Tuneup.collecting
25
+ end
26
+
27
+ def tuneup_data
28
+ most_recent_data = Fiveruns::Tuneup.stack.first
29
+ most_recent_data.blank? ? most_recent_data : most_recent_data['stack']
30
+ end
31
+
32
+ def tuneup_schemas
33
+ Fiveruns::Tuneup.stack.first['schemas']
34
+ end
35
+
36
+ def trend
37
+ numbers= if Fiveruns::Tuneup.trend.size > 50
38
+ Fiveruns::Tuneup.trend[-50..-1]
39
+ else
40
+ Fiveruns::Tuneup.trend
41
+ end
42
+ return unless numbers.size > 1
43
+ tag(:img,
44
+ :src => build_data_url("image/png",bumpspark(numbers)), :alt => '',
45
+ :title => "Trend over last #{pluralize(numbers.size, 'run')}")
46
+ end
47
+
48
+ def open_step?(step)
49
+ [/^Around filter/, /^Invoke/].any? { |pattern| step.name =~ pattern }
50
+ end
51
+
52
+ def tuneup_step_link(step)
53
+ name = tuneup_style_step_name(tuneup_truncate_step_name(step))
54
+ link = if step.children.any?
55
+ link_to_function(name, "TuneUpSandbox.$('#{dom_id(step, :children)}').toggle();TuneUpSandbox.$('#{dom_id(step)}').toggleClassName('tuneup-opened');", :class => "tuneup-step-link", :title => step.name)
56
+ else
57
+ content_tag(:span, name, :title => step.name)
58
+ end
59
+ link << additional_step_links(step)
60
+ end
61
+
62
+ def link_to_show
63
+ %|<a id="tuneup-back-to-run-link" onclick="#{redisplay_last_run} return false;" href="#">&lt;&lt;&lt; Back to Run</a>|.html_safe!
64
+ end
65
+
66
+ def redisplay_last_run(namespaced=true)
67
+ namespace_js = lambda { |fun| namespaced ? "TuneUpSandbox.#{fun}" : fun }
68
+ "#{namespace_js['$']}('tuneup-panel').show();"
69
+ end
70
+
71
+
72
+ def additional_step_links(step)
73
+ returning '' do |text|
74
+ text << sql_link(step) if step.sql
75
+ text << schema_link(step) if step.table_name
76
+ end.html_safe!
77
+ end
78
+
79
+ def schema_link(step)
80
+ link_to_schema(image_tag('/images/tuneup/schema.png', :alt => 'Schema'), step.table_name, :class => 'tuneup-schema tuneup-halo')
81
+ end
82
+
83
+ def sql_link(step)
84
+ link_to_function(image_tag('/images/tuneup/magnify.png', :alt => 'Query'), :class => 'tuneup-sql tuneup-halo', :title => 'View Query') do |page|
85
+ page << %(TuneUpSandbox.$("#{dom_id(step, :sql)}").toggle(); return false;)
86
+ end
87
+ end
88
+
89
+ def link_to_schema(text, table, html_options={})
90
+ link_to_function(text, "TuneUp.switchSchema('#{table}')", html_options.merge(:title => "View Schema"))
91
+ end
92
+
93
+ def tuneup_truncate_step_name(step)
94
+ chars = 50 - (step.depth * 2)
95
+ tuneup_truncate(step.name, chars)
96
+ end
97
+
98
+ def tuneup_bar(step=tuneup_data, options={})
99
+ width = options.delete(:width) || 200
100
+ bars = Fiveruns::Tuneup::Step.layers.map do |layer|
101
+ percent = step.percentages_by_layer[layer]
102
+ if percent == 0
103
+ next
104
+ else
105
+ begin
106
+ size = (percent * width).to_i
107
+ rescue
108
+ raise "Can't find percent for #{layer.inspect} from #{step.percentages_by_layer.inspect}"\
109
+ end
110
+ end
111
+ size = 1 if size.zero?
112
+ content_tag(:li, ((size >= 10 && layer != :other) ? layer.to_s[0, 1].capitalize : ''),
113
+ :class => "tuneup-layer-#{layer}",
114
+ :style => "width:#{size}px",
115
+ :title => layer.to_s.titleize)
116
+ end
117
+ content_tag(:ul, bars.compact.join, options.merge(:class => 'tuneup-bar'))
118
+ end
119
+
120
+ def tuneup_style_step_name(name)
121
+ case name
122
+ when /^Perform (\S+) action in (\S+Controller)$/
123
+ "Perform <strong>#{h $1}</strong> action in <strong>#{h $2}</strong>"
124
+ when /^Invoke (\S+) action$/
125
+ "Invoke <strong>#{h $1}</strong> action"
126
+ when /^(Find|Create|Delete|Update) ([A-Z]\S*)(.*?)$/
127
+ "#{h $1} <strong>#{h $2}</strong>#{h $3}"
128
+ when /^(Render.*?)(\S+)$/
129
+ "#{h $1}<strong>#{h $2}</strong>"
130
+ when /^(\S+ filter )(.*?)$/
131
+ "#{h $1}<strong>#{h $2}</strong>"
132
+ when 'Other'
133
+ "(<i>Other</i>)"
134
+ else
135
+ h(name)
136
+ end
137
+ end
138
+
139
+ def tuneup_truncate(text, max=32)
140
+ if text.size > max
141
+ component = (max - 3) / 2
142
+ remainder = (max - 3) % 2
143
+ begin
144
+ text.sub(/^(.{#{component}}).*?(.{#{component + remainder}})$/s, '\1...\2')
145
+ rescue
146
+ text
147
+ end
148
+ else
149
+ text
150
+ end
151
+ end
152
+
153
+ def tuneup_reload_panel
154
+ update_page do |page|
155
+ page << "$('tuneup-flash').removeClassName('tuneup-show');"
156
+ page << %[$('tuneup-content').update("#{escape_javascript(render(:partial => 'tuneup/panel/show.html.erb'))}");]
157
+ page << 'TuneUp.adjustAbsoluteElements(_document.body);'
158
+ page << 'TuneUp.adjustFixedElements();'
159
+ end
160
+ end
161
+
162
+ def tuneup_show_flash(type, locals)
163
+ types = [:error, :notice].reject { |t| t == type }
164
+ update_page do |page|
165
+ page << %[$('tuneup-flash').update("#{escape_javascript(render(:partial => 'flash.html.erb', :locals => locals.merge(:type => type)))}");]
166
+ page << "$('tuneup-flash').addClassName('tuneup-show')"
167
+ types.each do |other_type|
168
+ page << "$('tuneup-flash').removeClassName('tuneup-#{other_type}')"
169
+ end
170
+ page << "$('tuneup-flash').addClassName('tuneup-#{type}')"
171
+ page << 'TuneUp.adjustAbsoluteElements(_document.body);'
172
+ page << 'TuneUp.adjustFixedElements();'
173
+ end
174
+ end
175
+
176
+ def link_to_edit_step(step)
177
+ return nil unless step.file && step.line && RUBY_PLATFORM.include?('darwin')
178
+ link_to(image_tag('/images/tuneup/edit.png', :alt => 'Edit'), "txmt://open?url=file://#{CGI.escape step.file}&amp;line=#{step.line}", :class => 'tuneup-edit tuneup-halo', :title => 'Open in TextMate')
179
+ end
180
+
181
+ end
@@ -0,0 +1,14 @@
1
+ Fiveruns::Tuneup.start do
2
+ require 'dispatcher'
3
+
4
+ Fiveruns::Tuneup::Routing.install
5
+
6
+ Dispatcher.to_prepare :tuneup_controller_filters do
7
+ TuneupController.filter_chain.clear
8
+ end
9
+ [ActionController::Base, ActiveRecord::Base, ActionView::Base].each do |target|
10
+ target.extend Fiveruns::Tuneup::CustomMethods
11
+ end
12
+ ActionController::Base.append_view_path(File.dirname(__FILE__) << "/../views")
13
+ require File.dirname(__FILE__) << "/../install" # Check for assets
14
+ end
@@ -0,0 +1,32 @@
1
+ namespace :fiveruns do
2
+
3
+ namespace :tuneup do
4
+
5
+ namespace :tmp do
6
+
7
+ desc "Clear tempory data (runs, etc)"
8
+ task :clear => :environment do
9
+ rm_rf File.join(RAILS_ROOT, 'tmp', 'tuneup')
10
+ end
11
+
12
+ end
13
+
14
+ namespace :assets do
15
+
16
+ desc "Install assets"
17
+ task :install => :environment do
18
+ require File.dirname(__FILE__) << "/../install"
19
+ end
20
+
21
+ desc "Uninstall assets"
22
+ task :uninstall => :environment do
23
+ require File.dirname(__FILE__) << "/../uninstall"
24
+ end
25
+
26
+ task :reset => [:uninstall, :install]
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'Shoulda'
File without changes
@@ -0,0 +1,6 @@
1
+ # Remove Assets
2
+ Dir[File.join(RAILS_ROOT, 'public', '*', 'tuneup')].each do |asset_dir|
3
+ show_name = asset_dir.split(File::SEPARATOR)[-3, 3].join(File::SEPARATOR)
4
+ FileUtils.rm_rf(asset_dir) rescue nil
5
+ STDERR.puts "FiveRuns TuneUp: Removed #{show_name}"
6
+ end
@@ -0,0 +1,15 @@
1
+ <div id='tuneup-data'>
2
+ <div id='tuneup-top'>
3
+ <div id='tuneup-summary'>
4
+ <%= image_tag('tuneup/pin.png', :id => 'tuneup-pin',
5
+ :style => 'float:left;', :onclick => 'TuneUp.pinToggle()') %>
6
+ <%= tuneup_bar(tuneup_data.children.first, :id => 'tuneup-root-bar') %>
7
+ <%= trend %> <%= tuneup_data.time.to_i %> ms
8
+ </div>
9
+ </div>
10
+ <%= render :partial => 'schema.html.erb' %>
11
+ <ul id="tuneup-details">
12
+ <%= render :partial => 'step.html.erb', :collection => tuneup_data.children %>
13
+ <li style="clear:both"></li>
14
+ </ul>
15
+ </div>
@@ -0,0 +1,6 @@
1
+ <p>
2
+ <%= message %>
3
+ <% if type == :error %>
4
+ <emph>If problems persist, please contact <%= link_to "FiveRuns Support", 'mailto:support@fiveruns.com' %>.</emph>
5
+ <% end %>
6
+ </p>
@@ -0,0 +1 @@
1
+ <p class='tuneup-full'><%= tuneup_collection_link %></p>
@@ -0,0 +1,17 @@
1
+ <div id='tuneup-schema' style='display:none;'>
2
+ <% Fiveruns::Tuneup.schemas.each do |table, schema| %>
3
+ <div id='tuneup-schema-table-<%= table %>' class='tuneup-schema-table' style='display:none;'>
4
+ <h3>Schema for '<%= table %>'</h3>
5
+ <table>
6
+ <tr>
7
+ <th>Name</th><th>Type</th>
8
+ </tr>
9
+ <% schema[:columns].each do |column| %>
10
+ <tr>
11
+ <td><%=h column[:name] %></td><td><%=h column[:sql_type] %></td>
12
+ </tr>
13
+ <% end %>
14
+ </table>
15
+ </div>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,23 @@
1
+ <form id='<%= dom_id(step, :sql) %>' style='display:none;'>
2
+ <textarea cols='80' rows='<%= sql.query.split("\n").size %>'><%= sql.query %></textarea>
3
+ <% if sql.explain %>
4
+ <table>
5
+ <tr>
6
+ <% sql.explain.fields.each do |field| %>
7
+ <th><%=h field %></th>
8
+ <% end %>
9
+ </tr>
10
+ <% sql.explain.rows.each do |row| %>
11
+ <tr>
12
+ <% row.each_with_index do |value, index| %>
13
+ <% if index == sql.explain.table_offset %>
14
+ <td><%= link_to_schema value, value %></td>
15
+ <% else %>
16
+ <td><%=h value%></td>
17
+ <% end %>
18
+ <% end %>
19
+ </tr>
20
+ <% end %>
21
+ </table>
22
+ <% end %>
23
+ </form>