guard 1.4.0 → 2.18.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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -677
  3. data/LICENSE +4 -2
  4. data/README.md +91 -753
  5. data/bin/_guard-core +11 -0
  6. data/bin/guard +108 -3
  7. data/lib/guard/aruba_adapter.rb +59 -0
  8. data/lib/guard/cli/environments/bundler.rb +22 -0
  9. data/lib/guard/cli/environments/evaluate_only.rb +35 -0
  10. data/lib/guard/cli/environments/valid.rb +69 -0
  11. data/lib/guard/cli.rb +129 -128
  12. data/lib/guard/commander.rb +104 -0
  13. data/lib/guard/commands/all.rb +37 -0
  14. data/lib/guard/commands/change.rb +31 -0
  15. data/lib/guard/commands/notification.rb +26 -0
  16. data/lib/guard/commands/pause.rb +29 -0
  17. data/lib/guard/commands/reload.rb +36 -0
  18. data/lib/guard/commands/scope.rb +38 -0
  19. data/lib/guard/commands/show.rb +24 -0
  20. data/lib/guard/config.rb +18 -0
  21. data/lib/guard/deprecated/dsl.rb +45 -0
  22. data/lib/guard/deprecated/evaluator.rb +39 -0
  23. data/lib/guard/deprecated/guard.rb +328 -0
  24. data/lib/guard/deprecated/guardfile.rb +84 -0
  25. data/lib/guard/deprecated/watcher.rb +27 -0
  26. data/lib/guard/dsl.rb +332 -363
  27. data/lib/guard/dsl_describer.rb +132 -122
  28. data/lib/guard/dsl_reader.rb +51 -0
  29. data/lib/guard/group.rb +34 -14
  30. data/lib/guard/guardfile/evaluator.rb +232 -0
  31. data/lib/guard/guardfile/generator.rb +128 -0
  32. data/lib/guard/guardfile.rb +24 -60
  33. data/lib/guard/interactor.rb +31 -255
  34. data/lib/guard/internals/debugging.rb +68 -0
  35. data/lib/guard/internals/groups.rb +40 -0
  36. data/lib/guard/internals/helpers.rb +13 -0
  37. data/lib/guard/internals/plugins.rb +53 -0
  38. data/lib/guard/internals/queue.rb +51 -0
  39. data/lib/guard/internals/scope.rb +121 -0
  40. data/lib/guard/internals/session.rb +180 -0
  41. data/lib/guard/internals/state.rb +25 -0
  42. data/lib/guard/internals/tracing.rb +33 -0
  43. data/lib/guard/internals/traps.rb +10 -0
  44. data/lib/guard/jobs/base.rb +21 -0
  45. data/lib/guard/jobs/pry_wrapper.rb +336 -0
  46. data/lib/guard/jobs/sleep.rb +26 -0
  47. data/lib/guard/notifier.rb +46 -212
  48. data/lib/guard/options.rb +22 -0
  49. data/lib/guard/plugin.rb +303 -0
  50. data/lib/guard/plugin_util.rb +191 -0
  51. data/lib/guard/rake_task.rb +42 -0
  52. data/lib/guard/runner.rb +80 -140
  53. data/lib/guard/templates/Guardfile +14 -0
  54. data/lib/guard/terminal.rb +13 -0
  55. data/lib/guard/ui/colors.rb +56 -0
  56. data/lib/guard/ui/config.rb +70 -0
  57. data/lib/guard/ui/logger.rb +30 -0
  58. data/lib/guard/ui.rb +163 -128
  59. data/lib/guard/version.rb +1 -2
  60. data/lib/guard/watcher/pattern/deprecated_regexp.rb +45 -0
  61. data/lib/guard/watcher/pattern/match_result.rb +18 -0
  62. data/lib/guard/watcher/pattern/matcher.rb +33 -0
  63. data/lib/guard/watcher/pattern/pathname_path.rb +15 -0
  64. data/lib/guard/watcher/pattern/simple_path.rb +23 -0
  65. data/lib/guard/watcher/pattern.rb +24 -0
  66. data/lib/guard/watcher.rb +52 -95
  67. data/lib/guard.rb +108 -376
  68. data/lib/tasks/releaser.rb +116 -0
  69. data/man/guard.1 +12 -9
  70. data/man/guard.1.html +18 -12
  71. metadata +148 -77
  72. data/images/guard.png +0 -0
  73. data/lib/guard/guard.rb +0 -156
  74. data/lib/guard/hook.rb +0 -120
  75. data/lib/guard/interactors/coolline.rb +0 -64
  76. data/lib/guard/interactors/helpers/completion.rb +0 -32
  77. data/lib/guard/interactors/helpers/terminal.rb +0 -46
  78. data/lib/guard/interactors/readline.rb +0 -94
  79. data/lib/guard/interactors/simple.rb +0 -19
  80. data/lib/guard/notifiers/emacs.rb +0 -69
  81. data/lib/guard/notifiers/gntp.rb +0 -118
  82. data/lib/guard/notifiers/growl.rb +0 -99
  83. data/lib/guard/notifiers/growl_notify.rb +0 -92
  84. data/lib/guard/notifiers/libnotify.rb +0 -96
  85. data/lib/guard/notifiers/notifysend.rb +0 -84
  86. data/lib/guard/notifiers/rb_notifu.rb +0 -102
  87. data/lib/guard/notifiers/terminal_notifier.rb +0 -66
  88. data/lib/guard/notifiers/tmux.rb +0 -69
  89. data/lib/guard/version.rbc +0 -130
@@ -1,150 +1,160 @@
1
- module Guard
1
+ # encoding: utf-8
2
+ require "formatador"
3
+
4
+ require "guard/ui"
5
+ require "guard/notifier"
6
+ require "guard"
7
+
8
+ require "set"
9
+ require "ostruct"
2
10
 
3
- # The DslDescriber overrides methods to create an internal structure
4
- # of the Guardfile that is used in some inspection utility methods
5
- # like the CLI commands `show` and `list`.
11
+ module Guard
12
+ # The DslDescriber evaluates the Guardfile and creates an internal structure
13
+ # of it that is used in some inspection utility methods like the CLI commands
14
+ # `show` and `list`.
6
15
  #
7
16
  # @see Guard::Dsl
8
17
  # @see Guard::CLI
9
18
  #
10
- class DslDescriber < Dsl
11
-
12
- require 'guard/dsl'
13
- require 'guard/ui'
14
-
15
- class << self
16
-
17
- # Evaluate the DSL methods in the `Guardfile`.
18
- #
19
- # @option options [Array<Symbol,String>] groups the groups to evaluate
20
- # @option options [String] guardfile the path to a valid Guardfile
21
- # @option options [String] guardfile_contents a string representing the content of a valid Guardfile
22
- # @raise [ArgumentError] when options are not a Hash
23
- #
24
- def evaluate_guardfile(options = {})
25
- @@guardfile_structure = [{ :guards => [] }]
26
- super options
27
- end
28
-
29
- # List the Guard plugins that are available for use in your system and marks
30
- # those that are currently used in your `Guardfile`.
31
- #
32
- # @example Guard list output
33
- #
34
- # Available guards:
35
- # bundler *
36
- # livereload
37
- # ronn
38
- # rspec *
39
- # spork
40
- #
41
- # See also https://github.com/guard/guard/wiki/List-of-available-Guards
42
- # * denotes ones already in your Guardfile
43
- #
44
- # @param [Hash] options the Guard options
45
- #
46
- def list(options)
47
- evaluate_guardfile(options)
48
-
49
- installed_guards = guardfile_structure.inject([]) do |installed, group|
50
- group[:guards].each { |guard| installed << guard[:name].to_s } if group[:guards]
51
- installed
52
- end
53
-
54
- ::Guard::UI.info 'Available guards:'
55
-
56
- ::Guard.guard_gem_names.sort.uniq.each do |name|
57
- ::Guard::UI.info " #{ name }#{ installed_guards.include?(name) ? '*' : '' }"
58
- end
19
+ class DslDescriber
20
+ def initialize(options = nil)
21
+ fail "options passed to DslDescriber are ignored!" unless options.nil?
22
+ end
59
23
 
60
- ::Guard::UI.info ''
61
- ::Guard::UI.info 'See also https://github.com/guard/guard/wiki/List-of-available-Guards'
62
- ::Guard::UI.info '* denotes ones already in your Guardfile'
24
+ # List the Guard plugins that are available for use in your system and marks
25
+ # those that are currently used in your `Guardfile`.
26
+ #
27
+ # @see CLI#list
28
+ #
29
+ def list
30
+ # TODO: remove dependency on Guard in this whole file
31
+ # collect metadata
32
+ data = PluginUtil.plugin_names.sort.inject({}) do |hash, name|
33
+ hash[name.capitalize] = Guard.state.session.plugins.all(name).any?
34
+ hash
63
35
  end
64
36
 
65
- # Shows all Guard plugins and their options that are defined in
66
- # the `Guardfile`.
67
- #
68
- # @example guard show output
69
- #
70
- # (global):
71
- # bundler
72
- # coffeescript: input => "app/assets/javascripts", noop => true
73
- # jasmine
74
- # rspec: cli => "--fail-fast --format Fuubar
75
- #
76
- # @param [Hash] options the Guard options
77
- #
78
- def show(options)
79
- evaluate_guardfile(options)
80
-
81
- guardfile_structure.each do |group|
82
- unless group[:guards].empty?
83
- if group[:group]
84
- ::Guard::UI.info "Group #{ group[:group] }:"
85
- else
86
- ::Guard::UI.info '(global):'
87
- end
88
-
89
- group[:guards].each do |guard|
90
- line = " #{ guard[:name] }"
37
+ # presentation
38
+ header = [:Plugin, :Guardfile]
39
+ final_rows = []
40
+ data.each do |name, used|
41
+ final_rows << { Plugin: name, Guardfile: used ? "✔" : "✘" }
42
+ end
91
43
 
92
- unless guard[:options].empty?
93
- line += ": #{ guard[:options].inject({}) { |options, (k, v)| options[k.to_s] = v; options }.sort.collect { |k, v| "#{ k } => #{ v.inspect }" }.join(', ') }"
94
- end
44
+ # render
45
+ Formatador.display_compact_table(final_rows, header)
46
+ end
95
47
 
96
- ::Guard::UI.info line
97
- end
48
+ # Shows all Guard plugins and their options that are defined in
49
+ # the `Guardfile`.
50
+ #
51
+ # @see CLI#show
52
+ #
53
+ def show
54
+ # collect metadata
55
+ groups = Guard.state.session.groups.all
56
+
57
+ objects = []
58
+
59
+ empty_plugin = OpenStruct.new
60
+ empty_plugin.options = [["", nil]]
61
+
62
+ groups.each do |group|
63
+ plugins = Array(Guard.state.session.plugins.all(group: group.name))
64
+ plugins = [empty_plugin] if plugins.empty?
65
+ plugins.each do |plugin|
66
+ options = plugin.options
67
+ options = [["", nil]] if options.empty?
68
+ options.each do |option, raw_value|
69
+ value = raw_value.nil? ? "" : raw_value.inspect
70
+ objects << [group.title, plugin.title, option.to_s, value]
98
71
  end
99
72
  end
100
-
101
- ::Guard::UI.info ''
102
73
  end
103
74
 
104
- private
105
-
106
- # Get the Guardfile structure.
107
- #
108
- # @return [Array<Hash>] the structure
109
- #
110
- def guardfile_structure
111
- @@guardfile_structure
75
+ # presentation
76
+ rows = []
77
+ prev_group = prev_plugin = prev_option = prev_value = nil
78
+ objects.each do |group, plugin, option, value|
79
+ group_changed = prev_group != group
80
+ plugin_changed = (prev_plugin != plugin || group_changed)
81
+
82
+ rows << :split if group_changed || plugin_changed
83
+
84
+ rows << {
85
+ Group: group_changed ? group : "",
86
+ Plugin: plugin_changed ? plugin : "",
87
+ Option: option,
88
+ Value: value
89
+ }
90
+
91
+ prev_group = group
92
+ prev_plugin = plugin
93
+ prev_option = option
94
+ prev_value = value
112
95
  end
113
96
 
97
+ # render
98
+ Formatador.display_compact_table(
99
+ rows.drop(1),
100
+ [:Group, :Plugin, :Option, :Value]
101
+ )
114
102
  end
115
103
 
116
- private
117
-
118
- # Declares a group of guards.
104
+ # Shows all notifiers and their options that are defined in
105
+ # the `Guardfile`.
119
106
  #
120
- # @param [String] name the group's name called from the CLI
121
- # @yield a block where you can declare several guards
107
+ # @see CLI#show
122
108
  #
123
- # @see Guard::Dsl#group
124
- #
125
- def group(name)
126
- @@guardfile_structure << { :group => name.to_sym, :guards => [] }
127
- @group = true
109
+ def notifiers
110
+ supported = Notifier.supported
111
+ Notifier.connect(notify: true, silent: true)
112
+ detected = Notifier.detected
113
+ Notifier.disconnect
114
+
115
+ detected_names = detected.map { |item| item[:name] }
116
+
117
+ final_rows = supported.each_with_object([]) do |(name, _), rows|
118
+ available = detected_names.include?(name) ? "✔" : "✘"
119
+
120
+ notifier = detected.detect { |n| n[:name] == name }
121
+ used = notifier ? "✔" : "✘"
122
+
123
+ options = notifier ? notifier[:options] : {}
124
+
125
+ if options.empty?
126
+ rows << :split
127
+ _add_row(rows, name, available, used, "", "")
128
+ else
129
+ options.each_with_index do |(option, value), index|
130
+ if index == 0
131
+ rows << :split
132
+ _add_row(rows, name, available, used, option.to_s, value.inspect)
133
+ else
134
+ _add_row(rows, "", "", "", option.to_s, value.inspect)
135
+ end
136
+ end
137
+ end
128
138
 
129
- yield if block_given?
139
+ rows
140
+ end
130
141
 
131
- @group = false
142
+ Formatador.display_compact_table(
143
+ final_rows.drop(1),
144
+ [:Name, :Available, :Used, :Option, :Value]
145
+ )
132
146
  end
133
147
 
134
- # Declares a Guard.
135
- #
136
- # @param [String] name the Guard name
137
- # @param [Hash] options the options accepted by the Guard
138
- # @yield a block where you can declare several watch patterns and actions
139
- #
140
- # @see Guard::Dsl#guard
141
- #
142
- def guard(name, options = { })
143
- @group ||= false
144
- node = (@group ? @@guardfile_structure.last : @@guardfile_structure.first)
148
+ private
145
149
 
146
- node[:guards] << { :name => name, :options => options }
150
+ def _add_row(rows, name, available, used, option, value)
151
+ rows << {
152
+ Name: name,
153
+ Available: available,
154
+ Used: used,
155
+ Option: option,
156
+ Value: value
157
+ }
147
158
  end
148
-
149
159
  end
150
160
  end
@@ -0,0 +1,51 @@
1
+ require "guard/dsl"
2
+
3
+ module Guard
4
+ # TODO: this should probably be a base class for Dsl instead (in Guard 3.x)
5
+ class DslReader < Dsl
6
+ attr_reader :plugin_names
7
+
8
+ def initialize
9
+ super
10
+ @plugin_names = []
11
+ end
12
+
13
+ def guard(name, _options = {})
14
+ @plugin_names << name.to_s
15
+ end
16
+
17
+ # Stub everything else
18
+ def notification(_notifier, _opts = {})
19
+ end
20
+
21
+ def interactor(_options)
22
+ end
23
+
24
+ def group(*_args)
25
+ end
26
+
27
+ def watch(_pattern, &_action)
28
+ end
29
+
30
+ def callback(*_args, &_block)
31
+ end
32
+
33
+ def ignore(*_regexps)
34
+ end
35
+
36
+ def ignore!(*_regexps)
37
+ end
38
+
39
+ def logger(_options)
40
+ end
41
+
42
+ def scope(_scope = {})
43
+ end
44
+
45
+ def directories(_directories)
46
+ end
47
+
48
+ def clearing(_on)
49
+ end
50
+ end
51
+ end
data/lib/guard/group.rb CHANGED
@@ -1,23 +1,27 @@
1
1
  module Guard
2
-
3
- # A group of Guard plugins. There are two reasons why you want to group your guards:
2
+ # A group of Guard plugins. There are two reasons why you want to group your
3
+ # Guard plugins:
4
4
  #
5
- # - You can start only certain Groups from the command line by passing the `--group` option.
6
- # - Abort task execution chain on failure within a group.
5
+ # * You can start only certain groups from the command line by passing the
6
+ # `--group` option to `guard start`.
7
+ # * Abort task execution chain on failure within a group with the
8
+ # `:halt_on_fail` option.
7
9
  #
8
10
  # @example Group that aborts on failure
9
11
  #
10
- # group :frontend, :halt_on_fail => true do
11
- # guard 'coffeescript', :input => 'spec/coffeescripts', :output => 'spec/javascripts'
12
+ # group :frontend, halt_on_fail: true do
13
+ # guard 'coffeescript', input: 'spec/coffeescripts',
14
+ # output: 'spec/javascripts'
12
15
  # guard 'jasmine-headless-webkit' do
13
- # watch(%r{^spec/javascripts/(.*)\..*}) { |m| newest_js_file("spec/javascripts/#{m[1]}_spec") }
16
+ # watch(%r{^spec/javascripts/(.*)\..*}) do |m|
17
+ # newest_js_file("spec/javascripts/#{m[1]}_spec")
18
+ # end
14
19
  # end
15
20
  # end
16
21
  #
17
22
  # @see Guard::CLI
18
23
  #
19
24
  class Group
20
-
21
25
  attr_accessor :name, :options
22
26
 
23
27
  # Initializes a Group.
@@ -25,20 +29,36 @@ module Guard
25
29
  # @param [String] name the name of the group
26
30
  # @param [Hash] options the group options
27
31
  # @option options [Boolean] halt_on_fail if a task execution
28
- # should be halted for all Guard plugins in this group if a Guard plugin throws `:task_has_failed`
32
+ # should be halted for all Guard plugins in this group if a Guard plugin
33
+ # throws `:task_has_failed`
29
34
  #
30
35
  def initialize(name, options = {})
31
- @name = name.to_sym
36
+ @name = name.to_sym
32
37
  @options = options
33
38
  end
34
39
 
35
- # String representation of the Guard group.
40
+ # Returns the group title.
36
41
  #
37
- # @return [String] the group name
42
+ # @example Title for a group named 'backend'
43
+ # > Guard::Group.new('backend').title
44
+ # => "Backend"
38
45
  #
39
- def to_s
40
- "#{@name} group"
46
+ # @return [String]
47
+ #
48
+ def title
49
+ @title ||= name.to_s.capitalize
41
50
  end
42
51
 
52
+ # String representation of the group.
53
+ #
54
+ # @example String representation of a group named 'backend'
55
+ # > Guard::Group.new('backend').to_s
56
+ # => "#<Guard::Group @name=backend @options={}>"
57
+ #
58
+ # @return [String] the string representation
59
+ #
60
+ def to_s
61
+ "#<#{self.class} @name=#{name} @options=#{options}>"
62
+ end
43
63
  end
44
64
  end
@@ -0,0 +1,232 @@
1
+ require "guard/config"
2
+ require "guard/deprecated/evaluator" unless Guard::Config.new.strict?
3
+
4
+ require "guard/options"
5
+ require "guard/plugin"
6
+
7
+ require "guard/dsl"
8
+ require "guard/dsl_reader"
9
+
10
+ module Guard
11
+ module Guardfile
12
+ # This class is responsible for evaluating the Guardfile. It delegates to
13
+ # Guard::Dsl for the actual objects generation from the Guardfile content.
14
+ #
15
+ # @see Guard::Dsl
16
+ #
17
+ # TODO: rename this to a Locator or Loader or something
18
+ class Evaluator
19
+ Deprecated::Evaluator.add_deprecated(self) unless Config.new.strict?
20
+
21
+ DEFAULT_GUARDFILES = %w(
22
+ guardfile.rb
23
+ Guardfile
24
+ ~/.Guardfile
25
+ ).freeze
26
+
27
+ ERROR_NO_GUARDFILE = "No Guardfile found,"\
28
+ " please create one with `guard init`."
29
+
30
+ attr_reader :options, :guardfile_path
31
+
32
+ ERROR_NO_PLUGINS = "No Guard plugins found in Guardfile,"\
33
+ " please add at least one."
34
+
35
+ class Error < RuntimeError
36
+ end
37
+
38
+ class NoGuardfileError < Error
39
+ end
40
+
41
+ class NoCustomGuardfile < Error
42
+ end
43
+
44
+ class NoPluginsError < Error
45
+ end
46
+
47
+ def guardfile_source
48
+ @source
49
+ end
50
+
51
+ # Initializes a new Guard::Guardfile::Evaluator object.
52
+ #
53
+ # @option opts [String] guardfile the path to a valid Guardfile
54
+ # @option opts [String] contents a string representing the
55
+ # content of a valid Guardfile
56
+ #
57
+ def initialize(opts = {})
58
+ @type = nil
59
+ @path = nil
60
+ @user_config = nil
61
+
62
+ opts = _from_deprecated(opts)
63
+
64
+ if opts[:contents]
65
+ @type = :inline
66
+ @contents = opts[:contents]
67
+ elsif opts[:guardfile]
68
+ @type = :custom
69
+ @path = Pathname.new(opts[:guardfile]) # may be updated by _read
70
+ end
71
+ end
72
+
73
+ # Evaluates the DSL methods in the `Guardfile`.
74
+ #
75
+ # @example Programmatically evaluate a Guardfile
76
+ # Guard::Guardfile::Evaluator.new.evaluate
77
+ #
78
+ # @example Programmatically evaluate a Guardfile with a custom Guardfile
79
+ # path
80
+ #
81
+ # options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
82
+ # Guard::Guardfile::Evaluator.new(options).evaluate
83
+ #
84
+ # @example Programmatically evaluate a Guardfile with an inline Guardfile
85
+ #
86
+ # options = { contents: 'guard :rspec' }
87
+ # Guard::Guardfile::Evaluator.new(options).evaluate
88
+ #
89
+ def evaluate
90
+ inline? || _use_provided || _use_default!
91
+
92
+ contents = _guardfile_contents
93
+ fail NoPluginsError, ERROR_NO_PLUGINS unless /guard/m =~ contents
94
+
95
+ Dsl.new.evaluate(contents, @path || "", 1)
96
+ end
97
+
98
+ # Tests if the current `Guardfile` contains a specific Guard plugin.
99
+ #
100
+ # @example Programmatically test if a Guardfile contains a specific Guard
101
+ # plugin
102
+ #
103
+ # File.read('Guardfile')
104
+ # => "guard :rspec"
105
+ #
106
+ # Guard::Guardfile::Evaluator.new.guardfile_include?('rspec)
107
+ # => true
108
+ #
109
+ # @param [String] plugin_name the name of the Guard
110
+ # @return [Boolean] whether the Guard plugin has been declared
111
+ #
112
+ # TODO: rename this method to it matches RSpec examples better
113
+ def guardfile_include?(plugin_name)
114
+ reader = DslReader.new
115
+ reader.evaluate(@contents, @path || "", 1)
116
+ reader.plugin_names.include?(plugin_name)
117
+ end
118
+
119
+ attr_reader :path
120
+
121
+ def custom?
122
+ @type == :custom
123
+ end
124
+
125
+ # Gets the content of the `Guardfile` concatenated with the global
126
+ # user configuration file.
127
+ #
128
+ # @example Programmatically get the content of the current Guardfile
129
+ # Guard::Guardfile::Evaluator.new.guardfile_contents
130
+ # => "guard :rspec"
131
+ #
132
+ # @return [String] the Guardfile content
133
+ #
134
+ def guardfile_contents
135
+ config = File.read(_user_config_path) if File.exist?(_user_config_path)
136
+ [_guardfile_contents_without_user_config, config].compact.join("\n")
137
+ end
138
+
139
+ def inline?
140
+ @type == :inline
141
+ end
142
+
143
+ private
144
+
145
+ def _guardfile_contents_without_user_config
146
+ @guardfile_contents || ""
147
+ end
148
+
149
+ def _instance_eval_guardfile(contents)
150
+ Dsl.new.evaluate(contents, @guardfile_path || "", 1)
151
+ rescue => ex
152
+ UI.error "Invalid Guardfile, original error is:\n#{ $! }"
153
+ raise ex
154
+ end
155
+
156
+ def _fetch_guardfile_contents
157
+ _use_inline || _use_provided || _use_default
158
+ @evaluated = true
159
+
160
+ return if _guardfile_contents_usable?
161
+ UI.error "No Guard plugins found in Guardfile,"\
162
+ " please add at least one."
163
+ end
164
+
165
+ def _use_inline
166
+ source_from_option = @source.nil? && options[:guardfile_contents]
167
+ inline = @source == :inline
168
+
169
+ return false unless source_from_option || inline
170
+
171
+ @source = :inline
172
+ @guardfile_contents = options[:guardfile_contents]
173
+
174
+ UI.info "Using inline Guardfile."
175
+ true
176
+ end
177
+
178
+ def _use_provided
179
+ return unless custom?
180
+ @path, @contents = _read(@path)
181
+ true
182
+ rescue Errno::ENOENT
183
+ fail NoCustomGuardfile, "No Guardfile exists at #{ @path }."
184
+ end
185
+
186
+ def _use_default!
187
+ DEFAULT_GUARDFILES.each do |guardfile|
188
+ begin
189
+ @path, @contents = _read(guardfile)
190
+ @type = :default
191
+ break
192
+ rescue Errno::ENOENT
193
+ if guardfile == DEFAULT_GUARDFILES.last
194
+ fail NoGuardfileError, ERROR_NO_GUARDFILE
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ def _read(path)
201
+ full_path = Pathname.new(path.to_s).expand_path
202
+ [full_path, full_path.read]
203
+ rescue Errno::ENOENT
204
+ fail
205
+ rescue SystemCallError => e
206
+ UI.error "Error reading file #{full_path}:"
207
+ UI.error e.inspect
208
+ UI.error e.backtrace
209
+ abort
210
+ end
211
+
212
+ def _guardfile_contents
213
+ @user_config ||= Pathname.new("~/.guard.rb").expand_path.read
214
+ [@contents, @user_config].compact.join("\n")
215
+ rescue Errno::ENOENT
216
+ @contents || ""
217
+ end
218
+
219
+ def _guardfile_contents_usable?
220
+ guardfile_contents && guardfile_contents =~ /guard/m
221
+ end
222
+
223
+ def _from_deprecated(opts)
224
+ res = opts.dup
225
+ if opts.key?(:guardfile_contents)
226
+ res[:contents] = opts[:guardfile_contents]
227
+ end
228
+ res
229
+ end
230
+ end
231
+ end
232
+ end