vernier 1.7.1 → 1.8.1
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/.ruby-version +1 -0
- data/Rakefile +1 -0
- data/exe/vernier +7 -3
- data/lib/vernier/autorun.rb +7 -4
- data/lib/vernier/collector.rb +2 -1
- data/lib/vernier/middleware.rb +1 -1
- data/lib/vernier/output/cpuprofile.rb +145 -0
- data/lib/vernier/output/firefox.rb +64 -17
- data/lib/vernier/output/top.rb +6 -4
- data/lib/vernier/result.rb +16 -4
- data/lib/vernier/version.rb +1 -1
- data/lib/vernier.rb +1 -0
- metadata +5 -4
- data/vernier.gemspec +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4be5edc549ea93934096d98e46c4ffcabc140d06e27303f6ec6b01de8201983c
|
4
|
+
data.tar.gz: a6322324723a2f31f15a0b7e98a6de72bf5c555e29e21951b7f466466ecedd6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92377006ae54cc5cc89934cc3c393fdfe02746035235b507196ef9d360b6d843c50db4382e0b53ec253f1d08f10f78e28d7daf10979f26187bb7c925933dec56
|
7
|
+
data.tar.gz: 0e963a838d3c319d93d73ae224c9e11caa51562583ef37f2d5fff40781281d30ee714273a9ce021c9e8285942825a3356388d2f68b51315fb5275c5bb96b49a6
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.6
|
data/Rakefile
CHANGED
data/exe/vernier
CHANGED
@@ -9,10 +9,9 @@ module Vernier
|
|
9
9
|
module CLI
|
10
10
|
class Metadata < Array
|
11
11
|
require 'json'
|
12
|
-
require 'base64'
|
13
12
|
|
14
13
|
def to_s
|
15
|
-
|
14
|
+
[to_json].pack("m")
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
@@ -52,6 +51,9 @@ FLAGS:
|
|
52
51
|
options[:metadata] ||= Metadata.new
|
53
52
|
options[:metadata] << [key, value]
|
54
53
|
end
|
54
|
+
o.on('--format [FORMAT]', String, "output format: firefox (default) or cpuprofile") do |output_format|
|
55
|
+
options[:format] = output_format
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
@@ -77,7 +79,7 @@ FLAGS:
|
|
77
79
|
|
78
80
|
parsed_profile = Vernier::ParsedProfile.read_file(file)
|
79
81
|
|
80
|
-
puts Vernier::Output::Top.new(parsed_profile).output
|
82
|
+
puts Vernier::Output::Top.new(parsed_profile, top).output
|
81
83
|
puts Vernier::Output::FileListing.new(parsed_profile).output
|
82
84
|
end
|
83
85
|
end
|
@@ -88,6 +90,8 @@ run = Vernier::CLI.run(options)
|
|
88
90
|
view = Vernier::CLI.view(options)
|
89
91
|
|
90
92
|
case ARGV.shift
|
93
|
+
when "-v", "--version"
|
94
|
+
puts Vernier::VERSION
|
91
95
|
when "run"
|
92
96
|
run.parse!
|
93
97
|
run.abort(run.help) if ARGV.empty?
|
data/lib/vernier/autorun.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "tempfile"
|
2
2
|
require "vernier"
|
3
|
-
require "base64"
|
4
3
|
require "json"
|
5
4
|
|
6
5
|
module Vernier
|
@@ -22,7 +21,7 @@ module Vernier
|
|
22
21
|
allocation_interval = options.fetch(:allocation_interval, 0).to_i
|
23
22
|
hooks = options.fetch(:hooks, "").split(",")
|
24
23
|
metadata = if options[:metadata]
|
25
|
-
JSON.parse(
|
24
|
+
JSON.parse(@options[:metadata].unpack1("m")).to_h { |k, v| [k.to_sym, v] }
|
26
25
|
else
|
27
26
|
{}
|
28
27
|
end
|
@@ -49,12 +48,16 @@ module Vernier
|
|
49
48
|
end
|
50
49
|
prefix = "profile-"
|
51
50
|
timestamp = Time.now.strftime("%Y%m%d-%H%M%S")
|
52
|
-
suffix = "
|
51
|
+
suffix = if options[:format] == "cpuprofile"
|
52
|
+
".vernier.cpuprofile"
|
53
|
+
else
|
54
|
+
".vernier.json.gz"
|
55
|
+
end
|
53
56
|
|
54
57
|
output_path = File.expand_path("#{output_dir}/#{prefix}#{timestamp}-#{$$}#{suffix}")
|
55
58
|
end
|
56
59
|
|
57
|
-
result.write(out: output_path)
|
60
|
+
result.write(out: output_path, format: options[:format] || "firefox")
|
58
61
|
|
59
62
|
STDERR.puts(result.inspect)
|
60
63
|
STDERR.puts("written to #{output_path}")
|
data/lib/vernier/collector.rb
CHANGED
@@ -11,6 +11,7 @@ module Vernier
|
|
11
11
|
|
12
12
|
@mode = mode
|
13
13
|
@out = options[:out]
|
14
|
+
@format = options[:format]
|
14
15
|
|
15
16
|
@markers = []
|
16
17
|
@hooks = []
|
@@ -142,7 +143,7 @@ module Vernier
|
|
142
143
|
#result.instance_variable_set(:@markers, markers)
|
143
144
|
|
144
145
|
if @out
|
145
|
-
result.write(out: @out)
|
146
|
+
result.write(out: @out, format: @format)
|
146
147
|
end
|
147
148
|
|
148
149
|
result
|
data/lib/vernier/middleware.rb
CHANGED
@@ -18,7 +18,7 @@ module Vernier
|
|
18
18
|
result = Vernier.trace(interval:, allocation_interval:, hooks: [:rails]) do
|
19
19
|
@app.call(env)
|
20
20
|
end
|
21
|
-
body = result.
|
21
|
+
body = result.to_firefox(gzip: true)
|
22
22
|
filename = "#{request.path.gsub("/", "_")}_#{DateTime.now.strftime("%Y-%m-%d-%H-%M-%S")}.vernier.json.gz"
|
23
23
|
headers = {
|
24
24
|
"Content-Type" => "application/octet-stream",
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Vernier
|
4
|
+
module Output
|
5
|
+
class Cpuprofile
|
6
|
+
def initialize(profile)
|
7
|
+
@profile = profile
|
8
|
+
end
|
9
|
+
|
10
|
+
def output
|
11
|
+
JSON.generate(data)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :profile
|
17
|
+
|
18
|
+
def ns_to_us(timestamp)
|
19
|
+
(timestamp / 1_000.0).to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def data
|
23
|
+
# Get the main thread data (cpuprofile format is single-threaded)
|
24
|
+
main_thread = profile.main_thread
|
25
|
+
return empty_profile if main_thread.nil?
|
26
|
+
|
27
|
+
samples = main_thread[:samples]
|
28
|
+
timestamps = main_thread[:timestamps] || []
|
29
|
+
|
30
|
+
nodes = build_nodes
|
31
|
+
sample_node_ids = samples.map { |stack_idx| stack_to_node_id(stack_idx) }
|
32
|
+
time_deltas = calculate_time_deltas(timestamps)
|
33
|
+
|
34
|
+
{
|
35
|
+
nodes: nodes,
|
36
|
+
startTime: ns_to_us(profile.started_at),
|
37
|
+
endTime: ns_to_us(profile.end_time),
|
38
|
+
samples: sample_node_ids,
|
39
|
+
timeDeltas: time_deltas
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def empty_profile
|
44
|
+
{
|
45
|
+
nodes: [root_node],
|
46
|
+
startTime: 0,
|
47
|
+
endTime: 0,
|
48
|
+
samples: [],
|
49
|
+
timeDeltas: []
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_nodes
|
54
|
+
stack_table = profile.stack_table
|
55
|
+
|
56
|
+
nodes = []
|
57
|
+
@node_id_map = {}
|
58
|
+
|
59
|
+
root = root_node
|
60
|
+
nodes << root
|
61
|
+
@node_id_map[nil] = 0
|
62
|
+
|
63
|
+
stack_table.stack_count.times do |stack_idx|
|
64
|
+
create_node_for_stack(stack_idx, nodes, stack_table)
|
65
|
+
end
|
66
|
+
|
67
|
+
nodes
|
68
|
+
end
|
69
|
+
|
70
|
+
def root_node
|
71
|
+
{
|
72
|
+
id: 0,
|
73
|
+
callFrame: {
|
74
|
+
functionName: "(root)",
|
75
|
+
scriptId: "0",
|
76
|
+
url: "",
|
77
|
+
lineNumber: -1,
|
78
|
+
columnNumber: -1,
|
79
|
+
},
|
80
|
+
hitCount: 0,
|
81
|
+
children: []
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_node_for_stack(stack_idx, nodes, stack_table)
|
86
|
+
return @node_id_map[stack_idx] if @node_id_map.key?(stack_idx)
|
87
|
+
|
88
|
+
frame_idx = stack_table.stack_frame_idx(stack_idx)
|
89
|
+
parent_stack_idx = stack_table.stack_parent_idx(stack_idx)
|
90
|
+
|
91
|
+
parent_node_id = if parent_stack_idx.nil?
|
92
|
+
0 # root node
|
93
|
+
else
|
94
|
+
create_node_for_stack(parent_stack_idx, nodes, stack_table)
|
95
|
+
end
|
96
|
+
|
97
|
+
func_idx = stack_table.frame_func_idx(frame_idx)
|
98
|
+
line = stack_table.frame_line_no(frame_idx) - 1
|
99
|
+
|
100
|
+
func_name = stack_table.func_name(func_idx)
|
101
|
+
filename = stack_table.func_filename(func_idx)
|
102
|
+
|
103
|
+
node_id = nodes.length
|
104
|
+
node = {
|
105
|
+
id: node_id,
|
106
|
+
callFrame: {
|
107
|
+
functionName: func_name || "(anonymous)",
|
108
|
+
scriptId: func_idx.to_s,
|
109
|
+
url: filename || "",
|
110
|
+
lineNumber: line || 0,
|
111
|
+
columnNumber: 0
|
112
|
+
},
|
113
|
+
hitCount: 0,
|
114
|
+
children: []
|
115
|
+
}
|
116
|
+
|
117
|
+
nodes << node
|
118
|
+
@node_id_map[stack_idx] = node_id
|
119
|
+
|
120
|
+
parent_node = nodes[parent_node_id]
|
121
|
+
parent_node[:children] << node_id unless parent_node[:children].include?(node_id)
|
122
|
+
end
|
123
|
+
|
124
|
+
def stack_to_node_id(stack_idx)
|
125
|
+
@node_id_map[stack_idx] || 0
|
126
|
+
end
|
127
|
+
|
128
|
+
def calculate_time_deltas(timestamps)
|
129
|
+
return [] if timestamps.empty?
|
130
|
+
|
131
|
+
deltas = []
|
132
|
+
|
133
|
+
timestamps.each_with_index do |timestamp, i|
|
134
|
+
if i == 0
|
135
|
+
deltas << 0
|
136
|
+
else
|
137
|
+
deltas << ns_to_us(timestamp - timestamps[i - 1])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
deltas
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -8,35 +8,59 @@ require_relative "filename_filter"
|
|
8
8
|
module Vernier
|
9
9
|
module Output
|
10
10
|
# https://profiler.firefox.com/
|
11
|
-
# https://github.com/firefox-devtools/profiler/blob/main/src/types/profile.
|
11
|
+
# https://github.com/firefox-devtools/profiler/blob/main/src/types/profile.ts
|
12
12
|
class Firefox
|
13
13
|
class Categorizer
|
14
|
+
RAILS_COMPONENTS = %w[ activesupport activemodel activerecord actionview
|
15
|
+
actionpack activejob actionmailer actioncable
|
16
|
+
activestorage actionmailbox actiontext railties ]
|
17
|
+
|
18
|
+
AVAILABLE_COLORS = %w[ transparent purple green orange yellow lightblue
|
19
|
+
blue brown magenta red lightred darkgrey grey ]
|
20
|
+
|
21
|
+
ORDERED_CATEGORIES = %w[ Kernel Rails gem Ruby ] # This is in the order of preference
|
22
|
+
|
14
23
|
attr_reader :categories
|
24
|
+
|
15
25
|
def initialize
|
16
26
|
@categories = []
|
17
27
|
@categories_by_name = {}
|
18
28
|
|
19
|
-
add_category(name: "
|
20
|
-
rails_components = %w[ activesupport activemodel activerecord
|
21
|
-
actionview actionpack activejob actionmailer actioncable
|
22
|
-
activestorage actionmailbox actiontext railties ]
|
29
|
+
add_category(name: "Kernel", color: "magenta") do |c|
|
23
30
|
c.add_subcategory(
|
24
|
-
name: "
|
25
|
-
matcher:
|
31
|
+
name: "Kernel",
|
32
|
+
matcher: starts_with("<internal")
|
26
33
|
)
|
34
|
+
end
|
35
|
+
|
36
|
+
add_category(name: "gem", color: "lightblue") do |c|
|
27
37
|
c.add_subcategory(
|
28
38
|
name: "gem",
|
29
39
|
matcher: starts_with(*Gem.path)
|
30
40
|
)
|
41
|
+
end
|
42
|
+
|
43
|
+
add_category(name: "Rails", color: "red") do |c|
|
44
|
+
RAILS_COMPONENTS.each do |subcategory|
|
45
|
+
c.add_subcategory(
|
46
|
+
name: subcategory,
|
47
|
+
matcher: gem_path(subcategory)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
add_category(name: "Ruby", color: "purple") do |c|
|
31
53
|
c.add_subcategory(
|
32
54
|
name: "stdlib",
|
33
55
|
matcher: starts_with(RbConfig::CONFIG["rubylibdir"])
|
34
56
|
)
|
35
57
|
end
|
58
|
+
|
36
59
|
add_category(name: "Idle", color: "transparent")
|
37
60
|
add_category(name: "Stalled", color: "transparent")
|
38
61
|
|
39
62
|
add_category(name: "GC", color: "red")
|
63
|
+
|
40
64
|
add_category(name: "cfunc", color: "yellow", matcher: "<cfunc>")
|
41
65
|
|
42
66
|
add_category(name: "Thread", color: "grey")
|
@@ -69,7 +93,10 @@ module Vernier
|
|
69
93
|
|
70
94
|
class Category
|
71
95
|
attr_reader :idx, :name, :color, :matcher, :subcategories
|
96
|
+
|
72
97
|
def initialize(idx, name:, color:, matcher: nil)
|
98
|
+
raise ArgumentError, "invalid color: #{color}" if color && AVAILABLE_COLORS.none?(color)
|
99
|
+
|
73
100
|
@idx = idx
|
74
101
|
@name = name
|
75
102
|
@color = color
|
@@ -315,19 +342,13 @@ module Vernier
|
|
315
342
|
func_implementations[func_idx]
|
316
343
|
end
|
317
344
|
|
318
|
-
cfunc_category = @categorizer.get_category("cfunc")
|
319
|
-
ruby_category = @categorizer.get_category("Ruby")
|
320
345
|
func_categories, func_subcategories = [], []
|
321
346
|
filenames.each do |filename|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
else
|
326
|
-
func_categories << ruby_category
|
327
|
-
subcategory = ruby_category.subcategories.detect {|c| c.matches?(filename) }&.idx || 0
|
328
|
-
func_subcategories << subcategory
|
329
|
-
end
|
347
|
+
category, subcategory = categorize_filename(filename)
|
348
|
+
func_categories << category
|
349
|
+
func_subcategories << subcategory
|
330
350
|
end
|
351
|
+
|
331
352
|
@frame_categories = @stack_table_hash[:frame_table].fetch(:func).map do |func_idx|
|
332
353
|
func_categories[func_idx]
|
333
354
|
end
|
@@ -336,6 +357,32 @@ module Vernier
|
|
336
357
|
end
|
337
358
|
end
|
338
359
|
|
360
|
+
def categorize_filename(filename)
|
361
|
+
return cfunc_category_and_subcategory if filename == "<cfunc>"
|
362
|
+
|
363
|
+
category, subcategory = find_category_and_subcategory(filename, Categorizer::ORDERED_CATEGORIES)
|
364
|
+
return category, subcategory if subcategory
|
365
|
+
|
366
|
+
ruby_category_and_subcategory
|
367
|
+
end
|
368
|
+
|
369
|
+
def cfunc_category_and_subcategory
|
370
|
+
[@categorizer.get_category("cfunc"), 0]
|
371
|
+
end
|
372
|
+
|
373
|
+
def ruby_category_and_subcategory
|
374
|
+
[@categorizer.get_category("Ruby"), 0]
|
375
|
+
end
|
376
|
+
|
377
|
+
def find_category_and_subcategory(filename, categories)
|
378
|
+
categories.each do |category_name|
|
379
|
+
category = @categorizer.get_category(category_name)
|
380
|
+
subcategory = category.subcategories.detect {|c| c.matches?(filename) }&.idx
|
381
|
+
return category, subcategory if subcategory
|
382
|
+
end
|
383
|
+
[nil, nil]
|
384
|
+
end
|
385
|
+
|
339
386
|
def filter_filenames(filenames)
|
340
387
|
filter = FilenameFilter.new
|
341
388
|
filenames.map do |filename|
|
data/lib/vernier/output/top.rb
CHANGED
@@ -3,14 +3,16 @@
|
|
3
3
|
module Vernier
|
4
4
|
module Output
|
5
5
|
class Top
|
6
|
-
def initialize(profile)
|
6
|
+
def initialize(profile, row_limit)
|
7
7
|
@profile = profile
|
8
|
+
@row_limit = row_limit
|
8
9
|
end
|
9
10
|
|
10
11
|
class Table
|
11
|
-
def initialize(header)
|
12
|
+
def initialize(header, row_limit)
|
12
13
|
@header = header
|
13
14
|
@rows = []
|
15
|
+
@row_limit = row_limit
|
14
16
|
yield self
|
15
17
|
end
|
16
18
|
|
@@ -24,7 +26,7 @@ module Vernier
|
|
24
26
|
row_separator,
|
25
27
|
format_row(@header),
|
26
28
|
row_separator
|
27
|
-
] + @rows.map do |row|
|
29
|
+
] + @rows.first(@row_limit).map do |row|
|
28
30
|
format_row(row)
|
29
31
|
end + [row_separator]
|
30
32
|
).join("\n")
|
@@ -70,7 +72,7 @@ module Vernier
|
|
70
72
|
top_by_self[name] += weight
|
71
73
|
end
|
72
74
|
|
73
|
-
Table.new %w[Samples % name] do |t|
|
75
|
+
Table.new %w[Samples % name], @row_limit do |t|
|
74
76
|
top_by_self.sort_by(&:last).reverse.each do |frame, samples|
|
75
77
|
pct = 100.0 * samples / total
|
76
78
|
t << [samples.to_s, pct.round(1).to_s, frame]
|
data/lib/vernier/result.rb
CHANGED
@@ -29,13 +29,25 @@ module Vernier
|
|
29
29
|
(current_time_real_ns - current_time_mono_ns + started_at_mono_ns)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def to_firefox(gzip: false)
|
33
33
|
Output::Firefox.new(self).output(gzip:)
|
34
34
|
end
|
35
|
+
alias_method :to_gecko, :to_firefox
|
35
36
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
37
|
+
def to_cpuprofile
|
38
|
+
Output::Cpuprofile.new(self).output
|
39
|
+
end
|
40
|
+
|
41
|
+
def write(out:, format: "firefox")
|
42
|
+
case format
|
43
|
+
when "cpuprofile"
|
44
|
+
File.binwrite(out, to_cpuprofile)
|
45
|
+
when nil, "firefox"
|
46
|
+
gzip = out.end_with?(".gz")
|
47
|
+
File.binwrite(out, to_firefox(gzip:))
|
48
|
+
else
|
49
|
+
raise ArgumentError, "unknown format: #{format}"
|
50
|
+
end
|
39
51
|
end
|
40
52
|
|
41
53
|
def elapsed_seconds
|
data/lib/vernier/version.rb
CHANGED
data/lib/vernier.rb
CHANGED
@@ -8,6 +8,7 @@ require_relative "vernier/result"
|
|
8
8
|
require_relative "vernier/hooks"
|
9
9
|
require_relative "vernier/vernier"
|
10
10
|
require_relative "vernier/output/firefox"
|
11
|
+
require_relative "vernier/output/cpuprofile"
|
11
12
|
require_relative "vernier/output/top"
|
12
13
|
require_relative "vernier/output/file_listing"
|
13
14
|
require_relative "vernier/output/filename_filter"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vernier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hawthorn
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activesupport
|
@@ -61,6 +61,7 @@ extensions:
|
|
61
61
|
- ext/vernier/extconf.rb
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
|
+
- ".ruby-version"
|
64
65
|
- CODE_OF_CONDUCT.md
|
65
66
|
- Gemfile
|
66
67
|
- LICENSE.txt
|
@@ -93,6 +94,7 @@ files:
|
|
93
94
|
- lib/vernier/hooks/memory_usage.rb
|
94
95
|
- lib/vernier/marker.rb
|
95
96
|
- lib/vernier/middleware.rb
|
97
|
+
- lib/vernier/output/cpuprofile.rb
|
96
98
|
- lib/vernier/output/file_listing.rb
|
97
99
|
- lib/vernier/output/filename_filter.rb
|
98
100
|
- lib/vernier/output/firefox.rb
|
@@ -103,7 +105,6 @@ files:
|
|
103
105
|
- lib/vernier/stack_table_helpers.rb
|
104
106
|
- lib/vernier/thread_names.rb
|
105
107
|
- lib/vernier/version.rb
|
106
|
-
- vernier.gemspec
|
107
108
|
homepage: https://github.com/jhawthorn/vernier
|
108
109
|
licenses:
|
109
110
|
- MIT
|
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
126
|
- !ruby/object:Gem::Version
|
126
127
|
version: '0'
|
127
128
|
requirements: []
|
128
|
-
rubygems_version: 3.
|
129
|
+
rubygems_version: 3.7.2
|
129
130
|
specification_version: 4
|
130
131
|
summary: A next generation CRuby profiler
|
131
132
|
test_files: []
|
data/vernier.gemspec
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/vernier/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "vernier"
|
7
|
-
spec.version = Vernier::VERSION
|
8
|
-
spec.authors = ["John Hawthorn"]
|
9
|
-
spec.email = ["john@hawthorn.email"]
|
10
|
-
|
11
|
-
spec.summary = "A next generation CRuby profiler"
|
12
|
-
spec.description = "Next-generation Ruby 3.2.1+ sampling profiler. Tracks multiple threads, GVL activity, GC pauses, idle time, and more."
|
13
|
-
spec.homepage = "https://github.com/jhawthorn/vernier"
|
14
|
-
spec.license = "MIT"
|
15
|
-
|
16
|
-
unless ENV["IGNORE_REQUIRED_RUBY_VERSION"]
|
17
|
-
spec.required_ruby_version = ">= 3.2.1"
|
18
|
-
end
|
19
|
-
|
20
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
21
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
22
|
-
spec.metadata["changelog_uri"] = spec.homepage
|
23
|
-
|
24
|
-
# Specify which files should be added to the gem when it is released.
|
25
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
26
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
27
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
28
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
29
|
-
end
|
30
|
-
end
|
31
|
-
spec.bindir = "exe"
|
32
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
|
-
spec.require_paths = ["lib"]
|
34
|
-
spec.extensions = ["ext/vernier/extconf.rb"]
|
35
|
-
|
36
|
-
spec.add_development_dependency "activesupport"
|
37
|
-
spec.add_development_dependency "gvltest"
|
38
|
-
spec.add_development_dependency "rack"
|
39
|
-
end
|