guard 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -32,10 +32,13 @@ module Guard
32
32
  @options = options
33
33
  end
34
34
 
35
+ # String representation of the Guard group.
36
+ #
37
+ # @return [String] the group name
38
+ #
35
39
  def to_s
36
40
  "#{@name} group"
37
41
  end
38
42
 
39
43
  end
40
-
41
44
  end
data/lib/guard/guard.rb CHANGED
@@ -39,7 +39,10 @@ module Guard
39
39
  # the Guard::GuardName instance will be removed from the active guards.
40
40
  #
41
41
  class Guard
42
- include Hook
42
+ require 'guard/hook'
43
+ require 'guard/ui'
44
+
45
+ include ::Guard::Hook
43
46
 
44
47
  attr_accessor :watchers, :options, :group
45
48
 
@@ -7,6 +7,9 @@ module Guard
7
7
  #
8
8
  class Guardfile
9
9
 
10
+ require 'guard'
11
+ require 'guard/ui'
12
+
10
13
  class << self
11
14
 
12
15
  # Creates the initial Guardfile template when it does not
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
@@ -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 { |interactor| interactor.available?(true) }.new
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
- module Guard
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
- autoload :TerminalHelper, 'guard/interactors/helpers/terminal'
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,3 +1,5 @@
1
+ require 'guard'
2
+
1
3
  module Guard
2
4
 
3
5
  # Module for providing word completion to an interactor.
@@ -1,8 +1,10 @@
1
- module Guard
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
- autoload :TerminalHelper, 'guard/interactors/helpers/terminal'
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
  #
@@ -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
- NOTIFIERS = {
47
- :gntp => ::Guard::Notifier::GNTP,
48
- :growl => ::Guard::Notifier::Growl,
49
- :growl_notify => ::Guard::Notifier::GrowlNotify,
50
- :libnotify => ::Guard::Notifier::Libnotify,
51
- :notifysend => ::Guard::Notifier::NotifySend,
52
- :notifu => ::Guard::Notifier::Notifu
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 #{ NOTIFIERS[notification[:name]].to_s.split('::').last } to send notifications."
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
- if NOTIFIERS.has_key?(name) && NOTIFIERS[name].available?(silent)
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
- NOTIFIERS[notification[:name]].notify(type, title, message, image, options.merge(notification[:options]))
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 = [:growl_notify, :gntp, :growl, :libnotify, :notifysend, :notifu].any? { |notifier| add_notification(notifier, { }, true) }
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
- when :failed
175
- images_path.join('failed.png').to_s
176
- when :pending
177
- images_path.join('pending.png').to_s
178
- when :success
179
- images_path.join('success.png').to_s
180
- else
181
- image
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
- when :failed
202
- 'failed'
203
- when :pending
204
- 'pending'
205
- when :success
206
- 'success'
207
- else
208
- 'notify'
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