guard 0.8.8 → 0.9.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 (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