guard-rspec 2.1.0 → 4.7.3

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +5 -0
  6. data/.rubocop_todo.yml +40 -0
  7. data/.travis.yml +14 -0
  8. data/CONTRIBUTING.md +38 -0
  9. data/Gemfile +25 -0
  10. data/Guardfile +28 -0
  11. data/{LICENSE → LICENSE.txt} +4 -2
  12. data/README.md +99 -114
  13. data/Rakefile +38 -0
  14. data/gemfiles/Gemfile.rspec-2.99 +6 -0
  15. data/gemfiles/Gemfile.rspec-3.4 +6 -0
  16. data/gemfiles/common +9 -0
  17. data/guard-rspec.gemspec +25 -0
  18. data/lib/guard/rspec/command.rb +71 -0
  19. data/lib/guard/rspec/deprecator.rb +86 -0
  20. data/lib/guard/rspec/dsl.rb +72 -0
  21. data/lib/guard/rspec/inspectors/base_inspector.rb +73 -0
  22. data/lib/guard/rspec/inspectors/factory.rb +23 -0
  23. data/lib/guard/rspec/inspectors/focused_inspector.rb +39 -0
  24. data/lib/guard/rspec/inspectors/keeping_inspector.rb +97 -0
  25. data/lib/guard/rspec/inspectors/simple_inspector.rb +21 -0
  26. data/lib/guard/rspec/notifier.rb +55 -0
  27. data/lib/guard/rspec/options.rb +37 -0
  28. data/lib/guard/rspec/results.rb +23 -0
  29. data/lib/guard/rspec/rspec_process.rb +93 -0
  30. data/lib/guard/rspec/runner.rb +71 -174
  31. data/lib/guard/rspec/templates/Guardfile +49 -17
  32. data/lib/guard/rspec/version.rb +1 -1
  33. data/lib/guard/rspec.rb +30 -59
  34. data/lib/guard/rspec_defaults.rb +5 -0
  35. data/lib/guard/rspec_formatter.rb +147 -0
  36. data/lib/guard/rspec_formatter_results_path.rb +29 -0
  37. data/spec/acceptance/fixtures/succeeding_spec.rb +4 -0
  38. data/spec/acceptance/formatter_spec.rb +46 -0
  39. data/spec/lib/guard/rspec/command_spec.rb +95 -0
  40. data/spec/lib/guard/rspec/deprecator_spec.rb +101 -0
  41. data/spec/lib/guard/rspec/inspectors/base_inspector_spec.rb +144 -0
  42. data/spec/lib/guard/rspec/inspectors/factory_spec.rb +45 -0
  43. data/spec/lib/guard/rspec/inspectors/focused_inspector_spec.rb +140 -0
  44. data/spec/lib/guard/rspec/inspectors/keeping_inspector_spec.rb +200 -0
  45. data/spec/lib/guard/rspec/inspectors/shared_examples.rb +121 -0
  46. data/spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb +59 -0
  47. data/spec/lib/guard/rspec/notifier_spec.rb +90 -0
  48. data/spec/lib/guard/rspec/results_spec.rb +66 -0
  49. data/spec/lib/guard/rspec/rspec_process_spec.rb +152 -0
  50. data/spec/lib/guard/rspec/runner_spec.rb +372 -0
  51. data/spec/lib/guard/rspec/template_spec.rb +78 -0
  52. data/spec/lib/guard/rspec_formatter_spec.rb +277 -0
  53. data/spec/lib/guard/rspec_spec.rb +91 -0
  54. data/spec/spec_helper.rb +145 -0
  55. metadata +103 -42
  56. data/lib/guard/rspec/formatter.rb +0 -56
  57. data/lib/guard/rspec/inspector.rb +0 -72
@@ -0,0 +1,71 @@
1
+ require "rspec/core"
2
+ require "pathname"
3
+
4
+ require "guard/rspec"
5
+
6
+ module Guard
7
+ class RSpec < Plugin
8
+ class Command < String
9
+ FAILURE_EXIT_CODE = 2
10
+
11
+ attr_accessor :paths, :options
12
+
13
+ def initialize(paths, options = {})
14
+ @paths = paths
15
+ @options = options
16
+ super(_parts.join(" "))
17
+ end
18
+
19
+ private
20
+
21
+ def _parts
22
+ parts = [options[:cmd]]
23
+ parts << _visual_formatter
24
+ parts << _guard_formatter
25
+ parts << "--failure-exit-code #{FAILURE_EXIT_CODE}"
26
+ parts << options[:cmd_additional_args] || ""
27
+
28
+ parts << _paths(options).join(" ")
29
+ end
30
+
31
+ def _paths(options)
32
+ chdir = options[:chdir]
33
+ return paths unless chdir
34
+ paths.map { |path| path.sub(File.join(chdir, "/"), "") }
35
+ end
36
+
37
+ def _visual_formatter
38
+ return if _cmd_include_formatter?
39
+ _rspec_formatters || "-f progress"
40
+ end
41
+
42
+ def _rspec_formatters
43
+ # RSpec::Core::ConfigurationOptions#parse_options method was renamed to
44
+ # #options in rspec-core v3.0.0.beta2 so call the first one if
45
+ # available. Fixes #249
46
+ config = ::RSpec::Core::ConfigurationOptions.new([])
47
+ config.parse_options if config.respond_to?(:parse_options)
48
+ formatters = config.options[:formatters] || nil
49
+
50
+ # RSpec's parser returns an array in the format
51
+ #
52
+ # [[formatter, output], ...],
53
+ #
54
+ # so match their format Construct a matching command line option,
55
+ # including output target
56
+
57
+ return formatters unless formatters
58
+ formatters.map { |entries| "-f #{entries.join ' -o '}" }.join(" ")
59
+ end
60
+
61
+ def _cmd_include_formatter?
62
+ options[:cmd] =~ /(?:^|\s)(?:-f\s*|--format(?:=|\s+))([\w:]+)/
63
+ end
64
+
65
+ def _guard_formatter
66
+ dir = Pathname.new(__FILE__).dirname.dirname
67
+ "-r #{dir + 'rspec_formatter.rb'} -f Guard::RSpecFormatter"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,86 @@
1
+ module Guard
2
+ class RSpec < Plugin
3
+ class Deprecator
4
+ attr_accessor :options
5
+
6
+ def self.warns_about_deprecated_options(options = {})
7
+ new(options).warns_about_deprecated_options
8
+ end
9
+
10
+ def initialize(options = {})
11
+ @options = options
12
+ end
13
+
14
+ def warns_about_deprecated_options
15
+ _spec_opts_env
16
+ _version_option
17
+ _exclude_option
18
+ _use_cmd_option
19
+ _keep_failed_option
20
+ _focus_on_failed_option
21
+ end
22
+
23
+ private
24
+
25
+ def _spec_opts_env
26
+ return if ENV["SPEC_OPTS"].nil?
27
+ Compat::UI.warning(
28
+ "The SPEC_OPTS environment variable is present." \
29
+ " This can conflict with guard-rspec."
30
+ )
31
+ end
32
+
33
+ def _version_option
34
+ return unless options.key?(:version)
35
+ _deprecated(
36
+ "The :version option is deprecated." \
37
+ " Only RSpec ~> 2.14 is now supported."
38
+ )
39
+ end
40
+
41
+ def _exclude_option
42
+ return unless options.key?(:exclude)
43
+ _deprecated(
44
+ "The :exclude option is deprecated." \
45
+ " Please Guard ignore method instead." \
46
+ " https://github.com/guard/guard#ignore"
47
+ )
48
+ end
49
+
50
+ def _use_cmd_option
51
+ %w(color drb fail_fast formatter env bundler
52
+ binstubs rvm cli spring turnip zeus foreman).each do |option|
53
+ next unless options.key?(option.to_sym)
54
+ _deprecated(
55
+ "The :#{option} option is deprecated." \
56
+ " Please customize the new :cmd option to fit your need."
57
+ )
58
+ end
59
+ end
60
+
61
+ def _keep_failed_option
62
+ return unless options.key?(:keep_failed)
63
+ _deprecated(
64
+ "The :keep_failed option is deprecated." \
65
+ " Please set new :failed_mode option value to" \
66
+ " :keep instead." \
67
+ " https://github.com/guard/guard-rspec#list-of-available-options"
68
+ )
69
+ end
70
+
71
+ def _focus_on_failed_option
72
+ return unless options.key?(:focus_on_failed)
73
+ _deprecated(
74
+ "The :focus_on_failed option is deprecated." \
75
+ " Please set new :failed_mode option value to" \
76
+ " :focus instead." \
77
+ " https://github.com/guard/guard-rspec#list-of-available-options"
78
+ )
79
+ end
80
+
81
+ def _deprecated(message)
82
+ Compat::UI.warning %(Guard::RSpec DEPRECATION WARNING: #{message})
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,72 @@
1
+ require "ostruct"
2
+
3
+ require "guard/rspec"
4
+
5
+ module Guard
6
+ class RSpec < Plugin
7
+ class Dsl
8
+ def initialize(dsl)
9
+ @dsl = dsl
10
+ end
11
+
12
+ def watch_spec_files_for(expr)
13
+ @dsl.send(:watch, expr) { |m| rspec.spec.call(m[1]) }
14
+ end
15
+
16
+ def self.detect_spec_file_for(rspec, file)
17
+ # TODO: when spec not found ... run specs in topmost found path?
18
+ # Or show warning?
19
+
20
+ path = "#{rspec.spec_dir}/#{file}_spec.rb"
21
+ return path unless file.start_with?("lib/")
22
+ return path if Dir.exist?("#{rspec.spec_dir}/lib")
23
+
24
+ without_lib = file.sub(%r{^lib/}, "")
25
+ "#{rspec.spec_dir}/#{without_lib}_spec.rb"
26
+ end
27
+
28
+ def rspec
29
+ @rspec ||= OpenStruct.new(to_s: "spec").tap do |rspec|
30
+ rspec.spec_dir = "spec"
31
+ rspec.spec = ->(m) { Dsl.detect_spec_file_for(rspec, m) }
32
+ rspec.spec_helper = "#{rspec.spec_dir}/spec_helper.rb"
33
+ rspec.spec_files = %r{^#{rspec.spec_dir}/.+_spec\.rb$}
34
+ rspec.spec_support = %r{^#{rspec.spec_dir}/support/(.+)\.rb$}
35
+ end
36
+ end
37
+
38
+ def ruby
39
+ # Ruby apps
40
+ @ruby ||= OpenStruct.new.tap do |ruby|
41
+ ruby.lib_files = %r{^(lib/.+)\.rb$}
42
+ end
43
+ end
44
+
45
+ def rails(options = {})
46
+ # Rails example
47
+ @rails ||= _build_rails_rules(_view_extensions(options) * "|")
48
+ end
49
+
50
+ private
51
+
52
+ def _view_extensions(options)
53
+ options.dup.delete(:view_extensions) || %w(erb haml slim)
54
+ end
55
+
56
+ def _build_rails_rules(exts)
57
+ OpenStruct.new.tap do |rails|
58
+ rails.app_files = %r{^app/(.+)\.rb$}
59
+
60
+ rails.views = %r{^app/(views/.+/[^/]*\.(?:#{exts}))$}
61
+ rails.view_dirs = %r{^app/views/(.+)/[^/]*\.(?:#{exts})$}
62
+ rails.layouts = %r{^app/layouts/(.+)/[^/]*\.(?:#{exts})$}
63
+
64
+ rails.controllers = %r{^app/controllers/(.+)_controller\.rb$}
65
+ rails.routes = "config/routes.rb"
66
+ rails.app_controller = "app/controllers/application_controller.rb"
67
+ rails.spec_helper = "#{rspec.spec_dir}/rails_helper.rb"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,73 @@
1
+ module Guard
2
+ class RSpec < Plugin
3
+ module Inspectors
4
+ class BaseInspector
5
+ attr_accessor :options, :spec_paths
6
+
7
+ def initialize(options = {})
8
+ @options = options
9
+ @spec_paths = @options[:spec_paths]
10
+ @chdir = @options[:chdir]
11
+ end
12
+
13
+ def paths(_paths)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def failed(_locations)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def reload
22
+ raise NotImplementedError
23
+ end
24
+
25
+ private
26
+
27
+ # Leave only spec/feature files from spec_paths, remove others
28
+ def _clean(paths)
29
+ paths.uniq!
30
+ paths.compact!
31
+ spec_dirs = _select_only_spec_dirs(paths)
32
+ spec_files = _select_only_spec_files(paths)
33
+ (spec_dirs + spec_files).uniq
34
+ end
35
+
36
+ def _select_only_spec_dirs(paths)
37
+ chdir_paths = _spec_paths_with_chdir
38
+ paths.select do |path|
39
+ File.directory?(path) || chdir_paths.include?(path)
40
+ end
41
+ end
42
+
43
+ def _select_only_spec_files(paths)
44
+ spec_files = _collect_files("*[_.]spec.rb")
45
+ feature_files = _collect_files("*.feature")
46
+ files = (spec_files + feature_files).flatten
47
+
48
+ paths.select do |path|
49
+ (files & [@chdir ? File.join(@chdir, path) : path]).any?
50
+ end
51
+ end
52
+
53
+ def _spec_paths_with_chdir
54
+ _paths_with_chdir(spec_paths, @chdir)
55
+ end
56
+
57
+ def _collect_files(pattern)
58
+ base_paths = _spec_paths_with_chdir
59
+ base_paths.map do |path|
60
+ # TODO: not tested properly
61
+ Dir[File.join(path, "**{,/*/**}", pattern)]
62
+ end
63
+ end
64
+
65
+ def _paths_with_chdir(paths, chdir)
66
+ paths.map do |path|
67
+ chdir ? File.join(chdir, path) : path
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ require "guard/rspec/inspectors/simple_inspector.rb"
2
+ require "guard/rspec/inspectors/keeping_inspector.rb"
3
+ require "guard/rspec/inspectors/focused_inspector.rb"
4
+
5
+ module Guard
6
+ class RSpec < Plugin
7
+ module Inspectors
8
+ class Factory
9
+ class << self
10
+ def create(options = {})
11
+ case options[:failed_mode]
12
+ when :focus then FocusedInspector.new(options)
13
+ when :keep then KeepingInspector.new(options)
14
+ else; SimpleInspector.new(options)
15
+ end
16
+ end
17
+
18
+ private :new
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ require "guard/rspec/inspectors/base_inspector.rb"
2
+
3
+ module Guard
4
+ class RSpec < Plugin
5
+ module Inspectors
6
+ # Inspector that focuses on set of paths if any of them is failing.
7
+ # Returns only that set of paths on all future calls to #paths
8
+ # until they all pass
9
+ class FocusedInspector < BaseInspector
10
+ attr_accessor :focused_locations
11
+
12
+ def initialize(options = {})
13
+ super
14
+ @focused_locations = []
15
+ end
16
+
17
+ def paths(paths)
18
+ if focused_locations.any?
19
+ focused_locations
20
+ else
21
+ _clean(paths)
22
+ end
23
+ end
24
+
25
+ def failed(locations)
26
+ if locations.empty?
27
+ @focused_locations = []
28
+ elsif focused_locations.empty?
29
+ @focused_locations = locations
30
+ end
31
+ end
32
+
33
+ def reload
34
+ @focused_locations = []
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,97 @@
1
+ require "guard/rspec/inspectors/base_inspector.rb"
2
+
3
+ module Guard
4
+ class RSpec < Plugin
5
+ module Inspectors
6
+ # Inspector that remembers all failed paths and
7
+ # returns that paths in future calls to #paths method
8
+ # along with any new paths passed as parameter to #paths
9
+ class KeepingInspector < BaseInspector
10
+ attr_accessor :failed_locations
11
+
12
+ def initialize(options = {})
13
+ super
14
+ @failed_locations = []
15
+ end
16
+
17
+ def paths(paths)
18
+ _with_failed_locations(_clean(paths))
19
+ end
20
+
21
+ def failed(locations)
22
+ @failed_locations = locations
23
+ end
24
+
25
+ def reload
26
+ @failed_locations = []
27
+ end
28
+
29
+ private
30
+
31
+ # Return paths + failed locations.
32
+ # Do not include location in result if its path is already included.
33
+ def _with_failed_locations(paths)
34
+ failed_paths = failed_locations.map { |l| _location_path(l) }
35
+ (paths | failed_paths).uniq
36
+ end
37
+
38
+ # Extract file path from location
39
+ def _location_path(location)
40
+ location.match(%r{^(\./)?(.*?)(:\d+)?$})[2]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ #
48
+ # FIXME uncomment when RSpec #952 will be resolved
49
+ #
50
+ # This is correct version of KeepingInspector class,
51
+ # bit it doesn't work because of bug with RSpec
52
+ # https://github.com/rspec/rspec-core/issues/952
53
+ #
54
+ # module Guard
55
+ # class RSpec < Plugin
56
+ # module Inspectors
57
+ # # Inspector that remembers all failed paths and
58
+ # # returns that paths in future calls to #paths method
59
+ # # along with any new paths passed as parameter to #paths
60
+ # class KeepingInspector < BaseInspector
61
+ # attr_accessor :failed_locations
62
+ #
63
+ # def initialize(options = {})
64
+ # super
65
+ # @failed_locations = []
66
+ # end
67
+ #
68
+ # def paths(paths)
69
+ # _with_failed_locations(_clean(paths))
70
+ # end
71
+ #
72
+ # def failed(locations)
73
+ # @failed_locations = locations
74
+ # end
75
+ #
76
+ # def reload
77
+ # @failed_locations = []
78
+ # end
79
+ #
80
+ # private
81
+ #
82
+ # # Return paths + failed locations.
83
+ # # Do not include location in result if its path is already included.
84
+ # def _with_failed_locations(paths)
85
+ # locations = failed_locations.select { |l|
86
+ # !paths.include?(_location_path(l)) }
87
+ # paths | locations
88
+ # end
89
+ #
90
+ # # Extract file path from location
91
+ # def _location_path(location)
92
+ # location.match(/^(\.\/)?(.*?)(:\d+)?$/)[2]
93
+ # end
94
+ # end
95
+ # end
96
+ # end
97
+ # end
@@ -0,0 +1,21 @@
1
+ require "guard/rspec/inspectors/base_inspector"
2
+
3
+ module Guard
4
+ class RSpec < Plugin
5
+ module Inspectors
6
+ class SimpleInspector < BaseInspector
7
+ def paths(paths)
8
+ _clean(paths)
9
+ end
10
+
11
+ def failed(_locations)
12
+ # Don't care
13
+ end
14
+
15
+ def reload
16
+ # Nothing to reload
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,55 @@
1
+ module Guard
2
+ class RSpec < Plugin
3
+ class Notifier
4
+ attr_accessor :options
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ end
9
+
10
+ def notify(summary)
11
+ return unless options[:notification]
12
+ failure_count, pending_count = _parse_summary(summary)
13
+ image = _image(failure_count, pending_count)
14
+ priority = _priority(image)
15
+ Guard::Compat::UI.notify(summary,
16
+ title: @options[:title],
17
+ image: image,
18
+ priority: priority)
19
+ end
20
+
21
+ def notify_failure
22
+ return unless options[:notification]
23
+ Guard::Compat::UI.notify("Failed",
24
+ title: @options[:title],
25
+ image: :failed,
26
+ priority: 2)
27
+ end
28
+
29
+ private
30
+
31
+ def _parse_summary(summary)
32
+ summary.match(/(\d+) failures( \((\d+) pending\))?/) do |m|
33
+ return m[1].to_i, m[3].to_i
34
+ end
35
+ [0, 0]
36
+ end
37
+
38
+ def _image(failure_count, pending_count)
39
+ if failure_count > 0
40
+ :failed
41
+ elsif pending_count > 0
42
+ :pending
43
+ else
44
+ :success
45
+ end
46
+ end
47
+
48
+ def _priority(image)
49
+ { failed: 2,
50
+ pending: -1,
51
+ success: -2 }[image]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,37 @@
1
+ module Guard
2
+ class RSpec < Plugin
3
+ module Options
4
+ DEFAULTS = {
5
+ all_on_start: false,
6
+ all_after_pass: false,
7
+ run_all: { message: "Running all specs" },
8
+ failed_mode: :none, # :keep and :focus are other posibilities
9
+ spec_paths: %w(spec),
10
+ cmd: nil,
11
+ cmd_additional_args: nil,
12
+ launchy: nil,
13
+ notification: true,
14
+ title: "RSpec results",
15
+ bundler_env: :original_env
16
+ }.freeze
17
+
18
+ class << self
19
+ def with_defaults(options = {})
20
+ _deep_merge(DEFAULTS, options)
21
+ end
22
+
23
+ private
24
+
25
+ def _deep_merge(hash1, hash2)
26
+ hash1.merge(hash2) do |_key, oldval, newval|
27
+ if oldval.instance_of?(Hash) && newval.instance_of?(Hash)
28
+ _deep_merge(oldval, newval)
29
+ else
30
+ newval
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,23 @@
1
+ module Guard
2
+ class RSpec < Plugin
3
+ class Results
4
+ class InvalidData < RuntimeError
5
+ end
6
+
7
+ attr_reader :summary
8
+ attr_reader :failed_paths
9
+
10
+ def initialize(filename)
11
+ lines = File.readlines(filename)
12
+ if lines.empty? || lines.first.empty?
13
+ dump = lines.inspect
14
+ raise InvalidData, "Invalid results in: #{filename},"\
15
+ " lines:\n#{dump}\n"
16
+ end
17
+
18
+ @summary = lines.first.chomp
19
+ @failed_paths = lines[1..11].map(&:chomp).compact
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,93 @@
1
+ require "guard/rspec/command"
2
+
3
+ module Guard
4
+ class RSpec < Plugin
5
+ class RSpecProcess
6
+ class Failure < RuntimeError
7
+ end
8
+
9
+ attr_reader :results, :options
10
+
11
+ def initialize(command, formatter_tmp_file, options = {})
12
+ @command = command
13
+ @formatter_tmp_file = formatter_tmp_file
14
+ @results = nil
15
+ @options = options
16
+
17
+ @exit_code = _run
18
+ @results = _read_results
19
+ end
20
+
21
+ def all_green?
22
+ exit_code.zero?
23
+ end
24
+
25
+ private
26
+
27
+ def _run
28
+ _with_desired_bundler_env do
29
+ exit_code = _really_run
30
+
31
+ msg = "Guard::RSpec: RSpec command %s exited with: %s"
32
+ Compat::UI.debug(format(msg, command, exit_code.inspect))
33
+
34
+ unless [0, Command::FAILURE_EXIT_CODE].include?(exit_code)
35
+ msg = "Failed: %s (exit code: %s)"
36
+ raise Failure, format(msg, command.inspect, exit_code.inspect)
37
+ end
38
+ exit_code
39
+ end
40
+ end
41
+
42
+ def _really_run
43
+ env = { "GUARD_RSPEC_RESULTS_FILE" => formatter_tmp_file }
44
+
45
+ _warn_unless_absolute_path(formatter_tmp_file)
46
+
47
+ Compat::UI.debug("Guard::RSpec: results file: #{formatter_tmp_file}")
48
+
49
+ pid = Kernel.spawn(env, command) # use spawn to stub in JRuby
50
+ result = ::Process.wait2(pid)
51
+ result.last.exitstatus
52
+ rescue Errno::ENOENT => ex
53
+ raise Failure, "Failed: #{command.inspect} (#{ex})"
54
+ end
55
+
56
+ def _read_results
57
+ Results.new(formatter_tmp_file)
58
+ rescue Errno::ENOENT
59
+ msg = "Guard::RSpec cannot open results file: %s. This is likely a bug"\
60
+ "so please report this at"\
61
+ " http://github.com/guard/guard-rspec/issues/new along with as much"\
62
+ "information as possible to reproduce this issue."
63
+ Compat::UI.error(format(msg, formatter_tmp_file.inspect))
64
+ raise
65
+ ensure
66
+ File.delete(formatter_tmp_file) if File.exist?(formatter_tmp_file)
67
+ end
68
+
69
+ def _with_desired_bundler_env
70
+ desired_bundler_env = options[:bundler_env]
71
+ if !defined?(::Bundler) || desired_bundler_env == :inherit
72
+ yield
73
+ elsif desired_bundler_env == :clean_env
74
+ ::Bundler.with_clean_env { yield }
75
+ else
76
+ ::Bundler.with_original_env { yield }
77
+ end
78
+ end
79
+
80
+ def _warn_unless_absolute_path(formatter_tmp_file)
81
+ return if Pathname(formatter_tmp_file).absolute?
82
+
83
+ msg = "Guard::RSpec: The results file %s is not an absolute path."\
84
+ " Please provide an absolute path to avoid issues."
85
+ Compat::UI.warning(format(msg, formatter_tmp_file.inspect))
86
+ end
87
+
88
+ attr_reader :command
89
+ attr_reader :exit_code
90
+ attr_reader :formatter_tmp_file
91
+ end
92
+ end
93
+ end