guard 1.8.3 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +68 -10
- data/README.md +54 -33
- data/lib/guard.rb +133 -483
- data/lib/guard/cli.rb +78 -82
- data/lib/guard/commander.rb +121 -0
- data/lib/guard/commands/all.rb +1 -1
- data/lib/guard/commands/reload.rb +1 -1
- data/lib/guard/deprecated_methods.rb +59 -0
- data/lib/guard/deprecator.rb +107 -0
- data/lib/guard/dsl.rb +143 -329
- data/lib/guard/dsl_describer.rb +101 -57
- data/lib/guard/group.rb +27 -8
- data/lib/guard/guard.rb +25 -150
- data/lib/guard/guardfile.rb +35 -85
- data/lib/guard/guardfile/evaluator.rb +245 -0
- data/lib/guard/guardfile/generator.rb +89 -0
- data/lib/guard/interactor.rb +147 -163
- data/lib/guard/notifier.rb +83 -137
- data/lib/guard/notifiers/base.rb +220 -0
- data/lib/guard/notifiers/emacs.rb +39 -37
- data/lib/guard/notifiers/file_notifier.rb +29 -25
- data/lib/guard/notifiers/gntp.rb +68 -75
- data/lib/guard/notifiers/growl.rb +49 -52
- data/lib/guard/notifiers/growl_notify.rb +51 -56
- data/lib/guard/notifiers/libnotify.rb +41 -48
- data/lib/guard/notifiers/notifysend.rb +58 -38
- data/lib/guard/notifiers/rb_notifu.rb +54 -54
- data/lib/guard/notifiers/terminal_notifier.rb +48 -36
- data/lib/guard/notifiers/terminal_title.rb +23 -19
- data/lib/guard/notifiers/tmux.rb +110 -93
- data/lib/guard/options.rb +21 -0
- data/lib/guard/plugin.rb +66 -0
- data/lib/guard/plugin/base.rb +178 -0
- data/lib/guard/plugin/hooker.rb +123 -0
- data/lib/guard/plugin_util.rb +158 -0
- data/lib/guard/rake_task.rb +47 -0
- data/lib/guard/runner.rb +62 -82
- data/lib/guard/setuper.rb +248 -0
- data/lib/guard/ui.rb +24 -80
- data/lib/guard/ui/colors.rb +60 -0
- data/lib/guard/version.rb +1 -2
- data/lib/guard/watcher.rb +30 -30
- data/man/guard.1 +4 -4
- data/man/guard.1.html +6 -4
- metadata +25 -11
- data/lib/guard/hook.rb +0 -120
data/lib/guard/ui.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'lumberjack'
|
2
2
|
|
3
|
+
require 'guard/ui/colors'
|
4
|
+
|
3
5
|
module Guard
|
4
6
|
|
5
7
|
# The UI class helps to format messages for the user. Everything that is logged
|
@@ -10,6 +12,7 @@ module Guard
|
|
10
12
|
# processing, please just write it to STDOUT with `puts`.
|
11
13
|
#
|
12
14
|
module UI
|
15
|
+
include Colors
|
13
16
|
|
14
17
|
class << self
|
15
18
|
|
@@ -17,8 +20,8 @@ module Guard
|
|
17
20
|
#
|
18
21
|
def logger
|
19
22
|
@logger ||= begin
|
20
|
-
|
21
|
-
Lumberjack::Logger.new(
|
23
|
+
opts = options.marshal_dump
|
24
|
+
Lumberjack::Logger.new(opts.delete(:device) { $stderr }, opts)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
@@ -27,7 +30,7 @@ module Guard
|
|
27
30
|
# @return [Hash] the logger options
|
28
31
|
#
|
29
32
|
def options
|
30
|
-
@options ||=
|
33
|
+
@options ||= ::Guard::Options.new(level: :info, template: ':time - :severity - :message', time_format: '%H:%M:%S')
|
31
34
|
end
|
32
35
|
|
33
36
|
# Set the logger options
|
@@ -38,7 +41,7 @@ module Guard
|
|
38
41
|
# @option options [String] time_format the time format
|
39
42
|
#
|
40
43
|
def options=(options)
|
41
|
-
@options = options
|
44
|
+
@options = ::Guard::Options.new(options)
|
42
45
|
end
|
43
46
|
|
44
47
|
# Show an info message.
|
@@ -47,10 +50,10 @@ module Guard
|
|
47
50
|
# @option options [Boolean] reset whether to clean the output before
|
48
51
|
# @option options [String] plugin manually define the calling plugin
|
49
52
|
#
|
50
|
-
def info(message, options = {
|
53
|
+
def info(message, options = {})
|
51
54
|
filter(options[:plugin]) do |plugin|
|
52
55
|
reset_line if options[:reset]
|
53
|
-
|
56
|
+
logger.info(message, plugin)
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
@@ -60,10 +63,10 @@ module Guard
|
|
60
63
|
# @option options [Boolean] reset whether to clean the output before
|
61
64
|
# @option options [String] plugin manually define the calling plugin
|
62
65
|
#
|
63
|
-
def warning(message, options = {
|
66
|
+
def warning(message, options = {})
|
64
67
|
filter(options[:plugin]) do |plugin|
|
65
68
|
reset_line if options[:reset]
|
66
|
-
|
69
|
+
logger.warn(color(message, :yellow), plugin)
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
@@ -73,10 +76,10 @@ module Guard
|
|
73
76
|
# @option options [Boolean] reset whether to clean the output before
|
74
77
|
# @option options [String] plugin manually define the calling plugin
|
75
78
|
#
|
76
|
-
def error(message, options = {
|
79
|
+
def error(message, options = {})
|
77
80
|
filter(options[:plugin]) do |plugin|
|
78
81
|
reset_line if options[:reset]
|
79
|
-
|
82
|
+
logger.error(color(message, :red), plugin)
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
@@ -87,10 +90,12 @@ module Guard
|
|
87
90
|
# @option options [Boolean] reset whether to clean the output before
|
88
91
|
# @option options [String] plugin manually define the calling plugin
|
89
92
|
#
|
90
|
-
def deprecation(message, options = {
|
93
|
+
def deprecation(message, options = {})
|
94
|
+
return unless ::Guard.options.show_deprecations
|
95
|
+
|
91
96
|
filter(options[:plugin]) do |plugin|
|
92
97
|
reset_line if options[:reset]
|
93
|
-
|
98
|
+
logger.warn(color(message, :yellow), plugin)
|
94
99
|
end
|
95
100
|
end
|
96
101
|
|
@@ -100,10 +105,10 @@ module Guard
|
|
100
105
|
# @option options [Boolean] reset whether to clean the output before
|
101
106
|
# @option options [String] plugin manually define the calling plugin
|
102
107
|
#
|
103
|
-
def debug(message, options = {
|
108
|
+
def debug(message, options = {})
|
104
109
|
filter(options[:plugin]) do |plugin|
|
105
110
|
reset_line if options[:reset]
|
106
|
-
|
111
|
+
logger.debug(color(message, :yellow), plugin)
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
@@ -116,7 +121,7 @@ module Guard
|
|
116
121
|
# Clear the output if clearable.
|
117
122
|
#
|
118
123
|
def clear(options = {})
|
119
|
-
if ::Guard.options
|
124
|
+
if ::Guard.options.clear && (@clearable || options[:force])
|
120
125
|
@clearable = false
|
121
126
|
system('clear;')
|
122
127
|
end
|
@@ -142,8 +147,8 @@ module Guard
|
|
142
147
|
groups = ::Guard.scope[:groups] || []
|
143
148
|
end
|
144
149
|
|
145
|
-
scope_message ||= plugins.join(',') unless plugins.empty?
|
146
|
-
scope_message ||= groups.join(',') unless groups.empty?
|
150
|
+
scope_message ||= plugins.map(&:title).join(', ') unless plugins.empty?
|
151
|
+
scope_message ||= groups.map(&:title).join(', ') unless groups.empty?
|
147
152
|
scope_message ||= 'all'
|
148
153
|
|
149
154
|
info "#{ action } #{ scope_message }"
|
@@ -159,8 +164,8 @@ module Guard
|
|
159
164
|
# @yieldparam [String] param the calling plugin name
|
160
165
|
#
|
161
166
|
def filter(plugin)
|
162
|
-
only =
|
163
|
-
except =
|
167
|
+
only = options.only
|
168
|
+
except = options.except
|
164
169
|
plugin = plugin || calling_plugin_name
|
165
170
|
|
166
171
|
if (!only && !except) || (only && only.match(plugin)) || (except && !except.match(plugin))
|
@@ -179,16 +184,6 @@ module Guard
|
|
179
184
|
name ? name[1].split('/').map { |part| part.split(/[^a-z0-9]/i).map { |word| word.capitalize }.join }.join('::') : 'Guard'
|
180
185
|
end
|
181
186
|
|
182
|
-
# Reset a color sequence.
|
183
|
-
#
|
184
|
-
# @deprecated
|
185
|
-
# @param [String] text the text
|
186
|
-
#
|
187
|
-
def reset_color(text)
|
188
|
-
deprecation('UI.reset_color(text) is deprecated, please use color(text, ' ') instead.')
|
189
|
-
color(text, '')
|
190
|
-
end
|
191
|
-
|
192
187
|
# Checks if color output can be enabled.
|
193
188
|
#
|
194
189
|
# @return [Boolean] whether color is enabled or not
|
@@ -243,56 +238,5 @@ module Guard
|
|
243
238
|
|
244
239
|
end
|
245
240
|
|
246
|
-
# Brighten the color
|
247
|
-
ANSI_ESCAPE_BRIGHT = '1'
|
248
|
-
|
249
|
-
# Black foreground color
|
250
|
-
ANSI_ESCAPE_BLACK = '30'
|
251
|
-
|
252
|
-
# Red foreground color
|
253
|
-
ANSI_ESCAPE_RED = '31'
|
254
|
-
|
255
|
-
# Green foreground color
|
256
|
-
ANSI_ESCAPE_GREEN = '32'
|
257
|
-
|
258
|
-
# Yellow foreground color
|
259
|
-
ANSI_ESCAPE_YELLOW = '33'
|
260
|
-
|
261
|
-
# Blue foreground color
|
262
|
-
ANSI_ESCAPE_BLUE = '34'
|
263
|
-
|
264
|
-
# Magenta foreground color
|
265
|
-
ANSI_ESCAPE_MAGENTA = '35'
|
266
|
-
|
267
|
-
# Cyan foreground color
|
268
|
-
ANSI_ESCAPE_CYAN = '36'
|
269
|
-
|
270
|
-
# White foreground color
|
271
|
-
ANSI_ESCAPE_WHITE = '37'
|
272
|
-
|
273
|
-
# Black background color
|
274
|
-
ANSI_ESCAPE_BGBLACK = '40'
|
275
|
-
|
276
|
-
# Red background color
|
277
|
-
ANSI_ESCAPE_BGRED = '41'
|
278
|
-
|
279
|
-
# Green background color
|
280
|
-
ANSI_ESCAPE_BGGREEN = '42'
|
281
|
-
|
282
|
-
# Yellow background color
|
283
|
-
ANSI_ESCAPE_BGYELLOW = '43'
|
284
|
-
|
285
|
-
# Blue background color
|
286
|
-
ANSI_ESCAPE_BGBLUE = '44'
|
287
|
-
|
288
|
-
# Magenta background color
|
289
|
-
ANSI_ESCAPE_BGMAGENTA = '45'
|
290
|
-
|
291
|
-
# Cyan background color
|
292
|
-
ANSI_ESCAPE_BGCYAN = '46'
|
293
|
-
|
294
|
-
# White background color
|
295
|
-
ANSI_ESCAPE_BGWHITE = '47'
|
296
|
-
|
297
241
|
end
|
298
242
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Guard
|
2
|
+
module UI
|
3
|
+
|
4
|
+
module Colors
|
5
|
+
|
6
|
+
# Brighten the color
|
7
|
+
ANSI_ESCAPE_BRIGHT = '1'
|
8
|
+
|
9
|
+
# Black foreground color
|
10
|
+
ANSI_ESCAPE_BLACK = '30'
|
11
|
+
|
12
|
+
# Red foreground color
|
13
|
+
ANSI_ESCAPE_RED = '31'
|
14
|
+
|
15
|
+
# Green foreground color
|
16
|
+
ANSI_ESCAPE_GREEN = '32'
|
17
|
+
|
18
|
+
# Yellow foreground color
|
19
|
+
ANSI_ESCAPE_YELLOW = '33'
|
20
|
+
|
21
|
+
# Blue foreground color
|
22
|
+
ANSI_ESCAPE_BLUE = '34'
|
23
|
+
|
24
|
+
# Magenta foreground color
|
25
|
+
ANSI_ESCAPE_MAGENTA = '35'
|
26
|
+
|
27
|
+
# Cyan foreground color
|
28
|
+
ANSI_ESCAPE_CYAN = '36'
|
29
|
+
|
30
|
+
# White foreground color
|
31
|
+
ANSI_ESCAPE_WHITE = '37'
|
32
|
+
|
33
|
+
# Black background color
|
34
|
+
ANSI_ESCAPE_BGBLACK = '40'
|
35
|
+
|
36
|
+
# Red background color
|
37
|
+
ANSI_ESCAPE_BGRED = '41'
|
38
|
+
|
39
|
+
# Green background color
|
40
|
+
ANSI_ESCAPE_BGGREEN = '42'
|
41
|
+
|
42
|
+
# Yellow background color
|
43
|
+
ANSI_ESCAPE_BGYELLOW = '43'
|
44
|
+
|
45
|
+
# Blue background color
|
46
|
+
ANSI_ESCAPE_BGBLUE = '44'
|
47
|
+
|
48
|
+
# Magenta background color
|
49
|
+
ANSI_ESCAPE_BGMAGENTA = '45'
|
50
|
+
|
51
|
+
# Cyan background color
|
52
|
+
ANSI_ESCAPE_BGCYAN = '46'
|
53
|
+
|
54
|
+
# White background color
|
55
|
+
ANSI_ESCAPE_BGWHITE = '47'
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/guard/version.rb
CHANGED
data/lib/guard/watcher.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
|
+
require 'guard/ui'
|
2
|
+
|
1
3
|
module Guard
|
2
4
|
|
3
|
-
# The watcher defines a RegExp that will be matched against file system
|
4
|
-
#
|
5
|
-
#
|
5
|
+
# The watcher defines a RegExp that will be matched against file system
|
6
|
+
# modifications.
|
7
|
+
# When a watcher matches a change, an optional action block is executed to
|
8
|
+
# enable processing the file system change result.
|
6
9
|
#
|
7
10
|
class Watcher
|
8
11
|
|
9
|
-
require 'guard/ui'
|
10
|
-
|
11
12
|
attr_accessor :pattern, :action
|
12
13
|
|
13
|
-
#
|
14
|
+
# Initializes a file watcher.
|
14
15
|
#
|
15
|
-
# @param [String, Regexp] pattern the pattern to be watched by the Guard
|
16
|
-
#
|
16
|
+
# @param [String, Regexp] pattern the pattern to be watched by the Guard
|
17
|
+
# plugin
|
18
|
+
# @param [Block] action the action to execute before passing the result to
|
19
|
+
# the Guard plugin
|
17
20
|
#
|
18
21
|
def initialize(pattern, action = nil)
|
19
22
|
@pattern, @action = pattern, action
|
@@ -36,14 +39,15 @@ module Guard
|
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
39
|
-
# Finds the files that matches a Guard.
|
42
|
+
# Finds the files that matches a Guard plugin.
|
40
43
|
#
|
41
|
-
# @param [Guard::
|
44
|
+
# @param [Guard::Plugin] guard the Guard plugin which watchers are used
|
42
45
|
# @param [Array<String>] files the changed files
|
43
46
|
# @return [Array<Object>] the matched watcher response
|
44
47
|
#
|
45
48
|
def self.match_files(guard, files)
|
46
49
|
return [] if files.empty?
|
50
|
+
|
47
51
|
guard.watchers.inject([]) do |paths, watcher|
|
48
52
|
files.each do |file|
|
49
53
|
if matches = watcher.match(file)
|
@@ -64,31 +68,35 @@ module Guard
|
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
|
-
#
|
71
|
+
# Tests if a file would be matched by any of the Guard plugin watchers.
|
68
72
|
#
|
69
|
-
# @param [Array<Guard::
|
73
|
+
# @param [Array<Guard::Plugin>] plugins the Guard plugins to use the
|
74
|
+
# watchers from
|
70
75
|
# @param [Array<String>] files the files to test
|
71
76
|
# @return [Boolean] Whether a file matches
|
72
77
|
#
|
73
|
-
def self.match_files?(
|
74
|
-
|
75
|
-
|
78
|
+
def self.match_files?(plugins, files)
|
79
|
+
plugins.any? do |plugin|
|
80
|
+
plugin.watchers.any? do |watcher|
|
76
81
|
files.any? { |file| watcher.match(file) }
|
77
82
|
end
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
81
|
-
#
|
86
|
+
# Tests if any of the files is the Guardfile.
|
82
87
|
#
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
# @param [Array<String>] files the files to test
|
89
|
+
# @return [Boolean] whether one of these files is the Guardfile
|
90
|
+
#
|
91
|
+
def self.match_guardfile?(files)
|
92
|
+
files.any? { |file| "#{ Dir.pwd }/#{ file }" == ::Guard.evaluator.guardfile_path }
|
86
93
|
end
|
87
94
|
|
88
95
|
# Test the watchers pattern against a file.
|
89
96
|
#
|
90
97
|
# @param [String] file the file to test
|
91
|
-
# @return [Array<String>] an array of matches (or containing a single path
|
98
|
+
# @return [Array<String>] an array of matches (or containing a single path
|
99
|
+
# if the pattern is a string)
|
92
100
|
#
|
93
101
|
def match(file)
|
94
102
|
f = file
|
@@ -105,18 +113,10 @@ module Guard
|
|
105
113
|
end
|
106
114
|
end
|
107
115
|
|
108
|
-
# Test if any of the files is the Guardfile.
|
109
|
-
#
|
110
|
-
# @param [Array<String>] files the files to test
|
111
|
-
# @return [Boolean] whether one of these files is the Guardfile
|
112
|
-
#
|
113
|
-
def self.match_guardfile?(files)
|
114
|
-
files.any? { |file| "#{ Dir.pwd }/#{ file }" == Dsl.guardfile_path }
|
115
|
-
end
|
116
|
-
|
117
116
|
# Executes a watcher action.
|
118
117
|
#
|
119
|
-
# @param [String, MatchData] matches the matched path or the match from the
|
118
|
+
# @param [String, MatchData] matches the matched path or the match from the
|
119
|
+
# Regex
|
120
120
|
# @return [String] the final paths
|
121
121
|
#
|
122
122
|
def call_action(matches)
|
data/man/guard.1
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
.\" generated with Ronn/v0.7.3
|
2
2
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
3
|
.
|
4
|
-
.TH "GUARD" "1" "
|
4
|
+
.TH "GUARD" "1" "September 2013" "" ""
|
5
5
|
.
|
6
6
|
.SH "NAME"
|
7
7
|
\fBguard\fR \- Guard keeps an eye on your file modifications\.
|
@@ -98,11 +98,11 @@ Thibaud Guillaume\-Gentil is the main author\.
|
|
98
98
|
.P
|
99
99
|
A list of contributors based on all commits can be found here: https://github\.com/guard/guard/contributors
|
100
100
|
.
|
101
|
-
.
|
102
|
-
|
101
|
+
.SH "CHANGELOG"
|
102
|
+
The changelog can be found at: https://github\.com/guard/guard/blob/master/CHANGELOG\.md
|
103
103
|
.
|
104
104
|
.P
|
105
105
|
This manual has been written by Remy Coutable\.
|
106
106
|
.
|
107
107
|
.SH "WWW"
|
108
|
-
|
108
|
+
http://guardgem\.org/
|
data/man/guard.1.html
CHANGED
@@ -59,6 +59,7 @@
|
|
59
59
|
<a href="#COMMANDS">COMMANDS</a>
|
60
60
|
<a href="#EXAMPLES">EXAMPLES</a>
|
61
61
|
<a href="#AUTHORS-CONTRIBUTORS">AUTHORS / CONTRIBUTORS</a>
|
62
|
+
<a href="#CHANGELOG">CHANGELOG</a>
|
62
63
|
<a href="#WWW">WWW</a>
|
63
64
|
</div>
|
64
65
|
|
@@ -173,19 +174,20 @@ For instance to initialize guard-rspec, run <code>guard init rspec</code>.</p>
|
|
173
174
|
<p>A list of contributors based on all commits can be found here:
|
174
175
|
https://github.com/guard/guard/contributors</p>
|
175
176
|
|
176
|
-
<
|
177
|
-
|
177
|
+
<h2 id="CHANGELOG">CHANGELOG</h2>
|
178
|
+
|
179
|
+
<p>The changelog can be found at: https://github.com/guard/guard/blob/master/CHANGELOG.md</p>
|
178
180
|
|
179
181
|
<p>This manual has been written by Remy Coutable.</p>
|
180
182
|
|
181
183
|
<h2 id="WWW">WWW</h2>
|
182
184
|
|
183
|
-
<p>
|
185
|
+
<p>http://guardgem.org/</p>
|
184
186
|
|
185
187
|
|
186
188
|
<ol class='man-decor man-foot man foot'>
|
187
189
|
<li class='tl'></li>
|
188
|
-
<li class='tc'>
|
190
|
+
<li class='tc'>September 2013</li>
|
189
191
|
<li class='tr'>guard(1)</li>
|
190
192
|
</ol>
|
191
193
|
|