guard 1.8.3 → 2.0.0.pre
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/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/cli.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require 'thor'
|
2
2
|
|
3
|
+
require 'guard'
|
4
|
+
require 'guard/version'
|
5
|
+
require 'guard/dsl_describer'
|
6
|
+
require 'guard/guardfile'
|
7
|
+
|
3
8
|
module Guard
|
4
9
|
|
5
10
|
# Facade for the Guard command line interface managed by [Thor](https://github.com/wycats/thor).
|
@@ -8,97 +13,78 @@ module Guard
|
|
8
13
|
#
|
9
14
|
class CLI < Thor
|
10
15
|
|
11
|
-
require 'guard'
|
12
|
-
require 'guard/version'
|
13
|
-
require 'guard/dsl_describer'
|
14
|
-
require 'guard/guardfile'
|
15
|
-
|
16
16
|
default_task :start
|
17
17
|
|
18
18
|
desc 'start', 'Starts Guard'
|
19
19
|
|
20
20
|
method_option :clear,
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
21
|
+
type: :boolean,
|
22
|
+
default: false,
|
23
|
+
aliases: '-c',
|
24
|
+
banner: 'Auto clear shell before each action'
|
25
25
|
|
26
26
|
method_option :notify,
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
27
|
+
type: :boolean,
|
28
|
+
default: true,
|
29
|
+
aliases: '-n',
|
30
|
+
banner: 'Notifications feature'
|
31
31
|
|
32
32
|
method_option :debug,
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
33
|
+
type: :boolean,
|
34
|
+
default: false,
|
35
|
+
aliases: '-d',
|
36
|
+
banner: 'Show debug information'
|
37
37
|
|
38
38
|
method_option :group,
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
39
|
+
type: :array,
|
40
|
+
default: [],
|
41
|
+
aliases: '-g',
|
42
|
+
banner: 'Run only the passed groups'
|
43
43
|
|
44
44
|
method_option :plugin,
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
45
|
+
type: :array,
|
46
|
+
default: [],
|
47
|
+
aliases: '-P',
|
48
|
+
banner: 'Run only the passed plugins'
|
49
49
|
|
50
50
|
method_option :watchdir,
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
51
|
+
type: :array,
|
52
|
+
aliases: '-w',
|
53
|
+
banner: 'Specify the directories to watch'
|
54
54
|
|
55
55
|
method_option :guardfile,
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
|
60
|
-
# DEPRECATED
|
61
|
-
method_option :no_vendor,
|
62
|
-
:type => :boolean,
|
63
|
-
:default => false,
|
64
|
-
:aliases => '-I',
|
65
|
-
:banner => 'DEPRECATED: Ignore vendored dependencies'
|
66
|
-
|
67
|
-
# DEPRECATED
|
68
|
-
method_option :watch_all_modifications,
|
69
|
-
:type => :boolean,
|
70
|
-
:default => false,
|
71
|
-
:aliases => '-A',
|
72
|
-
:banner => 'DEPRECATED: Watch for all file modifications including moves and deletions'
|
56
|
+
type: :string,
|
57
|
+
aliases: '-G',
|
58
|
+
banner: 'Specify a Guardfile'
|
73
59
|
|
74
60
|
method_option :no_interactions,
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
61
|
+
type: :boolean,
|
62
|
+
default: false,
|
63
|
+
aliases: '-i',
|
64
|
+
banner: 'Turn off completely any Guard terminal interactions'
|
79
65
|
|
80
66
|
method_option :no_bundler_warning,
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
67
|
+
type: :boolean,
|
68
|
+
default: false,
|
69
|
+
aliases: '-B',
|
70
|
+
banner: 'Turn off warning when Bundler is not present'
|
85
71
|
|
86
72
|
method_option :show_deprecations,
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:
|
73
|
+
type: :boolean,
|
74
|
+
default: false,
|
75
|
+
banner: 'Turn on deprecation warnings'
|
90
76
|
|
91
77
|
# Listen options
|
92
78
|
method_option :latency,
|
93
|
-
:
|
94
|
-
:
|
95
|
-
:
|
79
|
+
type: :numeric,
|
80
|
+
aliases: '-l',
|
81
|
+
banner: 'Overwrite Listen\'s default latency'
|
96
82
|
|
97
83
|
method_option :force_polling,
|
98
|
-
:
|
99
|
-
:
|
100
|
-
:
|
101
|
-
:
|
84
|
+
type: :boolean,
|
85
|
+
default: false,
|
86
|
+
aliases: '-p',
|
87
|
+
banner: 'Force usage of the Listen polling listener'
|
102
88
|
|
103
89
|
# Start Guard by initializing the defined Guard plugins and watch the file system.
|
104
90
|
# This is the default task, so calling `guard` is the same as calling `guard start`.
|
@@ -106,7 +92,7 @@ module Guard
|
|
106
92
|
# @see Guard.start
|
107
93
|
#
|
108
94
|
def start
|
109
|
-
|
95
|
+
_verify_bundler_presence unless options[:no_bundler_warning]
|
110
96
|
::Guard.start(options)
|
111
97
|
|
112
98
|
return if ENV['GUARD_ENV'] == 'test'
|
@@ -116,7 +102,7 @@ module Guard
|
|
116
102
|
end
|
117
103
|
end
|
118
104
|
|
119
|
-
desc 'list', 'Lists
|
105
|
+
desc 'list', 'Lists Guard plugins that can be used with init'
|
120
106
|
|
121
107
|
# List the Guard plugins that are available for use in your system and marks
|
122
108
|
# those that are currently used in your `Guardfile`.
|
@@ -124,7 +110,17 @@ module Guard
|
|
124
110
|
# @see Guard::DslDescriber.list
|
125
111
|
#
|
126
112
|
def list
|
127
|
-
::Guard::DslDescriber.
|
113
|
+
::Guard::DslDescriber.new(options).list
|
114
|
+
end
|
115
|
+
|
116
|
+
desc 'notifiers', 'Lists notifiers and its options'
|
117
|
+
|
118
|
+
# List the Notifiers for use in your system.
|
119
|
+
#
|
120
|
+
# @see Guard::DslDescriber.notifiers
|
121
|
+
#
|
122
|
+
def notifiers
|
123
|
+
::Guard::DslDescriber.new(options).notifiers
|
128
124
|
end
|
129
125
|
|
130
126
|
desc 'version', 'Show the Guard version'
|
@@ -138,35 +134,35 @@ module Guard
|
|
138
134
|
puts "Guard version #{ ::Guard::VERSION }"
|
139
135
|
end
|
140
136
|
|
141
|
-
desc 'init [GUARDS]', 'Generates a Guardfile at the current directory (if it is not already there) and adds all installed
|
137
|
+
desc 'init [GUARDS]', 'Generates a Guardfile at the current directory (if it is not already there) and adds all installed Guard plugins or the given GUARDS into it'
|
142
138
|
|
143
139
|
method_option :bare,
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:
|
140
|
+
type: :boolean,
|
141
|
+
default: false,
|
142
|
+
aliases: '-b',
|
143
|
+
banner: 'Generate a bare Guardfile without adding any installed plugin into it'
|
148
144
|
|
149
145
|
# Initializes the templates of all installed Guard plugins and adds them
|
150
146
|
# to the `Guardfile` when no Guard name is passed. When passing
|
151
147
|
# Guard plugin names it does the same but only for those Guard plugins.
|
152
148
|
#
|
153
|
-
# @see Guard::
|
154
|
-
# @see Guard::
|
149
|
+
# @see Guard::Guardfile.initialize_template
|
150
|
+
# @see Guard::Guardfile.initialize_all_templates
|
155
151
|
#
|
156
|
-
# @param [Array<String>]
|
152
|
+
# @param [Array<String>] plugin_names the name of the Guard plugins to initialize
|
157
153
|
#
|
158
|
-
def init(*
|
159
|
-
|
154
|
+
def init(*plugin_names)
|
155
|
+
_verify_bundler_presence
|
160
156
|
|
161
|
-
::Guard::Guardfile.create_guardfile(:
|
157
|
+
::Guard::Guardfile.create_guardfile(abort_on_existence: options[:bare])
|
162
158
|
|
163
159
|
return if options[:bare]
|
164
160
|
|
165
|
-
if
|
161
|
+
if plugin_names.empty?
|
166
162
|
::Guard::Guardfile.initialize_all_templates
|
167
163
|
else
|
168
|
-
|
169
|
-
::Guard::Guardfile.initialize_template(
|
164
|
+
plugin_names.each do |plugin_name|
|
165
|
+
::Guard::Guardfile.initialize_template(plugin_name)
|
170
166
|
end
|
171
167
|
end
|
172
168
|
end
|
@@ -180,7 +176,7 @@ module Guard
|
|
180
176
|
# @see Guard::DslDescriber.show
|
181
177
|
#
|
182
178
|
def show
|
183
|
-
::Guard::DslDescriber.
|
179
|
+
::Guard::DslDescriber.new(options).show
|
184
180
|
end
|
185
181
|
|
186
182
|
private
|
@@ -188,7 +184,7 @@ module Guard
|
|
188
184
|
# Verifies if Guard is run with `bundle exec` and
|
189
185
|
# shows a hint to do so if not.
|
190
186
|
#
|
191
|
-
def
|
187
|
+
def _verify_bundler_presence
|
192
188
|
if File.exists?('Gemfile') && !ENV['BUNDLE_GEMFILE']
|
193
189
|
::Guard::UI.info <<EOF
|
194
190
|
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
module Commander
|
4
|
+
|
5
|
+
# Start Guard by evaluating the `Guardfile`, initializing declared Guard plugins
|
6
|
+
# and starting the available file change listener.
|
7
|
+
# Main method for Guard that is called from the CLI when Guard starts.
|
8
|
+
#
|
9
|
+
# - Setup Guard internals
|
10
|
+
# - Evaluate the `Guardfile`
|
11
|
+
# - Configure Notifiers
|
12
|
+
# - Initialize the declared Guard plugins
|
13
|
+
# - Start the available file change listener
|
14
|
+
#
|
15
|
+
# @option options [Boolean] clear if auto clear the UI should be done
|
16
|
+
# @option options [Boolean] notify if system notifications should be shown
|
17
|
+
# @option options [Boolean] debug if debug output should be shown
|
18
|
+
# @option options [Array<String>] group the list of groups to start
|
19
|
+
# @option options [String] watchdir the director to watch
|
20
|
+
# @option options [String] guardfile the path to the Guardfile
|
21
|
+
# @see CLI#start
|
22
|
+
#
|
23
|
+
def start(options = {})
|
24
|
+
setup(options) unless running
|
25
|
+
|
26
|
+
within_preserved_state do
|
27
|
+
::Guard::UI.debug 'Guard starts all plugins'
|
28
|
+
runner.run(:start)
|
29
|
+
::Guard::UI.info "Guard is now watching at '#{ @watchdirs.join "', '" }'"
|
30
|
+
listener.start
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Stop Guard listening to file changes.
|
35
|
+
#
|
36
|
+
def stop
|
37
|
+
setup unless running
|
38
|
+
|
39
|
+
within_preserved_state do
|
40
|
+
::Guard::UI.debug 'Guard stops all plugins'
|
41
|
+
runner.run(:stop)
|
42
|
+
::Guard::Notifier.turn_off
|
43
|
+
::Guard::UI.info 'Bye bye...', reset: true
|
44
|
+
listener.stop
|
45
|
+
@running = false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Reload Guardfile and all Guard plugins currently enabled.
|
50
|
+
# If no scope is given, then the Guardfile will be re-evaluated,
|
51
|
+
# which results in a stop/start, which makes the reload obsolete.
|
52
|
+
#
|
53
|
+
# @param [Hash] scopes hash with a Guard plugin or a group scope
|
54
|
+
#
|
55
|
+
def reload(scopes = {})
|
56
|
+
setup unless running
|
57
|
+
|
58
|
+
within_preserved_state do
|
59
|
+
::Guard::UI.clear(force: true)
|
60
|
+
::Guard::UI.action_with_scopes('Reload', scopes)
|
61
|
+
|
62
|
+
if scopes.empty?
|
63
|
+
evaluator.reevaluate_guardfile
|
64
|
+
else
|
65
|
+
runner.run(:reload, scopes)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Trigger `run_all` on all Guard plugins currently enabled.
|
71
|
+
#
|
72
|
+
# @param [Hash] scopes hash with a Guard plugin or a group scope
|
73
|
+
#
|
74
|
+
def run_all(scopes = {})
|
75
|
+
setup unless running
|
76
|
+
|
77
|
+
within_preserved_state do
|
78
|
+
::Guard::UI.clear(force: true)
|
79
|
+
::Guard::UI.action_with_scopes('Run all', scopes)
|
80
|
+
runner.run(:run_all, scopes)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Pause Guard listening to file changes.
|
85
|
+
#
|
86
|
+
def pause
|
87
|
+
if listener.paused?
|
88
|
+
::Guard::UI.info 'Un-paused files modification listening', reset: true
|
89
|
+
listener.unpause
|
90
|
+
else
|
91
|
+
::Guard::UI.info 'Paused files modification listening', reset: true
|
92
|
+
listener.pause
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Runs a block where the interactor is
|
97
|
+
# blocked and execution is synchronized
|
98
|
+
# to avoid state inconsistency.
|
99
|
+
#
|
100
|
+
# @param [Boolean] restart_interactor whether to restart the interactor or
|
101
|
+
# not
|
102
|
+
# @yield the block to run
|
103
|
+
#
|
104
|
+
def within_preserved_state
|
105
|
+
lock.synchronize do
|
106
|
+
begin
|
107
|
+
interactor.stop if interactor
|
108
|
+
@result = yield
|
109
|
+
rescue Interrupt
|
110
|
+
# Bring back Pry when the block is halted with Ctrl-C
|
111
|
+
end
|
112
|
+
|
113
|
+
interactor.start if running
|
114
|
+
end
|
115
|
+
|
116
|
+
@result
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/lib/guard/commands/all.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
module DeprecatedMethods
|
4
|
+
|
5
|
+
# @deprecated Use `Guard.plugins(filter)` instead.
|
6
|
+
#
|
7
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
8
|
+
# upgrade for Guard 2.0
|
9
|
+
#
|
10
|
+
def guards(filter = nil)
|
11
|
+
::Guard::UI.deprecation(::Guard::Deprecator::GUARDS_DEPRECATION)
|
12
|
+
plugins(filter)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @deprecated Use `Guard.add_plugin(name, options = {})` instead.
|
16
|
+
#
|
17
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
18
|
+
# upgrade for Guard 2.0
|
19
|
+
#
|
20
|
+
def add_guard(*args)
|
21
|
+
::Guard::UI.deprecation(::Guard::Deprecator::ADD_GUARD_DEPRECATION)
|
22
|
+
add_plugin(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @deprecated Use
|
26
|
+
# `Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
|
27
|
+
# fail_gracefully)` instead.
|
28
|
+
#
|
29
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
30
|
+
# upgrade for Guard 2.0
|
31
|
+
#
|
32
|
+
def get_guard_class(name, fail_gracefully = false)
|
33
|
+
::Guard::UI.deprecation(::Guard::Deprecator::GET_GUARD_CLASS_DEPRECATION)
|
34
|
+
::Guard::PluginUtil.new(name).plugin_class(fail_gracefully: fail_gracefully)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @deprecated Use `Guard::PluginUtil.new(name).plugin_location` instead.
|
38
|
+
#
|
39
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
40
|
+
# upgrade for Guard 2.0
|
41
|
+
#
|
42
|
+
def locate_guard(name)
|
43
|
+
::Guard::UI.deprecation(::Guard::Deprecator::LOCATE_GUARD_DEPRECATION)
|
44
|
+
::Guard::PluginUtil.new(name).plugin_location
|
45
|
+
end
|
46
|
+
|
47
|
+
# @deprecated Use `Guard::PluginUtil.plugin_names` instead.
|
48
|
+
#
|
49
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
50
|
+
# upgrade for Guard 2.0
|
51
|
+
#
|
52
|
+
def guard_gem_names
|
53
|
+
::Guard::UI.deprecation(::Guard::Deprecator::GUARD_GEM_NAMES_DEPRECATION)
|
54
|
+
::Guard::PluginUtil.plugin_names
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|