guard 2.10.5 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/guard.rb +0 -3
- data/lib/guard/aruba_adapter.rb +6 -6
- data/lib/guard/cli.rb +5 -0
- data/lib/guard/commander.rb +1 -1
- data/lib/guard/commands/all.rb +2 -2
- data/lib/guard/commands/notification.rb +1 -1
- data/lib/guard/commands/reload.rb +2 -2
- data/lib/guard/commands/show.rb +1 -1
- data/lib/guard/deprecated/evaluator.rb +3 -1
- data/lib/guard/deprecated/guard.rb +57 -2
- data/lib/guard/dsl.rb +2 -3
- data/lib/guard/dsl_describer.rb +8 -20
- data/lib/guard/guardfile/evaluator.rb +5 -5
- data/lib/guard/guardfile/generator.rb +3 -3
- data/lib/guard/internals/debugging.rb +5 -5
- data/lib/guard/internals/session.rb +19 -8
- data/lib/guard/internals/state.rb +0 -13
- data/lib/guard/jobs/pry_wrapper.rb +5 -5
- data/lib/guard/notifier.rb +43 -219
- data/lib/guard/plugin_util.rb +1 -1
- data/lib/guard/terminal.rb +3 -2
- data/lib/guard/ui.rb +7 -2
- data/lib/guard/version.rb +1 -1
- data/lib/guard/watcher.rb +3 -3
- metadata +30 -15
- data/lib/guard/notifier/detected.rb +0 -87
- data/lib/guard/notifiers/base.rb +0 -221
- data/lib/guard/notifiers/emacs.rb +0 -99
- data/lib/guard/notifiers/file_notifier.rb +0 -54
- data/lib/guard/notifiers/gntp.rb +0 -111
- data/lib/guard/notifiers/growl.rb +0 -104
- data/lib/guard/notifiers/libnotify.rb +0 -86
- data/lib/guard/notifiers/notifysend.rb +0 -110
- data/lib/guard/notifiers/rb_notifu.rb +0 -100
- data/lib/guard/notifiers/terminal_notifier.rb +0 -90
- data/lib/guard/notifiers/terminal_title.rb +0 -31
- data/lib/guard/notifiers/tmux.rb +0 -335
- data/lib/guard/sheller.rb +0 -143
@@ -1,87 +0,0 @@
|
|
1
|
-
require "nenv"
|
2
|
-
|
3
|
-
require_relative "../notifiers/emacs"
|
4
|
-
require_relative "../notifiers/file_notifier"
|
5
|
-
require_relative "../notifiers/gntp"
|
6
|
-
require_relative "../notifiers/growl"
|
7
|
-
require_relative "../notifiers/libnotify"
|
8
|
-
require_relative "../notifiers/notifysend"
|
9
|
-
require_relative "../notifiers/rb_notifu"
|
10
|
-
require_relative "../notifiers/terminal_notifier"
|
11
|
-
require_relative "../notifiers/terminal_title"
|
12
|
-
require_relative "../notifiers/tmux"
|
13
|
-
|
14
|
-
module Guard
|
15
|
-
module Notifier
|
16
|
-
# @private api
|
17
|
-
|
18
|
-
YamlEnvStorage = Nenv::Builder.build do
|
19
|
-
create_method(:notifiers=) { |data| YAML::dump(data) }
|
20
|
-
create_method(:notifiers) { |data| data ? YAML::load(data) : [] }
|
21
|
-
end
|
22
|
-
|
23
|
-
# @private api
|
24
|
-
class Detected
|
25
|
-
NO_SUPPORTED_NOTIFIERS = "Guard could not detect any of the supported" +
|
26
|
-
" notification libraries."
|
27
|
-
|
28
|
-
class NoneAvailableError < RuntimeError
|
29
|
-
end
|
30
|
-
|
31
|
-
def initialize(supported)
|
32
|
-
@supported = supported
|
33
|
-
@environment = YamlEnvStorage.new("guard")
|
34
|
-
end
|
35
|
-
|
36
|
-
def reset
|
37
|
-
@environment.notifiers = nil
|
38
|
-
end
|
39
|
-
|
40
|
-
def detect
|
41
|
-
return unless _data.empty?
|
42
|
-
@supported.each do |group|
|
43
|
-
group.detect { |name, _| add(name, silent: true) }
|
44
|
-
end
|
45
|
-
|
46
|
-
fail NoneAvailableError, NO_SUPPORTED_NOTIFIERS if _data.empty?
|
47
|
-
end
|
48
|
-
|
49
|
-
def available
|
50
|
-
_data.map { |entry| [_to_module(entry[:name]), entry[:options]] }
|
51
|
-
end
|
52
|
-
|
53
|
-
def add(name, opts)
|
54
|
-
klass = _to_module(name)
|
55
|
-
return false unless klass
|
56
|
-
|
57
|
-
all = @environment.notifiers
|
58
|
-
|
59
|
-
# Silently skip if it's already available, because otherwise
|
60
|
-
# we'd have to do :turn_off, then configure, then :turn_on
|
61
|
-
names = all.map(&:first).map(&:last)
|
62
|
-
unless names.include?(name)
|
63
|
-
return false unless klass.available?(opts)
|
64
|
-
@environment.notifiers = all << { name: name, options: opts }
|
65
|
-
true
|
66
|
-
end
|
67
|
-
|
68
|
-
# Just overwrite the options (without turning the notifier off or on),
|
69
|
-
# so those options will be passed in next calls to notify()
|
70
|
-
all.each { |item| item[:options] = opts if item[:name] == name }
|
71
|
-
true
|
72
|
-
end
|
73
|
-
|
74
|
-
def _to_module(name)
|
75
|
-
@supported.each do |group|
|
76
|
-
next unless (notifier = group.detect { |n, _| n == name })
|
77
|
-
return notifier.last
|
78
|
-
end
|
79
|
-
nil
|
80
|
-
end
|
81
|
-
|
82
|
-
def _data
|
83
|
-
@environment.notifiers || []
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
data/lib/guard/notifiers/base.rb
DELETED
@@ -1,221 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require "guard/ui"
|
3
|
-
|
4
|
-
module Guard
|
5
|
-
module Notifier
|
6
|
-
# Base class for all notifiers.
|
7
|
-
#
|
8
|
-
class Base
|
9
|
-
HOSTS = {
|
10
|
-
darwin: "Mac OS X",
|
11
|
-
linux: "Linux",
|
12
|
-
freebsd: "FreeBSD",
|
13
|
-
openbsd: "OpenBSD",
|
14
|
-
sunos: "SunOS",
|
15
|
-
solaris: "Solaris",
|
16
|
-
mswin: "Windows",
|
17
|
-
mingw: "Windows",
|
18
|
-
cygwin: "Windows"
|
19
|
-
}
|
20
|
-
|
21
|
-
ERROR_ADD_GEM_AND_RUN_BUNDLE = "Please add \"gem '%s'\" to your Gemfile "\
|
22
|
-
"and run Guard with \"bundle exec\"."
|
23
|
-
|
24
|
-
attr_reader :options
|
25
|
-
|
26
|
-
def initialize(opts = {})
|
27
|
-
@options = opts
|
28
|
-
end
|
29
|
-
|
30
|
-
# This method should be overriden by subclasses and return an array of
|
31
|
-
# OSes the notifier supports. By default, it returns :all which mean
|
32
|
-
# there's no check against the current OS.
|
33
|
-
#
|
34
|
-
# @see HOSTS for the list of possible OSes
|
35
|
-
#
|
36
|
-
def self.supported_hosts
|
37
|
-
:all
|
38
|
-
end
|
39
|
-
|
40
|
-
# Test if the notifier can be used.
|
41
|
-
#
|
42
|
-
# @param [Hash] opts notifier options
|
43
|
-
# @option opts [Boolean] silent true if no error messages should be shown
|
44
|
-
# @return [Boolean] the availability status
|
45
|
-
#
|
46
|
-
def self.available?(opts = {})
|
47
|
-
if _supported_host?
|
48
|
-
true
|
49
|
-
else
|
50
|
-
hosts = supported_hosts.map { |host| HOSTS[host.to_sym] }.join(", ")
|
51
|
-
unless opts.fetch(:silent) { false }
|
52
|
-
::Guard::UI.error "The :#{name} notifier runs only on #{hosts}."
|
53
|
-
end
|
54
|
-
false
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# This method must be overriden.
|
59
|
-
#
|
60
|
-
def notify(_message, opts = {})
|
61
|
-
options.delete(:silent)
|
62
|
-
opts.replace(options.merge(opts))
|
63
|
-
normalize_standard_options!(opts)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Returns the title of the notifier.
|
67
|
-
#
|
68
|
-
# @example Un-modulize the class name
|
69
|
-
# Guard::Notifier::FileNotifier.title
|
70
|
-
# #=> 'FileNotifier'
|
71
|
-
#
|
72
|
-
# @return [String] the title of the notifier
|
73
|
-
#
|
74
|
-
def self.title
|
75
|
-
to_s.sub(/.+::(\w+)$/, '\1')
|
76
|
-
end
|
77
|
-
|
78
|
-
# Returns the name of the notifier.
|
79
|
-
#
|
80
|
-
# @example Un-modulize, underscorize and downcase the class name
|
81
|
-
# Guard::Notifier::FileNotifier.name
|
82
|
-
# #=> 'file_notifier'
|
83
|
-
#
|
84
|
-
# @return [String] the name of the notifier
|
85
|
-
#
|
86
|
-
def self.name
|
87
|
-
title.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
88
|
-
end
|
89
|
-
|
90
|
-
# Returns the name of the notifier's gem. By default it returns the
|
91
|
-
# notifier name. This method can be overriden by subclasses.
|
92
|
-
#
|
93
|
-
# @example Un-modulize, underscorize and downcase the class name
|
94
|
-
# Guard::Notifier::FileNotifier.gem_name
|
95
|
-
# #=> 'file_notifier'
|
96
|
-
#
|
97
|
-
# @return [String] the name of the notifier's gem
|
98
|
-
#
|
99
|
-
def self.gem_name
|
100
|
-
name
|
101
|
-
end
|
102
|
-
|
103
|
-
# This method tries to require the gem whose name is returned by
|
104
|
-
# `.gem_name`. If a LoadError or NameError occurs, it displays an error
|
105
|
-
# message (unless opts[:silent] is true) and returns false.
|
106
|
-
#
|
107
|
-
# @param [Hash] opts some options
|
108
|
-
# @option opts [Boolean] silent true if no error messages should be shown
|
109
|
-
#
|
110
|
-
# @return [Boolean] whether or not the gem is loaded
|
111
|
-
#
|
112
|
-
def self.require_gem_safely(opts = {})
|
113
|
-
require gem_name
|
114
|
-
true
|
115
|
-
rescue LoadError, NameError
|
116
|
-
unless opts[:silent]
|
117
|
-
UI.error ERROR_ADD_GEM_AND_RUN_BUNDLE % [gem_name]
|
118
|
-
end
|
119
|
-
false
|
120
|
-
end
|
121
|
-
|
122
|
-
# Returns the title of the notifier.
|
123
|
-
#
|
124
|
-
# @example Un-modulize the class name
|
125
|
-
# Guard::Notifier::FileNotifier.new.title
|
126
|
-
# #=> 'FileNotifier'
|
127
|
-
#
|
128
|
-
# @return [String] the title of the notifier
|
129
|
-
#
|
130
|
-
def title
|
131
|
-
self.class.title
|
132
|
-
end
|
133
|
-
|
134
|
-
# Returns the name of the notifier.
|
135
|
-
#
|
136
|
-
# @example Un-modulize, underscorize and downcase the class name
|
137
|
-
# Guard::Notifier::FileNotifier.new.name
|
138
|
-
# #=> 'file_notifier'
|
139
|
-
#
|
140
|
-
# @return [String] the name of the notifier
|
141
|
-
#
|
142
|
-
def name
|
143
|
-
self.class.name
|
144
|
-
end
|
145
|
-
|
146
|
-
# Paths where all Guard images are located
|
147
|
-
#
|
148
|
-
# @return [Pathname] the path to the images directory
|
149
|
-
#
|
150
|
-
def images_path
|
151
|
-
@images_path ||= Pathname.new(__FILE__).dirname + "../../../images"
|
152
|
-
end
|
153
|
-
|
154
|
-
# @private
|
155
|
-
#
|
156
|
-
# Checks if the current OS is supported by the notifier.
|
157
|
-
#
|
158
|
-
# @see .supported_hosts
|
159
|
-
#
|
160
|
-
def self._supported_host?
|
161
|
-
supported_hosts == :all ||
|
162
|
-
RbConfig::CONFIG["host_os"] =~ /#{supported_hosts.join('|')}/
|
163
|
-
end
|
164
|
-
|
165
|
-
# Set or modify the `:title`, `:type` and `:image` options for a
|
166
|
-
# notification. Should be used in `#notify`.
|
167
|
-
#
|
168
|
-
# @param [Hash] opts additional notification library options
|
169
|
-
# @option opts [String] type the notification type. Either 'success',
|
170
|
-
# 'pending', 'failed' or 'notify'
|
171
|
-
# @option opts [String] title the notification title
|
172
|
-
# @option opts [String] image the path to the notification image
|
173
|
-
#
|
174
|
-
def normalize_standard_options!(opts)
|
175
|
-
opts[:title] ||= "Guard"
|
176
|
-
opts[:type] ||= _notification_type(opts.fetch(:image, :success))
|
177
|
-
opts[:image] = _image_path(opts.delete(:image) { :success })
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
# Get the image path for an image symbol for the following
|
183
|
-
# known image types:
|
184
|
-
#
|
185
|
-
# - failed
|
186
|
-
# - pending
|
187
|
-
# - success
|
188
|
-
#
|
189
|
-
# If the image is not a known symbol, it will be returned unmodified.
|
190
|
-
#
|
191
|
-
# @param [Symbol, String] image the image symbol or path to an image
|
192
|
-
#
|
193
|
-
# @return [String] the image path
|
194
|
-
#
|
195
|
-
def _image_path(image)
|
196
|
-
case image
|
197
|
-
when :failed, :pending, :success
|
198
|
-
images_path.join("#{image}.png").to_s
|
199
|
-
else
|
200
|
-
image
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
# Get the notification type depending on the
|
205
|
-
# image that has been selected for the notification.
|
206
|
-
#
|
207
|
-
# @param [Symbol, String] image the image symbol or path to an image
|
208
|
-
#
|
209
|
-
# @return [String] the notification type
|
210
|
-
#
|
211
|
-
def _notification_type(image)
|
212
|
-
case image
|
213
|
-
when :failed, :pending, :success
|
214
|
-
image
|
215
|
-
else
|
216
|
-
:notify
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
require "guard/notifiers/base"
|
2
|
-
require "guard/sheller"
|
3
|
-
|
4
|
-
module Guard
|
5
|
-
module Notifier
|
6
|
-
# Send a notification to Emacs with emacsclient
|
7
|
-
# (http://www.emacswiki.org/emacs/EmacsClient).
|
8
|
-
#
|
9
|
-
# @example Add the `:emacs` notifier to your `Guardfile`
|
10
|
-
# notification :emacs
|
11
|
-
#
|
12
|
-
class Emacs < Base
|
13
|
-
DEFAULTS = {
|
14
|
-
client: "emacsclient",
|
15
|
-
success: "ForestGreen",
|
16
|
-
failed: "Firebrick",
|
17
|
-
default: "Black",
|
18
|
-
fontcolor: "White",
|
19
|
-
}
|
20
|
-
|
21
|
-
def self.available?(opts = {})
|
22
|
-
return false unless super
|
23
|
-
|
24
|
-
client_name = opts.fetch(:client, DEFAULTS[:client])
|
25
|
-
cmd = "#{client_name} --eval '1' 2> #{IO::NULL} || echo 'N/A'"
|
26
|
-
stdout = Sheller.stdout(cmd)
|
27
|
-
return false if stdout.nil?
|
28
|
-
!%w(N/A 'N/A').include?(stdout.chomp)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Shows a system notification.
|
32
|
-
#
|
33
|
-
# @param [String] type the notification type. Either 'success',
|
34
|
-
# 'pending', 'failed' or 'notify'
|
35
|
-
# @param [String] title the notification title
|
36
|
-
# @param [String] message the notification message body
|
37
|
-
# @param [String] image the path to the notification image
|
38
|
-
# @param [Hash] opts additional notification library options
|
39
|
-
# @option opts [String] success the color to use for success
|
40
|
-
# notifications (default is 'ForestGreen')
|
41
|
-
# @option opts [String] failed the color to use for failure
|
42
|
-
# notifications (default is 'Firebrick')
|
43
|
-
# @option opts [String] pending the color to use for pending
|
44
|
-
# notifications
|
45
|
-
# @option opts [String] default the default color to use (default is
|
46
|
-
# 'Black')
|
47
|
-
# @option opts [String] client the client to use for notification
|
48
|
-
# (default is 'emacsclient')
|
49
|
-
# @option opts [String, Integer] priority specify an int or named key
|
50
|
-
# (default is 0)
|
51
|
-
#
|
52
|
-
def notify(message, opts = {})
|
53
|
-
super
|
54
|
-
|
55
|
-
opts = DEFAULTS.merge(opts)
|
56
|
-
color = emacs_color(opts[:type], opts)
|
57
|
-
fontcolor = emacs_color(:fontcolor, opts)
|
58
|
-
elisp = <<-EOF.gsub(/\s+/, " ").strip
|
59
|
-
(set-face-attribute 'mode-line nil
|
60
|
-
:background "#{color}"
|
61
|
-
:foreground "#{fontcolor}")
|
62
|
-
EOF
|
63
|
-
|
64
|
-
_run_cmd(opts[:client], "--eval", elisp)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Get the Emacs color for the notification type.
|
68
|
-
# You can configure your own color by overwrite the defaults.
|
69
|
-
#
|
70
|
-
# @param [String] type the notification type
|
71
|
-
# @param [Hash] options aditional notification options
|
72
|
-
#
|
73
|
-
# @option options [String] success the color to use for success
|
74
|
-
# notifications (default is 'ForestGreen')
|
75
|
-
#
|
76
|
-
# @option options [String] failed the color to use for failure
|
77
|
-
# notifications (default is 'Firebrick')
|
78
|
-
#
|
79
|
-
# @option options [String] pending the color to use for pending
|
80
|
-
# notifications
|
81
|
-
#
|
82
|
-
# @option options [String] default the default color to use (default is
|
83
|
-
# 'Black')
|
84
|
-
#
|
85
|
-
# @return [String] the name of the emacs color
|
86
|
-
#
|
87
|
-
def emacs_color(type, options = {})
|
88
|
-
default = options.fetch(:default, DEFAULTS[:default])
|
89
|
-
options.fetch(type.to_sym, default)
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
def _run_cmd(cmd, *args)
|
95
|
-
Sheller.run(cmd, *args)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require "guard/notifiers/base"
|
2
|
-
|
3
|
-
module Guard
|
4
|
-
module Notifier
|
5
|
-
# Writes Guard notification results to a file.
|
6
|
-
#
|
7
|
-
# @example Add the `:file` notifier to your `Guardfile`
|
8
|
-
# notification :file, path: 'tmp/guard_result'
|
9
|
-
#
|
10
|
-
class FileNotifier < Base
|
11
|
-
DEFAULTS = {
|
12
|
-
format: "%s\n%s\n%s\n"
|
13
|
-
}
|
14
|
-
|
15
|
-
# @param [Hash] opts some options
|
16
|
-
# @option opts [Boolean] path the path to a file where Guard notification
|
17
|
-
# results will be written
|
18
|
-
#
|
19
|
-
def self.available?(opts = {})
|
20
|
-
super && opts.has_key?(:path)
|
21
|
-
end
|
22
|
-
|
23
|
-
# Writes the notification to a file. By default it writes type, title,
|
24
|
-
# and message separated by newlines.
|
25
|
-
#
|
26
|
-
# @param [String] message the notification message body
|
27
|
-
# @param [Hash] opts additional notification library options
|
28
|
-
# @option opts [String] type the notification type. Either 'success',
|
29
|
-
# 'pending', 'failed' or 'notify'
|
30
|
-
# @option opts [String] title the notification title
|
31
|
-
# @option opts [String] image the path to the notification image
|
32
|
-
# @option opts [String] format printf style format for file contents
|
33
|
-
# @option opts [String] path the path of where to write the file
|
34
|
-
#
|
35
|
-
def notify(message, opts = {})
|
36
|
-
super
|
37
|
-
|
38
|
-
if opts[:path]
|
39
|
-
format = opts.fetch(:format, DEFAULTS[:format])
|
40
|
-
|
41
|
-
_write(opts[:path], format % [opts[:type], opts[:title], message])
|
42
|
-
else
|
43
|
-
::Guard::UI.error ":file notifier requires a :path option"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def _write(path, contents)
|
50
|
-
File.write(path, contents)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|