flakey_spec_catcher 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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