flakey_spec_catcher 0.5.0 → 0.6.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/bin/flakey_spec_catcher +6 -3
- data/lib/flakey_spec_catcher/capsule_manager.rb +1 -12
- data/lib/flakey_spec_catcher/change_capsule.rb +12 -13
- data/lib/flakey_spec_catcher/change_context.rb +15 -20
- data/lib/flakey_spec_catcher/cli_override.rb +4 -1
- data/lib/flakey_spec_catcher/git_controller.rb +44 -1
- data/lib/flakey_spec_catcher/user_config.rb +3 -0
- data/lib/flakey_spec_catcher/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16de08551fe8e8417b75b81548de5a56cc64b0a90e3b4458c0e515938b52a954
|
4
|
+
data.tar.gz: 5e98f8c50760a963463b713e04eaf74240b382a99b9e577187bdef61789e28ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb1e1e3dbbeba8c3441f1b7f56d9b79e3438d36261a679afef5855f59cdd27d34d6eb195f2705b76f399513ca9ecb5d0d2d17cbb893851d1bf7f4a10b82b2ce1
|
7
|
+
data.tar.gz: 050eed36f9fcb9c50b3a1bc0ce22ead64572d5b9ebcc2efe0474882e5f61315528104c79151fc8571303e09106c440ebf02f7f42d5f7e87c697bf97c42e6736a
|
data/bin/flakey_spec_catcher
CHANGED
@@ -27,7 +27,6 @@ module FlakeySpecCatcher
|
|
27
27
|
@change_capsules.map(&:file_name).uniq
|
28
28
|
end
|
29
29
|
|
30
|
-
# rubocop:disable Metrics/AbcSize
|
31
30
|
def condense_reruns
|
32
31
|
# Don't re-run if the parent context of a change will be run
|
33
32
|
reruns = []
|
@@ -35,21 +34,11 @@ module FlakeySpecCatcher
|
|
35
34
|
.sort_by { |c| c.line_number.to_i }
|
36
35
|
|
37
36
|
all_contexts.each do |context|
|
38
|
-
next if reruns.include?(context.file_name)
|
39
|
-
|
40
|
-
found_parent_match = false
|
41
|
-
all_contexts.each do |other|
|
42
|
-
next if context == other
|
43
|
-
|
44
|
-
found_parent_match = true if context.parent_matches_context(other)
|
45
|
-
end
|
46
|
-
|
47
|
-
next if found_parent_match
|
37
|
+
next if reruns.include?(context.file_name) || context.ancestor_present_in_reruns(reruns)
|
48
38
|
|
49
39
|
reruns.push(context.rerun_info) unless reruns.include?(context.rerun_info)
|
50
40
|
end
|
51
41
|
reruns
|
52
42
|
end
|
53
|
-
# rubocop:enable Metrics/AbcSize
|
54
43
|
end
|
55
44
|
end
|
@@ -5,7 +5,7 @@ module FlakeySpecCatcher
|
|
5
5
|
#
|
6
6
|
# Summarizes a git change for a single file.
|
7
7
|
#
|
8
|
-
# A ChangeCapsule object will represent the changes made to a
|
8
|
+
# A ChangeCapsule object will represent the changes made to a block of code. It
|
9
9
|
# accomplishes this using ChangeContext and ChangeSummary objects.
|
10
10
|
class ChangeCapsule
|
11
11
|
attr_reader :file_name, :change_summary, :change_contexts
|
@@ -28,9 +28,11 @@ module FlakeySpecCatcher
|
|
28
28
|
ignore_scope_closure = 0
|
29
29
|
lines_in_file = File.read(@file_name).split("\n")
|
30
30
|
lines_in_file.each_with_index do |line, index|
|
31
|
+
# Check if line matches an rspec example or examplegroup format
|
31
32
|
if line =~ spec_scope
|
32
33
|
handle_change_context(line, index, change_context_stack)
|
33
|
-
|
34
|
+
# Else, ignore other blocks that might pollute context stack
|
35
|
+
elsif line_matches_method_or_block(line)
|
34
36
|
ignore_scope_closure += 1
|
35
37
|
end
|
36
38
|
|
@@ -59,8 +61,6 @@ module FlakeySpecCatcher
|
|
59
61
|
if context.nil?
|
60
62
|
change_context = FlakeySpecCatcher::ChangeContext.new(description: nil,
|
61
63
|
line_number: nil,
|
62
|
-
parent_description: nil,
|
63
|
-
parent_line_number: nil,
|
64
64
|
file_name: @file_name)
|
65
65
|
@change_contexts.push(change_context)
|
66
66
|
else
|
@@ -75,6 +75,12 @@ module FlakeySpecCatcher
|
|
75
75
|
/\s*(#{SCOPE_SPECIFIERS.join("|")}).*\s+do\s*$/
|
76
76
|
end
|
77
77
|
|
78
|
+
def line_matches_method_or_block(line)
|
79
|
+
return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/
|
80
|
+
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
78
84
|
def pop_scope
|
79
85
|
/\s+end(\s+|$)/
|
80
86
|
end
|
@@ -99,16 +105,9 @@ module FlakeySpecCatcher
|
|
99
105
|
end
|
100
106
|
|
101
107
|
def handle_change_context(line, line_number, change_context_stack)
|
102
|
-
if !change_context_stack.empty?
|
103
|
-
parent_desc = change_context_stack[-1].description
|
104
|
-
parent_line = change_context_stack[-1].line_number
|
105
|
-
else
|
106
|
-
parent_desc = nil
|
107
|
-
parent_line = nil
|
108
|
-
end
|
109
108
|
change_context = FlakeySpecCatcher::ChangeContext.new(
|
110
|
-
description: line, line_number: (line_number + 1),
|
111
|
-
|
109
|
+
description: line, line_number: (line_number + 1),
|
110
|
+
file_name: @file_name, ancestor_contexts: change_context_stack.dup
|
112
111
|
)
|
113
112
|
|
114
113
|
change_context_stack.push(change_context) unless
|
@@ -15,35 +15,29 @@ module FlakeySpecCatcher
|
|
15
15
|
# the 'describe' block only.
|
16
16
|
class ChangeContext
|
17
17
|
attr_reader :description, :line_number
|
18
|
-
attr_reader :
|
19
|
-
attr_reader :file_name
|
18
|
+
attr_reader :ancestor_contexts, :file_name
|
20
19
|
|
21
|
-
def initialize(description:, line_number:,
|
22
|
-
parent_line_number:, file_name:)
|
20
|
+
def initialize(description:, line_number:, file_name:, ancestor_contexts: [])
|
23
21
|
@description = description
|
24
22
|
@line_number = line_number
|
25
|
-
|
26
|
-
@parent_line_number = parent_line_number
|
23
|
+
|
27
24
|
@file_name = file_name
|
25
|
+
@ancestor_contexts = ancestor_contexts
|
28
26
|
update_descriptions
|
29
27
|
end
|
30
28
|
|
31
29
|
def update_descriptions
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@parent_line_number = nil
|
37
|
-
elsif @parent_description.nil? || @parent_description.empty?
|
38
|
-
@parent_description = @file_name
|
39
|
-
@parent_line_number = nil
|
40
|
-
end
|
30
|
+
return unless @description.nil? || @description.empty?
|
31
|
+
|
32
|
+
@description = @file_name
|
33
|
+
@line_number = nil
|
41
34
|
end
|
42
35
|
|
43
36
|
def ==(other)
|
44
37
|
@description == other.description &&
|
45
38
|
@line_number == other.line_number &&
|
46
|
-
@file_name == other.file_name
|
39
|
+
@file_name == other.file_name &&
|
40
|
+
@ancestor_contexts == other.ancestor_contexts
|
47
41
|
end
|
48
42
|
|
49
43
|
def rerun_info
|
@@ -54,10 +48,11 @@ module FlakeySpecCatcher
|
|
54
48
|
end
|
55
49
|
end
|
56
50
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
51
|
+
def ancestor_present_in_reruns(reruns)
|
52
|
+
reruns.each do |rerun|
|
53
|
+
return true if @ancestor_contexts.map(&:rerun_info).include? rerun
|
54
|
+
end
|
55
|
+
false
|
61
56
|
end
|
62
57
|
end
|
63
58
|
end
|
@@ -7,9 +7,10 @@ module FlakeySpecCatcher
|
|
7
7
|
#
|
8
8
|
# Captures command line arguments for manual re-runs
|
9
9
|
class CliOverride
|
10
|
-
attr_reader :rerun_pattern, :rerun_usage, :repeat_factor
|
10
|
+
attr_reader :rerun_pattern, :rerun_usage, :repeat_factor, :enable_runs
|
11
11
|
|
12
12
|
def initialize
|
13
|
+
@enable_runs = true
|
13
14
|
parse_command_line_args
|
14
15
|
end
|
15
16
|
|
@@ -41,10 +42,12 @@ module FlakeySpecCatcher
|
|
41
42
|
|
42
43
|
opts.on('-v', '--version', 'Prints current flakey_spec_catcher_version') do
|
43
44
|
puts "flakey_spec_catcher Version: #{FlakeySpecCatcher::VERSION}"
|
45
|
+
@enable_runs = false
|
44
46
|
end
|
45
47
|
|
46
48
|
opts.on('-h', '--help', 'Displays available flakey_spec_catcher cli overrides') do
|
47
49
|
puts opts
|
50
|
+
@enable_runs = false
|
48
51
|
end
|
49
52
|
end.parse!
|
50
53
|
end
|
@@ -20,7 +20,7 @@ module FlakeySpecCatcher
|
|
20
20
|
attr_reader :capsule_manager
|
21
21
|
|
22
22
|
def initialize(test_mode: false, capsule_manager: FlakeySpecCatcher::CapsuleManager.new)
|
23
|
-
@branch =
|
23
|
+
@branch = find_remote_branch
|
24
24
|
@remote = `git remote`.gsub(/\s+/, '')
|
25
25
|
@capsule_manager = capsule_manager
|
26
26
|
initialize_git_comparison(test_mode)
|
@@ -34,6 +34,49 @@ module FlakeySpecCatcher
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
+
def find_remote_branch
|
38
|
+
working_branch = `git branch | grep '*'`.delete('*').gsub(/\s+/, '')
|
39
|
+
# `git remote show origin` will show us if our branch is configured to push
|
40
|
+
# to a non-master branch. Note that our push destination is what we're interested in
|
41
|
+
# Assume master if no matches
|
42
|
+
|
43
|
+
# Example output
|
44
|
+
# * remote origin
|
45
|
+
# Fetch URL: gerrit:repo
|
46
|
+
# Push URL: gerrit:repo
|
47
|
+
# HEAD branch: master
|
48
|
+
# Remote branches:
|
49
|
+
# dev/reports tracked
|
50
|
+
# edge tracked
|
51
|
+
# master tracked
|
52
|
+
# Local branch configured for 'git pull':
|
53
|
+
# master merges with remote master
|
54
|
+
# Local refs configured for 'git push':
|
55
|
+
# dev/reports pushes to dev/reports (up to date)
|
56
|
+
# master pushes to master (up to date)
|
57
|
+
|
58
|
+
remote_branches = `git remote show origin`.split("\n")
|
59
|
+
|
60
|
+
# Separate 'dev/reports pushes to dev/reports (up to date)' into
|
61
|
+
# ['dev/reports', 'dev/reports'] or [<LOCAL BRANCH>, <REMOTE BRANCH>]
|
62
|
+
remote_pairs = remote_branches.map { |r| r.scan(/(\S*)\s+pushes to\s+(\S*)\s+/).flatten }
|
63
|
+
|
64
|
+
# check if the working branch (currently checked out branch) corresponds to a remote_pair
|
65
|
+
# if so, use that remote pair for comparison, else use master
|
66
|
+
match = remote_pairs.find do |pair|
|
67
|
+
# working branch (pair[0]) pushes to remote (pair[1])
|
68
|
+
pair[0] == working_branch
|
69
|
+
end
|
70
|
+
|
71
|
+
remote_branch = if match.nil?
|
72
|
+
'master'
|
73
|
+
else
|
74
|
+
# match is formatted as [working_branch, remote]
|
75
|
+
match[1]
|
76
|
+
end
|
77
|
+
remote_branch
|
78
|
+
end
|
79
|
+
|
37
80
|
def initialize_git_comparison(test_mode)
|
38
81
|
if !test_mode
|
39
82
|
@working_commit_sha = `git rev-parse @`.gsub(/\s+/, '')
|
@@ -9,6 +9,8 @@ module FlakeySpecCatcher
|
|
9
9
|
attr_reader :repeat_factor, :ignore_files, :ignore_branches, :silent_mode
|
10
10
|
attr_reader :rerun_file_only, :rspec_usage_patterns
|
11
11
|
attr_reader :manual_rerun_pattern, :manual_rerun_usage
|
12
|
+
attr_reader :enable_runs
|
13
|
+
|
12
14
|
USER_CONFIG_ENV_VARS = %w[FSC_REPEAT_FACTOR FSC_IGNORE_FILES FSC_IGNORE_BRANCHES
|
13
15
|
FSC_SILENT_MODE FSC_RERUN_FILE_ONLY FSC_USAGE_PATTERNS].freeze
|
14
16
|
|
@@ -36,6 +38,7 @@ module FlakeySpecCatcher
|
|
36
38
|
@manual_rerun_pattern = @cli_override.rerun_pattern
|
37
39
|
@manual_rerun_usage = @cli_override.rerun_usage
|
38
40
|
@repeat_factor = @cli_override.repeat_factor if @cli_override.repeat_factor.to_i.positive?
|
41
|
+
@enable_runs = @cli_override.enable_runs
|
39
42
|
end
|
40
43
|
|
41
44
|
def remove_formatter_quotes(env_var)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flakey_spec_catcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Watson
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-12-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.7.
|
126
|
+
rubygems_version: 2.7.7
|
127
127
|
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: Run new or changed specs many times to prevent unreliable specs
|