guard 0.8.8 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/CHANGELOG.md +16 -1
  2. data/README.md +665 -293
  3. data/bin/fsevent_watch_guard +0 -0
  4. data/lib/guard.rb +66 -31
  5. data/lib/guard/cli.rb +9 -3
  6. data/lib/guard/dsl.rb +32 -5
  7. data/lib/guard/dsl_describer.rb +3 -2
  8. data/lib/guard/guard.rb +2 -2
  9. data/lib/guard/interactor.rb +179 -48
  10. data/lib/guard/listener.rb +32 -17
  11. data/lib/guard/listeners/darwin.rb +5 -9
  12. data/lib/guard/listeners/linux.rb +6 -10
  13. data/lib/guard/listeners/windows.rb +4 -2
  14. data/lib/guard/notifier.rb +171 -258
  15. data/lib/guard/notifiers/gntp.rb +114 -0
  16. data/lib/guard/notifiers/growl.rb +98 -0
  17. data/lib/guard/notifiers/growl_notify.rb +91 -0
  18. data/lib/guard/notifiers/libnotify.rb +96 -0
  19. data/lib/guard/notifiers/rb_notifu.rb +101 -0
  20. data/lib/guard/ui.rb +2 -2
  21. data/lib/guard/version.rb +1 -1
  22. data/lib/guard/watcher.rb +1 -1
  23. data/lib/vendor/darwin/Gemfile +6 -0
  24. data/lib/vendor/darwin/Guardfile +8 -0
  25. data/lib/vendor/darwin/LICENSE +20 -0
  26. data/lib/vendor/darwin/README.rdoc +254 -0
  27. data/lib/vendor/darwin/Rakefile +21 -0
  28. data/lib/vendor/darwin/ext/extconf.rb +61 -0
  29. data/lib/vendor/darwin/ext/fsevent/fsevent_watch.c +226 -0
  30. data/lib/vendor/darwin/lib/rb-fsevent.rb +2 -0
  31. data/lib/vendor/darwin/lib/rb-fsevent/fsevent.rb +105 -0
  32. data/lib/vendor/darwin/lib/rb-fsevent/version.rb +3 -0
  33. data/lib/vendor/darwin/rb-fsevent.gemspec +24 -0
  34. data/lib/vendor/darwin/spec/fixtures/folder1/file1.txt +0 -0
  35. data/lib/vendor/darwin/spec/fixtures/folder1/folder2/file2.txt +0 -0
  36. data/lib/vendor/darwin/spec/rb-fsevent/fsevent_spec.rb +75 -0
  37. data/lib/vendor/darwin/spec/spec_helper.rb +24 -0
  38. data/lib/vendor/linux/MIT-LICENSE +20 -0
  39. data/lib/vendor/linux/README.md +66 -0
  40. data/lib/vendor/linux/Rakefile +54 -0
  41. data/lib/vendor/linux/VERSION +1 -0
  42. data/lib/vendor/linux/lib/rb-inotify.rb +17 -0
  43. data/lib/vendor/linux/lib/rb-inotify/event.rb +139 -0
  44. data/lib/vendor/linux/lib/rb-inotify/native.rb +31 -0
  45. data/lib/vendor/linux/lib/rb-inotify/native/flags.rb +89 -0
  46. data/lib/vendor/linux/lib/rb-inotify/notifier.rb +308 -0
  47. data/lib/vendor/linux/lib/rb-inotify/watcher.rb +83 -0
  48. data/lib/vendor/linux/rb-inotify.gemspec +53 -0
  49. data/lib/vendor/windows/Gemfile +4 -0
  50. data/lib/vendor/windows/README.md +34 -0
  51. data/lib/vendor/windows/Rakefile +18 -0
  52. data/lib/vendor/windows/lib/rb-fchange.rb +14 -0
  53. data/lib/vendor/windows/lib/rb-fchange/event.rb +29 -0
  54. data/lib/vendor/windows/lib/rb-fchange/native.rb +45 -0
  55. data/lib/vendor/windows/lib/rb-fchange/native/flags.rb +78 -0
  56. data/lib/vendor/windows/lib/rb-fchange/notifier.rb +149 -0
  57. data/lib/vendor/windows/lib/rb-fchange/version.rb +3 -0
  58. data/lib/vendor/windows/lib/rb-fchange/watcher.rb +99 -0
  59. data/lib/vendor/windows/rb-fchange.gemspec +34 -0
  60. data/lib/vendor/windows/spec/fixtures/folder1/file1.txt +0 -0
  61. data/lib/vendor/windows/spec/fixtures/folder1/folder2/file2.txt +0 -0
  62. data/lib/vendor/windows/spec/rb-fchange/fchange_spec.rb +119 -0
  63. data/lib/vendor/windows/spec/spec_helper.rb +21 -0
  64. metadata +87 -22
  65. data/lib/guard/version.rbc +0 -180
@@ -31,16 +31,17 @@ module Guard
31
31
  # @param [Array] args the arguments for the listener
32
32
  # @return [Guard::Listener] the chosen listener
33
33
  #
34
- def self.select_and_init(*args)
35
- if mac? && Darwin.usable?
36
- Darwin.new(*args)
37
- elsif linux? && Linux.usable?
38
- Linux.new(*args)
39
- elsif windows? && Windows.usable?
40
- Windows.new(*args)
34
+ def self.select_and_init(watchdir = Dir.pwd, options = nil)
35
+ no_vendor = options && options.key?(:no_vendor) ? options[:no_vendor] : false
36
+ if mac? && Darwin.usable?(no_vendor)
37
+ Darwin.new(watchdir, options)
38
+ elsif linux? && Linux.usable?(no_vendor)
39
+ Linux.new(watchdir, options)
40
+ elsif windows? && Windows.usable?(no_vendor)
41
+ Windows.new(watchdir, options)
41
42
  else
42
43
  UI.info 'Using polling (Please help us to support your system better than that).'
43
- Polling.new(*args)
44
+ Polling.new(watchdir, options)
44
45
  end
45
46
  end
46
47
 
@@ -48,18 +49,23 @@ module Guard
48
49
  #
49
50
  # @param [String] directory the root directory to listen to
50
51
  # @option options [Boolean] relativize_paths use only relative paths
52
+ # @option options [Boolean] watch_all_modifications to enable deleted and moved file listening.
51
53
  # @option options [Array<String>] ignore_paths the paths to ignore by the listener
52
54
  #
53
55
  def initialize(directory = Dir.pwd, options = {})
54
- @directory = directory.to_s
55
56
  @sha1_checksums_hash = {}
56
57
  @file_timestamp_hash = {}
57
- @relativize_paths = options.fetch(:relativize_paths, true)
58
58
  @changed_files = []
59
59
  @paused = false
60
+
61
+ @directory = directory.to_s
62
+
63
+ options = options.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
64
+ @relativize_paths = options.fetch(:relativize_paths, true)
65
+ @watch_all_modifications = options.fetch(:watch_all_modifications, false)
66
+
60
67
  @ignore_paths = DEFAULT_IGNORE_PATHS
61
68
  @ignore_paths |= options[:ignore_paths] if options[:ignore_paths]
62
- @watch_all_modifications = options.fetch(:watch_all_modifications, false)
63
69
 
64
70
  update_last_event
65
71
  start_reactor
@@ -143,7 +149,7 @@ module Guard
143
149
  def modified_files(dirs, options = {})
144
150
  last_event = @last_event
145
151
  files = []
146
- if @watch_all_modifications
152
+ if watch_all_modifications?
147
153
  deleted_files = @file_timestamp_hash.collect do |path, ts|
148
154
  unless File.exists?(path)
149
155
  @sha1_checksums_hash.delete(path)
@@ -196,10 +202,19 @@ module Guard
196
202
  !!@relativize_paths
197
203
  end
198
204
 
205
+ # test if the listener should also watch for deleted and
206
+ # moved files
207
+ #
208
+ # @return [Boolean] whether to watch all file modifications or not
209
+ #
210
+ def watch_all_modifications?
211
+ !!@watch_all_modifications
212
+ end
213
+
199
214
  # Populate initial timestamp file hash to watch for deleted or moved files.
200
215
  #
201
216
  def timestamp_files
202
- all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if @watch_all_modifications
217
+ all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if watch_all_modifications?
203
218
  end
204
219
 
205
220
  # Removes the ignored paths from the directory list.
@@ -258,7 +273,7 @@ module Guard
258
273
  elsif mtime > last_event.to_i
259
274
  set_sha1_checksums_hash(path, sha1_checksum(path))
260
275
  true
261
- elsif @watch_all_modifications
276
+ elsif watch_all_modifications?
262
277
  ts = file_timestamp(path)
263
278
  if ts != @file_timestamp_hash[path]
264
279
  set_file_timestamp_hash(path, ts)
@@ -289,7 +304,7 @@ module Guard
289
304
  # Set save a files current timestamp
290
305
  #
291
306
  # @param [String] path the file path
292
- # @param [Int] file_timestamp the files modified timestamp
307
+ # @param [Integer] file_timestamp the files modified timestamp
293
308
  #
294
309
  def set_file_timestamp_hash(path, file_timestamp)
295
310
  @file_timestamp_hash[path] = file_timestamp
@@ -306,8 +321,8 @@ module Guard
306
321
 
307
322
  # Gets a files modified timestamp
308
323
  #
309
- # @path [String] path the file path
310
- # @return [Int] file modified timestamp
324
+ # @param [String] path the file path
325
+ # @return [Integer] file modified timestamp
311
326
  #
312
327
  def file_timestamp(path)
313
328
  File.mtime(path).to_i
@@ -29,17 +29,13 @@ module Guard
29
29
  #
30
30
  # @return [Boolean] whether usable or not
31
31
  #
32
- def self.usable?
32
+ def self.usable?(no_vendor = false)
33
+ return false unless RbConfig::CONFIG['target_os'] =~ /darwin/i
34
+
35
+ $LOAD_PATH << File.expand_path('../../../vendor/darwin/lib', __FILE__) unless no_vendor
33
36
  require 'rb-fsevent'
34
- if !defined?(FSEvent::VERSION) || (defined?(Gem::Version) &&
35
- Gem::Version.new(FSEvent::VERSION) < Gem::Version.new('0.4.0'))
36
- UI.info 'Please update rb-fsevent (>= 0.4.0)'
37
- false
38
- else
39
- true
40
- end
37
+ true
41
38
  rescue LoadError
42
- UI.info 'Please install rb-fsevent gem for Mac OSX FSEvents support'
43
39
  false
44
40
  end
45
41
 
@@ -32,17 +32,13 @@ module Guard
32
32
  #
33
33
  # @return [Boolean] whether usable or not
34
34
  #
35
- def self.usable?
35
+ def self.usable?(no_vendor = false)
36
+ return false unless RbConfig::CONFIG['target_os'] =~ /linux/i
37
+
38
+ $LOAD_PATH << File.expand_path('../../../vendor/linux/lib', __FILE__) unless no_vendor
36
39
  require 'rb-inotify'
37
- if !defined?(INotify::VERSION) || (defined?(Gem::Version) &&
38
- Gem::Version.new(INotify::VERSION.join('.')) < Gem::Version.new('0.8.5'))
39
- UI.info 'Please update rb-inotify (>= 0.8.5)'
40
- false
41
- else
42
- true
43
- end
40
+ true
44
41
  rescue LoadError
45
- UI.info 'Please install rb-inotify gem for Linux inotify support'
46
42
  false
47
43
  end
48
44
 
@@ -72,7 +68,7 @@ module Guard
72
68
  # @return [Boolean] whether inotify is active or not
73
69
  #
74
70
  def watch_change?
75
- !!@watch_change
71
+ !!(defined? @watch_change and @watch_change)
76
72
  end
77
73
 
78
74
  # Watch for file system changes.
@@ -29,11 +29,13 @@ module Guard
29
29
  #
30
30
  # @return [Boolean] whether usable or not
31
31
  #
32
- def self.usable?
32
+ def self.usable?(no_vendor = false)
33
+ return false unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
34
+
35
+ $LOAD_PATH << File.expand_path('../../../vendor/windows/lib', __FILE__) unless no_vendor
33
36
  require 'rb-fchange'
34
37
  true
35
38
  rescue LoadError
36
- UI.info 'Please install rb-fchange gem for Windows file events support'
37
39
  false
38
40
  end
39
41
 
@@ -1,290 +1,203 @@
1
1
  require 'rbconfig'
2
2
  require 'pathname'
3
3
  require 'guard/ui'
4
+ require 'guard/notifiers/gntp'
5
+ require 'guard/notifiers/growl'
6
+ require 'guard/notifiers/growl_notify'
7
+ require 'guard/notifiers/libnotify'
8
+ require 'guard/notifiers/rb_notifu'
4
9
 
5
10
  module Guard
6
11
 
7
- # The notifier class handles cross-platform system notifications that supports:
12
+ # The notifier handles sending messages to different notifiers. Currently the following
13
+ # libraries are supported:
8
14
  #
9
- # - Growl on Mac OS X
10
- # - Libnotify on Linux
11
- # - Notifu on Windows
15
+ # * Ruby GNTP
16
+ # * Growl
17
+ # * GrowlNotify
18
+ # * Libnotify
19
+ # * rb-notifu
20
+ #
21
+ # Please see the documentation of each notifier for more information about the requirements
22
+ # and configuration possibilities.
23
+ #
24
+ # Guard knows four different notification types:
25
+ #
26
+ # * success
27
+ # * pending
28
+ # * failed
29
+ # * notify
30
+ #
31
+ # The notification type selection is based on the image option that is
32
+ # sent to {#notify}. Each image type has its own notification type, and
33
+ # notifications with custom images goes all sent as type `notify`. The
34
+ # `gntp` and `growl_notify` notifiers are able to register these types
35
+ # at Growl and allows customization of each notification type.
36
+ #
37
+ # Guard can be configured to make use of more than one notifier at once, @see Guard::Dsl
12
38
  #
13
39
  module Notifier
40
+ extend self
41
+
42
+ # List of available notifiers.
43
+ NOTIFIERS = {
44
+ :gntp => ::Guard::Notifier::GNTP,
45
+ :growl => ::Guard::Notifier::Growl,
46
+ :growl_notify => ::Guard::Notifier::GrowlNotify,
47
+ :libnotify => ::Guard::Notifier::Libnotify,
48
+ :notifu => ::Guard::Notifier::Notifu
49
+ }
50
+
51
+ # Get the available notifications.
52
+ #
53
+ # @return [Hash] the notifications
54
+ #
55
+ def notifications
56
+ @notifications ||= []
57
+ end
14
58
 
15
- # Application name as shown in the specific notification settings
16
- APPLICATION_NAME = "Guard"
17
-
18
- class << self
19
-
20
- attr_accessor :growl_library, :gntp
21
-
22
- # Turn notifications off.
23
- #
24
- def turn_off
25
- ENV["GUARD_NOTIFY"] = 'false'
26
- end
27
-
28
- # Turn notifications on. This tries to load the platform
29
- # specific notification library.
30
- #
31
- # @return [Boolean] whether the notification could be enabled.
32
- #
33
- def turn_on
34
- ENV["GUARD_NOTIFY"] = 'true'
35
- case RbConfig::CONFIG['target_os']
36
- when /darwin/i
37
- require_growl
38
- when /linux/i
39
- require_libnotify
40
- when /mswin|mingw/i
41
- require_rbnotifu
42
- end
43
- end
44
-
45
- # Show a message with the system notification.
46
- #
47
- # @see .image_path
48
- #
49
- # @param [String] the message to show
50
- # @option options [Symbol, String] image the image symbol or path to an image
51
- # @option options [String] title the notification title
52
- #
53
- def notify(message, options = { })
54
- if enabled?
55
- image = options.delete(:image) || :success
56
- title = options.delete(:title) || "Guard"
57
-
58
- case RbConfig::CONFIG['target_os']
59
- when /darwin/i
60
- notify_mac(title, message, image, options)
61
- when /linux/i
62
- notify_linux(title, message, image, options)
63
- when /mswin|mingw/i
64
- notify_windows(title, message, image, options)
65
- end
66
- end
67
- end
68
-
69
- # Test if the notifications are enabled and available.
70
- #
71
- # @return [Boolean] whether the notifications are available
72
- #
73
- def enabled?
74
- ENV["GUARD_NOTIFY"] == 'true'
75
- end
76
-
77
- private
78
-
79
- # Send a message to Growl either with the `growl` gem or the `growl_notify` gem.
80
- #
81
- # @param [String] title the notification title
82
- # @param [String] message the message to show
83
- # @param [Symbol, String] the image to user
84
- # @param [Hash] options the growl options
85
- #
86
- def notify_mac(title, message, image, options = { })
87
- require_growl # need for guard-rspec formatter that is called out of guard scope
88
-
89
- notification = { :title => title, :icon => image_path(image) }.merge(options)
90
-
91
- case self.growl_library
92
- when :growl_notify
93
- notification.delete(:name)
94
-
95
- GrowlNotify.send_notification({
96
- :description => message,
97
- :application_name => APPLICATION_NAME
98
- }.merge(notification))
99
-
100
- when :ruby_gntp
101
- icon = "file://#{ notification.delete(:icon) }"
102
-
103
- self.gntp.notify({
104
- :name => [:pending, :success, :failed].include?(image) ? image.to_s : 'notify',
105
- :text => message,
106
- :icon => icon
107
- }.merge(notification))
59
+ # Set the available notifications.
60
+ #
61
+ # @param [Array<Hash>] notifications the notifications
62
+ #
63
+ def notifications=(notifications)
64
+ @notifications = notifications
65
+ end
108
66
 
109
- when :growl
110
- Growl.notify(message, {
111
- :name => APPLICATION_NAME
112
- }.merge(notification))
67
+ # Turn notifications on. If no notifications are defined
68
+ # in the `Guardfile` Guard auto detects the first available
69
+ # library.
70
+ #
71
+ def turn_on
72
+ auto_detect_notification if notifications.empty? && (!::Guard.options || ::Guard.options[:notify])
73
+
74
+ if notifications.empty?
75
+ ENV['GUARD_NOTIFY'] = 'false'
76
+ else
77
+ notifications.each do |notification|
78
+ ::Guard::UI.info "Guard uses #{ NOTIFIERS[notification[:name]].to_s.split('::').last } to send notifications."
113
79
  end
114
- end
115
-
116
- # Send a message to libnotify.
117
- #
118
- # @param [String] title the notification title
119
- # @param [String] message the message to show
120
- # @param [Symbol, String] the image to user
121
- # @param [Hash] options the libnotify options
122
- #
123
- def notify_linux(title, message, image, options = { })
124
- require_libnotify # need for guard-rspec formatter that is called out of guard scope
125
80
 
126
- notification = { :body => message, :summary => title, :icon_path => image_path(image), :transient => true }
127
- Libnotify.show notification.merge(options)
128
- end
129
-
130
- # Send a message to notifu.
131
- #
132
- # @param [String] title the notification title
133
- # @param [String] message the message to show
134
- # @param [Symbol, String] the image to user
135
- # @param [Hash] options the notifu options
136
- #
137
- def notify_windows(title, message, image, options = { })
138
- require_rbnotifu # need for guard-rspec formatter that is called out of guard scope
139
-
140
- notification = { :message => message, :title => title, :type => image_level(image), :time => 3 }
141
- Notifu.show notification.merge(options)
142
- end
143
-
144
- # Get the image path for an image symbol.
145
- #
146
- # Known symbols are:
147
- #
148
- # - failed
149
- # - pending
150
- # - success
151
- #
152
- # @param [Symbol] image the image name
153
- # @return [String] the image path
154
- #
155
- def image_path(image)
156
- images_path = Pathname.new(File.dirname(__FILE__)).join('../../images')
157
- case image
158
- when :failed
159
- images_path.join("failed.png").to_s
160
- when :pending
161
- images_path.join("pending.png").to_s
162
- when :success
163
- images_path.join("success.png").to_s
164
- else
165
- # path given
166
- image
167
- end
81
+ ENV['GUARD_NOTIFY'] = 'true'
168
82
  end
83
+ end
169
84
 
170
- # The notification level type for the given image.
171
- #
172
- # @param [Symbol] image the image
173
- # @return [Symbol] the level
174
- #
175
- def image_level(image)
176
- case image
177
- when :failed
178
- :error
179
- when :pending
180
- :warn
181
- when :success
182
- :info
183
- else
184
- :info
185
- end
186
- end
85
+ # Turn notifications off.
86
+ #
87
+ def turn_off
88
+ ENV['GUARD_NOTIFY'] = 'false'
89
+ end
187
90
 
188
- # Try to safely load growl and turns notifications off on load failure.
189
- # The Guard notifier knows three different library to handle sending
190
- # Growl messages and tries to loading them in the given order:
191
- #
192
- # - [Growl Notify](https://github.com/scottdavis/growl_notify)
193
- # - [Ruby GNTP](https://github.com/snaka/ruby_gntp)
194
- # - [Growl](https://github.com/visionmedia/growl)
195
- #
196
- # On successful loading of any of the libraries, the active library name is
197
- # accessible through `.growl_library`.
198
- #
199
- def require_growl
200
- self.growl_library = try_growl_notify || try_ruby_gntp || try_growl
91
+ # Test if the notifications are on.
92
+ #
93
+ # @return [Boolean] whether the notifications are on
94
+ #
95
+ def enabled?
96
+ ENV['GUARD_NOTIFY'] == 'true'
97
+ end
201
98
 
202
- unless self.growl_library
203
- turn_off
204
- UI.info "Please install growl_notify or growl gem for Mac OS X notification support and add it to your Gemfile"
205
- end
99
+ # Add a notification library to be used.
100
+ #
101
+ # @param [Symbol] name the name of the notifier to use
102
+ # @param [Boolean] silent disable any error message
103
+ # @param [Hash] options the notifier options
104
+ # @return [Boolean] if the notification could be added
105
+ #
106
+ def add_notification(name, options = { }, silent = false)
107
+ return turn_off if name == :off
108
+
109
+ if NOTIFIERS.has_key?(name) && NOTIFIERS[name].available?(silent)
110
+ notifications << { :name => name, :options => options }
111
+ true
112
+ else
113
+ false
206
114
  end
115
+ end
207
116
 
208
- # Try to load the `growl_notify` gem.
209
- #
210
- # @return [Symbol, nil] A symbol with the name of the loaded library
211
- #
212
- def try_growl_notify
213
- require 'growl_notify'
214
-
215
- begin
216
- if GrowlNotify.application_name != APPLICATION_NAME
217
- GrowlNotify.config do |c|
218
- c.notifications = c.default_notifications = [APPLICATION_NAME]
219
- c.application_name = c.notifications.first
220
- end
117
+ # Show a system notification with all configured notifiers.
118
+ #
119
+ # @param [String] message the message to show
120
+ # @option options [Symbol, String] image the image symbol or path to an image
121
+ # @option options [String] title the notification title
122
+ #
123
+ def notify(message, options = { })
124
+ if enabled?
125
+ type = notification_type(options[:image] || :success)
126
+ image = image_path(options.delete(:image) || :success)
127
+ title = options.delete(:title) || 'Guard'
128
+
129
+ notifications.each do |notification|
130
+ begin
131
+ NOTIFIERS[notification[:name]].notify(type, title, message, image, options.merge(notification[:options]))
132
+ rescue Exception => e
133
+ ::Guard::UI.error "Error sending notification with #{ notification[:name] }: #{ e.message }"
221
134
  end
222
-
223
- rescue ::GrowlNotify::GrowlNotFound
224
- turn_off
225
- UI.info "Please install Growl from http://growl.info"
226
135
  end
227
-
228
- :growl_notify
229
-
230
- rescue LoadError
231
- end
232
-
233
- # Try to load the `ruby_gntp` gem and register the available
234
- # notification channels.
235
- #
236
- # @return [Symbol, nil] A symbol with the name of the loaded library
237
- #
238
- def try_ruby_gntp
239
- require 'ruby_gntp'
240
-
241
- self.gntp = GNTP.new(APPLICATION_NAME)
242
- self.gntp.register(:notifications => [
243
- { :name => 'notify', :enabled => true },
244
- { :name => 'failed', :enabled => true },
245
- { :name => 'pending', :enabled => true },
246
- { :name => 'success', :enabled => true }
247
- ])
248
-
249
- :ruby_gntp
250
-
251
- rescue LoadError
252
136
  end
137
+ end
253
138
 
254
- # Try to load the `growl_notify` gem.
255
- #
256
- # @return [Symbol, nil] A symbol with the name of the loaded library
257
- #
258
- def try_growl
259
- require 'growl'
260
-
261
- :growl
262
-
263
- rescue LoadError
264
- end
139
+ private
265
140
 
266
- # Try to safely load libnotify and turns notifications
267
- # off on load failure.
268
- #
269
- def require_libnotify
270
- require 'libnotify'
141
+ # Auto detect the available notification library. This goes through
142
+ # the list of supported notification gems and picks the first that
143
+ # is available.
144
+ #
145
+ def auto_detect_notification
146
+ available = [:growl_notify, :gntp, :growl, :libnotify, :notifu].any? { |notifier| add_notification(notifier, { }, true) }
147
+ ::Guard::UI.info('Guard could not detect any of the supported notification libraries.') unless available
148
+ end
271
149
 
272
- rescue LoadError
273
- turn_off
274
- UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile"
150
+ # Get the image path for an image symbol for the following
151
+ # known image types:
152
+ #
153
+ # - failed
154
+ # - pending
155
+ # - success
156
+ #
157
+ # If the image is not a known symbol, it will be returned unmodified.
158
+ #
159
+ # @param [Symbol, String] image the image symbol or path to an image
160
+ # @return [String] the image path
161
+ #
162
+ def image_path(image)
163
+ case image
164
+ when :failed
165
+ images_path.join('failed.png').to_s
166
+ when :pending
167
+ images_path.join('pending.png').to_s
168
+ when :success
169
+ images_path.join('success.png').to_s
170
+ else
171
+ image
275
172
  end
173
+ end
276
174
 
277
- # Try to safely load rb-notifu and turns notifications
278
- # off on load failure.
279
- #
280
- def require_rbnotifu
281
- require 'rb-notifu'
175
+ # Paths where all Guard images are located
176
+ #
177
+ # @return [Pathname] the path to the images directory
178
+ #
179
+ def images_path
180
+ @images_path ||= Pathname.new(File.dirname(__FILE__)).join('../../images')
181
+ end
282
182
 
283
- rescue LoadError
284
- turn_off
285
- UI.info "Please install rb-notifu gem for Windows notification support and add it to your Gemfile"
183
+ # Get the notification type depending on the
184
+ # image that has been selected for the notification.
185
+ #
186
+ # @param [Symbol, String] image the image symbol or path to an image
187
+ # @return [String] the notification type
188
+ #
189
+ def notification_type(image)
190
+ case image
191
+ when :failed
192
+ 'failed'
193
+ when :pending
194
+ 'pending'
195
+ when :success
196
+ 'success'
197
+ else
198
+ 'notify'
286
199
  end
287
-
288
200
  end
289
201
  end
202
+
290
203
  end