joshbuddy-guard 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/CHANGELOG.md +370 -0
  2. data/LICENSE +20 -0
  3. data/README.md +470 -0
  4. data/bin/fsevent_watch_guard +0 -0
  5. data/bin/guard +6 -0
  6. data/images/failed.png +0 -0
  7. data/images/pending.png +0 -0
  8. data/images/success.png +0 -0
  9. data/lib/guard.rb +463 -0
  10. data/lib/guard/cli.rb +125 -0
  11. data/lib/guard/dsl.rb +370 -0
  12. data/lib/guard/dsl_describer.rb +150 -0
  13. data/lib/guard/group.rb +37 -0
  14. data/lib/guard/guard.rb +129 -0
  15. data/lib/guard/hook.rb +118 -0
  16. data/lib/guard/interactor.rb +116 -0
  17. data/lib/guard/listener.rb +351 -0
  18. data/lib/guard/listeners/darwin.rb +60 -0
  19. data/lib/guard/listeners/linux.rb +91 -0
  20. data/lib/guard/listeners/polling.rb +55 -0
  21. data/lib/guard/listeners/windows.rb +61 -0
  22. data/lib/guard/notifier.rb +290 -0
  23. data/lib/guard/templates/Guardfile +2 -0
  24. data/lib/guard/ui.rb +193 -0
  25. data/lib/guard/version.rb +6 -0
  26. data/lib/guard/watcher.rb +114 -0
  27. data/lib/vendor/darwin/Gemfile +6 -0
  28. data/lib/vendor/darwin/Guardfile +8 -0
  29. data/lib/vendor/darwin/LICENSE +20 -0
  30. data/lib/vendor/darwin/README.rdoc +254 -0
  31. data/lib/vendor/darwin/Rakefile +21 -0
  32. data/lib/vendor/darwin/ext/extconf.rb +61 -0
  33. data/lib/vendor/darwin/ext/fsevent/fsevent_watch.c +226 -0
  34. data/lib/vendor/darwin/lib/rb-fsevent.rb +2 -0
  35. data/lib/vendor/darwin/lib/rb-fsevent/fsevent.rb +105 -0
  36. data/lib/vendor/darwin/lib/rb-fsevent/version.rb +3 -0
  37. data/lib/vendor/darwin/rb-fsevent.gemspec +24 -0
  38. data/lib/vendor/darwin/spec/fixtures/folder1/file1.txt +0 -0
  39. data/lib/vendor/darwin/spec/fixtures/folder1/folder2/file2.txt +0 -0
  40. data/lib/vendor/darwin/spec/rb-fsevent/fsevent_spec.rb +75 -0
  41. data/lib/vendor/darwin/spec/spec_helper.rb +24 -0
  42. data/lib/vendor/linux/MIT-LICENSE +20 -0
  43. data/lib/vendor/linux/README.md +66 -0
  44. data/lib/vendor/linux/Rakefile +54 -0
  45. data/lib/vendor/linux/VERSION +1 -0
  46. data/lib/vendor/linux/lib/rb-inotify.rb +17 -0
  47. data/lib/vendor/linux/lib/rb-inotify/event.rb +139 -0
  48. data/lib/vendor/linux/lib/rb-inotify/native.rb +31 -0
  49. data/lib/vendor/linux/lib/rb-inotify/native/flags.rb +89 -0
  50. data/lib/vendor/linux/lib/rb-inotify/notifier.rb +308 -0
  51. data/lib/vendor/linux/lib/rb-inotify/watcher.rb +83 -0
  52. data/lib/vendor/linux/rb-inotify.gemspec +53 -0
  53. data/lib/vendor/windows/Gemfile +4 -0
  54. data/lib/vendor/windows/README.md +34 -0
  55. data/lib/vendor/windows/Rakefile +18 -0
  56. data/lib/vendor/windows/lib/rb-fchange.rb +14 -0
  57. data/lib/vendor/windows/lib/rb-fchange/event.rb +29 -0
  58. data/lib/vendor/windows/lib/rb-fchange/native.rb +45 -0
  59. data/lib/vendor/windows/lib/rb-fchange/native/flags.rb +78 -0
  60. data/lib/vendor/windows/lib/rb-fchange/notifier.rb +149 -0
  61. data/lib/vendor/windows/lib/rb-fchange/version.rb +3 -0
  62. data/lib/vendor/windows/lib/rb-fchange/watcher.rb +99 -0
  63. data/lib/vendor/windows/rb-fchange.gemspec +34 -0
  64. data/lib/vendor/windows/spec/fixtures/folder1/file1.txt +0 -0
  65. data/lib/vendor/windows/spec/fixtures/folder1/folder2/file2.txt +0 -0
  66. data/lib/vendor/windows/spec/rb-fchange/fchange_spec.rb +119 -0
  67. data/lib/vendor/windows/spec/spec_helper.rb +21 -0
  68. data/man/guard.1 +96 -0
  69. data/man/guard.1.html +181 -0
  70. metadata +193 -0
@@ -0,0 +1,55 @@
1
+ module Guard
2
+
3
+ # Polling listener that works cross-platform and
4
+ # has no dependencies. This is the listener that
5
+ # uses the most CPU processing power and has higher
6
+ # file IO that the other implementations.
7
+ #
8
+ class Polling < Listener
9
+
10
+ # Initialize the Listener.
11
+ #
12
+ def initialize(*)
13
+ super
14
+ @latency = 1.5
15
+ end
16
+
17
+ # Start the listener.
18
+ #
19
+ def start
20
+ @stop = false
21
+ super
22
+ watch_change
23
+ end
24
+
25
+ # Stop the listener.
26
+ #
27
+ def stop
28
+ super
29
+ @stop = true
30
+ end
31
+
32
+ # Watch the given directory for file changes.
33
+ #
34
+ # @param [String] directory the directory to watch
35
+ #
36
+ def watch(directory)
37
+ @existing = all_files
38
+ end
39
+
40
+ private
41
+
42
+ # Watch for file system changes.
43
+ #
44
+ def watch_change
45
+ until @stop
46
+ start = Time.now.to_f
47
+ files = modified_files([@directory], :all => true)
48
+ @callback.call(files) unless files.empty?
49
+ nap_time = @latency - (Time.now.to_f - start)
50
+ sleep(nap_time) if nap_time > 0
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,61 @@
1
+ module Guard
2
+
3
+ # Listener implementation for Windows `fchange`.
4
+ #
5
+ class Windows < Listener
6
+
7
+ # Initialize the Listener.
8
+ #
9
+ def initialize(*)
10
+ super
11
+ @fchange = FChange::Notifier.new
12
+ end
13
+
14
+ # Start the listener.
15
+ #
16
+ def start
17
+ super
18
+ worker.run
19
+ end
20
+
21
+ # Stop the listener.
22
+ #
23
+ def stop
24
+ super
25
+ worker.stop
26
+ end
27
+
28
+ # Check if the listener is usable on the current OS.
29
+ #
30
+ # @return [Boolean] whether usable or not
31
+ #
32
+ def self.usable?(no_vendor = false)
33
+ $LOAD_PATH << File.expand_path('../../../vendor/windows/lib', __FILE__) unless no_vendor
34
+ require 'rb-fchange'
35
+ true
36
+ rescue LoadError
37
+ false
38
+ end
39
+
40
+ private
41
+
42
+ # Watch the given directory for file changes.
43
+ #
44
+ # @param [String] directory the directory to watch
45
+ #
46
+ def watch(directory)
47
+ worker.watch(directory, :all_events, :recursive) do |event|
48
+ paths = [File.expand_path(event.watcher.path)]
49
+ files = modified_files(paths, :all => true)
50
+ @callback.call(files) unless files.empty?
51
+ end
52
+ end
53
+
54
+ # Get the listener worker.
55
+ #
56
+ def worker
57
+ @fchange
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,290 @@
1
+ require 'rbconfig'
2
+ require 'pathname'
3
+ require 'guard/ui'
4
+
5
+ module Guard
6
+
7
+ # The notifier class handles cross-platform system notifications that supports:
8
+ #
9
+ # - Growl on Mac OS X
10
+ # - Libnotify on Linux
11
+ # - Notifu on Windows
12
+ #
13
+ module Notifier
14
+
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))
108
+
109
+ when :growl
110
+ Growl.notify(message, {
111
+ :name => APPLICATION_NAME
112
+ }.merge(notification))
113
+ 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
+
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
168
+ end
169
+
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
187
+
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
201
+
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
206
+ end
207
+
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
221
+ end
222
+
223
+ rescue ::GrowlNotify::GrowlNotFound
224
+ turn_off
225
+ UI.info "Please install Growl from http://growl.info"
226
+ 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
+ end
253
+
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
265
+
266
+ # Try to safely load libnotify and turns notifications
267
+ # off on load failure.
268
+ #
269
+ def require_libnotify
270
+ require 'libnotify'
271
+
272
+ rescue LoadError
273
+ turn_off
274
+ UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile"
275
+ end
276
+
277
+ # Try to safely load rb-notifu and turns notifications
278
+ # off on load failure.
279
+ #
280
+ def require_rbnotifu
281
+ require 'rb-notifu'
282
+
283
+ rescue LoadError
284
+ turn_off
285
+ UI.info "Please install rb-notifu gem for Windows notification support and add it to your Gemfile"
286
+ end
287
+
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,2 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
@@ -0,0 +1,193 @@
1
+ module Guard
2
+
3
+ # The UI class helps to format messages for the user. Everything that is logged
4
+ # through this class is considered either as an error message or a diagnostic
5
+ # message and is written to standard error (STDERR).
6
+ #
7
+ # If your Guard does some output that is piped into another process for further
8
+ # processing, please just write it to STDOUT with `puts`.
9
+ #
10
+ module UI
11
+ class << self
12
+
13
+ color_enabled = nil
14
+
15
+ # Show an info message.
16
+ #
17
+ # @param [String] message the message to show
18
+ # @option options [Boolean] reset whether to clean the output before
19
+ #
20
+ def info(message, options = { })
21
+ unless ENV['GUARD_ENV'] == 'test'
22
+ reset_line if options[:reset]
23
+ STDERR.puts color(message) if message != ''
24
+ end
25
+ end
26
+
27
+ # Show a red error message that is prefixed with ERROR.
28
+ #
29
+ # @param [String] message the message to show
30
+ # @option options [Boolean] reset whether to clean the output before
31
+ #
32
+ def error(message, options = { })
33
+ unless ENV['GUARD_ENV'] == 'test'
34
+ reset_line if options[:reset]
35
+ STDERR.puts color('ERROR: ', :red) + message
36
+ end
37
+ end
38
+
39
+ # Show a red deprecation message that is prefixed with DEPRECATION.
40
+ #
41
+ # @param [String] message the message to show
42
+ # @option options [Boolean] reset whether to clean the output before
43
+ #
44
+ def deprecation(message, options = { })
45
+ unless ENV['GUARD_ENV'] == 'test'
46
+ reset_line if options[:reset]
47
+ STDERR.puts color('DEPRECATION: ', :red) + message
48
+ end
49
+ end
50
+
51
+ # Show a debug message that is prefixed with DEBUG and a timestamp.
52
+ #
53
+ # @param [String] message the message to show
54
+ # @option options [Boolean] reset whether to clean the output before
55
+ #
56
+ def debug(message, options = { })
57
+ unless ENV['GUARD_ENV'] == 'test'
58
+ reset_line if options[:reset]
59
+ STDERR.puts color("DEBUG (#{Time.now.strftime('%T')}): ", :yellow) + message if ::Guard.options && ::Guard.options[:debug]
60
+ end
61
+ end
62
+
63
+ # Reset a line.
64
+ #
65
+ def reset_line
66
+ STDERR.print(color_enabled? ? "\r\e[0m" : "\r\n")
67
+ end
68
+
69
+ # Clear the output.
70
+ #
71
+ def clear
72
+ system('clear;')
73
+ end
74
+
75
+ private
76
+
77
+ # Reset a color sequence.
78
+ #
79
+ # @deprecated
80
+ # @param [String] text the text
81
+ #
82
+ def reset_color(text)
83
+ deprecation('UI.reset_color(text) is deprecated, please use color(text, ' ') instead.')
84
+ color(text, '')
85
+ end
86
+
87
+ # Checks if color output can be enabled.
88
+ #
89
+ # @return [Boolean] whether color is enabled or not
90
+ #
91
+ def color_enabled?
92
+ if @color_enabled.nil?
93
+ if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
94
+ if ENV['ANSICON']
95
+ @color_enabled = true
96
+ else
97
+ begin
98
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
99
+ require 'Win32/Console/ANSI'
100
+ @color_enabled = true
101
+ rescue LoadError
102
+ @color_enabled = false
103
+ info "You must 'gem install win32console' to use color on Windows"
104
+ end
105
+ end
106
+ else
107
+ @color_enabled = true
108
+ end
109
+ end
110
+
111
+ @color_enabled
112
+ end
113
+
114
+ # Colorizes a text message. See the constant in the UI class for possible
115
+ # color_options parameters. You can pass optionally :bright, a foreground
116
+ # color and a background color.
117
+ #
118
+ # @example
119
+ #
120
+ # color('Hello World', :red, :bright)
121
+ #
122
+ # @param [String] the text to colorize
123
+ # @param [Array] color_options the color options
124
+ #
125
+ def color(text, *color_options)
126
+ color_code = ''
127
+ color_options.each do |color_option|
128
+ color_option = color_option.to_s
129
+ if color_option != ''
130
+ if !(color_option =~ /\d+/)
131
+ color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
132
+ end
133
+ color_code += ';' + color_option
134
+ end
135
+ end
136
+ color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
137
+ end
138
+
139
+ end
140
+
141
+ # Brighten the color
142
+ ANSI_ESCAPE_BRIGHT = '1'
143
+
144
+ # Black foreground color
145
+ ANSI_ESCAPE_BLACK = '30'
146
+
147
+ # Red foreground color
148
+ ANSI_ESCAPE_RED = '31'
149
+
150
+ # Green foreground color
151
+ ANSI_ESCAPE_GREEN = '32'
152
+
153
+ # Yellow foreground color
154
+ ANSI_ESCAPE_YELLOW = '33'
155
+
156
+ # Blue foreground color
157
+ ANSI_ESCAPE_BLUE = '34'
158
+
159
+ # Magenta foreground color
160
+ ANSI_ESCAPE_MAGENTA = '35'
161
+
162
+ # Cyan foreground color
163
+ ANSI_ESCAPE_CYAN = '36'
164
+
165
+ # White foreground color
166
+ ANSI_ESCAPE_WHITE = '37'
167
+
168
+ # Black background color
169
+ ANSI_ESCAPE_BGBLACK = '40'
170
+
171
+ # Red background color
172
+ ANSI_ESCAPE_BGRED = '41'
173
+
174
+ # Green background color
175
+ ANSI_ESCAPE_BGGREEN = '42'
176
+
177
+ # Yellow background color
178
+ ANSI_ESCAPE_BGYELLOW = '43'
179
+
180
+ # Blue background color
181
+ ANSI_ESCAPE_BGBLUE = '44'
182
+
183
+ # Magenta background color
184
+ ANSI_ESCAPE_BGMAGENTA = '45'
185
+
186
+ # Cyan background color
187
+ ANSI_ESCAPE_BGCYAN = '46'
188
+
189
+ # White background color
190
+ ANSI_ESCAPE_BGWHITE = '47'
191
+
192
+ end
193
+ end