guard 1.8.3 → 2.0.0.pre

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 (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