gestalt 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -26,10 +26,15 @@ You have a feeling that it could do better with single, so check to see what hap
26
26
  end
27
27
 
28
28
  This will give you output in the following format:
29
- duration method file
30
- duration method file
29
+ percentage times method file
30
+ percentage times method file
31
31
 
32
- The duration on the outermost call is the total for all nested calls, and the duration of the indented lines show how long the individual parts took.
32
+ percentage is the percent of the parent that these calls account for
33
+ times is how many times the thing was called
34
+ method tells you what was called
35
+ and file tells you where it was called from
36
+
37
+ Indents means nesting, durations for outer calls include inner calls and the times for inner calls happened for each of the outer calls.
33
38
 
34
39
  You can also get a summary after the fact:
35
40
 
data/Rakefile CHANGED
@@ -1,49 +1,147 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'date'
3
4
 
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "gestalt"
8
- gem.summary = %Q{Simple Ruby profiling}
9
- gem.description = %Q{Simple Ruby profiling}
10
- gem.email = "wbeary@engineyard.com"
11
- gem.homepage = "http://github.com/geemus/gestalt"
12
- gem.authors = ["geemus (Wesley Beary)"]
13
- gem.add_dependency "formatador", ">= 0.0.12"
14
- gem.add_development_dependency "shindo", ">= 0"
15
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
- end
17
- rescue LoadError
18
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
5
+ #############################################################################
6
+ #
7
+ # Helper functions
8
+ #
9
+ #############################################################################
10
+
11
+ def name
12
+ @name ||= Dir['*.gemspec'].first.split('.').first
19
13
  end
20
14
 
21
- require 'shindo/rake'
22
- Shindo::Rake.new
15
+ def version
16
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
23
19
 
24
- begin
25
- require 'rcov/rcovtask'
26
- Rcov::RcovTask.new do |tests|
27
- tests.libs << 'tests'
28
- tests.pattern = 'tests/**/*_tests.rb'
29
- tests.verbose = true
30
- end
31
- rescue LoadError
32
- task :rcov do
33
- abort "RCov is not available. In order to run rcov, you must: gem install spicycode-rcov"
34
- end
20
+ def date
21
+ Date.today.to_s
35
22
  end
36
23
 
37
- task :tests => :check_dependencies
24
+ def rubyforge_project
25
+ name
26
+ end
38
27
 
39
- task :default => :tests
28
+ def gemspec_file
29
+ "#{name}.gemspec"
30
+ end
31
+
32
+ def gem_file
33
+ "#{name}-#{version}.gem"
34
+ end
35
+
36
+ def replace_header(head, header_name)
37
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
+ end
39
+
40
+ #############################################################################
41
+ #
42
+ # Standard tasks
43
+ #
44
+ #############################################################################
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/testtask'
49
+ Rake::TestTask.new(:test) do |test|
50
+ test.libs << 'lib' << 'test'
51
+ test.pattern = 'test/**/test_*.rb'
52
+ test.verbose = true
53
+ end
54
+
55
+ desc "Generate RCov test coverage and open in your browser"
56
+ task :coverage do
57
+ require 'rcov'
58
+ sh "rm -fr coverage"
59
+ sh "rcov test/test_*.rb"
60
+ sh "open coverage/index.html"
61
+ end
40
62
 
41
63
  require 'rake/rdoctask'
42
64
  Rake::RDocTask.new do |rdoc|
43
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
-
45
65
  rdoc.rdoc_dir = 'rdoc'
46
- rdoc.title = "gestalt #{version}"
66
+ rdoc.title = "#{name} #{version}"
47
67
  rdoc.rdoc_files.include('README*')
48
68
  rdoc.rdoc_files.include('lib/**/*.rb')
49
69
  end
70
+
71
+ desc "Open an irb session preloaded with this library"
72
+ task :console do
73
+ sh "irb -rubygems -r ./lib/#{name}.rb"
74
+ end
75
+
76
+ #############################################################################
77
+ #
78
+ # Custom tasks (add your own tasks here)
79
+ #
80
+ #############################################################################
81
+
82
+
83
+
84
+ #############################################################################
85
+ #
86
+ # Packaging tasks
87
+ #
88
+ #############################################################################
89
+
90
+ task :release => :build do
91
+ unless `git branch` =~ /^\* master$/
92
+ puts "You must be on the master branch to release!"
93
+ exit!
94
+ end
95
+ sh "sudo gem install pkg/#{name}-#{version}.gem"
96
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
97
+ sh "git tag v#{version}"
98
+ sh "git push origin master"
99
+ sh "git push origin v#{version}"
100
+ sh "gem push pkg/#{name}-#{version}.gem"
101
+ end
102
+
103
+ task :build => :gemspec do
104
+ sh "mkdir -p pkg"
105
+ sh "gem build #{gemspec_file}"
106
+ sh "mv #{gem_file} pkg"
107
+ end
108
+
109
+ task :gemspec => :validate do
110
+ # read spec file and split out manifest section
111
+ spec = File.read(gemspec_file)
112
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
113
+
114
+ # replace name version and date
115
+ replace_header(head, :name)
116
+ replace_header(head, :version)
117
+ replace_header(head, :date)
118
+ #comment this out if your rubyforge_project has a different name
119
+ replace_header(head, :rubyforge_project)
120
+
121
+ # determine file list from git ls-files
122
+ files = `git ls-files`.
123
+ split("\n").
124
+ sort.
125
+ reject { |file| file =~ /^\./ }.
126
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
127
+ map { |file| " #{file}" }.
128
+ join("\n")
129
+
130
+ # piece file back together and write
131
+ manifest = " s.files = %w[\n#{files}\n ]\n"
132
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
133
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
134
+ puts "Updated #{gemspec_file}"
135
+ end
136
+
137
+ task :validate do
138
+ libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
139
+ unless libfiles.empty?
140
+ puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
141
+ exit!
142
+ end
143
+ unless Dir['VERSION*'].empty?
144
+ puts "A `VERSION` file at root level violates Gem best practices."
145
+ exit!
146
+ end
147
+ end
data/gestalt.gemspec CHANGED
@@ -1,54 +1,76 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
1
+ ## This is the rakegem gemspec template. Make sure you read and understand
2
+ ## all of the comments. Some sections require modification, and others can
3
+ ## be deleted if you don't need them. Once you understand the contents of
4
+ ## this file, feel free to delete any comments that begin with two hash marks.
5
+ ## You can find comprehensive Gem::Specification documentation, at
6
+ ## http://docs.rubygems.org/read/chapter/20
6
7
  Gem::Specification.new do |s|
7
- s.name = %q{gestalt}
8
- s.version = "0.0.1"
9
-
8
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["geemus (Wesley Beary)"]
12
- s.date = %q{2010-04-12}
13
- s.description = %q{Simple Ruby profiling}
14
- s.email = %q{wbeary@engineyard.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "gestalt.gemspec",
27
- "lib/gestalt.rb",
28
- "lib/gestalt/call.rb",
29
- "tests/gestalt_tests.rb",
30
- "tests/tests_helper.rb"
31
- ]
32
- s.homepage = %q{http://github.com/geemus/gestalt}
10
+ s.rubygems_version = '1.3.5'
11
+
12
+ ## Leave these as is they will be modified for you by the rake gemspec task.
13
+ ## If your rubyforge_project name is different, then edit it and comment out
14
+ ## the sub! line in the Rakefile
15
+ s.name = 'gestalt'
16
+ s.version = '0.0.2'
17
+ s.date = '2010-04-26'
18
+ s.rubyforge_project = 'gestalt'
19
+
20
+ ## Make sure your summary is short. The description may be as long
21
+ ## as you like.
22
+ s.summary = "Simple Ruby profiling and tracing."
23
+ s.description = "Simple Ruby profiling and tracing."
24
+
25
+ ## List the primary authors. If there are a bunch of authors, it's probably
26
+ ## better to set the email to an email list or something. If you don't have
27
+ ## a custom homepage, consider using your GitHub URL or the like.
28
+ s.authors = ["geemus (Wesley Beary)"]
29
+ s.email = 'geemus@gmail.com'
30
+ s.homepage = 'http://github.com/geemus/NAME'
31
+
32
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
+ s.require_paths = %w[lib]
35
+
36
+ ## This sections is only necessary if you have C extensions.
37
+ # s.require_paths << 'ext'
38
+ # s.extensions = %w[ext/extconf.rb]
39
+
40
+ ## If your gem includes any executables, list them here.
41
+ # s.executables = ["name"]
42
+ # s.default_executable = 'name'
43
+
44
+ ## Specify any RDoc options here. You'll want to add your README and
45
+ ## LICENSE files to the extra_rdoc_files list.
33
46
  s.rdoc_options = ["--charset=UTF-8"]
34
- s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.6}
36
- s.summary = %q{Simple Ruby profiling}
37
-
38
- if s.respond_to? :specification_version then
39
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
- s.specification_version = 3
41
-
42
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
- s.add_runtime_dependency(%q<formatador>, [">= 0.0.12"])
44
- s.add_development_dependency(%q<shindo>, [">= 0"])
45
- else
46
- s.add_dependency(%q<formatador>, [">= 0.0.12"])
47
- s.add_dependency(%q<shindo>, [">= 0"])
48
- end
49
- else
50
- s.add_dependency(%q<formatador>, [">= 0.0.12"])
51
- s.add_dependency(%q<shindo>, [">= 0"])
52
- end
53
- end
47
+ s.extra_rdoc_files = %w[README.rdoc]
48
+
49
+ ## List your runtime dependencies here. Runtime dependencies are those
50
+ ## that are needed for an end user to actually USE your code.
51
+ s.add_dependency("formatador", ">= 0.0.12")
54
52
 
53
+ ## List your development dependencies here. Development dependencies are
54
+ ## those that are only needed during development
55
+ s.add_development_dependency("shindo", ">= 0")
56
+
57
+ ## Leave this section as-is. It will be automatically generated from the
58
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
59
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
60
+ # = MANIFEST =
61
+ s.files = %w[
62
+ LICENSE
63
+ README.rdoc
64
+ Rakefile
65
+ gestalt.gemspec
66
+ lib/gestalt.rb
67
+ lib/gestalt/call.rb
68
+ tests/gestalt_tests.rb
69
+ tests/tests_helper.rb
70
+ ]
71
+ # = MANIFEST =
72
+
73
+ ## Test files will be grabbed from the file list. Make sure the path glob
74
+ ## matches what you actually use.
75
+ s.test_files = s.files.select { |path| path =~ /^[spec|tests]\/.*_[spec|tests]\.rb/ }
76
+ end
data/lib/gestalt/call.rb CHANGED
@@ -2,7 +2,7 @@ class Gestalt
2
2
 
3
3
  class Call
4
4
 
5
- attr_accessor :children
5
+ attr_accessor :children, :durations
6
6
  attr_accessor :action, :finished_at, :location, :started_at
7
7
 
8
8
  def initialize(attributes = {})
@@ -11,19 +11,48 @@ class Gestalt
11
11
  send("#{key}=", value)
12
12
  end
13
13
  @children ||= []
14
+ @durations ||= []
14
15
  end
15
16
 
16
- def display(formatador = Formatador.new)
17
- formatador.display_line("#{format("%.6f",duration)} [bold]#{action}[/] [light_black]#{location}[/]")
17
+ def ==(other)
18
+ action == other.action && location == other.location && children == other.children
19
+ end
20
+
21
+ def display(total, formatador = Formatador.new)
22
+ data = []
23
+ data << format("[bold]%.1f%%[/]", (duration / total) * 100.0)
24
+ if durations.length > 1
25
+ data << "[light_black]#{durations.length}x[/]"
26
+ end
27
+ data << "[bold]#{action}[/]"
28
+ data << "[light_black]#{location}[/]"
29
+ condensed = []
30
+ total = 0.0
31
+ for call in children
32
+ if condensed.last && condensed.last == call
33
+ condensed.last.durations.concat(call.durations)
34
+ else
35
+ condensed << call
36
+ end
37
+ total += call.duration
38
+ end
39
+ formatador.display_line(data.join(' '))
18
40
  formatador.indent do
19
- for child in children
20
- child.display(formatador)
41
+ for child in condensed
42
+ child.display(total, formatador)
21
43
  end
22
44
  end
23
45
  end
24
46
 
25
47
  def duration
26
- finished_at - started_at
48
+ durations.inject(0.0) {|memo, duration| duration + memo}
49
+ end
50
+
51
+ def durations
52
+ if @durations.empty?
53
+ @durations << finished_at - started_at
54
+ end
55
+ @durations
27
56
  end
28
57
 
29
58
  def finish
data/lib/gestalt.rb CHANGED
@@ -5,7 +5,9 @@ require 'formatador'
5
5
 
6
6
  class Gestalt
7
7
 
8
- attr_accessor :calls
8
+ VERSION = '0.0.2'
9
+
10
+ attr_accessor :calls, :formatador
9
11
 
10
12
  def initialize
11
13
  @calls = []
@@ -14,11 +16,21 @@ class Gestalt
14
16
  end
15
17
 
16
18
  def display_calls
17
- Formatador.display_line
19
+ formatador.display_line
20
+ condensed = []
21
+ total = 0.0
18
22
  for call in @calls
19
- call.display
23
+ if condensed.last && condensed.last == call
24
+ condensed.last.durations.concat(call.durations)
25
+ else
26
+ condensed << call
27
+ end
28
+ total += call.duration
29
+ end
30
+ for call in condensed
31
+ call.display(total, formatador)
20
32
  end
21
- Formatador.display_line
33
+ formatador.display_line
22
34
  end
23
35
 
24
36
  def display_profile
@@ -29,16 +41,19 @@ class Gestalt
29
41
  table = []
30
42
  for key, value in @totals
31
43
  table << {
32
- '#' => value[:occurances],
33
- :action => key,
44
+ :action => "#{value[:occurances]}x #{key}",
34
45
  :duration => format("%.6f", value[:duration])
35
46
  }
36
47
  end
37
48
  table = table.sort {|x,y| y[:duration] <=> x[:duration]}
38
49
 
39
- Formatador.display_line
40
- Formatador.display_table(table)
41
- Formatador.display_line
50
+ formatador.display_line
51
+ formatador.display_table(table)
52
+ formatador.display_line
53
+ end
54
+
55
+ def formatador
56
+ @formatador ||= Formatador.new
42
57
  end
43
58
 
44
59
  def run(&block)
@@ -68,6 +83,7 @@ class Gestalt
68
83
  end
69
84
  )
70
85
  yield
86
+ rescue StandardError, Interrupt
71
87
  Kernel.set_trace_func(nil)
72
88
  @stack.pop # pop Kernel#set_trace_func(nil)
73
89
  unless @stack.empty?
@@ -107,15 +123,26 @@ end
107
123
 
108
124
  if __FILE__ == $0
109
125
 
126
+ Gestalt.trace do
127
+ raise StandardError.new('exception')
128
+ slow = Slow.new
129
+ slow.slowing
130
+ end
131
+
110
132
  class Slow
111
133
 
112
- def single
113
- 'slow' << 'er'
134
+ def slow(est = false)
135
+ unless est
136
+ 'slow' << 'e' << 'r'
137
+ else
138
+ 'slow' << 'e' << 's' << 't'
139
+ end
114
140
  end
115
141
 
116
- def double
117
- single
118
- single
142
+ def slowing
143
+ slow
144
+ slow
145
+ slow(true)
119
146
  end
120
147
 
121
148
  end
@@ -123,14 +150,14 @@ if __FILE__ == $0
123
150
  Gestalt.trace do
124
151
 
125
152
  slow = Slow.new
126
- slow.single
153
+ slow.slowing
127
154
 
128
155
  end
129
156
 
130
157
  Gestalt.profile do
131
158
 
132
159
  slow = Slow.new
133
- slow.double
160
+ slow.slowing
134
161
 
135
162
  end
136
163
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - geemus (Wesley Beary)
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-12 00:00:00 -07:00
17
+ date: 2010-04-26 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -43,29 +43,25 @@ dependencies:
43
43
  version: "0"
44
44
  type: :development
45
45
  version_requirements: *id002
46
- description: Simple Ruby profiling
47
- email: wbeary@engineyard.com
46
+ description: Simple Ruby profiling and tracing.
47
+ email: geemus@gmail.com
48
48
  executables: []
49
49
 
50
50
  extensions: []
51
51
 
52
52
  extra_rdoc_files:
53
- - LICENSE
54
53
  - README.rdoc
55
54
  files:
56
- - .document
57
- - .gitignore
58
55
  - LICENSE
59
56
  - README.rdoc
60
57
  - Rakefile
61
- - VERSION
62
58
  - gestalt.gemspec
63
59
  - lib/gestalt.rb
64
60
  - lib/gestalt/call.rb
65
61
  - tests/gestalt_tests.rb
66
62
  - tests/tests_helper.rb
67
63
  has_rdoc: true
68
- homepage: http://github.com/geemus/gestalt
64
+ homepage: http://github.com/geemus/NAME
69
65
  licenses: []
70
66
 
71
67
  post_install_message:
@@ -89,10 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
85
  version: "0"
90
86
  requirements: []
91
87
 
92
- rubyforge_project:
88
+ rubyforge_project: gestalt
93
89
  rubygems_version: 1.3.6
94
90
  signing_key:
95
- specification_version: 3
96
- summary: Simple Ruby profiling
91
+ specification_version: 2
92
+ summary: Simple Ruby profiling and tracing.
97
93
  test_files: []
98
94
 
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.gitignore DELETED
@@ -1,39 +0,0 @@
1
- # rcov generated
2
- coverage
3
-
4
- # rdoc generated
5
- rdoc
6
-
7
- # yard generated
8
- doc
9
- .yardoc
10
-
11
- # jeweler generated
12
- pkg
13
-
14
- # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
15
- #
16
- # * Create a file at ~/.gitignore
17
- # * Include files you want ignored
18
- # * Run: git config --global core.excludesfile ~/.gitignore
19
- #
20
- # After doing this, these files will be ignored in all your git projects,
21
- # saving you from having to 'pollute' every project you touch with them
22
- #
23
- # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
24
- #
25
- # For MacOS:
26
- #
27
- #.DS_Store
28
- #
29
- # For TextMate
30
- #*.tmproj
31
- #tmtags
32
- #
33
- # For emacs:
34
- #*~
35
- #\#*
36
- #.\#*
37
- #
38
- # For vim:
39
- #*.swp
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.1