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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c2c74dc190189f31023ee816f41a7856aceee56ccca2de3f385b3559932cfde
4
- data.tar.gz: 15b1cf40884ea015014a2d0b4b96ea223f46f9381751282d370e21641a0456da
3
+ metadata.gz: 16de08551fe8e8417b75b81548de5a56cc64b0a90e3b4458c0e515938b52a954
4
+ data.tar.gz: 5e98f8c50760a963463b713e04eaf74240b382a99b9e577187bdef61789e28ca
5
5
  SHA512:
6
- metadata.gz: f3eea41fa5d50fd29d292810a5b1fbf0c25452e57c85c81999fb257063a02f823657e15bd2cb9e23c63fe90923367d89b9098e5aef56142dcf51f9638412d86e
7
- data.tar.gz: 7fbc79e679dfc5c4f38c995c377ab119eae0d4e890d1d5b7b97ee9516215f60e094439f246dfd7e97c2b4fa3f5c2dd5293979d230d26da7fc19174d1192ce327
6
+ metadata.gz: fb1e1e3dbbeba8c3441f1b7f56d9b79e3438d36261a679afef5855f59cdd27d34d6eb195f2705b76f399513ca9ecb5d0d2d17cbb893851d1bf7f4a10b82b2ce1
7
+ data.tar.gz: 050eed36f9fcb9c50b3a1bc0ce22ead64572d5b9ebcc2efe0474882e5f61315528104c79151fc8571303e09106c440ebf02f7f42d5f7e87c697bf97c42e6736a
@@ -4,6 +4,9 @@
4
4
  require 'flakey_spec_catcher'
5
5
 
6
6
  app = FlakeySpecCatcher::Runner.new
7
- app.show_settings
8
- app.rerun_preview
9
- exit app.run_specs
7
+
8
+ if app.user_config.enable_runs
9
+ app.show_settings
10
+ app.rerun_preview
11
+ exit app.run_specs
12
+ end
@@ -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 single file. It
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
- elsif line =~ /\s*do(\s+|$)/
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), parent_description: parent_desc,
111
- parent_line_number: parent_line, file_name: @file_name
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 :parent_description, :parent_line_number
19
- attr_reader :file_name
18
+ attr_reader :ancestor_contexts, :file_name
20
19
 
21
- def initialize(description:, line_number:, parent_description:,
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
- @parent_description = parent_description
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
- if @description.nil? || @description.empty?
33
- @description = @file_name
34
- @line_number = nil
35
- @parent_description = nil
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 parent_matches_context(other)
58
- @parent_description == other.description &&
59
- @parent_line_number == other.line_number &&
60
- @file_name == other.file_name
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 = `git branch | grep '*'`.delete('*').gsub(/\s+/, '')
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlakeySpecCatcher
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
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.5.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-10-11 00:00:00.000000000 Z
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.6
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