guard 2.6.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -58
  3. data/bin/guard +2 -2
  4. data/lib/guard.rb +64 -59
  5. data/lib/guard/cli.rb +66 -60
  6. data/lib/guard/cli.rb.orig +215 -0
  7. data/lib/guard/commander.rb +45 -69
  8. data/lib/guard/commands/all.rb +21 -19
  9. data/lib/guard/commands/change.rb +17 -22
  10. data/lib/guard/commands/notification.rb +15 -16
  11. data/lib/guard/commands/pause.rb +14 -15
  12. data/lib/guard/commands/reload.rb +19 -20
  13. data/lib/guard/commands/scope.rb +23 -19
  14. data/lib/guard/commands/show.rb +13 -16
  15. data/lib/guard/deprecated_methods.rb +6 -10
  16. data/lib/guard/deprecator.rb +52 -37
  17. data/lib/guard/dsl.rb +55 -33
  18. data/lib/guard/dsl_describer.rb +83 -31
  19. data/lib/guard/dsl_describer.rb.orig +184 -0
  20. data/lib/guard/group.rb +7 -6
  21. data/lib/guard/guard.rb +4 -4
  22. data/lib/guard/guard.rb.orig +42 -0
  23. data/lib/guard/guardfile.rb +12 -13
  24. data/lib/guard/guardfile/evaluator.rb +77 -55
  25. data/lib/guard/guardfile/evaluator.rb.orig +275 -0
  26. data/lib/guard/guardfile/generator.rb +25 -20
  27. data/lib/guard/interactor.rb +52 -293
  28. data/lib/guard/interactor.rb.orig +85 -0
  29. data/lib/guard/jobs/base.rb +21 -0
  30. data/lib/guard/jobs/pry_wrapper.rb +290 -0
  31. data/lib/guard/jobs/pry_wrapper.rb.orig +293 -0
  32. data/lib/guard/jobs/sleep.rb +25 -0
  33. data/lib/guard/notifier.rb +42 -39
  34. data/lib/guard/notifiers/base.rb +25 -24
  35. data/lib/guard/notifiers/emacs.rb +30 -24
  36. data/lib/guard/notifiers/file_notifier.rb +3 -7
  37. data/lib/guard/notifiers/gntp.rb +22 -22
  38. data/lib/guard/notifiers/growl.rb +16 -15
  39. data/lib/guard/notifiers/libnotify.rb +7 -10
  40. data/lib/guard/notifiers/notifysend.rb +15 -14
  41. data/lib/guard/notifiers/rb_notifu.rb +8 -10
  42. data/lib/guard/notifiers/terminal_notifier.rb +15 -11
  43. data/lib/guard/notifiers/terminal_title.rb +4 -8
  44. data/lib/guard/notifiers/tmux.rb +104 -71
  45. data/lib/guard/options.rb +1 -5
  46. data/lib/guard/plugin.rb +1 -3
  47. data/lib/guard/plugin/base.rb +12 -9
  48. data/lib/guard/plugin/hooker.rb +1 -5
  49. data/lib/guard/plugin_util.rb +46 -25
  50. data/lib/guard/plugin_util.rb.orig +178 -0
  51. data/lib/guard/rake_task.rb +4 -7
  52. data/lib/guard/reevaluator.rb +13 -0
  53. data/lib/guard/runner.rb +50 -78
  54. data/lib/guard/runner.rb.orig +200 -0
  55. data/lib/guard/setuper.rb +199 -130
  56. data/lib/guard/setuper.rb.orig +348 -0
  57. data/lib/guard/sheller.rb +107 -0
  58. data/lib/guard/tags +367 -0
  59. data/lib/guard/ui.rb +50 -38
  60. data/lib/guard/ui.rb.orig +254 -0
  61. data/lib/guard/ui/colors.rb +17 -21
  62. data/lib/guard/version.rb +1 -1
  63. data/lib/guard/version.rb.orig +3 -0
  64. data/lib/guard/watcher.rb +49 -62
  65. metadata +21 -4
  66. data/lib/guard/notifiers/growl_notify.rb +0 -93
@@ -0,0 +1,42 @@
1
+ require "guard/plugin/base"
2
+
3
+ module Guard
4
+ # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
5
+ # from {Plugin} instead. Please note that the constructor signature has
6
+ # changed from `Guard::Guard#initialize(watchers = [], options = {})` to
7
+ # `Guard::Plugin#initialize(options = {})`.
8
+ #
9
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
10
+ # upgrade for Guard 2.0
11
+ #
12
+ class Guard
13
+ include ::Guard::Plugin::Base
14
+
15
+ # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
16
+ # from {Plugin} instead. Please note that the constructor signature
17
+ # has changed from `Guard::Guard#initialize(watchers = [], options = {})`
18
+ # to `Guard::Plugin#initialize(options = {})`.
19
+ #
20
+ # Initializes a Guard plugin. Don't do any work here,
21
+ # especially as Guard plugins get initialized even if they are not in an
22
+ # active group!
23
+ #
24
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
25
+ # upgrade for Guard 2.0
26
+ #
27
+ # @param [Array<Guard::Watcher>] watchers the Guard plugin file watchers
28
+ # @param [Hash] options the custom Guard plugin options
29
+ # @option options [Symbol] group the group this Guard plugin belongs to
30
+ # @option options [Boolean] any_return allow any object to be returned from
31
+ # a watcher
32
+ # @option options [Boolean] first_match stop after the first watcher that
33
+ # returns a valid result
34
+ #
35
+ def initialize(watchers = [], options = {})
36
+ UI.deprecation(Deprecator::GUARD_GUARD_DEPRECATION % title)
37
+
38
+ _set_instance_variables_from_options(options.merge(watchers: watchers))
39
+ _register_callbacks
40
+ end
41
+ end
42
+ end
@@ -1,9 +1,8 @@
1
- require 'guard/guardfile/evaluator'
2
- require 'guard/guardfile/generator'
3
- require 'guard/ui'
1
+ require "guard/guardfile/evaluator"
2
+ require "guard/guardfile/generator"
3
+ require "guard/ui"
4
4
 
5
5
  module Guard
6
-
7
6
  # @deprecated Use instance methods of {Guardfile::Evaluator} and
8
7
  # {Guardfile::Generator} instead.
9
8
  #
@@ -11,34 +10,34 @@ module Guard
11
10
  # @see Guardfile::Generator
12
11
  #
13
12
  module Guardfile
14
-
15
13
  # @deprecated Use {Guardfile::Generator#create_guardfile} instead.
16
14
  #
17
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to upgrade for Guard 2.0
15
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
16
+ # upgrade for Guard 2.0
18
17
  #
19
18
  def self.create_guardfile(options = {})
20
- ::Guard::UI.deprecation(::Guard::Deprecator::CREATE_GUARDFILE_DEPRECATION)
19
+ UI.deprecation(Deprecator::CREATE_GUARDFILE_DEPRECATION)
21
20
  Generator.new(options).create_guardfile
22
21
  end
23
22
 
24
23
  # @deprecated Use {Guardfile::Generator#initialize_template} instead.
25
24
  #
26
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to upgrade for Guard 2.0
25
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
26
+ # upgrade for Guard 2.0
27
27
  #
28
28
  def self.initialize_template(plugin_name)
29
- ::Guard::UI.deprecation(::Guard::Deprecator::INITIALIZE_TEMPLATE_DEPRECATION)
29
+ UI.deprecation(Deprecator::INITIALIZE_TEMPLATE_DEPRECATION)
30
30
  Generator.new.initialize_template(plugin_name)
31
31
  end
32
32
 
33
33
  # @deprecated Use {Guardfile::Generator#initialize_all_templates} instead.
34
34
  #
35
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to upgrade for Guard 2.0
35
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
36
+ # upgrade for Guard 2.0
36
37
  #
37
38
  def self.initialize_all_templates
38
- ::Guard::UI.deprecation(::Guard::Deprecator::INITIALIZE_ALL_TEMPLATES_DEPRECATION)
39
+ UI.deprecation(Deprecator::INITIALIZE_ALL_TEMPLATES_DEPRECATION)
39
40
  Generator.new.initialize_all_templates
40
41
  end
41
-
42
42
  end
43
-
44
43
  end
@@ -1,24 +1,35 @@
1
- require 'guard/options'
1
+ require "guard/options"
2
+ require "guard/plugin"
2
3
 
3
4
  module Guard
4
5
  module Guardfile
5
-
6
- # This class is responsible for evaluating the Guardfile. It delegates
7
- # to Guard::Dsl for the actual objects generation from the Guardfile content.
6
+ # This class is responsible for evaluating the Guardfile. It delegates to
7
+ # Guard::Dsl for the actual objects generation from the Guardfile content.
8
8
  #
9
9
  # @see Guard::Dsl
10
10
  #
11
11
  class Evaluator
12
+ attr_reader :options, :guardfile_path
12
13
 
13
- attr_reader :options, :guardfile_source, :guardfile_path
14
+ def guardfile_source
15
+ @source
16
+ end
14
17
 
15
18
  # Initializes a new Guard::Guardfile::Evaluator object.
16
19
  #
17
20
  # @option opts [String] guardfile the path to a valid Guardfile
18
- # @option opts [String] guardfile_contents a string representing the content of a valid Guardfile
21
+ # @option opts [String] guardfile_contents a string representing the
22
+ # content of a valid Guardfile
19
23
  #
20
24
  def initialize(opts = {})
21
- @options = ::Guard::Options.new(opts.select { |k, _| [:guardfile, :guardfile_contents].include?(k.to_sym) })
25
+ @source = nil
26
+ @guardfile_path = nil
27
+
28
+ valid_options = opts.select do |k, _|
29
+ [:guardfile, :guardfile_contents].include?(k.to_sym)
30
+ end
31
+
32
+ @options = ::Guard::Options.new(valid_options)
22
33
  end
23
34
 
24
35
  # Evaluates the DSL methods in the `Guardfile`.
@@ -26,14 +37,20 @@ module Guard
26
37
  # @example Programmatically evaluate a Guardfile
27
38
  # Guard::Guardfile::Evaluator.new.evaluate_guardfile
28
39
  #
29
- # @example Programmatically evaluate a Guardfile with a custom Guardfile path
30
- # Guard::Guardfile::Evaluator.new(guardfile: '/Users/guardfile/MyAwesomeGuardfile').evaluate_guardfile
40
+ # @example Programmatically evaluate a Guardfile with a custom Guardfile
41
+ # path
42
+ #
43
+ # options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
44
+ # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
31
45
  #
32
46
  # @example Programmatically evaluate a Guardfile with an inline Guardfile
33
- # Guard::Guardfile::Evaluator.new(guardfile_contents: 'guard :rspec').evaluate_guardfile
47
+ #
48
+ # options = { guardfile_contents: 'guard :rspec' }
49
+ # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
34
50
  #
35
51
  def evaluate_guardfile
36
52
  _fetch_guardfile_contents
53
+ ::Guard.add_builtin_plugins(guardfile_path)
37
54
  _instance_eval_guardfile(guardfile_contents)
38
55
  end
39
56
 
@@ -42,7 +59,7 @@ module Guard
42
59
  #
43
60
  def reevaluate_guardfile
44
61
  # Don't re-evaluate inline Guardfile
45
- return if @guardfile_source == :inline
62
+ return if @source == :inline
46
63
 
47
64
  _before_reevaluate_guardfile
48
65
  evaluate_guardfile
@@ -51,7 +68,9 @@ module Guard
51
68
 
52
69
  # Tests if the current `Guardfile` contains a specific Guard plugin.
53
70
  #
54
- # @example Programmatically test if a Guardfile contains a specific Guard plugin
71
+ # @example Programmatically test if a Guardfile contains a specific Guard
72
+ # plugin
73
+ #
55
74
  # File.read('Guardfile')
56
75
  # => "guard :rspec"
57
76
  #
@@ -62,7 +81,8 @@ module Guard
62
81
  # @return [Boolean] whether the Guard plugin has been declared
63
82
  #
64
83
  def guardfile_include?(plugin_name)
65
- _guardfile_contents_without_user_config.match(/^guard\s*\(?\s*['":]#{ plugin_name }['"]?/)
84
+ regexp = /^guard\s*\(?\s*['":]#{ plugin_name }['"]?/
85
+ _guardfile_contents_without_user_config.match(regexp)
66
86
  end
67
87
 
68
88
  # Gets the content of the `Guardfile` concatenated with the global
@@ -86,7 +106,7 @@ module Guard
86
106
  # @return [String] the Guardfile content
87
107
  #
88
108
  def _guardfile_contents_without_user_config
89
- @guardfile_contents || ''
109
+ @guardfile_contents || ""
90
110
  end
91
111
 
92
112
  # Evaluates the content of the `Guardfile`.
@@ -94,7 +114,7 @@ module Guard
94
114
  # @param [String] contents the content to evaluate.
95
115
  #
96
116
  def _instance_eval_guardfile(contents)
97
- ::Guard::Dsl.new.instance_eval(contents, @guardfile_path || '', 1)
117
+ ::Guard::Dsl.new.instance_eval(contents, @guardfile_path || "", 1)
98
118
  rescue => ex
99
119
  ::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
100
120
  raise ex
@@ -103,62 +123,60 @@ module Guard
103
123
  # Gets the content to evaluate and stores it into @guardfile_contents.
104
124
  #
105
125
  def _fetch_guardfile_contents
106
- _use_inline_guardfile || _use_provided_guardfile || _use_default_guardfile
126
+ _use_inline || _use_provided || _use_default
107
127
 
108
- unless _guardfile_contents_usable?
109
- ::Guard::UI.error 'No Guard plugins found in Guardfile, please add at least one.'
110
- end
128
+ return if _guardfile_contents_usable?
129
+ ::Guard::UI.error "No Guard plugins found in Guardfile,"\
130
+ " please add at least one."
111
131
  end
112
132
 
113
133
  # Use the provided inline Guardfile if provided.
114
134
  #
115
- def _use_inline_guardfile
116
- if (@guardfile_source.nil? && options[:guardfile_contents]) || @guardfile_source == :inline
135
+ def _use_inline
136
+ source_from_option = @source.nil? && options[:guardfile_contents]
137
+ inline = @source == :inline
117
138
 
118
- @guardfile_source = :inline
119
- @guardfile_contents = options[:guardfile_contents]
139
+ return false unless (source_from_option) || inline
120
140
 
121
- ::Guard::UI.info 'Using inline Guardfile.'
141
+ @source = :inline
142
+ @guardfile_contents = options[:guardfile_contents]
122
143
 
123
- true
124
- else
125
- false
126
- end
144
+ ::Guard::UI.info "Using inline Guardfile."
145
+ true
127
146
  end
128
147
 
129
148
  # Try to use the provided Guardfile. Exits Guard if the Guardfile cannot
130
149
  # be found.
131
150
  #
132
- def _use_provided_guardfile
133
- if (@guardfile_source.nil? && options[:guardfile]) || @guardfile_source == :custom
151
+ def _use_provided
152
+ source_from_file = @source.nil? && options[:guardfile]
153
+ return false unless source_from_file || (@source == :custom)
134
154
 
135
- @guardfile_source = :custom
136
-
137
- options[:guardfile] = File.expand_path(options[:guardfile])
138
- if File.exist?(options[:guardfile])
139
- _read_guardfile(options[:guardfile])
140
- ::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
141
- true
142
- else
143
- ::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
144
- exit 1
145
- end
155
+ @source = :custom
146
156
 
157
+ options[:guardfile] = File.expand_path(options[:guardfile])
158
+ if File.exist?(options[:guardfile])
159
+ _read_guardfile(options[:guardfile])
160
+ ::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
147
161
  true
148
162
  else
149
- false
163
+ ::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
164
+ exit 1
150
165
  end
166
+
167
+ true
151
168
  end
152
169
 
153
170
  # Try to use one of the default Guardfiles (local or home Guardfile).
154
171
  # Exits Guard if no Guardfile is found.
155
172
  #
156
- def _use_default_guardfile
173
+ def _use_default
157
174
  if guardfile_path = _find_default_guardfile
158
- @guardfile_source = :default
175
+ @source = :default
159
176
  _read_guardfile(guardfile_path)
160
177
  else
161
- ::Guard::UI.error 'No Guardfile found, please create one with `guard init`.'
178
+ ::Guard::UI.error \
179
+ "No Guardfile found, please create one with `guard init`."
162
180
  exit 1
163
181
  end
164
182
  end
@@ -167,7 +185,9 @@ module Guard
167
185
  # or nil otherwise.
168
186
  #
169
187
  def _find_default_guardfile
170
- [_local_guardfile_path, _home_guardfile_path].find { |path| File.exist?(path) }
188
+ [_local_guardfile_path, _home_guardfile_path].detect do |path|
189
+ File.exist?(path)
190
+ end
171
191
  end
172
192
 
173
193
  # Reads the current `Guardfile` content.
@@ -201,13 +221,17 @@ module Guard
201
221
  def _after_reevaluate_guardfile
202
222
  ::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
203
223
 
204
- if ::Guard.plugins.empty?
205
- ::Guard::Notifier.notify('No plugins found in Guardfile, please add at least one.', title: 'Guard re-evaluate', image: :failed)
224
+ if !::Guard.send(:_non_builtin_plugins?)
225
+ ::Guard::Notifier.notify(
226
+ "No plugins found in Guardfile, please add at least one.",
227
+ title: "Guard re-evaluate",
228
+ image: :failed)
206
229
  else
207
- msg = 'Guardfile has been re-evaluated.'
230
+ msg = "Guardfile has been re-evaluated."
208
231
  ::Guard::UI.info(msg)
209
- ::Guard::Notifier.notify(msg, title: 'Guard re-evaluate')
232
+ ::Guard::Notifier.notify(msg, title: "Guard re-evaluate")
210
233
 
234
+ ::Guard.setup_scope
211
235
  ::Guard.runner.run(:start)
212
236
  end
213
237
  end
@@ -226,7 +250,7 @@ module Guard
226
250
  # @return [String] the path to the local Guardfile
227
251
  #
228
252
  def _local_guardfile_path
229
- File.expand_path(File.join(Dir.pwd, 'Guardfile'))
253
+ File.expand_path(File.join(Dir.pwd, "Guardfile"))
230
254
  end
231
255
 
232
256
  # The path to the `.Guardfile` that is located at
@@ -235,7 +259,7 @@ module Guard
235
259
  # @return [String] the path to `~/.Guardfile`
236
260
  #
237
261
  def _home_guardfile_path
238
- File.expand_path(File.join('~', '.Guardfile'))
262
+ File.expand_path(File.join("~", ".Guardfile"))
239
263
  end
240
264
 
241
265
  # The path to the user configuration `.guard.rb`
@@ -244,10 +268,8 @@ module Guard
244
268
  # @return [String] the path to `~/.guard.rb`
245
269
  #
246
270
  def _user_config_path
247
- File.expand_path(File.join('~', '.guard.rb'))
271
+ File.expand_path(File.join("~", ".guard.rb"))
248
272
  end
249
-
250
273
  end
251
-
252
274
  end
253
275
  end
@@ -0,0 +1,275 @@
1
+ require "guard/options"
2
+ require "guard/plugin"
3
+
4
+ module Guard
5
+ module Guardfile
6
+ # This class is responsible for evaluating the Guardfile. It delegates to
7
+ # Guard::Dsl for the actual objects generation from the Guardfile content.
8
+ #
9
+ # @see Guard::Dsl
10
+ #
11
+ class Evaluator
12
+ attr_reader :options, :guardfile_path
13
+
14
+ def guardfile_source
15
+ @source
16
+ end
17
+
18
+ # Initializes a new Guard::Guardfile::Evaluator object.
19
+ #
20
+ # @option opts [String] guardfile the path to a valid Guardfile
21
+ # @option opts [String] guardfile_contents a string representing the
22
+ # content of a valid Guardfile
23
+ #
24
+ def initialize(opts = {})
25
+ @source = nil
26
+ @guardfile_path = nil
27
+
28
+ valid_options = opts.select do |k, _|
29
+ [:guardfile, :guardfile_contents].include?(k.to_sym)
30
+ end
31
+
32
+ @options = ::Guard::Options.new(valid_options)
33
+ end
34
+
35
+ # Evaluates the DSL methods in the `Guardfile`.
36
+ #
37
+ # @example Programmatically evaluate a Guardfile
38
+ # Guard::Guardfile::Evaluator.new.evaluate_guardfile
39
+ #
40
+ # @example Programmatically evaluate a Guardfile with a custom Guardfile
41
+ # path
42
+ #
43
+ # options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
44
+ # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
45
+ #
46
+ # @example Programmatically evaluate a Guardfile with an inline Guardfile
47
+ #
48
+ # options = { guardfile_contents: 'guard :rspec' }
49
+ # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
50
+ #
51
+ def evaluate_guardfile
52
+ _fetch_guardfile_contents
53
+ ::Guard.add_builtin_plugins
54
+ _instance_eval_guardfile(guardfile_contents)
55
+ end
56
+
57
+ # Re-evaluates the `Guardfile` to update
58
+ # the current Guard configuration.
59
+ #
60
+ def reevaluate_guardfile
61
+ # Don't re-evaluate inline Guardfile
62
+ return if @source == :inline
63
+
64
+ _before_reevaluate_guardfile
65
+ evaluate_guardfile
66
+ _after_reevaluate_guardfile
67
+ end
68
+
69
+ # Tests if the current `Guardfile` contains a specific Guard plugin.
70
+ #
71
+ # @example Programmatically test if a Guardfile contains a specific Guard
72
+ # plugin
73
+ #
74
+ # File.read('Guardfile')
75
+ # => "guard :rspec"
76
+ #
77
+ # Guard::Guardfile::Evaluator.new.guardfile_include?('rspec)
78
+ # => true
79
+ #
80
+ # @param [String] plugin_name the name of the Guard
81
+ # @return [Boolean] whether the Guard plugin has been declared
82
+ #
83
+ def guardfile_include?(plugin_name)
84
+ regexp = /^guard\s*\(?\s*['":]#{ plugin_name }['"]?/
85
+ _guardfile_contents_without_user_config.match(regexp)
86
+ end
87
+
88
+ # Gets the content of the `Guardfile` concatenated with the global
89
+ # user configuration file.
90
+ #
91
+ # @example Programmatically get the content of the current Guardfile
92
+ # Guard::Guardfile::Evaluator.new.guardfile_contents
93
+ # => "guard :rspec"
94
+ #
95
+ # @return [String] the Guardfile content
96
+ #
97
+ def guardfile_contents
98
+ config = File.read(_user_config_path) if File.exist?(_user_config_path)
99
+ [_guardfile_contents_without_user_config, config].compact.join("\n")
100
+ end
101
+
102
+ private
103
+
104
+ # Gets the content of the `Guardfile`.
105
+ #
106
+ # @return [String] the Guardfile content
107
+ #
108
+ def _guardfile_contents_without_user_config
109
+ @guardfile_contents || ""
110
+ end
111
+
112
+ # Evaluates the content of the `Guardfile`.
113
+ #
114
+ # @param [String] contents the content to evaluate.
115
+ #
116
+ def _instance_eval_guardfile(contents)
117
+ ::Guard::Dsl.new.instance_eval(contents, @guardfile_path || "", 1)
118
+ rescue => ex
119
+ ::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
120
+ raise ex
121
+ end
122
+
123
+ # Gets the content to evaluate and stores it into @guardfile_contents.
124
+ #
125
+ def _fetch_guardfile_contents
126
+ _use_inline || _use_provided || _use_default
127
+
128
+ return if _guardfile_contents_usable?
129
+ ::Guard::UI.error "No Guard plugins found in Guardfile,"\
130
+ " please add at least one."
131
+ end
132
+
133
+ # Use the provided inline Guardfile if provided.
134
+ #
135
+ def _use_inline
136
+ source_from_option = @source.nil? && options[:guardfile_contents]
137
+ inline = @source == :inline
138
+
139
+ return false unless (source_from_option) || inline
140
+
141
+ @source = :inline
142
+ @guardfile_contents = options[:guardfile_contents]
143
+
144
+ ::Guard::UI.info "Using inline Guardfile."
145
+ true
146
+ end
147
+
148
+ # Try to use the provided Guardfile. Exits Guard if the Guardfile cannot
149
+ # be found.
150
+ #
151
+ def _use_provided
152
+ source_from_file = @source.nil? && options[:guardfile]
153
+ return false unless source_from_file || (@source == :custom)
154
+
155
+ @source = :custom
156
+
157
+ options[:guardfile] = File.expand_path(options[:guardfile])
158
+ if File.exist?(options[:guardfile])
159
+ _read_guardfile(options[:guardfile])
160
+ ::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
161
+ true
162
+ else
163
+ ::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
164
+ exit 1
165
+ end
166
+
167
+ true
168
+ end
169
+
170
+ # Try to use one of the default Guardfiles (local or home Guardfile).
171
+ # Exits Guard if no Guardfile is found.
172
+ #
173
+ def _use_default
174
+ if guardfile_path = _find_default_guardfile
175
+ @source = :default
176
+ _read_guardfile(guardfile_path)
177
+ else
178
+ ::Guard::UI.error \
179
+ "No Guardfile found, please create one with `guard init`."
180
+ exit 1
181
+ end
182
+ end
183
+
184
+ # Returns the first default Guardfile (either local or home Guardfile)
185
+ # or nil otherwise.
186
+ #
187
+ def _find_default_guardfile
188
+ [_local_guardfile_path, _home_guardfile_path].detect do |path|
189
+ File.exist?(path)
190
+ end
191
+ end
192
+
193
+ # Reads the current `Guardfile` content.
194
+ #
195
+ # @param [String] guardfile_path the path to the Guardfile
196
+ #
197
+ def _read_guardfile(guardfile_path)
198
+ @guardfile_path = guardfile_path
199
+ @guardfile_contents = File.read(guardfile_path)
200
+ rescue => ex
201
+ ::Guard::UI.error "Error reading file #{ guardfile_path }:"
202
+ ::Guard::UI.error ex.inspect
203
+ ::Guard::UI.error ex.backtrace
204
+ exit 1
205
+ end
206
+
207
+ # Stops Guard and clear internal state
208
+ # before the Guardfile will be re-evaluated.
209
+ #
210
+ def _before_reevaluate_guardfile
211
+ ::Guard.runner.run(:stop)
212
+ ::Guard.reset_groups
213
+ ::Guard.reset_plugins
214
+ ::Guard.reset_scope
215
+ ::Guard::Notifier.clear_notifiers
216
+ end
217
+
218
+ # Starts Guard and notification and show a message
219
+ # after the Guardfile has been re-evaluated.
220
+ #
221
+ def _after_reevaluate_guardfile
222
+ ::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
223
+
224
+ if !::Guard.send(:_non_builtin_plugins?)
225
+ ::Guard::Notifier.notify(
226
+ "No plugins found in Guardfile, please add at least one.",
227
+ title: "Guard re-evaluate",
228
+ image: :failed)
229
+ else
230
+ msg = "Guardfile has been re-evaluated."
231
+ ::Guard::UI.info(msg)
232
+ ::Guard::Notifier.notify(msg, title: "Guard re-evaluate")
233
+
234
+ ::Guard.setup_scope
235
+ ::Guard.runner.run(:start)
236
+ end
237
+ end
238
+
239
+ # Tests if the current `Guardfile` content is usable.
240
+ #
241
+ # @return [Boolean] if the Guardfile is usable
242
+ #
243
+ def _guardfile_contents_usable?
244
+ guardfile_contents && guardfile_contents =~ /guard/m
245
+ end
246
+
247
+ # The path to the `Guardfile` that is located at
248
+ # the directory, where Guard has been started from.
249
+ #
250
+ # @return [String] the path to the local Guardfile
251
+ #
252
+ def _local_guardfile_path
253
+ File.expand_path(File.join(Dir.pwd, "Guardfile"))
254
+ end
255
+
256
+ # The path to the `.Guardfile` that is located at
257
+ # the users home directory.
258
+ #
259
+ # @return [String] the path to `~/.Guardfile`
260
+ #
261
+ def _home_guardfile_path
262
+ File.expand_path(File.join("~", ".Guardfile"))
263
+ end
264
+
265
+ # The path to the user configuration `.guard.rb`
266
+ # that is located at the users home directory.
267
+ #
268
+ # @return [String] the path to `~/.guard.rb`
269
+ #
270
+ def _user_config_path
271
+ File.expand_path(File.join("~", ".guard.rb"))
272
+ end
273
+ end
274
+ end
275
+ end