guard 2.9.2 → 2.10.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/README.md +41 -3
- data/lib/guard.rb +6 -2
- data/lib/guard/deprecated/guard.rb +12 -0
- data/lib/guard/deprecated/guard.rb.orig +178 -0
- data/lib/guard/dsl.rb +25 -14
- data/lib/guard/internals/session.rb +7 -2
- data/lib/guard/internals/session.rb.orig +135 -0
- data/lib/guard/templates/Guardfile +4 -2
- data/lib/guard/ui.rb.orig +274 -0
- data/lib/guard/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6996dd69034de1636618026e8606df7f10b2b22b
|
4
|
+
data.tar.gz: c374f6846a61be304447f9518ad72d219ba0b12f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d4cf024a8ce54ad66c2bd9ba03b46a457924da685ec6987e6ae0c4823e2ebc30fd15627b9dae5b01f7c844158cc420f1396d532c525e4b6d4175feb0167aef2
|
7
|
+
data.tar.gz: fc31605dee865f1371c2e6fca5d71c35ef7f4d1ca5255acf364972f9312785ebb897776e985632d966edc88b58b0d9e2d913b6987a9cc9576943041b0e74f304
|
data/README.md
CHANGED
@@ -198,10 +198,11 @@ $ bundle exec guard --clear
|
|
198
198
|
$ bundle exec guard -c # shortcut
|
199
199
|
```
|
200
200
|
|
201
|
-
You
|
201
|
+
You may prefer to enable clearing in all projects by addin the `clearing`
|
202
|
+
statement (described below) in you `~/.guardrc` instead:
|
202
203
|
|
203
|
-
```
|
204
|
-
|
204
|
+
```ruby
|
205
|
+
clearing :on
|
205
206
|
```
|
206
207
|
|
207
208
|
#### `-n`/`--notify` option
|
@@ -262,6 +263,9 @@ directory - by selecting which ones to actually track.*
|
|
262
263
|
If your watched directories are outside the current one, or if `--watchdirs` isn't working
|
263
264
|
as you expect, be sure to read: [Correctly using watchdirs](https://github.com/guard/guard/wiki/Correctly-using-the---watchdir-option)
|
264
265
|
|
266
|
+
You may find it more convenient to use the `directories` statement (described
|
267
|
+
below) in your Guardfile
|
268
|
+
|
265
269
|
|
266
270
|
#### `-G`/`--guardfile` option
|
267
271
|
|
@@ -641,6 +645,40 @@ plural and the singular option, the plural has precedence.
|
|
641
645
|
|
642
646
|
**Please be sure to call the `scope` method after you've declared your Guard plugins!**
|
643
647
|
|
648
|
+
### directories
|
649
|
+
|
650
|
+
This option limits the directories watch to those given, which can improve
|
651
|
+
responsiveness, performance and help reduce resource usage (CPU, memory) on
|
652
|
+
larger projects.
|
653
|
+
|
654
|
+
```ruby
|
655
|
+
directories %w(app config lib spec features)
|
656
|
+
```
|
657
|
+
|
658
|
+
Note: The `--watchdir` option overrides this. (see `--watchdir` above for extra
|
659
|
+
info).
|
660
|
+
|
661
|
+
Note: Since recursion cannot be diabled on OSX, all other backends were made
|
662
|
+
recursive - so if you want to watch selected directories AND files in the root
|
663
|
+
directory of your project, move them to another directory and create symlinks
|
664
|
+
back, e.g.
|
665
|
+
|
666
|
+
```
|
667
|
+
mkdir config
|
668
|
+
mv Gemfile config
|
669
|
+
ln -s config/Gemfile Gemfile
|
670
|
+
```
|
671
|
+
|
672
|
+
### clearing
|
673
|
+
|
674
|
+
Guard can clear the screen before every action (which some people prefer).
|
675
|
+
|
676
|
+
The this clearing behavior can be set to `:on` or `:off`:
|
677
|
+
|
678
|
+
```ruby
|
679
|
+
clearing :on
|
680
|
+
```
|
681
|
+
|
644
682
|
### notification
|
645
683
|
|
646
684
|
If you don't specify any notification configuration in your `Guardfile`, Guard goes through the list of available
|
data/lib/guard.rb
CHANGED
@@ -57,8 +57,6 @@ module Guard
|
|
57
57
|
|
58
58
|
@queue = Internals::Queue.new(Guard)
|
59
59
|
|
60
|
-
UI.reset_and_clear
|
61
|
-
|
62
60
|
_evaluate(state.session.evaluator_options)
|
63
61
|
|
64
62
|
# NOTE: this should be *after* evaluate so :directories can work
|
@@ -146,6 +144,12 @@ module Guard
|
|
146
144
|
def _evaluate(options)
|
147
145
|
evaluator = Guardfile::Evaluator.new(options)
|
148
146
|
evaluator.evaluate
|
147
|
+
|
148
|
+
# TODO: remove this workaround when options are removed
|
149
|
+
state.session.clearing(state.session.options[:clear])
|
150
|
+
|
151
|
+
UI.reset_and_clear
|
152
|
+
|
149
153
|
msg = "No plugins found in Guardfile, please add at least one."
|
150
154
|
UI.error msg if _pluginless_guardfile?
|
151
155
|
|
@@ -172,6 +172,18 @@ module Guard
|
|
172
172
|
msg = "No plugins found in Guardfile, please add at least one."
|
173
173
|
::Guard::UI.error msg if _pluginless_guardfile?
|
174
174
|
end
|
175
|
+
|
176
|
+
OPTIONS = <<-EOS.gsub(/^\s*/, "")
|
177
|
+
Starting with Guard 2.9.0 Guard.options is deprecated and ideally you
|
178
|
+
should be able to set specific options through an API or a DSL
|
179
|
+
method. Feel free to add feature requests if there's something
|
180
|
+
missing.
|
181
|
+
EOS
|
182
|
+
|
183
|
+
def options
|
184
|
+
UI.deprecation(OPTIONS)
|
185
|
+
::Guard.state.session.options
|
186
|
+
end
|
175
187
|
end
|
176
188
|
end
|
177
189
|
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require "guard/config"
|
2
|
+
fail "Deprecations disabled (strict mode)" if Guard::Config.new.strict?
|
3
|
+
|
4
|
+
require "guard/ui"
|
5
|
+
require "guard/plugin_util"
|
6
|
+
require "guard/guardfile/evaluator"
|
7
|
+
|
8
|
+
module Guard
|
9
|
+
# @deprecated Every method in this module is deprecated
|
10
|
+
module Deprecated
|
11
|
+
module Guard
|
12
|
+
def self.add_deprecated(klass)
|
13
|
+
klass.send(:extend, ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
MORE_INFO_ON_UPGRADING_TO_GUARD_2 = <<-EOS.gsub(/^\s*/, "")
|
18
|
+
For more information on how to upgrade for Guard 2.0, please head
|
19
|
+
over to: https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0%s
|
20
|
+
EOS
|
21
|
+
|
22
|
+
# @deprecated Use `Guard.plugins(filter)` instead.
|
23
|
+
#
|
24
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
25
|
+
# upgrade for Guard 2.0
|
26
|
+
#
|
27
|
+
GUARDS = <<-EOS.gsub(/^\s*/, "")
|
28
|
+
Starting with Guard 2.0 'Guard.guards(filter)' is deprecated.
|
29
|
+
|
30
|
+
Please use 'Guard.plugins(filter)' instead.
|
31
|
+
|
32
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
|
33
|
+
EOS
|
34
|
+
|
35
|
+
def guards(filter = nil)
|
36
|
+
::Guard::UI.deprecation(GUARDS)
|
37
|
+
plugins(filter)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @deprecated Use `Guard.add_plugin(name, options = {})` instead.
|
41
|
+
#
|
42
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
43
|
+
# upgrade for Guard 2.0
|
44
|
+
#
|
45
|
+
ADD_GUARD = <<-EOS.gsub(/^\s*/, "")
|
46
|
+
Starting with Guard 2.0 'Guard.add_guard(name, options = {})' is
|
47
|
+
deprecated.
|
48
|
+
|
49
|
+
Please use 'Guard.add_plugin(name, options = {})' instead.
|
50
|
+
|
51
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
|
52
|
+
EOS
|
53
|
+
|
54
|
+
def add_guard(*args)
|
55
|
+
::Guard::UI.deprecation(ADD_GUARD)
|
56
|
+
add_plugin(*args)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @deprecated Use
|
60
|
+
# `Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
|
61
|
+
# fail_gracefully)` instead.
|
62
|
+
#
|
63
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
64
|
+
# upgrade for Guard 2.0
|
65
|
+
#
|
66
|
+
GET_GUARD_CLASS = <<-EOS.gsub(/^\s*/, "")
|
67
|
+
Starting with Guard 2.0 'Guard.get_guard_class(name, fail_gracefully
|
68
|
+
= false)' is deprecated and is now always on.
|
69
|
+
|
70
|
+
Please use 'Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
|
71
|
+
fail_gracefully)' instead.
|
72
|
+
|
73
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
|
74
|
+
EOS
|
75
|
+
|
76
|
+
def get_guard_class(name, fail_gracefully = false)
|
77
|
+
UI.deprecation(GET_GUARD_CLASS)
|
78
|
+
PluginUtil.new(name).plugin_class(fail_gracefully: fail_gracefully)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @deprecated Use `Guard::PluginUtil.new(name).plugin_location` instead.
|
82
|
+
#
|
83
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
84
|
+
# upgrade for Guard 2.0
|
85
|
+
#
|
86
|
+
LOCATE_GUARD = <<-EOS.gsub(/^\s*/, "")
|
87
|
+
Starting with Guard 2.0 'Guard.locate_guard(name)' is deprecated.
|
88
|
+
|
89
|
+
Please use 'Guard::PluginUtil.new(name).plugin_location' instead.
|
90
|
+
|
91
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
|
92
|
+
EOS
|
93
|
+
|
94
|
+
def locate_guard(name)
|
95
|
+
UI.deprecation(LOCATE_GUARD)
|
96
|
+
PluginUtil.new(name).plugin_location
|
97
|
+
end
|
98
|
+
|
99
|
+
# @deprecated Use `Guard::PluginUtil.plugin_names` instead.
|
100
|
+
#
|
101
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
102
|
+
# upgrade for Guard 2.0
|
103
|
+
#
|
104
|
+
# Deprecator message for the `Guard.guard_gem_names` method
|
105
|
+
GUARD_GEM_NAMES = <<-EOS.gsub(/^\s*/, "")
|
106
|
+
Starting with Guard 2.0 'Guard.guard_gem_names' is deprecated.
|
107
|
+
|
108
|
+
Please use 'Guard::PluginUtil.plugin_names' instead.
|
109
|
+
|
110
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
|
111
|
+
EOS
|
112
|
+
|
113
|
+
def guard_gem_names
|
114
|
+
UI.deprecation(GUARD_GEM_NAMES)
|
115
|
+
PluginUtil.plugin_names
|
116
|
+
end
|
117
|
+
|
118
|
+
RUNNING = <<-EOS.gsub(/^\s*/, "")
|
119
|
+
Starting with Guard 2.7.1 it was discovered that Guard.running was
|
120
|
+
never initialized or used internally.
|
121
|
+
EOS
|
122
|
+
|
123
|
+
def running
|
124
|
+
UI.deprecation(RUNNING)
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
LOCK = <<-EOS.gsub(/^\s*/, "")
|
129
|
+
Starting with Guard 2.7.1 it was discovered that this accessor was
|
130
|
+
never initialized or used internally.
|
131
|
+
EOS
|
132
|
+
def lock
|
133
|
+
UI.deprecation(LOCK)
|
134
|
+
end
|
135
|
+
|
136
|
+
EVALUATOR = <<-EOS.gsub(/^\s*/, "")
|
137
|
+
Starting with Guard 2.8.2 this method shouldn't be used
|
138
|
+
EOS
|
139
|
+
|
140
|
+
def evaluator
|
141
|
+
UI.deprecation(EVALUATOR)
|
142
|
+
options = ::Guard.state.session.evaluator_options
|
143
|
+
::Guard::Guardfile::Evaluator.new(options)
|
144
|
+
end
|
145
|
+
|
146
|
+
RESET_EVALUATOR = <<-EOS.gsub(/^\s*/, "")
|
147
|
+
Starting with Guard 2.8.2 this method shouldn't be used
|
148
|
+
EOS
|
149
|
+
|
150
|
+
def reset_evaluator(_options)
|
151
|
+
UI.deprecation(RESET_EVALUATOR)
|
152
|
+
end
|
153
|
+
|
154
|
+
RUNNER = <<-EOS.gsub(/^\s*/, "")
|
155
|
+
Starting with Guard 2.8.2 this method shouldn't be used
|
156
|
+
EOS
|
157
|
+
|
158
|
+
def runner
|
159
|
+
UI.deprecation(RUNNER)
|
160
|
+
::Guard::Runner.new
|
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
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
data/lib/guard/dsl.rb
CHANGED
@@ -379,6 +379,31 @@ module Guard
|
|
379
379
|
raise Error, format(msg, e, backtrace)
|
380
380
|
end
|
381
381
|
|
382
|
+
# Sets the directories to pass to Listen
|
383
|
+
#
|
384
|
+
# @example watch only given directories
|
385
|
+
# directories %w(lib specs)
|
386
|
+
#
|
387
|
+
# @param [Array] directories directories for Listen to watch
|
388
|
+
#
|
389
|
+
def directories(directories)
|
390
|
+
directories.each do |dir|
|
391
|
+
fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
|
392
|
+
end
|
393
|
+
Guard.state.session.watchdirs = directories
|
394
|
+
end
|
395
|
+
|
396
|
+
# Sets Guard to clear the screen before every task is run
|
397
|
+
#
|
398
|
+
# @example switching clearing the screen on
|
399
|
+
# clearing(:on)
|
400
|
+
#
|
401
|
+
# @param [Symbol] on ':on' to turn on, ':off' (default) to turn off
|
402
|
+
#
|
403
|
+
def clearing(on)
|
404
|
+
Guard.state.session.clearing(on == :on)
|
405
|
+
end
|
406
|
+
|
382
407
|
private
|
383
408
|
|
384
409
|
def _cleanup_backtrace(backtrace)
|
@@ -404,19 +429,5 @@ module Guard
|
|
404
429
|
end
|
405
430
|
end
|
406
431
|
end
|
407
|
-
|
408
|
-
# Sets the directories to pass to Listen
|
409
|
-
#
|
410
|
-
# @example watch only given directories
|
411
|
-
# directories %w(lib specs)
|
412
|
-
#
|
413
|
-
# @param [Array] directories directories for Listen to watch
|
414
|
-
#
|
415
|
-
def directories(directories)
|
416
|
-
directories.each do |dir|
|
417
|
-
fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
|
418
|
-
end
|
419
|
-
Guard.state.session.watchdirs = directories
|
420
|
-
end
|
421
432
|
end
|
422
433
|
end
|
@@ -81,11 +81,16 @@ module Guard
|
|
81
81
|
attr_reader :guardfile_group_scope
|
82
82
|
attr_reader :guardfile_plugin_scope
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
def clearing(on)
|
85
|
+
@clear = on
|
86
|
+
end
|
87
|
+
|
88
|
+
def clearing?
|
86
89
|
@clear
|
87
90
|
end
|
88
91
|
|
92
|
+
alias :clear? :clearing?
|
93
|
+
|
89
94
|
def debug?
|
90
95
|
@debug
|
91
96
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require "guard/internals/plugins"
|
2
|
+
require "guard/internals/groups"
|
3
|
+
|
4
|
+
require "guard/options"
|
5
|
+
|
6
|
+
module Guard
|
7
|
+
# @private api
|
8
|
+
module Internals
|
9
|
+
# TODO: split into a commandline class and session (plugins, groups)
|
10
|
+
# TODO: swap session and metadata
|
11
|
+
# This class contains variables set during
|
12
|
+
# evaluation of the guardfile (and are reset
|
13
|
+
# before reevaluation)
|
14
|
+
class Session
|
15
|
+
attr_reader :options
|
16
|
+
attr_reader :plugins
|
17
|
+
attr_reader :groups
|
18
|
+
|
19
|
+
DEFAULT_OPTIONS = {
|
20
|
+
clear: false,
|
21
|
+
debug: false,
|
22
|
+
no_bundler_warning: false,
|
23
|
+
|
24
|
+
# User defined scopes
|
25
|
+
group: [],
|
26
|
+
plugin: [],
|
27
|
+
|
28
|
+
# Notifier
|
29
|
+
notify: true,
|
30
|
+
|
31
|
+
# Interactor
|
32
|
+
no_interactions: false,
|
33
|
+
|
34
|
+
# Guardfile options:
|
35
|
+
# guardfile_contents
|
36
|
+
guardfile: nil,
|
37
|
+
|
38
|
+
# Listener options
|
39
|
+
# TODO: rename to watchdirs?
|
40
|
+
watchdir: Dir.pwd,
|
41
|
+
latency: nil,
|
42
|
+
force_polling: false,
|
43
|
+
wait_for_delay: nil,
|
44
|
+
listen_on: nil
|
45
|
+
}
|
46
|
+
|
47
|
+
def cmdline_groups
|
48
|
+
@cmdline_groups.dup.freeze
|
49
|
+
end
|
50
|
+
|
51
|
+
def cmdline_plugins
|
52
|
+
@cmdline_plugins.dup.freeze
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(new_options)
|
56
|
+
@options = Options.new(new_options, DEFAULT_OPTIONS)
|
57
|
+
|
58
|
+
@plugins = Internals::Plugins.new
|
59
|
+
@groups = Internals::Groups.new
|
60
|
+
|
61
|
+
@cmdline_groups = @options[:group]
|
62
|
+
@cmdline_plugins = @options[:plugin]
|
63
|
+
|
64
|
+
@clear = @options[:clear]
|
65
|
+
@debug = @options[:debug]
|
66
|
+
@watchdirs = Array(@options[:watchdir])
|
67
|
+
@notify = @options[:notify]
|
68
|
+
@interactor_name = @options[:no_interactions] ? :sleep : :pry_wrapper
|
69
|
+
|
70
|
+
@guardfile_plugin_scope = []
|
71
|
+
@guardfile_group_scope = []
|
72
|
+
end
|
73
|
+
|
74
|
+
def guardfile_scope(scope)
|
75
|
+
opts = scope.dup
|
76
|
+
@guardfile_plugin_scope = Array(opts.delete(:plugins))
|
77
|
+
@guardfile_group_scope = Array(opts.delete(:groups))
|
78
|
+
fail "Unknown options: #{opts.inspect}" unless opts.empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_reader :guardfile_group_scope
|
82
|
+
attr_reader :guardfile_plugin_scope
|
83
|
+
|
84
|
+
# TODO: not tested
|
85
|
+
def clear?
|
86
|
+
@clear
|
87
|
+
end
|
88
|
+
|
89
|
+
def debug?
|
90
|
+
@debug
|
91
|
+
end
|
92
|
+
|
93
|
+
def watchdirs
|
94
|
+
@watchdirs_from_guardfile ||= nil
|
95
|
+
@watchdirs_from_guardfile || @watchdirs
|
96
|
+
end
|
97
|
+
|
98
|
+
# set by Dsl with :directories() command
|
99
|
+
def watchdirs=(dirs)
|
100
|
+
dirs = [Dir.pwd] if dirs.empty?
|
101
|
+
@watchdirs_from_guardfile = dirs.map { |dir| File.expand_path dir }
|
102
|
+
end
|
103
|
+
|
104
|
+
def listener_args
|
105
|
+
if options[:listen_on]
|
106
|
+
[:on, options[:listen_on]]
|
107
|
+
else
|
108
|
+
listener_options = {}
|
109
|
+
[:latency, :force_polling, :wait_for_delay].each do |option|
|
110
|
+
listener_options[option] = options[option] if options[option]
|
111
|
+
end
|
112
|
+
expanded_watchdirs = watchdirs.map { |dir| File.expand_path dir }
|
113
|
+
[:to, *expanded_watchdirs, listener_options]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def evaluator_options
|
118
|
+
opts = { guardfile: options[:guardfile] }
|
119
|
+
# TODO: deprecate :guardfile_contents
|
120
|
+
if options[:guardfile_contents]
|
121
|
+
opts[:contents] = options[:guardfile_contents]
|
122
|
+
end
|
123
|
+
opts
|
124
|
+
end
|
125
|
+
|
126
|
+
def notify_options
|
127
|
+
{ notify: @options[:notify] }
|
128
|
+
end
|
129
|
+
|
130
|
+
def interactor_name
|
131
|
+
@interactor_name
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
|
5
|
-
#
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
6
5
|
# directories %(app lib config test spec feature)
|
6
|
+
|
7
|
+
## Uncomment to clear the screen before every task
|
8
|
+
# clearing :on
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require "lumberjack"
|
2
|
+
|
3
|
+
require "guard/internals/state"
|
4
|
+
|
5
|
+
require "guard/options"
|
6
|
+
|
7
|
+
require "guard/ui/colors"
|
8
|
+
|
9
|
+
require "guard/terminal"
|
10
|
+
|
11
|
+
module Guard
|
12
|
+
# The UI class helps to format messages for the user. Everything that is
|
13
|
+
# logged through this class is considered either as an error message or a
|
14
|
+
# diagnostic message and is written to standard error ($stderr).
|
15
|
+
#
|
16
|
+
# If your Guard plugin does some output that is piped into another process
|
17
|
+
# for further processing, please just write it to STDOUT with `puts`.
|
18
|
+
#
|
19
|
+
module UI
|
20
|
+
include Colors
|
21
|
+
|
22
|
+
class << self
|
23
|
+
# Get the Guard::UI logger instance
|
24
|
+
#
|
25
|
+
def logger
|
26
|
+
@logger ||= begin
|
27
|
+
Lumberjack::Logger.new(
|
28
|
+
options.fetch(:device) { $stderr },
|
29
|
+
options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Since logger is global, for Aruba in-process to properly
|
34
|
+
# separate output between calls, we need to reset
|
35
|
+
#
|
36
|
+
# We don't use logger=() since it's expected to be a Lumberjack instance
|
37
|
+
def reset_logger
|
38
|
+
@logger = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get the logger options
|
42
|
+
#
|
43
|
+
# @return [Hash] the logger options
|
44
|
+
#
|
45
|
+
def options
|
46
|
+
@options ||= ::Guard::Options.new(
|
47
|
+
level: :info,
|
48
|
+
template: ":time - :severity - :message",
|
49
|
+
time_format: "%H:%M:%S")
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set the logger options
|
53
|
+
#
|
54
|
+
# @param [Hash] options the logger options
|
55
|
+
# @option options [Symbol] level the log level
|
56
|
+
# @option options [String] template the logger template
|
57
|
+
# @option options [String] time_format the time format
|
58
|
+
#
|
59
|
+
# TODO: deprecate?
|
60
|
+
def options=(options)
|
61
|
+
@options = ::Guard::Options.new(options)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Assigns a log level
|
65
|
+
def level=(new_level)
|
66
|
+
logger.level = new_level
|
67
|
+
end
|
68
|
+
|
69
|
+
# Show an info message.
|
70
|
+
#
|
71
|
+
# @param [String] message the message to show
|
72
|
+
# @option options [Boolean] reset whether to clean the output before
|
73
|
+
# @option options [String] plugin manually define the calling plugin
|
74
|
+
#
|
75
|
+
def info(message, options = {})
|
76
|
+
_filtered_logger_message(message, :info, nil, options)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Show a yellow warning message that is prefixed with WARNING.
|
80
|
+
#
|
81
|
+
# @param [String] message the message to show
|
82
|
+
# @option options [Boolean] reset whether to clean the output before
|
83
|
+
# @option options [String] plugin manually define the calling plugin
|
84
|
+
#
|
85
|
+
def warning(message, options = {})
|
86
|
+
_filtered_logger_message(message, :warn, :yellow, options)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Show a red error message that is prefixed with ERROR.
|
90
|
+
#
|
91
|
+
# @param [String] message the message to show
|
92
|
+
# @option options [Boolean] reset whether to clean the output before
|
93
|
+
# @option options [String] plugin manually define the calling plugin
|
94
|
+
#
|
95
|
+
def error(message, options = {})
|
96
|
+
_filtered_logger_message(message, :error, :red, options)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Show a red deprecation message that is prefixed with DEPRECATION.
|
100
|
+
# It has a log level of `warn`.
|
101
|
+
#
|
102
|
+
# @param [String] message the message to show
|
103
|
+
# @option options [Boolean] reset whether to clean the output before
|
104
|
+
# @option options [String] plugin manually define the calling plugin
|
105
|
+
#
|
106
|
+
def deprecation(message, options = {})
|
107
|
+
unless ENV["GUARD_GEM_SILENCE_DEPRECATIONS"] == "1"
|
108
|
+
backtrace = Thread.current.backtrace[1..5].join("\n\t >")
|
109
|
+
msg = format("%s\nDeprecation backtrace: %s", message, backtrace)
|
110
|
+
warning(msg, options)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Show a debug message that is prefixed with DEBUG and a timestamp.
|
115
|
+
#
|
116
|
+
# @param [String] message the message to show
|
117
|
+
# @option options [Boolean] reset whether to clean the output before
|
118
|
+
# @option options [String] plugin manually define the calling plugin
|
119
|
+
#
|
120
|
+
def debug(message, options = {})
|
121
|
+
_filtered_logger_message(message, :debug, :yellow, options)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Reset a line.
|
125
|
+
#
|
126
|
+
def reset_line
|
127
|
+
$stderr.print(color_enabled? ? "\r\e[0m" : "\r\n")
|
128
|
+
end
|
129
|
+
|
130
|
+
# Clear the output if clearable.
|
131
|
+
#
|
132
|
+
def clear(opts = {})
|
133
|
+
return unless Guard.state.session.clear?
|
134
|
+
|
135
|
+
fail "UI not set up!" if @clearable.nil?
|
136
|
+
return unless @clearable || opts[:force]
|
137
|
+
|
138
|
+
@clearable = false
|
139
|
+
Terminal.clear
|
140
|
+
rescue Errno::ENOENT => e
|
141
|
+
warning("Failed to clear the screen: #{e.inspect}")
|
142
|
+
end
|
143
|
+
|
144
|
+
# TODO: arguments: UI uses Guard::options anyway
|
145
|
+
# @private api
|
146
|
+
def reset_and_clear
|
147
|
+
@clearable = false
|
148
|
+
clear(force: true)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Allow the screen to be cleared again.
|
152
|
+
#
|
153
|
+
def clearable
|
154
|
+
@clearable = true
|
155
|
+
end
|
156
|
+
|
157
|
+
# Show a scoped action message.
|
158
|
+
#
|
159
|
+
# @param [String] action the action to show
|
160
|
+
# @param [Hash] scope hash with a guard or a group scope
|
161
|
+
#
|
162
|
+
def action_with_scopes(action, scope)
|
163
|
+
titles = Guard.state.scope.titles(scope)
|
164
|
+
info "#{action} #{titles.join(", ")}"
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# Filters log messages depending on either the
|
170
|
+
# `:only`` or `:except` option.
|
171
|
+
#
|
172
|
+
# @param [String] plugin the calling plugin name
|
173
|
+
# @yield When the message should be logged
|
174
|
+
# @yieldparam [String] param the calling plugin name
|
175
|
+
#
|
176
|
+
def _filter(plugin)
|
177
|
+
only = options[:only]
|
178
|
+
except = options[:except]
|
179
|
+
plugin ||= calling_plugin_name
|
180
|
+
|
181
|
+
match = !(only || except)
|
182
|
+
match ||= (only && only.match(plugin))
|
183
|
+
match ||= (except && !except.match(plugin))
|
184
|
+
return unless match
|
185
|
+
yield plugin
|
186
|
+
end
|
187
|
+
|
188
|
+
# Display a message of the type `method` and with the color `color_name`
|
189
|
+
# (no color by default) conditionnaly given a `plugin_name`.
|
190
|
+
#
|
191
|
+
# @param [String] plugin_name the calling plugin name
|
192
|
+
# @option options [Boolean] reset whether to clean the output before
|
193
|
+
# @option options [String] plugin manually define the calling plugin
|
194
|
+
#
|
195
|
+
def _filtered_logger_message(message, method, color_name, options = {})
|
196
|
+
message = color(message, color_name) if color_name
|
197
|
+
|
198
|
+
_filter(options[:plugin]) do |plugin|
|
199
|
+
reset_line if options[:reset]
|
200
|
+
logger.send(method, message, plugin)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Tries to extract the calling Guard plugin name
|
205
|
+
# from the call stack.
|
206
|
+
#
|
207
|
+
# @param [Integer] depth the stack depth
|
208
|
+
# @return [String] the Guard plugin name
|
209
|
+
#
|
210
|
+
def calling_plugin_name(depth = 2)
|
211
|
+
name = /(guard\/[a-z_]*)(\/[a-z_]*)?.rb:/i.match(caller[depth])
|
212
|
+
return "Guard" unless name
|
213
|
+
name[1].split("/").map do |part|
|
214
|
+
part.split(/[^a-z0-9]/i).map(&:capitalize).join
|
215
|
+
end.join("::")
|
216
|
+
end
|
217
|
+
|
218
|
+
# Checks if color output can be enabled.
|
219
|
+
#
|
220
|
+
# @return [Boolean] whether color is enabled or not
|
221
|
+
#
|
222
|
+
def color_enabled?
|
223
|
+
@color_enabled_initialized ||= false
|
224
|
+
@color_enabled = nil unless @color_enabled_initialized
|
225
|
+
@color_enabled_initialized = true
|
226
|
+
if @color_enabled.nil?
|
227
|
+
if Gem.win_platform?
|
228
|
+
if ENV["ANSICON"]
|
229
|
+
@color_enabled = true
|
230
|
+
else
|
231
|
+
begin
|
232
|
+
require "rubygems" unless ENV["NO_RUBYGEMS"]
|
233
|
+
require "Win32/Console/ANSI"
|
234
|
+
@color_enabled = true
|
235
|
+
rescue LoadError
|
236
|
+
@color_enabled = false
|
237
|
+
info "Run 'gem install win32console' to use color on Windows"
|
238
|
+
end
|
239
|
+
end
|
240
|
+
else
|
241
|
+
@color_enabled = true
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
@color_enabled
|
246
|
+
end
|
247
|
+
|
248
|
+
# Colorizes a text message. See the constant in the UI class for possible
|
249
|
+
# color_options parameters. You can pass optionally :bright, a foreground
|
250
|
+
# color and a background color.
|
251
|
+
#
|
252
|
+
# @example
|
253
|
+
#
|
254
|
+
# color('Hello World', :red, :bright)
|
255
|
+
#
|
256
|
+
# @param [String] text the text to colorize
|
257
|
+
# @param [Array] color_options the color options
|
258
|
+
#
|
259
|
+
def color(text, *color_options)
|
260
|
+
color_code = ""
|
261
|
+
color_options.each do |color_option|
|
262
|
+
color_option = color_option.to_s
|
263
|
+
next if color_option == ""
|
264
|
+
|
265
|
+
unless color_option =~ /\d+/
|
266
|
+
color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
|
267
|
+
end
|
268
|
+
color_code += ";" + color_option
|
269
|
+
end
|
270
|
+
color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
data/lib/guard/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibaud Guillaume-Gentil
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/guard/deprecated/dsl.rb
|
114
114
|
- lib/guard/deprecated/evaluator.rb
|
115
115
|
- lib/guard/deprecated/guard.rb
|
116
|
+
- lib/guard/deprecated/guard.rb.orig
|
116
117
|
- lib/guard/deprecated/guardfile.rb
|
117
118
|
- lib/guard/deprecated/watcher.rb
|
118
119
|
- lib/guard/dsl.rb
|
@@ -132,6 +133,7 @@ files:
|
|
132
133
|
- lib/guard/internals/queue.rb
|
133
134
|
- lib/guard/internals/scope.rb
|
134
135
|
- lib/guard/internals/session.rb
|
136
|
+
- lib/guard/internals/session.rb.orig
|
135
137
|
- lib/guard/internals/state.rb
|
136
138
|
- lib/guard/internals/tracing.rb
|
137
139
|
- lib/guard/internals/traps.rb
|
@@ -166,6 +168,7 @@ files:
|
|
166
168
|
- lib/guard/templates/Guardfile.orig
|
167
169
|
- lib/guard/terminal.rb
|
168
170
|
- lib/guard/ui.rb
|
171
|
+
- lib/guard/ui.rb.orig
|
169
172
|
- lib/guard/ui/colors.rb
|
170
173
|
- lib/guard/version.rb
|
171
174
|
- lib/guard/version.rb.orig
|