guard 2.10.5 → 2.11.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.
- 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
|