guard 2.9.0 → 2.9.1
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 +43 -160
- data/lib/guard/cli.rb +49 -17
- data/lib/guard/commander.rb +18 -17
- data/lib/guard/commands/all.rb +1 -2
- data/lib/guard/commands/change.rb +1 -2
- data/lib/guard/commands/reload.rb +1 -2
- data/lib/guard/commands/scope.rb +1 -2
- data/lib/guard/deprecated/evaluator.rb +34 -0
- data/lib/guard/deprecated/guard.rb +15 -3
- data/lib/guard/deprecated/watcher.rb +27 -0
- data/lib/guard/dsl.rb +58 -17
- data/lib/guard/dsl_describer.rb +55 -73
- data/lib/guard/guardfile.rb +1 -1
- data/lib/guard/guardfile/evaluator.rb +96 -158
- data/lib/guard/guardfile/generator.rb +45 -41
- data/lib/guard/interactor.rb +4 -2
- data/lib/guard/internals/groups.rb +40 -0
- data/lib/guard/internals/plugins.rb +51 -0
- data/lib/guard/internals/queue.rb +50 -0
- data/lib/guard/internals/scope.rb +110 -0
- data/lib/guard/internals/session.rb +135 -0
- data/lib/guard/internals/state.rb +33 -0
- data/lib/guard/jobs/pry_wrapper.rb +33 -32
- data/lib/guard/jobs/sleep.rb +3 -4
- data/lib/guard/notifier.rb +2 -0
- data/lib/guard/notifier/detected.rb.orig +83 -0
- data/lib/guard/plugin.rb +242 -6
- data/lib/guard/plugin_util.rb +19 -18
- data/lib/guard/reevaluator.rb +50 -10
- data/lib/guard/runner.rb +30 -108
- data/lib/guard/ui.rb +6 -24
- data/lib/guard/version.rb +1 -1
- data/lib/guard/watcher.rb +4 -12
- metadata +11 -6
- data/lib/guard/metadata.rb +0 -190
- data/lib/guard/plugin/base.rb +0 -183
- data/lib/guard/plugin/hooker.rb +0 -108
- data/lib/guard/session.rb +0 -5
data/lib/guard/commands/all.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# required for async_queue_add
|
2
2
|
require "pry"
|
3
3
|
|
4
|
-
# TODO: remove this dependency
|
5
4
|
require "guard/interactor"
|
6
5
|
require "guard"
|
7
6
|
|
@@ -23,7 +22,7 @@ module Guard
|
|
23
22
|
BANNER
|
24
23
|
|
25
24
|
def process(*entries)
|
26
|
-
scopes, unknown =
|
25
|
+
scopes, unknown = Interactor.convert_scope(entries)
|
27
26
|
|
28
27
|
unless unknown.empty?
|
29
28
|
output.puts "Unknown scopes: #{ unknown.join(", ") }"
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require "pry"
|
2
2
|
|
3
|
-
# TODO: remove
|
4
3
|
require "guard"
|
5
4
|
|
6
5
|
module Guard
|
@@ -23,7 +22,7 @@ module Guard
|
|
23
22
|
return
|
24
23
|
end
|
25
24
|
|
26
|
-
|
25
|
+
Guard.async_queue_add(modified: files, added: [], removed: [])
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require "pry"
|
2
2
|
|
3
|
-
# TODO: should not be necessary!
|
4
3
|
require "guard/interactor"
|
5
4
|
require "guard"
|
6
5
|
|
@@ -22,7 +21,7 @@ module Guard
|
|
22
21
|
BANNER
|
23
22
|
|
24
23
|
def process(*entries)
|
25
|
-
scopes, unknown =
|
24
|
+
scopes, unknown = Interactor.convert_scope(entries)
|
26
25
|
|
27
26
|
unless unknown.empty?
|
28
27
|
output.puts "Unknown scopes: #{ unknown.join(", ") }"
|
data/lib/guard/commands/scope.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "guard/config"
|
2
|
+
fail "Deprecations disabled (strict mode)" if Guard::Config.new.strict?
|
3
|
+
|
4
|
+
require "guard/ui"
|
5
|
+
|
6
|
+
module Guard
|
7
|
+
module Deprecated
|
8
|
+
module Evaluator
|
9
|
+
def self.add_deprecated(klass)
|
10
|
+
klass.send(:include, self)
|
11
|
+
end
|
12
|
+
|
13
|
+
EVALUATE_GUARDFILE = <<-EOS.gsub(/^\s*/, "")
|
14
|
+
Starting with Guard 2.8.3 'Guard::Evaluator#evaluate_guardfile' is
|
15
|
+
deprecated in favor of '#evaluate'.
|
16
|
+
EOS
|
17
|
+
|
18
|
+
REEVALUATE_GUARDFILE = <<-EOS.gsub(/^\s*/, "")
|
19
|
+
Starting with Guard 2.8.3 'Guard::Evaluator#reevaluate_guardfile' is
|
20
|
+
deprecated in favor of '#reevaluate'.
|
21
|
+
EOS
|
22
|
+
|
23
|
+
def evaluate_guardfile
|
24
|
+
UI.deprecation(EVALUATE_GUARDFILE)
|
25
|
+
evaluate
|
26
|
+
end
|
27
|
+
|
28
|
+
def reevaluate_guardfile
|
29
|
+
UI.deprecation(REEVALUATE_GUARDFILE)
|
30
|
+
::Guard::Reevaluator.new.reevaluate
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -138,10 +138,9 @@ module Guard
|
|
138
138
|
EOS
|
139
139
|
|
140
140
|
def evaluator
|
141
|
-
# TODO: probably deprecate once it isn't used internally
|
142
|
-
# TODO: this will be changed to the following when scope is reworked
|
143
141
|
UI.deprecation(EVALUATOR)
|
144
|
-
::Guard
|
142
|
+
options = ::Guard.state.session.evaluator_options
|
143
|
+
::Guard::Guardfile::Evaluator.new(options)
|
145
144
|
end
|
146
145
|
|
147
146
|
RESET_EVALUATOR = <<-EOS.gsub(/^\s*/, "")
|
@@ -160,6 +159,19 @@ module Guard
|
|
160
159
|
UI.deprecation(RUNNER)
|
161
160
|
::Guard::Runner.new
|
162
161
|
end
|
162
|
+
|
163
|
+
EVALUATE_GUARDFILE = <<-EOS.gsub(/^\s*/, "")
|
164
|
+
Starting with Guard 2.8.2 this method shouldn't be used
|
165
|
+
EOS
|
166
|
+
|
167
|
+
def evaluate_guardfile
|
168
|
+
UI.deprecation(EVALUATE_GUARDFILE)
|
169
|
+
options = ::Guard.state.session.evaluator_options
|
170
|
+
evaluator = ::Guard::Guardfile::Evaluator.new(options)
|
171
|
+
evaluator.evaluate
|
172
|
+
msg = "No plugins found in Guardfile, please add at least one."
|
173
|
+
::Guard::UI.error msg if _pluginless_guardfile?
|
174
|
+
end
|
163
175
|
end
|
164
176
|
end
|
165
177
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "guard/config"
|
2
|
+
fail "Deprecations disabled (strict mode)" if Guard::Config.new.strict?
|
3
|
+
|
4
|
+
module Guard
|
5
|
+
module Deprecated
|
6
|
+
module Watcher
|
7
|
+
def self.add_deprecated(dsl_klass)
|
8
|
+
dsl_klass.send(:extend, ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
MATCH_GUARDFILE = <<-EOS.gsub(/^\s*/, "")
|
13
|
+
Starting with Guard 2.8.3 this method is deprecated.
|
14
|
+
EOS
|
15
|
+
|
16
|
+
def match_guardfile?(files)
|
17
|
+
require "guard/guardfile/evaluator"
|
18
|
+
UI.deprecation(MATCH_GUARDFILE)
|
19
|
+
options = ::Guard.state.session.evaluator_options
|
20
|
+
evaluator = ::Guard::Guardfile::Evaluator.new(options)
|
21
|
+
path = evaluator.guardfile_path
|
22
|
+
files.any? { |file| File.expand_path(file) == path }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/guard/dsl.rb
CHANGED
@@ -26,10 +26,10 @@ module Guard
|
|
26
26
|
# {Notifier} for more information about the supported libraries.
|
27
27
|
#
|
28
28
|
# A more advanced DSL use is the {#callback} keyword that allows you to
|
29
|
-
# execute arbitrary code before or after any of the {Plugin
|
30
|
-
# {Plugin
|
31
|
-
# {Plugin
|
32
|
-
# {Plugin
|
29
|
+
# execute arbitrary code before or after any of the {Plugin#start},
|
30
|
+
# {Plugin#stop}, {Plugin#reload}, {Plugin#run_all},
|
31
|
+
# {Plugin#run_on_changes}, {Plugin#run_on_additions},
|
32
|
+
# {Plugin#run_on_modifications} and {Plugin#run_on_removals}
|
33
33
|
# Guard plugins method.
|
34
34
|
# You can even insert more hooks inside these methods. Please [checkout the
|
35
35
|
# Wiki page](https://github.com/guard/guard/wiki/Hooks-and-callbacks) for
|
@@ -50,6 +50,10 @@ module Guard
|
|
50
50
|
class Dsl
|
51
51
|
Deprecated::Dsl.add_deprecated(self) unless Config.new.strict?
|
52
52
|
|
53
|
+
# Wrap exceptions during parsing Guardfile
|
54
|
+
class Error < RuntimeError
|
55
|
+
end
|
56
|
+
|
53
57
|
WARN_INVALID_LOG_LEVEL = "Invalid log level `%s` ignored. "\
|
54
58
|
"Please use either :debug, :info, :warn or :error."
|
55
59
|
|
@@ -88,9 +92,9 @@ module Guard
|
|
88
92
|
def interactor(options)
|
89
93
|
case options
|
90
94
|
when :off
|
91
|
-
|
95
|
+
Interactor.enabled = false
|
92
96
|
when Hash
|
93
|
-
|
97
|
+
Interactor.options = options
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
@@ -128,7 +132,7 @@ module Guard
|
|
128
132
|
|
129
133
|
if block_given?
|
130
134
|
groups.each do |group|
|
131
|
-
|
135
|
+
Guard.state.session.groups.add(group, options)
|
132
136
|
end
|
133
137
|
|
134
138
|
@current_groups ||= []
|
@@ -138,7 +142,7 @@ module Guard
|
|
138
142
|
|
139
143
|
@current_groups.pop
|
140
144
|
else
|
141
|
-
|
145
|
+
UI.error \
|
142
146
|
"No Guard plugins found in the group '#{ groups.join(", ") }',"\
|
143
147
|
" please add at least one."
|
144
148
|
end
|
@@ -176,7 +180,8 @@ module Guard
|
|
176
180
|
@current_groups ||= []
|
177
181
|
groups = @current_groups && @current_groups.last || [:default]
|
178
182
|
groups.each do |group|
|
179
|
-
|
183
|
+
opts = @plugin_options.merge(group: group)
|
184
|
+
Guard.state.session.plugins.add(name, opts)
|
180
185
|
end
|
181
186
|
|
182
187
|
@plugin_options = nil
|
@@ -214,7 +219,7 @@ module Guard
|
|
214
219
|
@plugin_options ||= nil
|
215
220
|
return guard(:plugin) { watch(pattern, &action) } unless @plugin_options
|
216
221
|
|
217
|
-
@plugin_options[:watchers] <<
|
222
|
+
@plugin_options[:watchers] << Watcher.new(pattern, action)
|
218
223
|
end
|
219
224
|
|
220
225
|
# Defines a callback to execute arbitrary code before or after any of
|
@@ -237,8 +242,6 @@ module Guard
|
|
237
242
|
# @param [Array] args the callback arguments
|
238
243
|
# @yield a callback block
|
239
244
|
#
|
240
|
-
# @see Guard::Hooker
|
241
|
-
#
|
242
245
|
def callback(*args, &block)
|
243
246
|
@plugin_options ||= nil
|
244
247
|
fail "callback must be called within a guard block" unless @plugin_options
|
@@ -262,8 +265,10 @@ module Guard
|
|
262
265
|
#
|
263
266
|
def ignore(*regexps)
|
264
267
|
# TODO: instead, use Guard.reconfigure(ignore: regexps) or something
|
265
|
-
|
268
|
+
Guard.listener.ignore(regexps) if Guard.listener
|
266
269
|
end
|
270
|
+
|
271
|
+
# TODO: deprecate
|
267
272
|
alias filter ignore
|
268
273
|
|
269
274
|
# Replaces ignored paths globally
|
@@ -276,7 +281,7 @@ module Guard
|
|
276
281
|
def ignore!(*regexps)
|
277
282
|
@ignore_regexps ||= []
|
278
283
|
@ignore_regexps << regexps
|
279
|
-
|
284
|
+
Guard.listener.ignore!(@ignore_regexps) if Guard.listener
|
280
285
|
end
|
281
286
|
alias filter! ignore!
|
282
287
|
|
@@ -341,7 +346,7 @@ module Guard
|
|
341
346
|
options[name] = Regexp.new(list.join("|"), Regexp::IGNORECASE)
|
342
347
|
end
|
343
348
|
|
344
|
-
|
349
|
+
UI.options.merge!(options)
|
345
350
|
end
|
346
351
|
|
347
352
|
# Sets the default scope on startup
|
@@ -361,7 +366,43 @@ module Guard
|
|
361
366
|
# @param [Hash] scopes the scope for the groups and plugins
|
362
367
|
#
|
363
368
|
def scope(scope = {})
|
364
|
-
|
369
|
+
Guard.state.session.guardfile_scope(scope)
|
370
|
+
end
|
371
|
+
|
372
|
+
def evaluate(contents, filename, lineno) # :nodoc
|
373
|
+
instance_eval(contents, filename.to_s, lineno)
|
374
|
+
rescue StandardError, ScriptError => e
|
375
|
+
prefix = "\n\t(dsl)> "
|
376
|
+
cleaned_backtrace = _cleanup_backtrace(e.backtrace)
|
377
|
+
backtrace = "#{prefix}#{cleaned_backtrace.join(prefix)}"
|
378
|
+
msg = "Invalid Guardfile, original error is: \n\n%s, \nbacktrace: %s"
|
379
|
+
raise Error, format(msg, e, backtrace)
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
def _cleanup_backtrace(backtrace)
|
385
|
+
dirs = { File.realpath(Dir.pwd) => ".", }
|
386
|
+
|
387
|
+
gem_env = ENV["GEM_HOME"] || ""
|
388
|
+
dirs[gem_env] = "$GEM_HOME" unless gem_env.empty?
|
389
|
+
|
390
|
+
gem_paths = (ENV["GEM_PATH"] || "").split(File::PATH_SEPARATOR)
|
391
|
+
gem_paths.each_with_index do |path, index|
|
392
|
+
dirs[path] = "$GEM_PATH[#{index}]"
|
393
|
+
end
|
394
|
+
|
395
|
+
backtrace.dup.map do |raw_line|
|
396
|
+
path = nil
|
397
|
+
symlinked_path = raw_line.split(":").first
|
398
|
+
begin
|
399
|
+
path = raw_line.sub(symlinked_path, File.realpath(symlinked_path))
|
400
|
+
dirs.detect { |dir, name| path.sub!(File.realpath(dir), name) }
|
401
|
+
path
|
402
|
+
rescue Errno::ENOENT
|
403
|
+
path || symlinked_path
|
404
|
+
end
|
405
|
+
end
|
365
406
|
end
|
366
407
|
|
367
408
|
# Sets the directories to pass to Listen
|
@@ -375,7 +416,7 @@ module Guard
|
|
375
416
|
directories.each do |dir|
|
376
417
|
fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
|
377
418
|
end
|
378
|
-
|
419
|
+
Guard.state.session.watchdirs = directories
|
379
420
|
end
|
380
421
|
end
|
381
422
|
end
|
data/lib/guard/dsl_describer.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "formatador"
|
3
3
|
|
4
|
-
require "guard/guardfile/evaluator"
|
5
4
|
require "guard/ui"
|
6
|
-
require "guard/
|
5
|
+
require "guard/notifier"
|
6
|
+
|
7
|
+
require "set"
|
8
|
+
require "ostruct"
|
7
9
|
|
8
10
|
module Guard
|
9
11
|
# The DslDescriber evaluates the Guardfile and creates an internal structure
|
@@ -14,20 +16,8 @@ module Guard
|
|
14
16
|
# @see Guard::CLI
|
15
17
|
#
|
16
18
|
class DslDescriber
|
17
|
-
|
18
|
-
|
19
|
-
# @option options [String] guardfile the path to a valid Guardfile
|
20
|
-
#
|
21
|
-
# @option options [String] guardfile_contents a string representing the
|
22
|
-
# content of a valid Guardfile
|
23
|
-
#
|
24
|
-
# @see Guard::Guardfile::Evaluator#initialize
|
25
|
-
#
|
26
|
-
def initialize(options = {})
|
27
|
-
::Guard.reset_groups
|
28
|
-
::Guard.reset_plugins
|
29
|
-
::Guard.reset_scope
|
30
|
-
::Guard.reset_options(options)
|
19
|
+
def initialize(options = nil)
|
20
|
+
fail "options passed to DslDescriber are ignored!" unless options.nil?
|
31
21
|
end
|
32
22
|
|
33
23
|
# List the Guard plugins that are available for use in your system and marks
|
@@ -36,17 +26,21 @@ module Guard
|
|
36
26
|
# @see CLI#list
|
37
27
|
#
|
38
28
|
def list
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
29
|
+
# collect metadata
|
30
|
+
data = PluginUtil.plugin_names.sort.inject({}) do |hash, name|
|
31
|
+
hash[name.capitalize] = Guard.state.session.plugins.all(name).any?
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
|
35
|
+
# presentation
|
36
|
+
header = [:Plugin, :Guardfile]
|
37
|
+
final_rows = []
|
38
|
+
data.each do |name, used|
|
39
|
+
final_rows << { Plugin: name, Guardfile: used ? "✔" : "✘" }
|
47
40
|
end
|
48
41
|
|
49
|
-
|
42
|
+
# render
|
43
|
+
Formatador.display_compact_table(final_rows, header)
|
50
44
|
end
|
51
45
|
|
52
46
|
# Shows all Guard plugins and their options that are defined in
|
@@ -55,53 +49,52 @@ module Guard
|
|
55
49
|
# @see CLI#show
|
56
50
|
#
|
57
51
|
def show
|
58
|
-
|
59
|
-
groups =
|
52
|
+
# collect metadata
|
53
|
+
groups = Guard.state.session.groups.all
|
60
54
|
|
61
|
-
|
55
|
+
objects = []
|
62
56
|
|
63
|
-
|
57
|
+
empty_plugin = OpenStruct.new
|
58
|
+
empty_plugin.options = [["", nil]]
|
64
59
|
|
60
|
+
groups.each do |group|
|
61
|
+
plugins = Array(Guard.state.session.plugins.all(group: group.name))
|
62
|
+
plugins = [empty_plugin] if plugins.empty?
|
65
63
|
plugins.each do |plugin|
|
66
|
-
options = plugin.options
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
rows << :split
|
72
|
-
rows << {
|
73
|
-
Group: group.title,
|
74
|
-
Plugin: plugin.title,
|
75
|
-
Option: "",
|
76
|
-
Value: ""
|
77
|
-
}
|
78
|
-
else
|
79
|
-
options.each_with_index do |(option, value), index|
|
80
|
-
if index == 0
|
81
|
-
rows << :split
|
82
|
-
rows << {
|
83
|
-
Group: group.title,
|
84
|
-
Plugin: plugin.title,
|
85
|
-
Option: option.to_s,
|
86
|
-
Value: value.inspect
|
87
|
-
}
|
88
|
-
else
|
89
|
-
rows << {
|
90
|
-
Group: "",
|
91
|
-
Plugin: "",
|
92
|
-
Option: option.to_s,
|
93
|
-
Value: value.inspect
|
94
|
-
}
|
95
|
-
end
|
96
|
-
end
|
64
|
+
options = plugin.options
|
65
|
+
options = [["", nil]] if options.empty?
|
66
|
+
options.each do |option, raw_value|
|
67
|
+
value = raw_value.nil? ? "" : raw_value.inspect
|
68
|
+
objects << [group.title, plugin.title, option.to_s, value]
|
97
69
|
end
|
98
70
|
end
|
71
|
+
end
|
99
72
|
|
100
|
-
|
73
|
+
# presentation
|
74
|
+
rows = []
|
75
|
+
prev_group = prev_plugin = prev_option = prev_value = nil
|
76
|
+
objects.each do |group, plugin, option, value|
|
77
|
+
group_changed = prev_group != group
|
78
|
+
plugin_changed = (prev_plugin != plugin || group_changed)
|
79
|
+
|
80
|
+
rows << :split if group_changed || plugin_changed
|
81
|
+
|
82
|
+
rows << {
|
83
|
+
Group: group_changed ? group : "",
|
84
|
+
Plugin: plugin_changed ? plugin : "",
|
85
|
+
Option: option,
|
86
|
+
Value: value
|
87
|
+
}
|
88
|
+
|
89
|
+
prev_group = group
|
90
|
+
prev_plugin = plugin
|
91
|
+
prev_option = option
|
92
|
+
prev_value = value
|
101
93
|
end
|
102
94
|
|
95
|
+
# render
|
103
96
|
Formatador.display_compact_table(
|
104
|
-
|
97
|
+
rows.drop(1),
|
105
98
|
[:Group, :Plugin, :Option, :Value]
|
106
99
|
)
|
107
100
|
end
|
@@ -112,8 +105,6 @@ module Guard
|
|
112
105
|
# @see CLI#show
|
113
106
|
#
|
114
107
|
def notifiers
|
115
|
-
_evaluate_guardfile
|
116
|
-
|
117
108
|
supported = ::Guard::Notifier::SUPPORTED
|
118
109
|
Notifier.connect(notify: false)
|
119
110
|
detected = Notifier.notifiers
|
@@ -156,15 +147,6 @@ module Guard
|
|
156
147
|
|
157
148
|
private
|
158
149
|
|
159
|
-
# Evaluates the `Guardfile` by delegating to
|
160
|
-
# {Guard::Guardfile::Evaluator#evaluate_guardfile}.
|
161
|
-
#
|
162
|
-
def _evaluate_guardfile
|
163
|
-
::Guard.save_scope
|
164
|
-
::Guard::Guardfile::Evaluator.new(::Guard.options).evaluate_guardfile
|
165
|
-
::Guard.restore_scope
|
166
|
-
end
|
167
|
-
|
168
150
|
def _merge_options(klass, notifier)
|
169
151
|
notify_options = notifier ? notifier[:options] : {}
|
170
152
|
|