hotch 0.5.1 → 0.7.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.
- checksums.yaml +4 -4
- data/.github/workflows/examples.yml +32 -0
- data/.github/workflows/rubocop.yml +27 -0
- data/.rubocop.yml +33 -0
- data/.rubocop_todo.yml +29 -0
- data/Gemfile +4 -2
- data/README.md +22 -4
- data/Rakefile +20 -1
- data/examples/bundler.rb +4 -2
- data/examples/example_test.rb +27 -0
- data/examples/memory_at_exit.rb +17 -0
- data/examples/memory_inline_report.rb +17 -0
- data/examples/simple.rb +5 -3
- data/hotch.gemspec +17 -9
- data/lib/hotch/memory/minitest.rb +2 -0
- data/lib/hotch/memory/run.rb +5 -0
- data/lib/hotch/memory.rb +39 -22
- data/lib/hotch/minitest.rb +2 -0
- data/lib/hotch/run.rb +4 -2
- data/lib/hotch/version.rb +3 -1
- data/lib/hotch.rb +36 -33
- metadata +70 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eb97e655dfb1434f9daca5881a176396784567b38767a4b0565ae5de04dfe89
|
4
|
+
data.tar.gz: c213f3fb8ffa21cf24ee59bab49f726ca79dfeac8b72c336cee3dc865b3e1714
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 463f7514b9afb0cea840fec91bf08d410380ef08fbe08040b50ee59ad90ff31186fe0185f124cb1db7042def01818ac215ae66fa922a995dfc47b5f193d25b16
|
7
|
+
data.tar.gz: 64994356dbfb2bfad732eeaf42b4e698bf002409de0a943b6fa2af31fc5de9a42c9ad3627f95250369d69adecbbb76a256fc69370dc13aabc9e125f468a10ea8
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Test examples
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
jobs:
|
6
|
+
run:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
ruby-version:
|
11
|
+
- "2.7"
|
12
|
+
- "3.0"
|
13
|
+
- "3.1"
|
14
|
+
runs-on:
|
15
|
+
- ubuntu-latest
|
16
|
+
name: ${{ matrix.ruby-version}} on ${{ matrix.runs-on }}
|
17
|
+
runs-on: ${{ matrix.runs-on }}
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@master
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby-version }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Install system dependencies
|
25
|
+
run: |
|
26
|
+
sudo apt install --yes graphviz
|
27
|
+
- name: Install dependencies
|
28
|
+
run: |
|
29
|
+
bundle install
|
30
|
+
- name:
|
31
|
+
run: |
|
32
|
+
bundle exec rake test:examples
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: RuboCop
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
jobs:
|
6
|
+
run:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
ruby-version:
|
11
|
+
- "3.1"
|
12
|
+
runs-on:
|
13
|
+
- ubuntu-latest
|
14
|
+
name: ${{ matrix.ruby-version}} on ${{ matrix.runs-on }}
|
15
|
+
runs-on: ${{ matrix.runs-on }}
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@master
|
18
|
+
- uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby-version }}
|
21
|
+
bundler-cache: true
|
22
|
+
- name: Install dependencies
|
23
|
+
run: |
|
24
|
+
bundle install
|
25
|
+
- name:
|
26
|
+
run: |
|
27
|
+
bundle exec rubocop
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
inherit_from: .rubocop_todo.yml
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
NewCops: enable
|
6
|
+
|
7
|
+
require:
|
8
|
+
- rubocop-minitest
|
9
|
+
- rubocop-rake
|
10
|
+
|
11
|
+
Layout/ArrayAlignment:
|
12
|
+
EnforcedStyle: with_fixed_indentation
|
13
|
+
|
14
|
+
Layout/FirstArgumentIndentation:
|
15
|
+
EnforcedStyle: consistent
|
16
|
+
|
17
|
+
Layout/FirstArrayElementIndentation:
|
18
|
+
EnforcedStyle: consistent
|
19
|
+
|
20
|
+
Layout/FirstHashElementIndentation:
|
21
|
+
EnforcedStyle: consistent
|
22
|
+
|
23
|
+
Style/Documentation:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/CaseEquality:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Layout/ParameterAlignment:
|
30
|
+
EnforcedStyle: with_fixed_indentation
|
31
|
+
|
32
|
+
Style/StringLiterals:
|
33
|
+
EnforcedStyle: double_quotes
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2022-12-12 12:04:13 UTC using RuboCop version 1.38.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
Lint/StructNewOverride:
|
11
|
+
Exclude:
|
12
|
+
- 'lib/hotch/memory.rb'
|
13
|
+
|
14
|
+
# Offense count: 2
|
15
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, AllowedMethods, AllowedPatterns, IgnoredMethods.
|
16
|
+
Metrics/MethodLength:
|
17
|
+
Max: 13
|
18
|
+
|
19
|
+
# Offense count: 1
|
20
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
21
|
+
Metrics/ParameterLists:
|
22
|
+
Max: 6
|
23
|
+
|
24
|
+
# Offense count: 2
|
25
|
+
# Configuration parameters: AllowedVariables.
|
26
|
+
Style/GlobalVars:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/hotch.rb'
|
29
|
+
- 'lib/hotch/memory.rb'
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -62,7 +62,7 @@ dry/struct/class_interface.rb:77 T_OBJECT 2000 0 0 0
|
|
62
62
|
Add this line to your application's Gemfile:
|
63
63
|
|
64
64
|
```ruby
|
65
|
-
gem 'hotch', '~> 0.
|
65
|
+
gem 'hotch', '~> 0.7.0'
|
66
66
|
```
|
67
67
|
|
68
68
|
And then execute:
|
@@ -138,6 +138,10 @@ Hotch::Minitest.run(options: { limit: 200 })
|
|
138
138
|
|
139
139
|
### Memory profiler
|
140
140
|
|
141
|
+
Shell usage:
|
142
|
+
|
143
|
+
$ ruby -rhotch/memory/run my_program.rb
|
144
|
+
|
141
145
|
Require `hotch/memory` and use `Hotch.memory { ... }` as in:
|
142
146
|
|
143
147
|
```ruby
|
@@ -183,6 +187,20 @@ Hotch.memory(aggregate: false) do
|
|
183
187
|
end
|
184
188
|
```
|
185
189
|
|
190
|
+
#### Inline reporting
|
191
|
+
|
192
|
+
This prints two ASCII tables showing the object alloctions two calls:
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
puts Hotch::Memory.report("memory") {
|
196
|
+
# ...
|
197
|
+
}
|
198
|
+
|
199
|
+
puts Hotch::Memory.report("another") {
|
200
|
+
# ...
|
201
|
+
}
|
202
|
+
```
|
203
|
+
|
186
204
|
### Minitest integration for the memory profiler
|
187
205
|
|
188
206
|
Load `hotch/memory/minitest` in your `test/test_helper.rb` like this:
|
@@ -191,9 +209,9 @@ Load `hotch/memory/minitest` in your `test/test_helper.rb` like this:
|
|
191
209
|
require 'minitest/autorun'
|
192
210
|
require 'hotch/memory/minitest'
|
193
211
|
|
194
|
-
Hotch::Minitest.run
|
195
|
-
Hotch::Minitest.run(name: "my name")
|
196
|
-
Hotch::Minitest.run(disable_gc: false) # on by default
|
212
|
+
Hotch::Memory::Minitest.run
|
213
|
+
Hotch::Memory::Minitest.run(name: "my name")
|
214
|
+
Hotch::Memory::Minitest.run(disable_gc: false) # on by default
|
197
215
|
```
|
198
216
|
|
199
217
|
|
data/Rakefile
CHANGED
@@ -1,8 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler/gem_tasks"
|
2
4
|
|
3
|
-
task :
|
5
|
+
task default: :test
|
4
6
|
|
5
7
|
desc "Run tests. Not yet..."
|
6
8
|
task :test do
|
7
9
|
abort "No tests yet. Sorry :-("
|
8
10
|
end
|
11
|
+
|
12
|
+
desc "Run examples"
|
13
|
+
namespace :test do
|
14
|
+
desc "Run files in examples/"
|
15
|
+
task :examples do
|
16
|
+
chdir "examples" do
|
17
|
+
ENV["HOTCH_VIEWER"] = nil
|
18
|
+
|
19
|
+
Dir.glob("*.rb").sort.each do |file|
|
20
|
+
puts "=" * 80
|
21
|
+
sh "bundle", "exec", "ruby", file
|
22
|
+
|
23
|
+
puts
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/examples/bundler.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require "hotch/minitest"
|
5
|
+
require "hotch/memory/minitest"
|
6
|
+
|
7
|
+
Hotch::Minitest.run
|
8
|
+
Hotch::Memory::Minitest.run
|
9
|
+
|
10
|
+
class ExampleTest < Minitest::Test
|
11
|
+
def foo
|
12
|
+
"x" * 23
|
13
|
+
end
|
14
|
+
|
15
|
+
def bar
|
16
|
+
["x"] * 23
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_hotch
|
20
|
+
10_000.times do
|
21
|
+
foo
|
22
|
+
bar
|
23
|
+
end
|
24
|
+
|
25
|
+
assert true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hotch/memory"
|
4
|
+
|
5
|
+
ary = []
|
6
|
+
|
7
|
+
puts Hotch::Memory.report("1") {
|
8
|
+
ary << "string"
|
9
|
+
}
|
10
|
+
|
11
|
+
puts Hotch::Memory.report("2") {
|
12
|
+
ary << "another"
|
13
|
+
}
|
14
|
+
|
15
|
+
puts Hotch::Memory.report("3") {
|
16
|
+
ary.join(" ")
|
17
|
+
}
|
data/examples/simple.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "hotch"
|
4
|
+
|
5
|
+
COUNT = ENV.fetch("COUNT", 1_000_000)
|
4
6
|
|
5
7
|
def foo
|
6
8
|
"x" * 23
|
@@ -16,7 +18,7 @@ Hotch(aggregate: false) do
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
Hotch() do
|
21
|
+
Hotch(mode: :cpu) do
|
20
22
|
COUNT.times do
|
21
23
|
bar
|
22
24
|
end
|
data/hotch.gemspec
CHANGED
@@ -1,26 +1,34 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# frozen_string_literals: true
|
4
|
+
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
3
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
7
|
+
require "hotch/version"
|
5
8
|
|
6
9
|
Gem::Specification.new do |spec|
|
7
10
|
spec.name = "hotch"
|
8
11
|
spec.version = Hotch::VERSION
|
9
12
|
spec.authors = ["Peter Leitzen"]
|
10
13
|
spec.email = ["peter@leitzen.de"]
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
14
|
+
spec.summary = "Profile helper"
|
15
|
+
spec.description = "Callstack and memory profiler"
|
13
16
|
spec.homepage = "https://github.com/splattael/hotch"
|
14
17
|
spec.license = "MIT"
|
15
18
|
|
16
19
|
spec.files = `git ls-files -z`.split("\x0")
|
17
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
21
|
spec.require_paths = ["lib"]
|
20
22
|
|
21
|
-
spec.
|
23
|
+
spec.required_ruby_version = ">= 2.7.0"
|
24
|
+
|
22
25
|
spec.add_runtime_dependency "allocation_tracer", "~> 0.6.3"
|
26
|
+
spec.add_runtime_dependency "stackprof", "~> 0.2.15"
|
23
27
|
|
24
|
-
spec.add_development_dependency "bundler"
|
25
|
-
spec.add_development_dependency "rake", "
|
28
|
+
spec.add_development_dependency "bundler"
|
29
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
30
|
+
spec.add_development_dependency "rubocop"
|
31
|
+
spec.add_development_dependency "rubocop-minitest"
|
32
|
+
spec.add_development_dependency "rubocop-rake"
|
33
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
26
34
|
end
|
data/lib/hotch/memory.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "allocation_tracer"
|
4
|
+
require "stringio"
|
2
5
|
|
3
6
|
class Hotch
|
4
|
-
def self.memory(name: $
|
7
|
+
def self.memory(name: $PROGRAM_NAME, aggregate: true, &block)
|
5
8
|
memory = if aggregate
|
6
9
|
$hotch_memory ||= Memory.new(name)
|
7
10
|
else
|
@@ -28,16 +31,24 @@ class Hotch
|
|
28
31
|
@disable_gc = disable_gc
|
29
32
|
end
|
30
33
|
|
34
|
+
def self.report(name, **args, &block)
|
35
|
+
hotch = new(name, **args)
|
36
|
+
hotch.run(&block)
|
37
|
+
hotch.report
|
38
|
+
end
|
39
|
+
|
31
40
|
def start
|
32
41
|
return if @started
|
42
|
+
|
33
43
|
GC.disable if @disable_gc
|
34
|
-
ObjectSpace::AllocationTracer.setup [
|
44
|
+
ObjectSpace::AllocationTracer.setup %i[path line type]
|
35
45
|
ObjectSpace::AllocationTracer.start
|
36
46
|
@started = true
|
37
47
|
end
|
38
48
|
|
39
49
|
def stop
|
40
50
|
return unless @started
|
51
|
+
|
41
52
|
results = ObjectSpace::AllocationTracer.stop
|
42
53
|
@started = nil
|
43
54
|
GC.enable if @disable_gc
|
@@ -52,7 +63,7 @@ class Hotch
|
|
52
63
|
end
|
53
64
|
|
54
65
|
def report
|
55
|
-
# TODO make it persistent (as CSV)
|
66
|
+
# TODO: make it persistent (as CSV)
|
56
67
|
report = @reports.inject(:+)
|
57
68
|
@reports.clear
|
58
69
|
|
@@ -80,7 +91,7 @@ class Hotch
|
|
80
91
|
private
|
81
92
|
|
82
93
|
def name
|
83
|
-
@name.gsub(/\W+/,
|
94
|
+
@name.gsub(/\W+/, "_")
|
84
95
|
end
|
85
96
|
|
86
97
|
class Report
|
@@ -94,9 +105,9 @@ class Hotch
|
|
94
105
|
end
|
95
106
|
|
96
107
|
def +(other)
|
97
|
-
by_key =
|
108
|
+
by_key = @lines.to_h { |line| [line.key, line] }
|
98
109
|
other.lines.each do |line|
|
99
|
-
if existing = by_key[line.key]
|
110
|
+
if (existing = by_key[line.key])
|
100
111
|
existing.sum(line)
|
101
112
|
else
|
102
113
|
by_key[line.key] = line
|
@@ -107,7 +118,7 @@ class Hotch
|
|
107
118
|
end
|
108
119
|
|
109
120
|
def format
|
110
|
-
# TODO refactor
|
121
|
+
# TODO: refactor
|
111
122
|
max_lengths = Array.new(Line.members.size, 0)
|
112
123
|
([@header, @total] + @lines).each do |line|
|
113
124
|
line.lengths.each.with_index do |length, i|
|
@@ -131,17 +142,11 @@ class Hotch
|
|
131
142
|
io.string
|
132
143
|
end
|
133
144
|
|
134
|
-
|
135
|
-
return if defined? @total
|
136
|
-
|
137
|
-
@total = Line::Total.new
|
138
|
-
@lines.each do |line|
|
139
|
-
@total.sum(line)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
145
|
+
# rubocop:disable Style/StructInheritance
|
143
146
|
class Line < Struct.new(:filename, :type, :count, :old_count, :total_age,
|
144
147
|
:min_age, :max_age, :total_memsize)
|
148
|
+
# rubocop:enable Style/StructInheritance
|
149
|
+
|
145
150
|
# [
|
146
151
|
# [path, lineno, type],
|
147
152
|
# [count, old_count, total_age, min_age, max_age, total_memsize]
|
@@ -149,7 +154,8 @@ class Hotch
|
|
149
154
|
def self.from_result(result, ignore_paths)
|
150
155
|
path, line, *args = result.flatten(1)
|
151
156
|
return if ignore_paths.any? { |ip| ip == path || ip === path }
|
152
|
-
|
157
|
+
|
158
|
+
filename = "#{strip_path(path)}:#{line}"
|
153
159
|
new(filename, *args)
|
154
160
|
end
|
155
161
|
|
@@ -172,15 +178,15 @@ class Hotch
|
|
172
178
|
end
|
173
179
|
end
|
174
180
|
|
175
|
-
private
|
176
|
-
|
177
181
|
MAX_PATH_LENGTH = 50
|
178
182
|
def self.strip_path(path)
|
183
|
+
return "?" unless path
|
184
|
+
|
179
185
|
strip = %r{#{Regexp.union($LOAD_PATH)}/?}
|
180
186
|
path.gsub!(strip, "")
|
181
187
|
if path.size > MAX_PATH_LENGTH + 3
|
182
|
-
# TODO Refactor
|
183
|
-
"
|
188
|
+
# TODO: Refactor
|
189
|
+
"...#{path[-MAX_PATH_LENGTH..]}"
|
184
190
|
else
|
185
191
|
path
|
186
192
|
end
|
@@ -192,6 +198,17 @@ class Hotch
|
|
192
198
|
end
|
193
199
|
end
|
194
200
|
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def total!
|
205
|
+
return if defined? @total
|
206
|
+
|
207
|
+
@total = Line::Total.new
|
208
|
+
@lines.each do |line|
|
209
|
+
@total.sum(line)
|
210
|
+
end
|
211
|
+
end
|
195
212
|
end
|
196
213
|
end
|
197
214
|
end
|
data/lib/hotch/minitest.rb
CHANGED
data/lib/hotch/run.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
hotch
|
3
|
+
require "hotch"
|
4
|
+
|
5
|
+
hotch = Hotch.new($PROGRAM_NAME, viewer: ENV.fetch("HOTCH_VIEWER", nil), filter: ENV.fetch("HOTCH_FILTER", nil))
|
4
6
|
hotch.start
|
5
7
|
|
6
8
|
hotch.report_at_exit
|
data/lib/hotch/version.rb
CHANGED
data/lib/hotch.rb
CHANGED
@@ -1,33 +1,39 @@
|
|
1
|
-
|
2
|
-
require 'tmpdir'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require
|
3
|
+
require "stackprof"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
require "hotch/version"
|
5
7
|
|
6
8
|
class Hotch
|
7
|
-
attr_reader :
|
9
|
+
attr_reader :viewer, :filter, :options
|
8
10
|
|
9
|
-
def initialize(name, viewer: nil, filter: nil, options: {})
|
11
|
+
def initialize(name, viewer: nil, mode: :wall, filter: nil, options: {})
|
10
12
|
@name = name
|
11
13
|
@viewer = viewer
|
12
14
|
@options = options
|
13
15
|
@reports = []
|
16
|
+
@mode = mode
|
14
17
|
|
15
18
|
@options[:filter] = Regexp.new(filter) if filter
|
16
19
|
end
|
17
20
|
|
18
|
-
def start(
|
19
|
-
|
21
|
+
def start(**options)
|
22
|
+
return if StackProf.running?
|
23
|
+
|
24
|
+
stackprof = { mode: @mode }.merge(options)
|
25
|
+
StackProf.start(**stackprof)
|
20
26
|
end
|
21
27
|
|
22
28
|
def stop
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
return unless StackProf.running?
|
30
|
+
|
31
|
+
StackProf.stop
|
32
|
+
@reports << StackProf::Report.new(results)
|
27
33
|
end
|
28
34
|
|
29
|
-
def run(
|
30
|
-
start(
|
35
|
+
def run(...)
|
36
|
+
start(...)
|
31
37
|
yield
|
32
38
|
ensure
|
33
39
|
stop
|
@@ -48,11 +54,9 @@ class Hotch
|
|
48
54
|
|
49
55
|
@reports.clear
|
50
56
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
return report, svg
|
55
|
-
end
|
57
|
+
return report, svg unless block_given?
|
58
|
+
|
59
|
+
yield report, svg
|
56
60
|
end
|
57
61
|
|
58
62
|
def report_at_exit
|
@@ -77,7 +81,7 @@ class Hotch
|
|
77
81
|
private
|
78
82
|
|
79
83
|
def name
|
80
|
-
@name.gsub(/\W+/,
|
84
|
+
@name.gsub(/\W+/, "_")
|
81
85
|
end
|
82
86
|
|
83
87
|
def report_dump(report, dir, file)
|
@@ -98,26 +102,25 @@ class Hotch
|
|
98
102
|
svg
|
99
103
|
end
|
100
104
|
|
101
|
-
def write_file(dir, file)
|
105
|
+
def write_file(dir, file, &block)
|
102
106
|
path = File.join(dir, file)
|
103
|
-
File.open(path,
|
104
|
-
yield fh
|
105
|
-
end
|
107
|
+
File.open(path, "wb", &block)
|
106
108
|
path
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
110
|
-
|
112
|
+
# rubocop:disable Naming/MethodName
|
113
|
+
def Hotch(name: $PROGRAM_NAME, aggregate: true, viewer: ENV.fetch("HOTCH_VIEWER", nil), mode: :wall,
|
114
|
+
filter: ENV.fetch("HOTCH_FILTER", nil), options: {}, &block)
|
111
115
|
hotch = if aggregate
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
116
|
+
$hotch ||= Hotch.new(name, viewer: viewer, mode: mode, filter: filter, options: options)
|
117
|
+
else
|
118
|
+
caller = Kernel.caller_locations(1).first
|
119
|
+
name = "#{name}:#{caller.path}:#{caller.lineno}"
|
120
|
+
Hotch.new(name, viewer: viewer, filter: filter, options: options)
|
121
|
+
end
|
118
122
|
|
119
123
|
hotch.report_at_exit
|
120
|
-
hotch.run
|
121
|
-
yield
|
122
|
-
end
|
124
|
+
hotch.run(&block)
|
123
125
|
end
|
126
|
+
# rubocop:enable Naming/MethodName
|
metadata
CHANGED
@@ -1,71 +1,113 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Leitzen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: allocation_tracer
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.6.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.6.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: stackprof
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.2.15
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.2.15
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 12.3.3
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 12.3.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
description: Callstack and memory profiler
|
70
112
|
email:
|
71
113
|
- peter@leitzen.de
|
@@ -73,12 +115,19 @@ executables: []
|
|
73
115
|
extensions: []
|
74
116
|
extra_rdoc_files: []
|
75
117
|
files:
|
118
|
+
- ".github/workflows/examples.yml"
|
119
|
+
- ".github/workflows/rubocop.yml"
|
76
120
|
- ".gitignore"
|
121
|
+
- ".rubocop.yml"
|
122
|
+
- ".rubocop_todo.yml"
|
77
123
|
- Gemfile
|
78
124
|
- LICENSE.txt
|
79
125
|
- README.md
|
80
126
|
- Rakefile
|
81
127
|
- examples/bundler.rb
|
128
|
+
- examples/example_test.rb
|
129
|
+
- examples/memory_at_exit.rb
|
130
|
+
- examples/memory_inline_report.rb
|
82
131
|
- examples/simple.rb
|
83
132
|
- hotch.gemspec
|
84
133
|
- images/dry-validation.profile_schema_call_valid.png
|
@@ -86,13 +135,15 @@ files:
|
|
86
135
|
- lib/hotch.rb
|
87
136
|
- lib/hotch/memory.rb
|
88
137
|
- lib/hotch/memory/minitest.rb
|
138
|
+
- lib/hotch/memory/run.rb
|
89
139
|
- lib/hotch/minitest.rb
|
90
140
|
- lib/hotch/run.rb
|
91
141
|
- lib/hotch/version.rb
|
92
142
|
homepage: https://github.com/splattael/hotch
|
93
143
|
licenses:
|
94
144
|
- MIT
|
95
|
-
metadata:
|
145
|
+
metadata:
|
146
|
+
rubygems_mfa_required: 'true'
|
96
147
|
post_install_message:
|
97
148
|
rdoc_options: []
|
98
149
|
require_paths:
|
@@ -101,15 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
152
|
requirements:
|
102
153
|
- - ">="
|
103
154
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
155
|
+
version: 2.7.0
|
105
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
157
|
requirements:
|
107
158
|
- - ">="
|
108
159
|
- !ruby/object:Gem::Version
|
109
160
|
version: '0'
|
110
161
|
requirements: []
|
111
|
-
|
112
|
-
rubygems_version: 2.7.7
|
162
|
+
rubygems_version: 3.3.26
|
113
163
|
signing_key:
|
114
164
|
specification_version: 4
|
115
165
|
summary: Profile helper
|