guard 1.8.3 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -10
  3. data/README.md +54 -33
  4. data/lib/guard.rb +133 -483
  5. data/lib/guard/cli.rb +78 -82
  6. data/lib/guard/commander.rb +121 -0
  7. data/lib/guard/commands/all.rb +1 -1
  8. data/lib/guard/commands/reload.rb +1 -1
  9. data/lib/guard/deprecated_methods.rb +59 -0
  10. data/lib/guard/deprecator.rb +107 -0
  11. data/lib/guard/dsl.rb +143 -329
  12. data/lib/guard/dsl_describer.rb +101 -57
  13. data/lib/guard/group.rb +27 -8
  14. data/lib/guard/guard.rb +25 -150
  15. data/lib/guard/guardfile.rb +35 -85
  16. data/lib/guard/guardfile/evaluator.rb +245 -0
  17. data/lib/guard/guardfile/generator.rb +89 -0
  18. data/lib/guard/interactor.rb +147 -163
  19. data/lib/guard/notifier.rb +83 -137
  20. data/lib/guard/notifiers/base.rb +220 -0
  21. data/lib/guard/notifiers/emacs.rb +39 -37
  22. data/lib/guard/notifiers/file_notifier.rb +29 -25
  23. data/lib/guard/notifiers/gntp.rb +68 -75
  24. data/lib/guard/notifiers/growl.rb +49 -52
  25. data/lib/guard/notifiers/growl_notify.rb +51 -56
  26. data/lib/guard/notifiers/libnotify.rb +41 -48
  27. data/lib/guard/notifiers/notifysend.rb +58 -38
  28. data/lib/guard/notifiers/rb_notifu.rb +54 -54
  29. data/lib/guard/notifiers/terminal_notifier.rb +48 -36
  30. data/lib/guard/notifiers/terminal_title.rb +23 -19
  31. data/lib/guard/notifiers/tmux.rb +110 -93
  32. data/lib/guard/options.rb +21 -0
  33. data/lib/guard/plugin.rb +66 -0
  34. data/lib/guard/plugin/base.rb +178 -0
  35. data/lib/guard/plugin/hooker.rb +123 -0
  36. data/lib/guard/plugin_util.rb +158 -0
  37. data/lib/guard/rake_task.rb +47 -0
  38. data/lib/guard/runner.rb +62 -82
  39. data/lib/guard/setuper.rb +248 -0
  40. data/lib/guard/ui.rb +24 -80
  41. data/lib/guard/ui/colors.rb +60 -0
  42. data/lib/guard/version.rb +1 -2
  43. data/lib/guard/watcher.rb +30 -30
  44. data/man/guard.1 +4 -4
  45. data/man/guard.1.html +6 -4
  46. metadata +25 -11
  47. data/lib/guard/hook.rb +0 -120
@@ -1,4 +1,4 @@
1
- require 'rbconfig'
1
+ require 'guard/notifiers/base'
2
2
 
3
3
  module Guard
4
4
  module Notifier
@@ -8,57 +8,57 @@ module Guard
8
8
  # @example Add the `:emacs` notifier to your `Guardfile`
9
9
  # notification :emacs
10
10
  #
11
- module Emacs
12
- extend self
11
+ class Emacs < Base
13
12
 
14
13
  DEFAULTS = {
15
- :client => 'emacsclient',
16
- :success => 'ForestGreen',
17
- :failed => 'Firebrick',
18
- :default => 'Black',
19
- :fontcolor => 'White',
14
+ client: 'emacsclient',
15
+ success: 'ForestGreen',
16
+ failed: 'Firebrick',
17
+ default: 'Black',
18
+ fontcolor: 'White',
20
19
  }
21
20
 
22
- # Test if Emacs with running server is available.
23
- #
24
- # @param [Boolean] silent true if no error messages should be shown
25
- # @param [Hash] options notifier options
26
- # @return [Boolean] the availability status
27
- #
28
- def available?(silent = false, options = {})
29
- result = `#{ options.fetch(:client, DEFAULTS[:client]) } --eval '1' 2> #{DEV_NULL} || echo 'N/A'`
21
+ def self.available?(opts = {})
22
+ super
23
+ result = `#{ opts.fetch(:client, DEFAULTS[:client]) } --eval '1' 2> #{DEV_NULL} || echo 'N/A'`
30
24
 
31
- if %w(N/A 'N/A').include?(result.chomp!)
32
- false
33
- else
34
- true
35
- end
25
+ !%w(N/A 'N/A').include?(result.chomp!)
36
26
  end
37
27
 
38
- # Show a system notification.
28
+ # Shows a system notification.
39
29
  #
40
- # @param [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
30
+ # @param [String] type the notification type. Either 'success',
31
+ # 'pending', 'failed' or 'notify'
41
32
  # @param [String] title the notification title
42
33
  # @param [String] message the notification message body
43
34
  # @param [String] image the path to the notification image
44
- # @param [Hash] options additional notification library options
45
- # @option options [String] success the color to use for success notifications (default is 'ForestGreen')
46
- # @option options [String] failed the color to use for failure notifications (default is 'Firebrick')
47
- # @option options [String] pending the color to use for pending notifications
48
- # @option options [String] default the default color to use (default is 'Black')
49
- # @option options [String] client the client to use for notification (default is 'emacsclient')
50
- # @option options [String, Integer] priority specify an int or named key (default is 0)
35
+ # @param [Hash] opts additional notification library options
36
+ # @option opts [String] success the color to use for success
37
+ # notifications (default is 'ForestGreen')
38
+ # @option opts [String] failed the color to use for failure
39
+ # notifications (default is 'Firebrick')
40
+ # @option opts [String] pending the color to use for pending
41
+ # notifications
42
+ # @option opts [String] default the default color to use (default is
43
+ # 'Black')
44
+ # @option opts [String] client the client to use for notification
45
+ # (default is 'emacsclient')
46
+ # @option opts [String, Integer] priority specify an int or named key
47
+ # (default is 0)
51
48
  #
52
- def notify(type, title, message, image, options = { })
53
- options = DEFAULTS.merge options
54
- color = emacs_color type, options
55
- fontcolor = emacs_color :fontcolor, options
49
+ def notify(message, opts = {})
50
+ normalize_standard_options!(opts)
51
+
52
+ opts = DEFAULTS.merge(opts)
53
+ color = emacs_color(opts[:type], opts)
54
+ fontcolor = emacs_color(:fontcolor, opts)
56
55
  elisp = <<-EOF.gsub(/\s+/, ' ').strip
57
56
  (set-face-attribute 'mode-line nil
58
57
  :background "#{color}"
59
58
  :foreground "#{fontcolor}")
60
59
  EOF
61
- run_cmd [ options[:client], '--eval', elisp ]
60
+
61
+ _run_cmd(opts[:client], '--eval', elisp)
62
62
  end
63
63
 
64
64
  # Get the Emacs color for the notification type.
@@ -73,15 +73,17 @@ module Guard
73
73
  # @return [String] the name of the emacs color
74
74
  #
75
75
  def emacs_color(type, options = {})
76
- default = options[:default] || DEFAULTS[:default]
76
+ default = options.fetch(:default, DEFAULTS[:default])
77
77
  options.fetch(type.to_sym, default)
78
78
  end
79
79
 
80
80
  private
81
81
 
82
- def run_cmd(args)
82
+ def _run_cmd(*args)
83
83
  IO.popen(args).readlines
84
84
  end
85
+
85
86
  end
87
+
86
88
  end
87
89
  end
@@ -1,54 +1,58 @@
1
+ require 'guard/notifiers/base'
2
+
1
3
  module Guard
2
4
  module Notifier
3
5
 
4
- # Writes guard notification results to a file
6
+ # Writes Guard notification results to a file.
5
7
  #
6
8
  # @example Add the `:file` notifier to your `Guardfile`
7
9
  # notification :file, path: 'tmp/guard_result'
8
10
  #
9
- module FileNotifier
10
- extend self
11
+ class FileNotifier < Base
11
12
 
12
- # Default options for FileNotifier
13
13
  DEFAULTS = {
14
- :format => "%s\n%s\n%s\n"
14
+ format: "%s\n%s\n%s\n"
15
15
  }
16
16
 
17
- # Test if the file notification option is available?
18
- #
19
- # @param [Boolean] silent true if no error messages should be shown
20
- # @param [Hash] options notifier options
21
- # @return [Boolean] the availability status
17
+ # @param [Hash] opts some options
18
+ # @option opts [Boolean] path the path to a file where Guard notification
19
+ # results will be written
22
20
  #
23
- def available?(silent = false, options = {})
24
- options.has_key?(:path)
21
+ def self.available?(opts = {})
22
+ super
23
+ opts.has_key?(:path)
25
24
  end
26
25
 
27
- # Write the notification to a file. By default it writes type, title, and
28
- # message separated by newlines.
26
+ # Writes the notification to a file. By default it writes type, title,
27
+ # and message separated by newlines.
29
28
  #
30
- # @param [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
31
- # @param [String] title the notification title
32
29
  # @param [String] message the notification message body
33
- # @param [String] image the path to the notification image
34
- # @param [Hash] options additional notification library options
35
- # @option options [String] format printf style format for file contents
36
- # @option options [String] path the path of where to write the file
30
+ # @param [Hash] opts additional notification library options
31
+ # @option opts [String] type the notification type. Either 'success',
32
+ # 'pending', 'failed' or 'notify'
33
+ # @option opts [String] title the notification title
34
+ # @option opts [String] image the path to the notification image
35
+ # @option opts [String] format printf style format for file contents
36
+ # @option opts [String] path the path of where to write the file
37
37
  #
38
- def notify(type, title, message, image, options = { })
39
- if options[:path]
40
- format = options.fetch(:format, DEFAULTS[:format])
38
+ def notify(message, opts = {})
39
+ normalize_standard_options!(opts)
40
+
41
+ if opts[:path]
42
+ format = opts.fetch(:format, DEFAULTS[:format])
41
43
 
42
- write(options[:path], format % [type, title, message])
44
+ _write(opts[:path], format % [opts[:type], opts[:title], message])
43
45
  else
44
46
  ::Guard::UI.error ':file notifier requires a :path option'
45
47
  end
46
48
  end
47
49
 
48
50
  private
49
- def write(path, contents)
51
+
52
+ def _write(path, contents)
50
53
  File.write(path, contents)
51
54
  end
55
+
52
56
  end
53
57
 
54
58
  end
@@ -1,19 +1,19 @@
1
- require 'rbconfig'
2
- require 'guard/ui'
1
+ require 'guard/notifiers/base'
3
2
 
4
3
  module Guard
5
4
  module Notifier
6
5
 
7
- # System notifications using the [ruby_gntp](https://github.com/snaka/ruby_gntp) gem.
6
+ # System notifications using the
7
+ # [ruby_gntp](https://github.com/snaka/ruby_gntp) gem.
8
8
  #
9
- # This gem is available for OS X, Linux and Windows and sends system notifications to
10
- # the following system notification frameworks through the
9
+ # This gem is available for OS X, Linux and Windows and sends system
10
+ # notifications to the following system notification frameworks through the
11
11
  # [Growl Network Transport Protocol](http://www.growlforwindows.com/gfw/help/gntp.aspx):
12
12
  #
13
13
  # * [Growl](http://growl.info)
14
14
  # * [Growl for Windows](http://www.growlforwindows.com)
15
15
  # * [Growl for Linux](http://mattn.github.com/growl-for-linux)
16
- # * [Snarl](https://sites.google.com/site/snarlapp/)
16
+ # * [Snarl](https://sites.google.com/site/snarlapp)
17
17
  #
18
18
  # @example Add the `ruby_gntp` gem to your `Gemfile`
19
19
  # group :development
@@ -24,96 +24,89 @@ module Guard
24
24
  # notification :gntp
25
25
  #
26
26
  # @example Add the `:gntp` notifier with configuration options to your `Guardfile`
27
- # notification :gntp, :sticky => true, :host => '192.168.1.5', :password => 'secret'
27
+ # notification :gntp, sticky: true, host: '192.168.1.5', password: 'secret'
28
28
  #
29
- module GNTP
30
- extend self
29
+ class GNTP < Base
31
30
 
32
- # Default options for the ruby gtnp gem
31
+ # Default options for the ruby gtnp notifications.
33
32
  DEFAULTS = {
34
- :sticky => false,
35
- :host => '127.0.0.1',
36
- :password => '',
37
- :port => 23053
33
+ sticky: false
38
34
  }
39
35
 
40
- # Is this notifier already registered
41
- #
42
- # @return [Boolean] registration status
43
- #
44
- def registered?
45
- @registered ||= false
46
- end
36
+ # Default options for the ruby gtnp client.
37
+ CLIENT_DEFAULTS = {
38
+ host: '127.0.0.1',
39
+ password: '',
40
+ port: 23053
41
+ }
47
42
 
48
- # Mark the notifier as registered.
49
- #
50
- def registered!
51
- @registered = true
43
+ def self.supported_hosts
44
+ %w[darwin linux freebsd openbsd sunos solaris mswin mingw cygwin]
52
45
  end
53
46
 
54
- # Test if the notification library is available.
55
- #
56
- # @param [Boolean] silent true if no error messages should be shown
57
- # @param [Hash] options notifier options
58
- # @return [Boolean] the availability status
59
- #
60
- def available?(silent = false, options = {})
61
- if RbConfig::CONFIG['host_os'] =~ /darwin|linux|freebsd|openbsd|sunos|solaris|mswin|mingw|cygwin/
62
- require 'ruby_gntp'
63
- true
64
-
65
- else
66
- ::Guard::UI.error 'The :gntp notifier runs only on Mac OS X, Linux, FreeBSD, OpenBSD, Solaris and Windows.' unless silent
67
- false
68
- end
47
+ def self.gem_name
48
+ 'ruby_gntp'
49
+ end
69
50
 
70
- rescue LoadError
71
- ::Guard::UI.error "Please add \"gem 'ruby_gntp'\" to your Gemfile and run Guard with \"bundle exec\"." unless silent
72
- false
51
+ def self.available?(opts = {})
52
+ super
53
+ require_gem_safely(opts)
73
54
  end
74
55
 
75
- # Show a system notification.
56
+ # Shows a system notification.
76
57
  #
77
- # @param [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
78
- # @param [String] title the notification title
79
58
  # @param [String] message the notification message body
80
- # @param [String] image the path to the notification image
81
- # @param [Hash] options additional notification library options
82
- # @option options [String] host the hostname or IP address to which to send a remote notification
83
- # @option options [String] password the password used for remote notifications
84
- # @option options [Integer] port the port to send a remote notification
85
- # @option options [Boolean] sticky make the notification sticky
59
+ # @param [Hash] opts additional notification library options
60
+ # @option opts [String] type the notification type. Either 'success',
61
+ # 'pending', 'failed' or 'notify'
62
+ # @option opts [String] title the notification title
63
+ # @option opts [String] image the path to the notification image
64
+ # @option opts [String] host the hostname or IP address to which to send
65
+ # a remote notification
66
+ # @option opts [String] password the password used for remote
67
+ # notifications
68
+ # @option opts [Integer] port the port to send a remote notification
69
+ # @option opts [Boolean] sticky make the notification sticky
86
70
  #
87
- def notify(type, title, message, image, options = { })
88
- require 'ruby_gntp'
71
+ def notify(message, opts = {})
72
+ self.class.require_gem_safely
73
+ normalize_standard_options!(opts)
89
74
 
90
- options = DEFAULTS.merge(options)
75
+ opts = DEFAULTS.merge(
76
+ name: opts.delete(:type).to_s,
77
+ text: message,
78
+ icon: opts.delete(:image)
79
+ ).merge(opts)
91
80
 
92
- gntp = ::GNTP.new('Guard', options.delete(:host), options.delete(:password), options.delete(:port))
81
+ _client(opts).notify(opts)
82
+ end
93
83
 
94
- unless registered?
95
- gntp.register({
96
- :app_icon => File.expand_path(File.join(__FILE__, '..', '..', '..', '..', 'images', 'guard.png')),
97
- :notifications => [
98
- { :name => 'notify', :enabled => true },
99
- { :name => 'failed', :enabled => true },
100
- { :name => 'pending', :enabled => true },
101
- { :name => 'success', :enabled => true }
102
- ]
103
- })
84
+ private
85
+
86
+ def _register!(gntp_client)
87
+ gntp_client.register(
88
+ app_icon: images_path.join('guard.png').to_s,
89
+ notifications: [
90
+ { name: 'notify', enabled: true },
91
+ { name: 'failed', enabled: true },
92
+ { name: 'pending', enabled: true },
93
+ { name: 'success', enabled: true }
94
+ ]
95
+ )
96
+ end
104
97
 
105
- registered!
98
+ def _client(opts = {})
99
+ @_client ||= begin
100
+ gntp = ::GNTP.new('Guard',
101
+ opts.delete(:host) { CLIENT_DEFAULTS[:host] },
102
+ opts.delete(:password) { CLIENT_DEFAULTS[:password] },
103
+ opts.delete(:port) { CLIENT_DEFAULTS[:port] })
104
+ _register!(gntp)
105
+ gntp
106
106
  end
107
-
108
- gntp.notify(options.merge({
109
- :name => type,
110
- :title => title,
111
- :text => message,
112
- :icon => image
113
- }))
114
107
  end
115
108
 
116
109
  end
110
+
117
111
  end
118
112
  end
119
-
@@ -1,5 +1,4 @@
1
- require 'rbconfig'
2
- require 'guard/ui'
1
+ require 'guard/notifiers/base'
3
2
 
4
3
  module Guard
5
4
  module Notifier
@@ -29,72 +28,70 @@ module Guard
29
28
  # notification :growl
30
29
  #
31
30
  # @example Add the `:growl_notify` notifier with configuration options to your `Guardfile`
32
- # notification :growl, :sticky => true, :host => '192.168.1.5', :password => 'secret'
31
+ # notification :growl, sticky: true, host: '192.168.1.5', password: 'secret'
33
32
  #
34
- module Growl
35
- extend self
33
+ class Growl < Base
36
34
 
37
- # Default options for growl gem
35
+ # Default options for the growl notifications.
38
36
  DEFAULTS = {
39
- :sticky => false,
40
- :priority => 0
37
+ sticky: false,
38
+ priority: 0
41
39
  }
42
40
 
43
- # Test if the notification library is available.
44
- #
45
- # @param [Boolean] silent true if no error messages should be shown
46
- # @param [Hash] options notifier options
47
- # @return [Boolean] the availability status
48
- #
49
- def available?(silent = false, options = {})
50
- if RbConfig::CONFIG['host_os'] =~ /darwin/
51
- require 'growl'
52
-
53
- if ::Growl.installed?
54
- true
55
- else
56
- ::Guard::UI.error "Please install the 'growlnotify' executable." unless silent
57
- false
58
- end
59
-
60
- else
61
- ::Guard::UI.error 'The :growl notifier runs only on Mac OS X.' unless silent
62
- false
63
- end
41
+ def self.supported_hosts
42
+ %w[darwin]
43
+ end
64
44
 
65
- rescue LoadError, NameError
66
- ::Guard::UI.error "Please add \"gem 'growl'\" to your Gemfile and run Guard with \"bundle exec\"." unless silent
67
- false
45
+ def self.available?(opts = {})
46
+ super
47
+ _register!(opts) if require_gem_safely(opts)
68
48
  end
69
49
 
70
- # Show a system notification.
50
+ # Shows a system notification.
71
51
  #
72
- # The documented options are for GrowlNotify 1.3, but the older options are
73
- # also supported. Please see `growlnotify --help`.
52
+ # The documented options are for GrowlNotify 1.3, but the older options
53
+ # are also supported. Please see `growlnotify --help`.
74
54
  #
75
- # Priority can be one of the following named keys: `Very Low`, `Moderate`, `Normal`,
76
- # `High`, `Emergency`. It can also be an int between -2 and 2.
55
+ # Priority can be one of the following named keys: `Very Low`,
56
+ # `Moderate`, `Normal`, `High`, `Emergency`. It can also be an integer
57
+ # between -2 and 2.
77
58
  #
78
- # @param [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
79
- # @param [String] title the notification title
80
59
  # @param [String] message the notification message body
81
- # @param [String] image the path to the notification image
82
- # @param [Hash] options additional notification library options
83
- # @option options [Boolean] sticky make the notification sticky
84
- # @option options [String, Integer] priority specify an int or named key (default is 0)
85
- # @option options [String] host the hostname or IP address to which to send a remote notification
86
- # @option options [String] password the password used for remote notifications
60
+ # @param [Hash] opts additional notification library options
61
+ # @option opts [String] type the notification type. Either 'success',
62
+ # 'pending', 'failed' or 'notify'
63
+ # @option opts [String] title the notification title
64
+ # @option opts [String] image the path to the notification image
65
+ # @option opts [Boolean] sticky make the notification sticky
66
+ # @option opts [String, Integer] priority specify an int or named key
67
+ # (default is 0)
68
+ # @option opts [String] host the hostname or IP address to which to
69
+ # send a remote notification
70
+ # @option opts [String] password the password used for remote
71
+ # notifications
87
72
  #
88
- def notify(type, title, message, image, options = { })
89
- require 'growl'
73
+ def notify(message, opts = {})
74
+ self.class.require_gem_safely
75
+ normalize_standard_options!(opts)
76
+ opts.delete(:type)
77
+
78
+ opts = DEFAULTS.merge(opts).merge(name: 'Guard')
90
79
 
91
- ::Growl.notify(message, DEFAULTS.merge(options).merge({
92
- :name => 'Guard',
93
- :title => title,
94
- :image => image
95
- }))
80
+ ::Growl.notify(message, opts)
81
+ end
82
+
83
+ # @private
84
+ #
85
+ def self._register!(options)
86
+ unless ::Growl.installed?
87
+ ::Guard::UI.error "Please install the 'growlnotify' executable." unless options[:silent]
88
+ return false
89
+ end
90
+
91
+ true
96
92
  end
97
93
 
98
94
  end
95
+
99
96
  end
100
97
  end