flakey_spec_catcher 0.9.4 → 0.10.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: 741a4b99da98b4eed541bd4dc36476c66a3df1efd21e6a79ea00547202b9e30e
4
- data.tar.gz: 48cb6f40ee8cf9f7019639622a8f3d9dc366b3b6691fde3418a1197dd0d0672e
3
+ metadata.gz: 9894969be42fdb7dfafa961942ce16b1313ca3cffdc746d9613ebe1398d39069
4
+ data.tar.gz: 75238a79f25ddb8cec6fd60064e9f06d5f5651b8bb3c27e423f317f653f65774
5
5
  SHA512:
6
- metadata.gz: e135869d651917524f5abd7015f651a636a3d4c584a99a2d6860e094f3754779e2d0798d81f5b51df3bb9da323743a720c7a8f15ad160cbc7cf228794995f1a7
7
- data.tar.gz: a665e8efe5d67ec47706fde62a3cfc7a087303950e32778819154bacac2da4f7efd5a7135ca2236ab2ab6851e338e519924b06a76d5d73be10a4a7348afd4409
6
+ metadata.gz: d3698a10fd2c5d4ae75f3fe0250d7578a82906eb6ad478c759756911501b8f53125a63f1ced325e51c6115a9f76c7ac2264ae28a42c8b65273376186e8e7aa34
7
+ data.tar.gz: 440e5ef180775556f3292548330cf9572db13d82394921fbbca6053b37ed4c088aa5c37b9dcb06ab2fb4049879c7fe2a093a60cf05da649abb950bf01d0af6cf
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /.byebug_history
1
2
  /coverage
2
3
  /Gemfile.lock
3
4
  /flakey_spec_catcher-*.gem
data/README.md CHANGED
@@ -160,8 +160,10 @@ FSC_USAGE_PATTERNS = '{ spec/ui => bundle exec rspec }, { spec/api => parallel_r
160
160
  --node-index Specify the index this node represents in a split run
161
161
  -d, --dry-run Performs all setup but doesn't run any tests
162
162
  --dry-run-quiet Prints list of tests to be run
163
+ --verbose Send all output from running tests to stdout
163
164
  -v, --version Prints current flakey_spec_catcher_version
164
165
  -h, --help Displays available flakey_spec_catcher cli overrides
166
+ --rspec-options '[OPTIONS]' Execute default usage with rspec options
165
167
  ```
166
168
 
167
169
  Examples:
@@ -28,11 +28,13 @@ Gem::Specification.new do |gem|
28
28
  gem.require_paths = ['lib']
29
29
 
30
30
  gem.metadata['allowed_push_host'] = 'https://rubygems.org'
31
- gem.required_ruby_version = '>= 2.3'
31
+ gem.required_ruby_version = '>= 2.6'
32
32
 
33
- gem.add_dependency 'rspec', '~> 3.8'
33
+ gem.add_dependency 'rspec', '~> 3.10'
34
+ gem.add_development_dependency 'byebug', '~> 11.1'
34
35
  gem.add_development_dependency 'climate_control', '~> 0.2'
35
- gem.add_development_dependency 'rake', '~> 12.3'
36
- gem.add_development_dependency 'simplecov', '~> 0.17'
36
+ gem.add_development_dependency 'rake', '~> 13.0'
37
+ gem.add_development_dependency 'rubocop', '~> 0.93.1'
38
+ gem.add_development_dependency 'simplecov', '~> 0.19'
37
39
  end
38
40
  # rubocop:enable Layout/ExtraSpacing, Layout/SpaceAroundOperators
@@ -76,7 +76,7 @@ module FlakeySpecCatcher
76
76
  end
77
77
 
78
78
  def line_matches_method_or_block(line)
79
- return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/
79
+ return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/ || line =~ /^\s*if\s+/
80
80
 
81
81
  false
82
82
  end
@@ -8,13 +8,15 @@ module FlakeySpecCatcher
8
8
  # Captures command line arguments for manual re-runs
9
9
  class CliOverride
10
10
  attr_reader :rerun_patterns, :rerun_usage, :repeat_factor, :enable_runs, :excluded_tags, :use_parent, :dry_run
11
- attr_reader :output_file, :split_nodes, :split_index
11
+ attr_reader :output_file, :split_nodes, :split_index, :verbose, :test_options, :break_on_first_failure
12
12
 
13
13
  def initialize
14
14
  @dry_run = false
15
15
  @enable_runs = true
16
16
  @excluded_tags = []
17
17
  @use_parent = false
18
+ @verbose = false
19
+ @test_options = []
18
20
  parse_command_line_args
19
21
  validate_arguments
20
22
  end
@@ -54,6 +56,10 @@ module FlakeySpecCatcher
54
56
  @repeat_factor = remove_formatter_quotes(repeat).to_i
55
57
  end
56
58
 
59
+ opts.on('--break-on-first-failure', 'Break on first failure') do |break_on_first_failure|
60
+ @break_on_first_failure = break_on_first_failure
61
+ end
62
+
57
63
  opts.on('-e', '--excluded-tags=EXCLUDED_TAGS',
58
64
  'Specify tags to exclude in a comma separated list') do |tags|
59
65
  @excluded_tags = parse_tags(tags)
@@ -78,10 +84,18 @@ module FlakeySpecCatcher
78
84
  @dry_run = true
79
85
  end
80
86
 
87
+ opts.on('--verbose', 'Send all output from running tests to stdout') do
88
+ @verbose = true
89
+ end
90
+
81
91
  opts.on('-h', '--help', 'Displays available flakey_spec_catcher cli overrides') do
82
92
  puts opts
83
93
  @enable_runs = false
84
94
  end
95
+
96
+ opts.on("--rspec-options '[OPTIONS]'", 'execute default usage with rspec options') do |arg|
97
+ @test_options = arg.split(/[ ](?=(?:[^"]*"[^"]*")*[^"]*$)(?=(?:[^']*'[^']*')*[^']*$)/)
98
+ end
85
99
  end.parse!
86
100
  end
87
101
 
@@ -56,45 +56,12 @@ module FlakeySpecCatcher
56
56
  return nil if @remote.nil?
57
57
 
58
58
  working_branch = `git branch | grep '*'`.delete('*').gsub(/\s+/, '')
59
- # `git remote show origin` will show us if our branch is configured to push
60
- # to a non-master branch. Note that our push destination is what we're interested in
61
- # Assume master if no matches
62
-
63
- # Example output
64
- # * remote origin
65
- # Fetch URL: gerrit:repo
66
- # Push URL: gerrit:repo
67
- # HEAD branch: master
68
- # Remote branches:
69
- # dev/reports tracked
70
- # edge tracked
71
- # master tracked
72
- # Local branch configured for 'git pull':
73
- # master merges with remote master
74
- # Local refs configured for 'git push':
75
- # dev/reports pushes to dev/reports (up to date)
76
- # master pushes to master (up to date)
77
-
78
- remote_branches = `git remote show #{@remote}`.split("\n")
79
-
80
- # Separate 'dev/reports pushes to dev/reports (up to date)' into
81
- # ['dev/reports', 'dev/reports'] or [<LOCAL BRANCH>, <REMOTE BRANCH>]
82
- remote_pairs = remote_branches.map { |r| r.scan(/(\S*)\s+pushes to\s+(\S*)\s+/).flatten }
83
-
84
- # check if the working branch (currently checked out branch) corresponds to a remote_pair
85
- # if so, use that remote pair for comparison, else use master
86
- match = remote_pairs.find do |pair|
87
- # working branch (pair[0]) pushes to remote (pair[1])
88
- pair[0] == working_branch
89
- end
59
+ branch_remote = `git config branch.#{working_branch}.remote`.strip
60
+ return 'master' unless @remote == branch_remote
90
61
 
91
- remote_branch = if match.nil?
92
- 'master'
93
- else
94
- # match is formatted as [working_branch, remote]
95
- match[1]
96
- end
97
- remote_branch
62
+ remote_branch = `git config branch.#{branch}.merge`.strip.sub(%r{^refs/heads/}, '')
63
+ remote_branch = nil if remote_branch.empty?
64
+ remote_branch || 'master'
98
65
  end
99
66
 
100
67
  def initialize_git_comparison(test_mode)
@@ -108,7 +75,7 @@ module FlakeySpecCatcher
108
75
  @git_comparison = "#{@base_commit_sha}..#{@working_commit_sha}"
109
76
  end
110
77
 
111
- # rubocop:disable Metrics/AbcSize
78
+ # rubocop:disable Metrics/CyclomaticComplexity
112
79
  def parse_changes
113
80
  # For each file, get the change block
114
81
  diff_files.each do |filename|
@@ -128,7 +95,7 @@ module FlakeySpecCatcher
128
95
  end
129
96
  end
130
97
  end
131
- # rubocop:enable Metrics/AbcSize
98
+ # rubocop:enable Metrics/CyclomaticComplexity
132
99
 
133
100
  def identify_change_contexts
134
101
  @capsule_manager.change_capsules.each(&:fill_contexts)
@@ -24,6 +24,7 @@ module FlakeySpecCatcher
24
24
  @rerun_manager = rerun_manager
25
25
  @rspec_result_manager = result_manager
26
26
  @test_run_count = 0
27
+ @temp_output_file = @user_config.output_file + 'temp' unless @user_config.output_file == File::NULL
27
28
  end
28
29
 
29
30
  # Debug Methods
@@ -35,10 +36,11 @@ module FlakeySpecCatcher
35
36
  puts " Current Sha: #{@git_controller.working_commit_sha}"
36
37
  puts " Base Sha: #{@git_controller.base_commit_sha}"
37
38
  puts " Repeat factor: #{@user_config.repeat_factor}"
39
+ puts " Break on first failure: #{@user_config.break_on_first_failure}" if @user_config.break_on_first_failure
38
40
  puts " Node Total: #{@user_config.split_nodes}" if @user_config.split_nodes
39
41
  puts " Node Index: #{@user_config.split_index}" if @user_config.split_index
40
42
  puts " Changed Specs Detected: #{@git_controller.changed_examples}"
41
- return if @user_config.output_file == '/dev/null'
43
+ return if @user_config.output_file == File::NULL
42
44
 
43
45
  puts " Verbose Output Path: #{@user_config.output_file}"
44
46
  end
@@ -74,10 +76,12 @@ module FlakeySpecCatcher
74
76
  @user_config.repeat_factor.times do
75
77
  iteration_status = handle_capsule_rerun(capsule)
76
78
  status = [status, iteration_status].max
79
+ break if @user_config.break_on_first_failure && !status.zero?
77
80
  end
78
81
  end
79
82
 
80
83
  display_results(status)
84
+ copy_to_user_output unless @user_config.output_file == File::NULL
81
85
 
82
86
  # Always return 0 if silent_mode is enabled
83
87
  @user_config.silent_mode ? 0 : status
@@ -93,16 +97,23 @@ module FlakeySpecCatcher
93
97
  def invoke_rspec_runner(test)
94
98
  configure_listener
95
99
  # Pass in CLI options to suppress normal output, and only run the specified test
96
- rspec_args = ['--out', @user_config.output_file, test]
97
- return_status = RSpec::Core::Runner.run(rspec_args)
100
+ rspec_args = ['--format', 'documentation', '--out', @user_config.output_file, test]
101
+ # Rspec output sent to stdout if verbose option is true
102
+ rspec_args << '-fd' if @user_config.verbose
103
+ return_status = RSpec::Core::Runner.run(@user_config.test_options.concat(rspec_args))
98
104
  RSpec.clear_examples
105
+ copy_output_to_temp_file unless @user_config.output_file == File::NULL
99
106
  return_status
100
107
  end
101
108
 
102
109
  def invoke_custom_rspec_runner(usage, testcase)
103
- custom_usage_output = `#{usage} #{testcase.join(' ')}`
110
+ if @user_config.verbose
111
+ $stdout << custom_usage_output = `#{usage} #{testcase.join(' ')}`
112
+ else
113
+ custom_usage_output = `#{usage} #{testcase.join(' ')}`
114
+ end
104
115
 
105
- File.open(@user_config.output_file, 'a') { |f| f.puts custom_usage_output } if @user_config.output_file != '/dev/null'
116
+ File.open(@user_config.output_file, 'a') { |f| f.puts custom_usage_output } if @user_config.output_file != File::NULL
106
117
 
107
118
  $?.exitstatus # rubocop:disable Style/SpecialGlobalVars
108
119
  end
@@ -134,5 +145,18 @@ module FlakeySpecCatcher
134
145
  :example_failed, :example_passed
135
146
  end
136
147
  end
148
+
149
+ def copy_output_to_temp_file
150
+ # copy contents of output file, it will get overwritten in RSpec::Core::Runner
151
+ File.open(@temp_output_file, 'a') do |f|
152
+ f.puts IO.readlines(@user_config.output_file)
153
+ end
154
+ end
155
+
156
+ def copy_to_user_output
157
+ # copy all appended output to original output file, delete the temp output file
158
+ IO.copy_stream(@temp_output_file, @user_config.output_file) if File.exist?(@temp_output_file)
159
+ File.delete(@temp_output_file) if File.exist?(@temp_output_file)
160
+ end
137
161
  end
138
162
  end
@@ -11,7 +11,8 @@ module FlakeySpecCatcher
11
11
  attr_reader :rerun_file_only, :rspec_usage_patterns, :excluded_tags
12
12
  attr_reader :manual_rerun_patterns, :manual_rerun_usage
13
13
  attr_reader :enable_runs, :output_file, :use_parent, :dry_run
14
- attr_reader :split_nodes, :split_index
14
+ attr_reader :split_nodes, :split_index, :verbose, :test_options
15
+ attr_reader :break_on_first_failure
15
16
 
16
17
  USER_CONFIG_ENV_VARS = %w[FSC_REPEAT_FACTOR FSC_IGNORE_FILES FSC_IGNORE_BRANCHES
17
18
  FSC_SILENT_MODE FSC_RERUN_FILE_ONLY FSC_USAGE_PATTERNS
@@ -44,6 +45,7 @@ module FlakeySpecCatcher
44
45
  @manual_rerun_usage = @cli_override.rerun_usage
45
46
  @use_parent = @cli_override.use_parent
46
47
  @repeat_factor = @cli_override.repeat_factor if @cli_override.repeat_factor.to_i.positive?
48
+ @break_on_first_failure = @cli_override.break_on_first_failure
47
49
  @enable_runs = @cli_override.enable_runs
48
50
  @dry_run = @cli_override.dry_run
49
51
  @split_nodes = @cli_override.split_nodes unless @cli_override.split_nodes.nil?
@@ -54,6 +56,8 @@ module FlakeySpecCatcher
54
56
  @cli_override.excluded_tags
55
57
  end
56
58
  @output_file = set_output_file
59
+ @verbose = @cli_override.verbose
60
+ @test_options = @cli_override.test_options
57
61
  end
58
62
  # rubocop:enable Metrics/AbcSize
59
63
 
@@ -68,7 +72,7 @@ module FlakeySpecCatcher
68
72
  if !@cli_override.output_file.nil?
69
73
  @cli_override.output_file
70
74
  elsif @output_file.nil? || @output_file.strip.empty?
71
- '/dev/null'
75
+ File::NULL
72
76
  else
73
77
  @output_file
74
78
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlakeySpecCatcher
4
- VERSION = '0.9.4'
4
+ VERSION = '0.10.0'
5
5
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flakey_spec_catcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Watson
8
8
  - Mikey Hargiss
9
9
  - Ben Nelson
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-02-25 00:00:00.000000000 Z
13
+ date: 2021-07-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -18,14 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '3.8'
21
+ version: '3.10'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '3.8'
28
+ version: '3.10'
29
+ - !ruby/object:Gem::Dependency
30
+ name: byebug
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '11.1'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '11.1'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: climate_control
31
45
  requirement: !ruby/object:Gem::Requirement
@@ -46,29 +60,43 @@ dependencies:
46
60
  requirements:
47
61
  - - "~>"
48
62
  - !ruby/object:Gem::Version
49
- version: '12.3'
63
+ version: '13.0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '13.0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rubocop
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: 0.93.1
50
78
  type: :development
51
79
  prerelease: false
52
80
  version_requirements: !ruby/object:Gem::Requirement
53
81
  requirements:
54
82
  - - "~>"
55
83
  - !ruby/object:Gem::Version
56
- version: '12.3'
84
+ version: 0.93.1
57
85
  - !ruby/object:Gem::Dependency
58
86
  name: simplecov
59
87
  requirement: !ruby/object:Gem::Requirement
60
88
  requirements:
61
89
  - - "~>"
62
90
  - !ruby/object:Gem::Version
63
- version: '0.17'
91
+ version: '0.19'
64
92
  type: :development
65
93
  prerelease: false
66
94
  version_requirements: !ruby/object:Gem::Requirement
67
95
  requirements:
68
96
  - - "~>"
69
97
  - !ruby/object:Gem::Version
70
- version: '0.17'
71
- description:
98
+ version: '0.19'
99
+ description:
72
100
  email:
73
101
  - bwatson@instructure.com
74
102
  - mhargiss@instructure.com
@@ -102,12 +130,12 @@ files:
102
130
  - lib/flakey_spec_catcher/version.rb
103
131
  - lib/helpers/colorize.rb
104
132
  - lib/helpers/indent_string.rb
105
- homepage:
133
+ homepage:
106
134
  licenses:
107
135
  - MIT
108
136
  metadata:
109
137
  allowed_push_host: https://rubygems.org
110
- post_install_message:
138
+ post_install_message:
111
139
  rdoc_options: []
112
140
  require_paths:
113
141
  - lib
@@ -115,15 +143,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
143
  requirements:
116
144
  - - ">="
117
145
  - !ruby/object:Gem::Version
118
- version: '2.3'
146
+ version: '2.6'
119
147
  required_rubygems_version: !ruby/object:Gem::Requirement
120
148
  requirements:
121
149
  - - ">="
122
150
  - !ruby/object:Gem::Version
123
151
  version: '0'
124
152
  requirements: []
125
- rubygems_version: 3.0.4
126
- signing_key:
153
+ rubygems_version: 3.0.1
154
+ signing_key:
127
155
  specification_version: 4
128
156
  summary: Run new or changed specs many times to prevent unreliable specs
129
157
  test_files: []