polyrun 2.1.3 → 2.2.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/CHANGELOG.md +10 -1
- data/CONTRIBUTING.md +22 -0
- data/docs/SETUP_PROFILE.md +1 -1
- data/ext/polyrun_coverage_merge/coverage_merge.c +492 -0
- data/ext/polyrun_coverage_merge/extconf.rb +3 -0
- data/lib/polyrun/benchmark/profile.rb +191 -0
- data/lib/polyrun/benchmark/report.rb +87 -0
- data/lib/polyrun/cli/benchmark_commands.rb +66 -0
- data/lib/polyrun/cli/coverage_commands.rb +4 -4
- data/lib/polyrun/cli/coverage_merge_io.rb +30 -4
- data/lib/polyrun/cli/failure_commands.rb +10 -3
- data/lib/polyrun/cli/help.rb +12 -8
- data/lib/polyrun/cli/report_commands.rb +25 -11
- data/lib/polyrun/cli/run_shards_parallel_children.rb +1 -1
- data/lib/polyrun/cli/run_shards_plan_options.rb +1 -1
- data/lib/polyrun/cli/spec_quality_commands.rb +16 -7
- data/lib/polyrun/cli.rb +8 -1
- data/lib/polyrun/coverage/example_diff.rb +127 -60
- data/lib/polyrun/coverage/example_diff_snapshot.rb +44 -0
- data/lib/polyrun/coverage/example_diff_track_filter.rb +51 -0
- data/lib/polyrun/coverage/file_stats_report.rb +36 -0
- data/lib/polyrun/coverage/formatter.rb +22 -1
- data/lib/polyrun/coverage/merge/formatters.rb +11 -3
- data/lib/polyrun/coverage/merge_merge_two.rb +112 -63
- data/lib/polyrun/coverage/merge_native.rb +37 -0
- data/lib/polyrun/coverage/reporting.rb +1 -1
- data/lib/polyrun/export/csv.rb +25 -0
- data/lib/polyrun/export/markdown.rb +47 -0
- data/lib/polyrun/hooks/shell_runner.rb +33 -0
- data/lib/polyrun/hooks.rb +4 -7
- data/lib/polyrun/reporting/failure_merge.rb +48 -12
- data/lib/polyrun/reporting/junit.rb +8 -7
- data/lib/polyrun/reporting/junit_report.rb +87 -0
- data/lib/polyrun/rspec/example_debug.rb +1 -1
- data/lib/polyrun/rspec/sharded_formatter_compat.rb +30 -7
- data/lib/polyrun/spec_quality/profile.rb +24 -12
- data/lib/polyrun/spec_quality/report.rb +93 -0
- data/lib/polyrun/spec_quality.rb +19 -11
- data/lib/polyrun/timing/summary.rb +55 -5
- data/lib/polyrun/version.rb +1 -1
- data/polyrun.gemspec +8 -1
- metadata +58 -2
|
@@ -1,27 +1,50 @@
|
|
|
1
1
|
module Polyrun
|
|
2
2
|
module RSpec
|
|
3
|
-
# Formatter tweaks for progress
|
|
3
|
+
# Formatter tweaks for progress formatters under +POLYRUN_SHARD_*+ workers.
|
|
4
4
|
module ShardedFormatterCompat
|
|
5
|
+
TextFormatterSilencer = Module.new do
|
|
6
|
+
def seed(_notification)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def dump_summary(_notification)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dump_pending(_notification)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
FuubarSeedSilencer = Module.new do
|
|
17
|
+
def seed(_notification)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
5
21
|
module_function
|
|
6
22
|
|
|
7
23
|
def install!(rspec_config: fetch_rspec_configuration!)
|
|
8
24
|
return unless sharded_worker?
|
|
9
25
|
|
|
10
26
|
rspec_config.silence_filter_announcements = true
|
|
11
|
-
|
|
27
|
+
silence_text_formatter_noise!
|
|
28
|
+
silence_fuubar_seed! if defined?(Fuubar)
|
|
12
29
|
end
|
|
13
30
|
|
|
14
31
|
def sharded_worker?
|
|
15
32
|
!ENV["POLYRUN_SHARD_TOTAL"].to_s.strip.empty?
|
|
16
33
|
end
|
|
17
34
|
|
|
18
|
-
def
|
|
35
|
+
def silence_text_formatter_noise!
|
|
36
|
+
require "rspec/core/formatters/base_text_formatter"
|
|
37
|
+
klass = ::RSpec::Core::Formatters::BaseTextFormatter
|
|
38
|
+
return if klass.ancestors.include?(TextFormatterSilencer)
|
|
39
|
+
|
|
40
|
+
klass.prepend(TextFormatterSilencer)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def silence_fuubar_seed!
|
|
19
44
|
return unless defined?(Fuubar)
|
|
45
|
+
return if Fuubar.ancestors.include?(FuubarSeedSilencer)
|
|
20
46
|
|
|
21
|
-
Fuubar.
|
|
22
|
-
def seed(_notification)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
47
|
+
Fuubar.prepend(FuubarSeedSilencer)
|
|
25
48
|
end
|
|
26
49
|
|
|
27
50
|
def fetch_rspec_configuration!
|
|
@@ -4,18 +4,30 @@ module Polyrun
|
|
|
4
4
|
module Profile
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
def snapshot
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
def snapshot(dimensions: %w[cpu mem io wall])
|
|
8
|
+
dims = enabled_dimensions(dimensions)
|
|
9
|
+
capture_all = dims.empty?
|
|
10
|
+
out = {}
|
|
11
|
+
|
|
12
|
+
if capture_all || dims.include?("cpu") || dims.include?("wall")
|
|
13
|
+
cpu = Process.times
|
|
14
|
+
out["cpu_user"] = cpu.utime
|
|
15
|
+
out["cpu_system"] = cpu.stime
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if capture_all || dims.include?("mem")
|
|
19
|
+
gc = GC.stat
|
|
20
|
+
out["gc_allocated"] = gc[:total_allocated_objects]
|
|
21
|
+
out["gc_heap_live"] = gc[:heap_live_slots]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if capture_all || dims.include?("io")
|
|
25
|
+
io = read_proc_io
|
|
26
|
+
out["io_read_bytes"] = io[:read_bytes]
|
|
27
|
+
out["io_write_bytes"] = io[:write_bytes]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
out
|
|
19
31
|
end
|
|
20
32
|
|
|
21
33
|
def diff(before, after)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# rubocop:disable Polyrun/FileLength, Metrics/ModuleLength -- report analysis + text formatting
|
|
2
|
+
require_relative "../export/csv"
|
|
3
|
+
require_relative "../export/markdown"
|
|
4
|
+
|
|
2
5
|
module Polyrun
|
|
3
6
|
module SpecQuality
|
|
4
7
|
# Human-readable spec quality report from merged JSON.
|
|
@@ -55,6 +58,96 @@ module Polyrun
|
|
|
55
58
|
lines.join("\n") + "\n"
|
|
56
59
|
end
|
|
57
60
|
|
|
61
|
+
EXAMPLE_CSV_HEADERS = %w[example unique_lines line_churn max_line_churn shard_index].freeze
|
|
62
|
+
|
|
63
|
+
def format_csv(merged, cfg: {}, top: 30, profile: nil, plan_shards: nil)
|
|
64
|
+
rows = merged.fetch("examples", {}).map do |location, row|
|
|
65
|
+
[
|
|
66
|
+
location,
|
|
67
|
+
row["unique_lines"],
|
|
68
|
+
row["line_churn"],
|
|
69
|
+
row["max_line_churn"],
|
|
70
|
+
row["polyrun_shard_index"]
|
|
71
|
+
]
|
|
72
|
+
end.sort_by { |row| [-row[2].to_i, row[0].to_s] }
|
|
73
|
+
rows = rows.first(top) if top
|
|
74
|
+
Export::Csv.generate(EXAMPLE_CSV_HEADERS, rows)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def format_markdown(merged, cfg: {}, top: 30, profile: nil, plan_shards: nil)
|
|
78
|
+
analysis = analyze(merged, cfg, plan_shards: plan_shards)
|
|
79
|
+
sections = markdown_sections(analysis, top).compact
|
|
80
|
+
Export::Markdown.document("Polyrun spec quality report", sections)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def markdown_sections(analysis, top)
|
|
84
|
+
[
|
|
85
|
+
markdown_shard_section(analysis[:shard_summary]),
|
|
86
|
+
markdown_zero_hit_section(analysis[:zero_hit], top),
|
|
87
|
+
markdown_hot_lines_section(analysis[:hot_lines], top),
|
|
88
|
+
markdown_churn_section(analysis[:line_churn], top)
|
|
89
|
+
]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def markdown_shard_section(shard_summary)
|
|
93
|
+
shard_rows = (shard_summary || {}).sort_by { |shard, _| shard.to_s }.map do |shard, stats|
|
|
94
|
+
[shard, stats["examples"], stats["zero_hit"], stats["line_churn"]]
|
|
95
|
+
end
|
|
96
|
+
return if shard_rows.empty?
|
|
97
|
+
|
|
98
|
+
{
|
|
99
|
+
heading: "Shard attribution",
|
|
100
|
+
headers: %w[shard examples zero_hit line_churn],
|
|
101
|
+
rows: shard_rows
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def markdown_zero_hit_section(zero_hit, top)
|
|
106
|
+
zero_rows = zero_hit.keys.sort.first(top).zip
|
|
107
|
+
{
|
|
108
|
+
heading: "Zero production lines",
|
|
109
|
+
headers: %w[example],
|
|
110
|
+
rows: zero_rows.empty? ? [["(none)"]] : zero_rows
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def markdown_hot_lines_section(hot_lines, top)
|
|
115
|
+
hot_rows = hot_lines.first(top).map do |line, stats|
|
|
116
|
+
[line, stats["example_count"], stats["total_hits"]]
|
|
117
|
+
end
|
|
118
|
+
{
|
|
119
|
+
heading: "Hot lines",
|
|
120
|
+
headers: %w[line example_count total_hits],
|
|
121
|
+
rows: hot_rows.empty? ? [["(none)", 0, 0]] : hot_rows
|
|
122
|
+
}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def markdown_churn_section(churn_rows, top)
|
|
126
|
+
rows = churn_rows.first(top).map do |location, row|
|
|
127
|
+
[location, row["line_churn"], row["max_line_churn"]]
|
|
128
|
+
end
|
|
129
|
+
{
|
|
130
|
+
heading: "Per-example line churn",
|
|
131
|
+
headers: %w[example line_churn max_line_churn],
|
|
132
|
+
rows: rows.empty? ? [["(none)", 0, 0]] : rows
|
|
133
|
+
}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def render(merged, format: "text", **kwargs)
|
|
137
|
+
case format.to_s.downcase
|
|
138
|
+
when "text", "console", "txt"
|
|
139
|
+
format_report(merged, **kwargs)
|
|
140
|
+
when "json"
|
|
141
|
+
JSON.pretty_generate(analyze(merged, kwargs[:cfg] || {}, plan_shards: kwargs[:plan_shards]))
|
|
142
|
+
when "csv"
|
|
143
|
+
format_csv(merged, **kwargs)
|
|
144
|
+
when "markdown", "md"
|
|
145
|
+
format_markdown(merged, **kwargs)
|
|
146
|
+
else
|
|
147
|
+
raise Polyrun::Error, "report-spec-quality: unknown format #{format.inspect} (use text, json, csv, or markdown)"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
58
151
|
def gate_violations(merged, cfg = {})
|
|
59
152
|
cfg = default_cfg(cfg)
|
|
60
153
|
analysis = analyze(merged, cfg)
|
data/lib/polyrun/spec_quality.rb
CHANGED
|
@@ -58,8 +58,12 @@ module Polyrun
|
|
|
58
58
|
@current = {
|
|
59
59
|
location: normalize_location(location),
|
|
60
60
|
wall_start: wall_start || Process.clock_gettime(Process::CLOCK_MONOTONIC),
|
|
61
|
-
coverage_before: Coverage::ExampleDiff.peek_blob
|
|
62
|
-
|
|
61
|
+
coverage_before: Coverage::ExampleDiff.peek_blob(
|
|
62
|
+
root: @config["root"],
|
|
63
|
+
track_under: @config["track_under"],
|
|
64
|
+
ignore_paths: @config["ignore_paths"]
|
|
65
|
+
),
|
|
66
|
+
profile_before: Profile.snapshot(dimensions: @config["profile"]),
|
|
63
67
|
sql_count: 0,
|
|
64
68
|
sql_fingerprints: Hash.new(0),
|
|
65
69
|
factory_counts: {}
|
|
@@ -78,16 +82,9 @@ module Polyrun
|
|
|
78
82
|
loc = location || cur[:location]
|
|
79
83
|
return if loc.nil? || loc.to_s.empty?
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
delta = Coverage::ExampleDiff.diff(cur[:coverage_before], after_cov)
|
|
83
|
-
delta = Coverage::ExampleDiff.apply_track_under(
|
|
84
|
-
delta,
|
|
85
|
-
root: @config["root"],
|
|
86
|
-
track_under: @config["track_under"],
|
|
87
|
-
ignore_paths: @config["ignore_paths"]
|
|
88
|
-
)
|
|
85
|
+
delta = coverage_delta_for_example(cur)
|
|
89
86
|
|
|
90
|
-
profile_after = Profile.snapshot
|
|
87
|
+
profile_after = Profile.snapshot(dimensions: @config["profile"])
|
|
91
88
|
profile_delta = Profile.diff(cur[:profile_before], profile_after)
|
|
92
89
|
wall = Process.clock_gettime(Process::CLOCK_MONOTONIC) - cur[:wall_start]
|
|
93
90
|
profile_delta["wall"] = wall
|
|
@@ -169,6 +166,17 @@ module Polyrun
|
|
|
169
166
|
Polyrun::Partition::TimingKeys.canonical_file_path(File.expand_path(s, root))
|
|
170
167
|
end
|
|
171
168
|
|
|
169
|
+
def coverage_delta_for_example(cur)
|
|
170
|
+
after_source = Coverage::ExampleDiff.coverage_active? ? ::Coverage.peek_result : {}
|
|
171
|
+
Coverage::ExampleDiff.diff(
|
|
172
|
+
cur[:coverage_before],
|
|
173
|
+
after_source,
|
|
174
|
+
root: @config["root"],
|
|
175
|
+
track_under: @config["track_under"],
|
|
176
|
+
ignore_paths: @config["ignore_paths"]
|
|
177
|
+
)
|
|
178
|
+
end
|
|
179
|
+
|
|
172
180
|
def build_row(cur, location, delta, profile_delta, factory_counts)
|
|
173
181
|
profile = Profile.slice_profile(profile_delta, @config["profile"])
|
|
174
182
|
repeated_sql = cur[:sql_fingerprints].select { |_sql, n| n >= min_query_count }.transform_keys(&:to_s)
|
|
@@ -1,26 +1,76 @@
|
|
|
1
1
|
require_relative "stats"
|
|
2
|
+
require_relative "../export/csv"
|
|
3
|
+
require_relative "../export/markdown"
|
|
2
4
|
|
|
3
5
|
module Polyrun
|
|
4
6
|
module Timing
|
|
5
7
|
# Human-readable slow-file list from merged timing JSON (per-file cost).
|
|
6
8
|
module Summary
|
|
9
|
+
CSV_HEADERS = %w[rank path last_seconds min max mean p95 runs failures timeouts].freeze
|
|
10
|
+
MARKDOWN_HEADERS = %w[rank path seconds].freeze
|
|
11
|
+
|
|
7
12
|
module_function
|
|
8
13
|
|
|
14
|
+
def ranked_entries(merged, top: 30)
|
|
15
|
+
return [] if merged.nil? || merged.empty?
|
|
16
|
+
|
|
17
|
+
merged.map { |path, entry| [path, Stats.normalize_entry(entry)] }
|
|
18
|
+
.sort_by { |(_, entry)| -Stats.binpack_weight(entry) }
|
|
19
|
+
.first(Integer(top))
|
|
20
|
+
end
|
|
21
|
+
|
|
9
22
|
# +merged+ is path (String) => seconds (Float) or stats Hash, as produced by +Timing::Merge.merge_files+.
|
|
10
23
|
def format_slow_files(merged, top: 30, title: "Polyrun slowest files (by wall time, seconds)")
|
|
11
24
|
return "#{title}\n (no data)\n" if merged.nil? || merged.empty?
|
|
12
25
|
|
|
13
|
-
pairs = merged.map { |path, sec| [path, Stats.binpack_weight(sec)] }
|
|
14
|
-
.sort_by { |(_, sec)| -sec.to_f }.first(Integer(top))
|
|
15
26
|
lines = [title, ""]
|
|
16
|
-
|
|
17
|
-
lines << format(" %2d. %s %.4f",
|
|
27
|
+
ranked_entries(merged, top: top).each_with_index do |(path, entry), index|
|
|
28
|
+
lines << format(" %2d. %s %.4f", index + 1, path, Stats.binpack_weight(entry).to_f)
|
|
18
29
|
end
|
|
19
30
|
lines.join("\n") + "\n"
|
|
20
31
|
end
|
|
21
32
|
|
|
33
|
+
def format_csv(merged, top: 30)
|
|
34
|
+
rows = ranked_entries(merged, top: top).each_with_index.map do |(path, entry), index|
|
|
35
|
+
[
|
|
36
|
+
index + 1,
|
|
37
|
+
path,
|
|
38
|
+
entry["last_seconds"],
|
|
39
|
+
entry["min"],
|
|
40
|
+
entry["max"],
|
|
41
|
+
entry["mean"],
|
|
42
|
+
entry["p95"],
|
|
43
|
+
entry["runs"],
|
|
44
|
+
entry["failures"],
|
|
45
|
+
entry["timeouts"]
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
Export::Csv.generate(CSV_HEADERS, rows)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def format_markdown(merged, top: 30, title: "Polyrun slowest files")
|
|
52
|
+
rows = ranked_entries(merged, top: top).each_with_index.map do |(path, entry), index|
|
|
53
|
+
[index + 1, path, format("%.4f", Stats.binpack_weight(entry).to_f)]
|
|
54
|
+
end
|
|
55
|
+
Export::Markdown.document(
|
|
56
|
+
title,
|
|
57
|
+
[{heading: "Slow files", headers: MARKDOWN_HEADERS, rows: rows}]
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def render(merged, format: "text", **kwargs)
|
|
62
|
+
case format.to_s.downcase
|
|
63
|
+
when "text", "console", "txt" then format_slow_files(merged, **kwargs)
|
|
64
|
+
when "csv" then format_csv(merged, **kwargs)
|
|
65
|
+
when "markdown", "md" then format_markdown(merged, **kwargs)
|
|
66
|
+
else
|
|
67
|
+
raise Polyrun::Error, "report-timing: unknown format #{format.inspect} (use text, csv, or markdown)"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
22
71
|
def write_file(merged, path, **kwargs)
|
|
23
|
-
|
|
72
|
+
format = kwargs.delete(:format) || "text"
|
|
73
|
+
File.write(path, render(merged, format: format, **kwargs))
|
|
24
74
|
path
|
|
25
75
|
end
|
|
26
76
|
end
|
data/lib/polyrun/version.rb
CHANGED
data/polyrun.gemspec
CHANGED
|
@@ -10,10 +10,14 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.license = "MIT"
|
|
11
11
|
spec.required_ruby_version = ">= 3.1.0"
|
|
12
12
|
|
|
13
|
-
spec.files =
|
|
13
|
+
spec.files = (
|
|
14
|
+
Dir["lib/**/*", "sig/**/*.rbs", "bin/polyrun", "README.md", "CHANGELOG.md", "docs/SETUP_PROFILE.md", "LICENSE", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "SECURITY.md", "polyrun.gemspec"] +
|
|
15
|
+
Dir["ext/**/extconf.rb", "ext/**/*.c", "ext/**/*.h"]
|
|
16
|
+
).uniq.reject { |f| File.directory?(f) }
|
|
14
17
|
spec.bindir = "bin"
|
|
15
18
|
spec.executables = ["polyrun"]
|
|
16
19
|
spec.require_paths = ["lib"]
|
|
20
|
+
spec.extensions = ["ext/polyrun_coverage_merge/extconf.rb"]
|
|
17
21
|
|
|
18
22
|
spec.metadata = {
|
|
19
23
|
"homepage_uri" => spec.homepage,
|
|
@@ -25,6 +29,9 @@ Gem::Specification.new do |spec|
|
|
|
25
29
|
# Normative: zero runtime dependencies (stdlib + vendored/native code only).
|
|
26
30
|
# Ruby 3.5+: `benchmark` is no longer a default gem; keep scripts and `rake bench_merge` warning-free.
|
|
27
31
|
spec.add_development_dependency "benchmark", ">= 0.3"
|
|
32
|
+
spec.add_development_dependency "benchmark-ips", "~> 2"
|
|
33
|
+
spec.add_development_dependency "memory_profiler", "~> 1"
|
|
34
|
+
spec.add_development_dependency "stackprof", "~> 0.2"
|
|
28
35
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
29
36
|
spec.add_development_dependency "rspec", "~> 3.12"
|
|
30
37
|
spec.add_development_dependency "appraisal", "~> 2.5"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: polyrun
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -23,6 +23,48 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.3'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: benchmark-ips
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: memory_profiler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: stackprof
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.2'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.2'
|
|
26
68
|
- !ruby/object:Gem::Dependency
|
|
27
69
|
name: rake
|
|
28
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -153,7 +195,8 @@ email:
|
|
|
153
195
|
- contact@kiskolabs.com
|
|
154
196
|
executables:
|
|
155
197
|
- polyrun
|
|
156
|
-
extensions:
|
|
198
|
+
extensions:
|
|
199
|
+
- ext/polyrun_coverage_merge/extconf.rb
|
|
157
200
|
extra_rdoc_files: []
|
|
158
201
|
files:
|
|
159
202
|
- CHANGELOG.md
|
|
@@ -164,8 +207,13 @@ files:
|
|
|
164
207
|
- SECURITY.md
|
|
165
208
|
- bin/polyrun
|
|
166
209
|
- docs/SETUP_PROFILE.md
|
|
210
|
+
- ext/polyrun_coverage_merge/coverage_merge.c
|
|
211
|
+
- ext/polyrun_coverage_merge/extconf.rb
|
|
167
212
|
- lib/polyrun.rb
|
|
213
|
+
- lib/polyrun/benchmark/profile.rb
|
|
214
|
+
- lib/polyrun/benchmark/report.rb
|
|
168
215
|
- lib/polyrun/cli.rb
|
|
216
|
+
- lib/polyrun/cli/benchmark_commands.rb
|
|
169
217
|
- lib/polyrun/cli/ci_shard_hooks.rb
|
|
170
218
|
- lib/polyrun/cli/ci_shard_run_command.rb
|
|
171
219
|
- lib/polyrun/cli/ci_shard_run_parse.rb
|
|
@@ -208,6 +256,9 @@ files:
|
|
|
208
256
|
- lib/polyrun/coverage/collector_finish.rb
|
|
209
257
|
- lib/polyrun/coverage/collector_fragment_meta.rb
|
|
210
258
|
- lib/polyrun/coverage/example_diff.rb
|
|
259
|
+
- lib/polyrun/coverage/example_diff_snapshot.rb
|
|
260
|
+
- lib/polyrun/coverage/example_diff_track_filter.rb
|
|
261
|
+
- lib/polyrun/coverage/file_stats_report.rb
|
|
211
262
|
- lib/polyrun/coverage/filter.rb
|
|
212
263
|
- lib/polyrun/coverage/formatter.rb
|
|
213
264
|
- lib/polyrun/coverage/merge.rb
|
|
@@ -222,6 +273,7 @@ files:
|
|
|
222
273
|
- lib/polyrun/coverage/merge/html/template.html.erb
|
|
223
274
|
- lib/polyrun/coverage/merge_fragment_meta.rb
|
|
224
275
|
- lib/polyrun/coverage/merge_merge_two.rb
|
|
276
|
+
- lib/polyrun/coverage/merge_native.rb
|
|
225
277
|
- lib/polyrun/coverage/rails.rb
|
|
226
278
|
- lib/polyrun/coverage/reporting.rb
|
|
227
279
|
- lib/polyrun/coverage/result.rb
|
|
@@ -242,8 +294,11 @@ files:
|
|
|
242
294
|
- lib/polyrun/database/url_builder/template_prepare.rb
|
|
243
295
|
- lib/polyrun/debug.rb
|
|
244
296
|
- lib/polyrun/env/ci.rb
|
|
297
|
+
- lib/polyrun/export/csv.rb
|
|
298
|
+
- lib/polyrun/export/markdown.rb
|
|
245
299
|
- lib/polyrun/hooks.rb
|
|
246
300
|
- lib/polyrun/hooks/dsl.rb
|
|
301
|
+
- lib/polyrun/hooks/shell_runner.rb
|
|
247
302
|
- lib/polyrun/hooks/worker_runner.rb
|
|
248
303
|
- lib/polyrun/hooks/worker_shell.rb
|
|
249
304
|
- lib/polyrun/log.rb
|
|
@@ -279,6 +334,7 @@ files:
|
|
|
279
334
|
- lib/polyrun/reporting/failure_merge.rb
|
|
280
335
|
- lib/polyrun/reporting/junit.rb
|
|
281
336
|
- lib/polyrun/reporting/junit_emit.rb
|
|
337
|
+
- lib/polyrun/reporting/junit_report.rb
|
|
282
338
|
- lib/polyrun/reporting/rspec_failure_fragment_formatter.rb
|
|
283
339
|
- lib/polyrun/reporting/rspec_junit.rb
|
|
284
340
|
- lib/polyrun/rspec.rb
|