guard 1.2.3 → 1.3.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.
- data/CHANGELOG.md +16 -1
- data/README.md +46 -7
- data/lib/guard.rb +45 -44
- data/lib/guard/cli.rb +15 -9
- data/lib/guard/dsl.rb +16 -9
- data/lib/guard/dsl_describer.rb +12 -13
- data/lib/guard/group.rb +4 -1
- data/lib/guard/guard.rb +4 -1
- data/lib/guard/guardfile.rb +3 -0
- data/lib/guard/hook.rb +3 -1
- data/lib/guard/interactor.rb +15 -11
- data/lib/guard/interactors/coolline.rb +7 -5
- data/lib/guard/interactors/helpers/completion.rb +2 -0
- data/lib/guard/interactors/readline.rb +14 -8
- data/lib/guard/interactors/simple.rb +3 -1
- data/lib/guard/notifier.rb +56 -37
- data/lib/guard/notifiers/emacs.rb +69 -0
- data/lib/guard/notifiers/gntp.rb +2 -1
- data/lib/guard/notifiers/growl.rb +1 -0
- data/lib/guard/notifiers/growl_notify.rb +2 -1
- data/lib/guard/notifiers/libnotify.rb +1 -0
- data/lib/guard/notifiers/notifysend.rb +1 -0
- data/lib/guard/notifiers/rb_notifu.rb +1 -0
- data/lib/guard/notifiers/terminal_notifier.rb +65 -0
- data/lib/guard/runner.rb +14 -10
- data/lib/guard/ui.rb +1 -1
- data/lib/guard/version.rb +1 -1
- data/lib/guard/version.rbc +1 -1
- data/lib/guard/watcher.rb +7 -5
- data/man/guard.1 +2 -2
- data/man/guard.1.html +3 -3
- metadata +5 -3
data/lib/guard/dsl_describer.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
require 'guard/dsl'
|
2
|
-
|
3
1
|
module Guard
|
4
2
|
|
5
|
-
autoload :UI, 'guard/ui'
|
6
|
-
|
7
3
|
# The DslDescriber overrides methods to create an internal structure
|
8
4
|
# of the Guardfile that is used in some inspection utility methods
|
9
5
|
# like the CLI commands `show` and `list`.
|
@@ -13,6 +9,9 @@ module Guard
|
|
13
9
|
#
|
14
10
|
class DslDescriber < Dsl
|
15
11
|
|
12
|
+
require 'guard/dsl'
|
13
|
+
require 'guard/ui'
|
14
|
+
|
16
15
|
class << self
|
17
16
|
|
18
17
|
# Evaluate the DSL methods in the `Guardfile`.
|
@@ -52,15 +51,15 @@ module Guard
|
|
52
51
|
installed
|
53
52
|
end
|
54
53
|
|
55
|
-
UI.info 'Available guards:'
|
54
|
+
::Guard::UI.info 'Available guards:'
|
56
55
|
|
57
56
|
::Guard.guard_gem_names.sort.uniq.each do |name|
|
58
|
-
UI.info " #{ name }#{ installed_guards.include?(name) ? '*' : '' }"
|
57
|
+
::Guard::UI.info " #{ name }#{ installed_guards.include?(name) ? '*' : '' }"
|
59
58
|
end
|
60
59
|
|
61
|
-
UI.info ''
|
62
|
-
UI.info 'See also https://github.com/guard/guard/wiki/List-of-available-Guards'
|
63
|
-
UI.info '* denotes ones already in your Guardfile'
|
60
|
+
::Guard::UI.info ''
|
61
|
+
::Guard::UI.info 'See also https://github.com/guard/guard/wiki/List-of-available-Guards'
|
62
|
+
::Guard::UI.info '* denotes ones already in your Guardfile'
|
64
63
|
end
|
65
64
|
|
66
65
|
# Shows all Guard plugins and their options that are defined in
|
@@ -82,9 +81,9 @@ module Guard
|
|
82
81
|
guardfile_structure.each do |group|
|
83
82
|
unless group[:guards].empty?
|
84
83
|
if group[:group]
|
85
|
-
UI.info "Group #{ group[:group] }:"
|
84
|
+
::Guard::UI.info "Group #{ group[:group] }:"
|
86
85
|
else
|
87
|
-
UI.info '(global):'
|
86
|
+
::Guard::UI.info '(global):'
|
88
87
|
end
|
89
88
|
|
90
89
|
group[:guards].each do |guard|
|
@@ -94,12 +93,12 @@ module Guard
|
|
94
93
|
line += ": #{ guard[:options].inject({}) { |options, (k, v)| options[k.to_s] = v; options }.sort.collect { |k, v| "#{ k } => #{ v.inspect }" }.join(', ') }"
|
95
94
|
end
|
96
95
|
|
97
|
-
UI.info line
|
96
|
+
::Guard::UI.info line
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
|
-
UI.info ''
|
101
|
+
::Guard::UI.info ''
|
103
102
|
end
|
104
103
|
|
105
104
|
private
|
data/lib/guard/group.rb
CHANGED
data/lib/guard/guard.rb
CHANGED
data/lib/guard/guardfile.rb
CHANGED
data/lib/guard/hook.rb
CHANGED
@@ -9,6 +9,8 @@ module Guard
|
|
9
9
|
#
|
10
10
|
module Hook
|
11
11
|
|
12
|
+
require 'guard/ui'
|
13
|
+
|
12
14
|
# The Hook module gets included.
|
13
15
|
#
|
14
16
|
# @param [Class] base the class that includes the module
|
@@ -57,7 +59,7 @@ module Guard
|
|
57
59
|
event
|
58
60
|
end.to_sym
|
59
61
|
|
60
|
-
UI.debug "Hook :#{ hook_name } executed for #{ self.class }"
|
62
|
+
::Guard::UI.debug "Hook :#{ hook_name } executed for #{ self.class }"
|
61
63
|
|
62
64
|
Hook.notify(self.class, hook_name, *args)
|
63
65
|
end
|
data/lib/guard/interactor.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
1
|
module Guard
|
2
2
|
|
3
|
-
autoload :ReadlineInteractor, 'guard/interactors/readline'
|
4
|
-
autoload :CoollineInteractor, 'guard/interactors/coolline'
|
5
|
-
autoload :SimpleInteractor, 'guard/interactors/simple'
|
6
|
-
autoload :DslDescriber, 'guard/dsl_describer'
|
7
|
-
autoload :UI, 'guard/ui'
|
8
|
-
|
9
3
|
# The interactor triggers specific action from input
|
10
4
|
# read by a interactor implementation.
|
11
5
|
#
|
@@ -38,6 +32,14 @@ module Guard
|
|
38
32
|
#
|
39
33
|
class Interactor
|
40
34
|
|
35
|
+
require 'guard'
|
36
|
+
require 'guard/ui'
|
37
|
+
require 'guard/dsl_describer'
|
38
|
+
require 'guard/notifier'
|
39
|
+
require 'guard/interactors/readline'
|
40
|
+
require 'guard/interactors/coolline'
|
41
|
+
require 'guard/interactors/simple'
|
42
|
+
|
41
43
|
ACTIONS = {
|
42
44
|
:help => %w[help h],
|
43
45
|
:reload => %w[reload r],
|
@@ -64,11 +66,11 @@ module Guard
|
|
64
66
|
def self.fabricate
|
65
67
|
case @interactor
|
66
68
|
when :coolline
|
67
|
-
CoollineInteractor.new if CoollineInteractor.available?
|
69
|
+
::Guard::CoollineInteractor.new if ::Guard::CoollineInteractor.available?
|
68
70
|
when :readline
|
69
|
-
ReadlineInteractor.new if ReadlineInteractor.available?
|
71
|
+
::Guard::ReadlineInteractor.new if ::Guard::ReadlineInteractor.available?
|
70
72
|
when :simple
|
71
|
-
SimpleInteractor.new
|
73
|
+
::Guard::SimpleInteractor.new
|
72
74
|
when :off
|
73
75
|
nil
|
74
76
|
else
|
@@ -90,7 +92,9 @@ module Guard
|
|
90
92
|
# @return [Interactor] an interactor implementation
|
91
93
|
#
|
92
94
|
def self.auto_detect
|
93
|
-
[CoollineInteractor, ReadlineInteractor, SimpleInteractor].detect
|
95
|
+
[::Guard::CoollineInteractor, ::Guard::ReadlineInteractor, ::Guard::SimpleInteractor].detect do |interactor|
|
96
|
+
interactor.available?(true)
|
97
|
+
end.new
|
94
98
|
end
|
95
99
|
|
96
100
|
# Template method for checking if the Interactor is
|
@@ -143,7 +147,7 @@ module Guard
|
|
143
147
|
when :help
|
144
148
|
help
|
145
149
|
when :show
|
146
|
-
DslDescriber.show(::Guard.options)
|
150
|
+
::Guard::DslDescriber.show(::Guard.options)
|
147
151
|
when :stop
|
148
152
|
::Guard.stop
|
149
153
|
exit
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
require 'guard'
|
2
|
+
require 'guard/ui'
|
3
|
+
require 'guard/interactor'
|
4
|
+
require 'guard/interactors/helpers/terminal'
|
5
|
+
require 'guard/interactors/helpers/completion'
|
2
6
|
|
3
|
-
|
4
|
-
autoload :CompletionHelper, 'guard/interactors/helpers/completion'
|
5
|
-
autoload :UI, 'guard/ui'
|
7
|
+
module Guard
|
6
8
|
|
7
9
|
# Interactor that uses coolline for getting the user input.
|
8
10
|
# This enables history support and auto-completion,
|
9
11
|
#
|
10
|
-
class CoollineInteractor < Interactor
|
12
|
+
class CoollineInteractor < ::Guard::Interactor
|
11
13
|
include ::Guard::CompletionHelper
|
12
14
|
include ::Guard::TerminalHelper
|
13
15
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
require 'guard'
|
2
|
+
require 'guard/ui'
|
3
|
+
require 'guard/interactor'
|
4
|
+
require 'guard/interactors/helpers/terminal'
|
5
|
+
require 'guard/interactors/helpers/completion'
|
2
6
|
|
3
|
-
|
4
|
-
autoload :CompletionHelper, 'guard/interactors/helpers/completion'
|
5
|
-
autoload :UI, 'guard/ui'
|
7
|
+
module Guard
|
6
8
|
|
7
9
|
# Interactor that used readline for getting the user input.
|
8
10
|
# This enables history support and auto-completion, but is
|
@@ -10,7 +12,7 @@ module Guard
|
|
10
12
|
#
|
11
13
|
# @see http://bugs.ruby-lang.org/issues/5539
|
12
14
|
#
|
13
|
-
class ReadlineInteractor < Interactor
|
15
|
+
class ReadlineInteractor < ::Guard::Interactor
|
14
16
|
include ::Guard::CompletionHelper
|
15
17
|
include ::Guard::TerminalHelper
|
16
18
|
|
@@ -29,6 +31,10 @@ module Guard
|
|
29
31
|
::Guard::UI.error 'The :readline interactor runs only fine on JRuby, Linux or with the gem \'rb-readline\' installed.' unless silent
|
30
32
|
false
|
31
33
|
end
|
34
|
+
|
35
|
+
rescue LoadError => e
|
36
|
+
::Guard::UI.error "Please install Ruby Readline support or add \"gem 'rb-readline'\" to your Gemfile and run Guard with \"bundle exec\"." unless silent
|
37
|
+
false
|
32
38
|
end
|
33
39
|
|
34
40
|
# Initialize the interactor.
|
@@ -49,10 +55,10 @@ module Guard
|
|
49
55
|
#
|
50
56
|
def stop
|
51
57
|
# Erase the current line for Ruby Readline
|
52
|
-
if Readline.respond_to?(:refresh_line)
|
58
|
+
if Readline.respond_to?(:refresh_line) && !defined?(::JRUBY_VERSION)
|
53
59
|
Readline.refresh_line
|
54
60
|
end
|
55
|
-
|
61
|
+
|
56
62
|
# Erase the current line for Rb-Readline
|
57
63
|
if defined?(RbReadline) && RbReadline.rl_outstream
|
58
64
|
RbReadline._rl_erase_entire_line
|
@@ -60,7 +66,7 @@ module Guard
|
|
60
66
|
|
61
67
|
super
|
62
68
|
end
|
63
|
-
|
69
|
+
|
64
70
|
# Read a line from stdin with Readline.
|
65
71
|
#
|
66
72
|
def read_line
|
@@ -1,9 +1,11 @@
|
|
1
|
+
require 'guard/interactor'
|
2
|
+
|
1
3
|
module Guard
|
2
4
|
|
3
5
|
# Simple interactor that that reads user
|
4
6
|
# input from standard input.
|
5
7
|
#
|
6
|
-
class SimpleInteractor < Interactor
|
8
|
+
class SimpleInteractor < ::Guard::Interactor
|
7
9
|
|
8
10
|
# Read a line from stdin with Readline.
|
9
11
|
#
|
data/lib/guard/notifier.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
|
-
|
3
2
|
require 'rbconfig'
|
4
3
|
require 'pathname'
|
5
|
-
require 'guard/ui'
|
6
|
-
require 'guard/notifiers/gntp'
|
7
|
-
require 'guard/notifiers/growl'
|
8
|
-
require 'guard/notifiers/growl_notify'
|
9
|
-
require 'guard/notifiers/libnotify'
|
10
|
-
require 'guard/notifiers/notifysend'
|
11
|
-
require 'guard/notifiers/rb_notifu'
|
12
4
|
|
13
5
|
module Guard
|
14
6
|
|
@@ -40,17 +32,32 @@ module Guard
|
|
40
32
|
# Guard can be configured to make use of more than one notifier at once, @see Guard::Dsl
|
41
33
|
#
|
42
34
|
module Notifier
|
35
|
+
|
36
|
+
require 'guard'
|
37
|
+
require 'guard/ui'
|
38
|
+
require 'guard/notifiers/gntp'
|
39
|
+
require 'guard/notifiers/growl'
|
40
|
+
require 'guard/notifiers/growl_notify'
|
41
|
+
require 'guard/notifiers/libnotify'
|
42
|
+
require 'guard/notifiers/notifysend'
|
43
|
+
require 'guard/notifiers/rb_notifu'
|
44
|
+
require 'guard/notifiers/emacs'
|
45
|
+
require 'guard/notifiers/terminal_notifier'
|
46
|
+
|
43
47
|
extend self
|
44
48
|
|
45
|
-
# List of available notifiers.
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
# List of available notifiers. It needs to be a nested hash instead of
|
50
|
+
# a simpler Hash, because it maintains its order on Ruby 1.8.7 also.
|
51
|
+
NOTIFIERS = [
|
52
|
+
[:growl, ::Guard::Notifier::Growl],
|
53
|
+
[:gntp, ::Guard::Notifier::GNTP],
|
54
|
+
[:growl_notify, ::Guard::Notifier::GrowlNotify],
|
55
|
+
[:libnotify, ::Guard::Notifier::Libnotify],
|
56
|
+
[:notifysend, ::Guard::Notifier::NotifySend],
|
57
|
+
[:notifu, ::Guard::Notifier::Notifu],
|
58
|
+
[:emacs, ::Guard::Notifier::Emacs],
|
59
|
+
[:terminal_notifier, ::Guard::Notifier::TerminalNotifier]
|
60
|
+
]
|
54
61
|
|
55
62
|
# Get the available notifications.
|
56
63
|
#
|
@@ -85,7 +92,7 @@ module Guard
|
|
85
92
|
ENV['GUARD_NOTIFY'] = 'false'
|
86
93
|
else
|
87
94
|
notifications.each do |notification|
|
88
|
-
::Guard::UI.info "Guard uses #{
|
95
|
+
::Guard::UI.info "Guard uses #{ get_notifier_module(notification[:name]).to_s.split('::').last } to send notifications."
|
89
96
|
end
|
90
97
|
|
91
98
|
ENV['GUARD_NOTIFY'] = 'true'
|
@@ -116,7 +123,9 @@ module Guard
|
|
116
123
|
def add_notification(name, options = { }, silent = false)
|
117
124
|
return turn_off if name == :off
|
118
125
|
|
119
|
-
|
126
|
+
notifier = get_notifier_module(name)
|
127
|
+
|
128
|
+
if notifier && notifier.available?(silent)
|
120
129
|
self.notifications = notifications << { :name => name, :options => options }
|
121
130
|
true
|
122
131
|
else
|
@@ -138,7 +147,7 @@ module Guard
|
|
138
147
|
|
139
148
|
notifications.each do |notification|
|
140
149
|
begin
|
141
|
-
|
150
|
+
get_notifier_module(notification[:name]).notify(type, title, message, image, options.merge(notification[:options]))
|
142
151
|
rescue Exception => e
|
143
152
|
::Guard::UI.error "Error sending notification with #{ notification[:name] }: #{ e.message }"
|
144
153
|
end
|
@@ -148,12 +157,22 @@ module Guard
|
|
148
157
|
|
149
158
|
private
|
150
159
|
|
160
|
+
# Get the notifier module for the given name.
|
161
|
+
#
|
162
|
+
# @param [Symbol] the notifier name
|
163
|
+
# @return [Module] the notifier module
|
164
|
+
#
|
165
|
+
def get_notifier_module(name)
|
166
|
+
notifier = NOTIFIERS.detect { |n| n.first == name }
|
167
|
+
notifier ? notifier.last : notifier
|
168
|
+
end
|
169
|
+
|
151
170
|
# Auto detect the available notification library. This goes through
|
152
171
|
# the list of supported notification gems and picks the first that
|
153
172
|
# is available.
|
154
173
|
#
|
155
174
|
def auto_detect_notification
|
156
|
-
available =
|
175
|
+
available = NOTIFIERS.map { |n| n.first }.any? { |notifier| add_notification(notifier, { }, true) }
|
157
176
|
::Guard::UI.info('Guard could not detect any of the supported notification libraries.') unless available
|
158
177
|
end
|
159
178
|
|
@@ -171,14 +190,14 @@ module Guard
|
|
171
190
|
#
|
172
191
|
def image_path(image)
|
173
192
|
case image
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
193
|
+
when :failed
|
194
|
+
images_path.join('failed.png').to_s
|
195
|
+
when :pending
|
196
|
+
images_path.join('pending.png').to_s
|
197
|
+
when :success
|
198
|
+
images_path.join('success.png').to_s
|
199
|
+
else
|
200
|
+
image
|
182
201
|
end
|
183
202
|
end
|
184
203
|
|
@@ -198,14 +217,14 @@ module Guard
|
|
198
217
|
#
|
199
218
|
def notification_type(image)
|
200
219
|
case image
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
220
|
+
when :failed
|
221
|
+
'failed'
|
222
|
+
when :pending
|
223
|
+
'pending'
|
224
|
+
when :success
|
225
|
+
'success'
|
226
|
+
else
|
227
|
+
'notify'
|
209
228
|
end
|
210
229
|
end
|
211
230
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
module Notifier
|
5
|
+
|
6
|
+
# Default options for EmacsClient
|
7
|
+
DEFAULTS = {
|
8
|
+
:client => 'emacsclient',
|
9
|
+
:success => 'ForestGreen',
|
10
|
+
:failed => 'Firebrick',
|
11
|
+
:default => 'Black',
|
12
|
+
}
|
13
|
+
|
14
|
+
# Send a notification to Emacs with emacsclient (http://www.emacswiki.org/emacs/EmacsClient).
|
15
|
+
#
|
16
|
+
# @example Add the `:emacs` notifier to your `Guardfile`
|
17
|
+
# notification :emacs
|
18
|
+
#
|
19
|
+
module Emacs
|
20
|
+
extend self
|
21
|
+
|
22
|
+
# Test if Emacs with running server is available.
|
23
|
+
#
|
24
|
+
# @param [Boolean] silent true if no error messages should be shown
|
25
|
+
# @return [Boolean] the availability status
|
26
|
+
#
|
27
|
+
def available?(silent = false)
|
28
|
+
result = `#{DEFAULTS[:client]} --eval '1' 2> /dev/null || echo 0`
|
29
|
+
|
30
|
+
if result.chomp! == "1"
|
31
|
+
true
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Show a system notification.
|
38
|
+
#
|
39
|
+
# @param [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
|
40
|
+
# @param [String] title the notification title
|
41
|
+
# @param [String] message the notification message body
|
42
|
+
# @param [String] image the path to the notification image
|
43
|
+
# @param [Hash] options additional notification library options
|
44
|
+
# @option options [Boolean] sticky make the notification sticky
|
45
|
+
# @option options [String, Integer] priority specify an int or named key (default is 0)
|
46
|
+
#
|
47
|
+
def notify(type, title, message, image, options = { })
|
48
|
+
system(%(#{DEFAULTS[:client]} --eval "(set-face-background 'modeline \\"#{emacs_color(type)}\\")"))
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the Emacs color for the notification type.
|
52
|
+
# You can configure your own color by overwrite the defaults.
|
53
|
+
#
|
54
|
+
# @param [String] type the notification type
|
55
|
+
# @return [String] the name of the emacs color
|
56
|
+
#
|
57
|
+
def emacs_color(type)
|
58
|
+
case type
|
59
|
+
when 'success'
|
60
|
+
DEFAULTS[:success]
|
61
|
+
when 'failed'
|
62
|
+
DEFAULTS[:failed]
|
63
|
+
else
|
64
|
+
DEFAULTS[:default]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|