saboteur 0.2.0 → 0.4.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 +153 -1
- data/README.md +526 -73
- data/lib/generators/saboteur/install/install_generator.rb +21 -0
- data/lib/saboteur/agent_skill.rb +40 -0
- data/lib/saboteur/baseline_health.rb +116 -0
- data/lib/saboteur/cli.rb +305 -30
- data/lib/saboteur/config.rb +65 -19
- data/lib/saboteur/config_file.rb +97 -0
- data/lib/saboteur/custom_map.rb +170 -0
- data/lib/saboteur/doctor.rb +88 -0
- data/lib/saboteur/engine/baseline_guard.rb +116 -0
- data/lib/saboteur/engine/boot.rb +9 -0
- data/lib/saboteur/engine/candidate_selection.rb +35 -0
- data/lib/saboteur/engine/coverage_store.rb +40 -6
- data/lib/saboteur/engine/data_inputs.rb +43 -0
- data/lib/saboteur/engine/diagnostics.rb +28 -0
- data/lib/saboteur/engine/diff_scope.rb +8 -0
- data/lib/saboteur/engine/distribution.rb +4 -2
- data/lib/saboteur/engine/run_fingerprint.rb +344 -0
- data/lib/saboteur/engine/scheduler.rb +7 -16
- data/lib/saboteur/engine/suite_files.rb +8 -1
- data/lib/saboteur/engine/verdict_check.rb +4 -2
- data/lib/saboteur/engine.rb +125 -25
- data/lib/saboteur/execution/fork_readiness.rb +46 -0
- data/lib/saboteur/execution/reevaluator.rb +7 -4
- data/lib/saboteur/execution/supervisor.rb +23 -11
- data/lib/saboteur/frameworks/rails.rb +329 -13
- data/lib/saboteur/help.rb +210 -0
- data/lib/saboteur/ignore_list.rb +71 -17
- data/lib/saboteur/install.rb +132 -0
- data/lib/saboteur/integration/base.rb +8 -0
- data/lib/saboteur/integration/rspec.rb +69 -4
- data/lib/saboteur/mutation_source/argument_removal.rb +86 -0
- data/lib/saboteur/mutation_source/builtin.rb +14 -3
- data/lib/saboteur/mutation_source/filter_replacement.rb +60 -0
- data/lib/saboteur/mutation_source/literal_replacement.rb +74 -0
- data/lib/saboteur/mutation_source/pair_removal.rb +101 -0
- data/lib/saboteur/replay.rb +33 -0
- data/lib/saboteur/reporter/agent.rb +87 -0
- data/lib/saboteur/reporter/agent_clipping.rb +29 -0
- data/lib/saboteur/reporter/agent_commands.rb +61 -0
- data/lib/saboteur/reporter/agent_incomplete.rb +37 -0
- data/lib/saboteur/reporter/agent_summary.rb +131 -0
- data/lib/saboteur/reporter/findings.rb +131 -0
- data/lib/saboteur/reporter/html.rb +213 -0
- data/lib/saboteur/reporter/replay.rb +23 -0
- data/lib/saboteur/reporter/stryker.rb +21 -4
- data/lib/saboteur/reporter/terminal.rb +76 -2
- data/lib/saboteur/result.rb +61 -9
- data/lib/saboteur/score.rb +89 -0
- data/lib/saboteur/version.rb +1 -1
- data/lib/saboteur/working_tree.rb +48 -0
- data/lib/saboteur.rb +7 -0
- metadata +30 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "open3"
|
|
5
|
+
|
|
6
|
+
module Saboteur
|
|
7
|
+
# The state of the working source a run looked at: the commit it was on and
|
|
8
|
+
# (the full SHA) and whether files differed from it, tracked changes and each
|
|
9
|
+
# untracked file alike.
|
|
10
|
+
# Saboteur's own output (cache and reports) is passed in as ignored paths, so a
|
|
11
|
+
# report from an earlier run does not make the tree look dirty. Without git, or
|
|
12
|
+
# outside a repository, the state is unknown.
|
|
13
|
+
class WorkingTree
|
|
14
|
+
State = Data.define(:head, :dirty, :changed_files) do
|
|
15
|
+
def label
|
|
16
|
+
return "unknown" if dirty.nil?
|
|
17
|
+
|
|
18
|
+
dirty ? "dirty" : "clean"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
UNKNOWN = State.new(head: nil, dirty: nil, changed_files: nil)
|
|
23
|
+
|
|
24
|
+
# ignored: paths relative to root that are not source (saboteur's cache and reports).
|
|
25
|
+
def initialize(root, ignored: [])
|
|
26
|
+
@root = root
|
|
27
|
+
@ignored = ignored
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def state
|
|
31
|
+
head, head_status = Open3.capture2e("git", "rev-parse", "HEAD", chdir: @root)
|
|
32
|
+
changes, changes_status = Open3.capture2e(*status_command, chdir: @root)
|
|
33
|
+
return UNKNOWN unless head_status.success? && changes_status.success?
|
|
34
|
+
|
|
35
|
+
count = changes.lines.size
|
|
36
|
+
State.new(head: head.strip, dirty: count.positive?, changed_files: count)
|
|
37
|
+
rescue SystemCallError
|
|
38
|
+
UNKNOWN
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def status_command
|
|
44
|
+
excluded = @ignored.map { |path| ":(exclude)#{path}" }
|
|
45
|
+
["git", "status", "--porcelain", "--untracked-files=all", "--", ".", *excluded]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/saboteur.rb
CHANGED
|
@@ -38,14 +38,21 @@ require_relative "saboteur/execution/supervisor"
|
|
|
38
38
|
require_relative "saboteur/execution/reevaluator"
|
|
39
39
|
require_relative "saboteur/execution/runner"
|
|
40
40
|
require_relative "saboteur/execution/worker_pool"
|
|
41
|
+
require_relative "saboteur/execution/fork_readiness"
|
|
41
42
|
require_relative "saboteur/selection/coverage_map"
|
|
42
43
|
require_relative "saboteur/selection/recorder"
|
|
43
44
|
require_relative "saboteur/selection/git_diff"
|
|
44
45
|
require_relative "saboteur/result"
|
|
46
|
+
require_relative "saboteur/custom_map"
|
|
45
47
|
require_relative "saboteur/config"
|
|
46
48
|
require_relative "saboteur/ignore_list"
|
|
47
49
|
require_relative "saboteur/frameworks/rails"
|
|
48
50
|
require_relative "saboteur/reporter/diff"
|
|
51
|
+
require_relative "saboteur/reporter/findings"
|
|
52
|
+
require_relative "saboteur/reporter/agent"
|
|
53
|
+
require_relative "saboteur/working_tree"
|
|
54
|
+
require_relative "saboteur/agent_skill"
|
|
49
55
|
require_relative "saboteur/reporter/terminal"
|
|
50
56
|
require_relative "saboteur/reporter/stryker"
|
|
57
|
+
require_relative "saboteur/reporter/html"
|
|
51
58
|
require_relative "saboteur/engine"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: saboteur
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vamsi Pavan Mahesh Gunturu
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fiddle
|
|
@@ -58,21 +58,32 @@ files:
|
|
|
58
58
|
- LICENSE
|
|
59
59
|
- README.md
|
|
60
60
|
- exe/saboteur
|
|
61
|
+
- lib/generators/saboteur/install/install_generator.rb
|
|
61
62
|
- lib/saboteur.rb
|
|
63
|
+
- lib/saboteur/agent_skill.rb
|
|
64
|
+
- lib/saboteur/baseline_health.rb
|
|
62
65
|
- lib/saboteur/cli.rb
|
|
63
66
|
- lib/saboteur/config.rb
|
|
67
|
+
- lib/saboteur/config_file.rb
|
|
68
|
+
- lib/saboteur/custom_map.rb
|
|
69
|
+
- lib/saboteur/doctor.rb
|
|
64
70
|
- lib/saboteur/engine.rb
|
|
71
|
+
- lib/saboteur/engine/baseline_guard.rb
|
|
65
72
|
- lib/saboteur/engine/boot.rb
|
|
73
|
+
- lib/saboteur/engine/candidate_selection.rb
|
|
66
74
|
- lib/saboteur/engine/candidates.rb
|
|
67
75
|
- lib/saboteur/engine/coverage_store.rb
|
|
76
|
+
- lib/saboteur/engine/data_inputs.rb
|
|
68
77
|
- lib/saboteur/engine/diagnostics.rb
|
|
69
78
|
- lib/saboteur/engine/diff_scope.rb
|
|
70
79
|
- lib/saboteur/engine/distribution.rb
|
|
71
80
|
- lib/saboteur/engine/result_cache.rb
|
|
81
|
+
- lib/saboteur/engine/run_fingerprint.rb
|
|
72
82
|
- lib/saboteur/engine/scheduler.rb
|
|
73
83
|
- lib/saboteur/engine/subject_selection.rb
|
|
74
84
|
- lib/saboteur/engine/suite_files.rb
|
|
75
85
|
- lib/saboteur/engine/verdict_check.rb
|
|
86
|
+
- lib/saboteur/execution/fork_readiness.rb
|
|
76
87
|
- lib/saboteur/execution/process_table.rb
|
|
77
88
|
- lib/saboteur/execution/process_tree.rb
|
|
78
89
|
- lib/saboteur/execution/protocol.rb
|
|
@@ -81,24 +92,41 @@ files:
|
|
|
81
92
|
- lib/saboteur/execution/supervisor.rb
|
|
82
93
|
- lib/saboteur/execution/worker_pool.rb
|
|
83
94
|
- lib/saboteur/frameworks/rails.rb
|
|
95
|
+
- lib/saboteur/help.rb
|
|
84
96
|
- lib/saboteur/hooks.rb
|
|
85
97
|
- lib/saboteur/ignore_list.rb
|
|
98
|
+
- lib/saboteur/install.rb
|
|
86
99
|
- lib/saboteur/integration/base.rb
|
|
87
100
|
- lib/saboteur/integration/rspec.rb
|
|
101
|
+
- lib/saboteur/mutation_source/argument_removal.rb
|
|
88
102
|
- lib/saboteur/mutation_source/base.rb
|
|
89
103
|
- lib/saboteur/mutation_source/builtin.rb
|
|
90
104
|
- lib/saboteur/mutation_source/edit.rb
|
|
105
|
+
- lib/saboteur/mutation_source/filter_replacement.rb
|
|
106
|
+
- lib/saboteur/mutation_source/literal_replacement.rb
|
|
91
107
|
- lib/saboteur/mutation_source/mutation.rb
|
|
108
|
+
- lib/saboteur/mutation_source/pair_removal.rb
|
|
109
|
+
- lib/saboteur/replay.rb
|
|
110
|
+
- lib/saboteur/reporter/agent.rb
|
|
111
|
+
- lib/saboteur/reporter/agent_clipping.rb
|
|
112
|
+
- lib/saboteur/reporter/agent_commands.rb
|
|
113
|
+
- lib/saboteur/reporter/agent_incomplete.rb
|
|
114
|
+
- lib/saboteur/reporter/agent_summary.rb
|
|
92
115
|
- lib/saboteur/reporter/diff.rb
|
|
116
|
+
- lib/saboteur/reporter/findings.rb
|
|
117
|
+
- lib/saboteur/reporter/html.rb
|
|
118
|
+
- lib/saboteur/reporter/replay.rb
|
|
93
119
|
- lib/saboteur/reporter/stryker.rb
|
|
94
120
|
- lib/saboteur/reporter/terminal.rb
|
|
95
121
|
- lib/saboteur/result.rb
|
|
122
|
+
- lib/saboteur/score.rb
|
|
96
123
|
- lib/saboteur/selection/coverage_map.rb
|
|
97
124
|
- lib/saboteur/selection/git_diff.rb
|
|
98
125
|
- lib/saboteur/selection/recorder.rb
|
|
99
126
|
- lib/saboteur/subject.rb
|
|
100
127
|
- lib/saboteur/subject_finder.rb
|
|
101
128
|
- lib/saboteur/version.rb
|
|
129
|
+
- lib/saboteur/working_tree.rb
|
|
102
130
|
homepage: https://github.com/vamsipavanmahesh/saboteur
|
|
103
131
|
licenses:
|
|
104
132
|
- MIT
|