guard 0.8.0 → 0.8.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.
- data/CHANGELOG.md +310 -303
- data/LICENSE +19 -19
- data/README.md +434 -434
- data/bin/guard +6 -6
- data/lib/guard.rb +384 -384
- data/lib/guard/cli.rb +178 -179
- data/lib/guard/dsl.rb +370 -370
- data/lib/guard/dsl_describer.rb +60 -60
- data/lib/guard/group.rb +22 -22
- data/lib/guard/guard.rb +98 -98
- data/lib/guard/hook.rb +118 -118
- data/lib/guard/interactor.rb +78 -78
- data/lib/guard/listener.rb +346 -346
- data/lib/guard/listeners/darwin.rb +66 -66
- data/lib/guard/listeners/linux.rb +98 -98
- data/lib/guard/listeners/polling.rb +55 -55
- data/lib/guard/listeners/windows.rb +61 -61
- data/lib/guard/notifier.rb +211 -211
- data/lib/guard/templates/Guardfile +2 -2
- data/lib/guard/ui.rb +188 -188
- data/lib/guard/version.rb +6 -6
- data/lib/guard/watcher.rb +110 -110
- data/man/guard.1 +93 -93
- data/man/guard.1.html +176 -176
- metadata +15 -15
data/lib/guard/dsl_describer.rb
CHANGED
@@ -1,60 +1,60 @@
|
|
1
|
-
require 'guard/dsl'
|
2
|
-
|
3
|
-
module Guard
|
4
|
-
|
5
|
-
# The DslDescriber overrides methods to create an internal structure
|
6
|
-
# of the Guardfile that is used in some inspection utility methods
|
7
|
-
# like the CLI commands `show` and `list`.
|
8
|
-
#
|
9
|
-
# @see Guard::Dsl
|
10
|
-
# @see Guard::CLI
|
11
|
-
#
|
12
|
-
class DslDescriber < Dsl
|
13
|
-
|
14
|
-
@@guardfile_structure = [ { :guards => [] } ]
|
15
|
-
|
16
|
-
class << self
|
17
|
-
|
18
|
-
# Get the Guardfile structure.
|
19
|
-
#
|
20
|
-
# @return [Array<Hash>] the structure
|
21
|
-
#
|
22
|
-
def guardfile_structure
|
23
|
-
@@guardfile_structure
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# Declares a group of guards.
|
30
|
-
#
|
31
|
-
# @param [String] name the group's name called from the CLI
|
32
|
-
# @yield a block where you can declare several guards
|
33
|
-
#
|
34
|
-
# @see Guard::Dsl#group
|
35
|
-
#
|
36
|
-
def group(name)
|
37
|
-
@@guardfile_structure << { :group => name.to_sym, :guards => [] }
|
38
|
-
@group = true
|
39
|
-
|
40
|
-
yield if block_given?
|
41
|
-
|
42
|
-
@group = false
|
43
|
-
end
|
44
|
-
|
45
|
-
# Declares a Guard.
|
46
|
-
#
|
47
|
-
# @param [String] name the Guard name
|
48
|
-
# @param [Hash] options the options accepted by the Guard
|
49
|
-
# @yield a block where you can declare several watch patterns and actions
|
50
|
-
#
|
51
|
-
# @see Guard::Dsl#guard
|
52
|
-
#
|
53
|
-
def guard(name, options = {})
|
54
|
-
node = (@group ? @@guardfile_structure.last : @@guardfile_structure.first)
|
55
|
-
|
56
|
-
node[:guards] << { :name => name, :options => options }
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
1
|
+
require 'guard/dsl'
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
|
5
|
+
# The DslDescriber overrides methods to create an internal structure
|
6
|
+
# of the Guardfile that is used in some inspection utility methods
|
7
|
+
# like the CLI commands `show` and `list`.
|
8
|
+
#
|
9
|
+
# @see Guard::Dsl
|
10
|
+
# @see Guard::CLI
|
11
|
+
#
|
12
|
+
class DslDescriber < Dsl
|
13
|
+
|
14
|
+
@@guardfile_structure = [ { :guards => [] } ]
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
# Get the Guardfile structure.
|
19
|
+
#
|
20
|
+
# @return [Array<Hash>] the structure
|
21
|
+
#
|
22
|
+
def guardfile_structure
|
23
|
+
@@guardfile_structure
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Declares a group of guards.
|
30
|
+
#
|
31
|
+
# @param [String] name the group's name called from the CLI
|
32
|
+
# @yield a block where you can declare several guards
|
33
|
+
#
|
34
|
+
# @see Guard::Dsl#group
|
35
|
+
#
|
36
|
+
def group(name)
|
37
|
+
@@guardfile_structure << { :group => name.to_sym, :guards => [] }
|
38
|
+
@group = true
|
39
|
+
|
40
|
+
yield if block_given?
|
41
|
+
|
42
|
+
@group = false
|
43
|
+
end
|
44
|
+
|
45
|
+
# Declares a Guard.
|
46
|
+
#
|
47
|
+
# @param [String] name the Guard name
|
48
|
+
# @param [Hash] options the options accepted by the Guard
|
49
|
+
# @yield a block where you can declare several watch patterns and actions
|
50
|
+
#
|
51
|
+
# @see Guard::Dsl#guard
|
52
|
+
#
|
53
|
+
def guard(name, options = {})
|
54
|
+
node = (@group ? @@guardfile_structure.last : @@guardfile_structure.first)
|
55
|
+
|
56
|
+
node[:guards] << { :name => name, :options => options }
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/guard/group.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
module Guard
|
2
|
-
|
3
|
-
# A group of Guards.
|
4
|
-
#
|
5
|
-
class Group
|
6
|
-
|
7
|
-
attr_accessor :name, :options
|
8
|
-
|
9
|
-
# Initialize a Group.
|
10
|
-
#
|
11
|
-
# @param [String] name the name of the group
|
12
|
-
# @option options [Boolean] halt_on_fail if a task execution
|
13
|
-
# should be halted for all Guards in this group if one Guard throws `:task_has_failed`
|
14
|
-
#
|
15
|
-
def initialize(name, options = {})
|
16
|
-
@name = name.to_sym
|
17
|
-
@options = options
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# A group of Guards.
|
4
|
+
#
|
5
|
+
class Group
|
6
|
+
|
7
|
+
attr_accessor :name, :options
|
8
|
+
|
9
|
+
# Initialize a Group.
|
10
|
+
#
|
11
|
+
# @param [String] name the name of the group
|
12
|
+
# @option options [Boolean] halt_on_fail if a task execution
|
13
|
+
# should be halted for all Guards in this group if one Guard throws `:task_has_failed`
|
14
|
+
#
|
15
|
+
def initialize(name, options = {})
|
16
|
+
@name = name.to_sym
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/guard/guard.rb
CHANGED
@@ -1,98 +1,98 @@
|
|
1
|
-
module Guard
|
2
|
-
|
3
|
-
# Main class that every Guard implementation must subclass.
|
4
|
-
#
|
5
|
-
# Guard will trigger the `start`, `stop`, `reload`, `run_all` and `run_on_change`
|
6
|
-
# methods depending on user interaction and file modification.
|
7
|
-
#
|
8
|
-
# Each Guard should provide a template Guardfile located within the Gem
|
9
|
-
# at `lib/guard/guard-name/templates/Guardfile`.
|
10
|
-
#
|
11
|
-
class Guard
|
12
|
-
include Hook
|
13
|
-
|
14
|
-
attr_accessor :watchers, :options, :group
|
15
|
-
|
16
|
-
# Initialize a Guard.
|
17
|
-
#
|
18
|
-
# @param [Array<Guard::Watcher>] watchers the Guard file watchers
|
19
|
-
# @param [Hash] options the custom Guard options
|
20
|
-
#
|
21
|
-
def initialize(watchers = [], options = {})
|
22
|
-
@group = options[:group] ? options.delete(:group).to_sym : :default
|
23
|
-
@watchers, @options = watchers, options
|
24
|
-
end
|
25
|
-
|
26
|
-
# Initialize the Guard. This will copy the Guardfile template inside the Guard gem.
|
27
|
-
# The template Guardfile must be located within the Gem at `lib/guard/guard-name/templates/Guardfile`.
|
28
|
-
#
|
29
|
-
# @param [String] name the name of the Guard
|
30
|
-
#
|
31
|
-
def self.init(name)
|
32
|
-
if ::Guard::Dsl.guardfile_include?(name)
|
33
|
-
::Guard::UI.info "Guardfile already includes #{ name } guard"
|
34
|
-
else
|
35
|
-
content = File.read('Guardfile')
|
36
|
-
guard = File.read("#{ ::Guard.locate_guard(name) }/lib/guard/#{ name }/templates/Guardfile")
|
37
|
-
File.open('Guardfile', 'wb') do |f|
|
38
|
-
f.puts(content)
|
39
|
-
f.puts("")
|
40
|
-
f.puts(guard)
|
41
|
-
end
|
42
|
-
::Guard::UI.info "#{name} guard added to Guardfile, feel free to edit it"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Call once when Guard starts. Please override initialize method to init stuff.
|
47
|
-
#
|
48
|
-
# @return [Boolean] Whether the start action was successful or not
|
49
|
-
#
|
50
|
-
def start
|
51
|
-
true
|
52
|
-
end
|
53
|
-
|
54
|
-
# Call once when Guard quit.
|
55
|
-
#
|
56
|
-
# @return [Boolean] Whether the stop action was successful or not
|
57
|
-
#
|
58
|
-
def stop
|
59
|
-
true
|
60
|
-
end
|
61
|
-
|
62
|
-
# Should be used for "reload" (really!) actions like reloading passenger/spork/bundler/...
|
63
|
-
#
|
64
|
-
# @return [Boolean] Whether the reload action was successful or not
|
65
|
-
#
|
66
|
-
def reload
|
67
|
-
true
|
68
|
-
end
|
69
|
-
|
70
|
-
# Should be used for long action like running all specs/tests/...
|
71
|
-
#
|
72
|
-
# @return [Boolean] Whether the run_all action was successful or not
|
73
|
-
#
|
74
|
-
def run_all
|
75
|
-
true
|
76
|
-
end
|
77
|
-
|
78
|
-
# Will be triggered when a file change matched a watcher.
|
79
|
-
#
|
80
|
-
# @param [Array<String>] paths the changes files or paths
|
81
|
-
# @return [Boolean] Whether the run_on_change action was successful or not
|
82
|
-
#
|
83
|
-
def run_on_change(paths)
|
84
|
-
true
|
85
|
-
end
|
86
|
-
|
87
|
-
# Will be triggered when a file deletion matched a watcher.
|
88
|
-
#
|
89
|
-
# @param [Array<String>] paths the deleted files or paths
|
90
|
-
# @return [Boolean] Whether the run_on_deletion action was successful or not
|
91
|
-
#
|
92
|
-
def run_on_deletion(paths)
|
93
|
-
true
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# Main class that every Guard implementation must subclass.
|
4
|
+
#
|
5
|
+
# Guard will trigger the `start`, `stop`, `reload`, `run_all` and `run_on_change`
|
6
|
+
# methods depending on user interaction and file modification.
|
7
|
+
#
|
8
|
+
# Each Guard should provide a template Guardfile located within the Gem
|
9
|
+
# at `lib/guard/guard-name/templates/Guardfile`.
|
10
|
+
#
|
11
|
+
class Guard
|
12
|
+
include Hook
|
13
|
+
|
14
|
+
attr_accessor :watchers, :options, :group
|
15
|
+
|
16
|
+
# Initialize a Guard.
|
17
|
+
#
|
18
|
+
# @param [Array<Guard::Watcher>] watchers the Guard file watchers
|
19
|
+
# @param [Hash] options the custom Guard options
|
20
|
+
#
|
21
|
+
def initialize(watchers = [], options = {})
|
22
|
+
@group = options[:group] ? options.delete(:group).to_sym : :default
|
23
|
+
@watchers, @options = watchers, options
|
24
|
+
end
|
25
|
+
|
26
|
+
# Initialize the Guard. This will copy the Guardfile template inside the Guard gem.
|
27
|
+
# The template Guardfile must be located within the Gem at `lib/guard/guard-name/templates/Guardfile`.
|
28
|
+
#
|
29
|
+
# @param [String] name the name of the Guard
|
30
|
+
#
|
31
|
+
def self.init(name)
|
32
|
+
if ::Guard::Dsl.guardfile_include?(name)
|
33
|
+
::Guard::UI.info "Guardfile already includes #{ name } guard"
|
34
|
+
else
|
35
|
+
content = File.read('Guardfile')
|
36
|
+
guard = File.read("#{ ::Guard.locate_guard(name) }/lib/guard/#{ name }/templates/Guardfile")
|
37
|
+
File.open('Guardfile', 'wb') do |f|
|
38
|
+
f.puts(content)
|
39
|
+
f.puts("")
|
40
|
+
f.puts(guard)
|
41
|
+
end
|
42
|
+
::Guard::UI.info "#{name} guard added to Guardfile, feel free to edit it"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Call once when Guard starts. Please override initialize method to init stuff.
|
47
|
+
#
|
48
|
+
# @return [Boolean] Whether the start action was successful or not
|
49
|
+
#
|
50
|
+
def start
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
# Call once when Guard quit.
|
55
|
+
#
|
56
|
+
# @return [Boolean] Whether the stop action was successful or not
|
57
|
+
#
|
58
|
+
def stop
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
# Should be used for "reload" (really!) actions like reloading passenger/spork/bundler/...
|
63
|
+
#
|
64
|
+
# @return [Boolean] Whether the reload action was successful or not
|
65
|
+
#
|
66
|
+
def reload
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
# Should be used for long action like running all specs/tests/...
|
71
|
+
#
|
72
|
+
# @return [Boolean] Whether the run_all action was successful or not
|
73
|
+
#
|
74
|
+
def run_all
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
# Will be triggered when a file change matched a watcher.
|
79
|
+
#
|
80
|
+
# @param [Array<String>] paths the changes files or paths
|
81
|
+
# @return [Boolean] Whether the run_on_change action was successful or not
|
82
|
+
#
|
83
|
+
def run_on_change(paths)
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
# Will be triggered when a file deletion matched a watcher.
|
88
|
+
#
|
89
|
+
# @param [Array<String>] paths the deleted files or paths
|
90
|
+
# @return [Boolean] Whether the run_on_deletion action was successful or not
|
91
|
+
#
|
92
|
+
def run_on_deletion(paths)
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/lib/guard/hook.rb
CHANGED
@@ -1,118 +1,118 @@
|
|
1
|
-
module Guard
|
2
|
-
|
3
|
-
# Guard has a hook mechanism that allows you to insert callbacks for individual Guards.
|
4
|
-
# By default, each of the Guard instance methods has a "_begin" and an "_end" hook.
|
5
|
-
# For example, the Guard::Guard#start method has a :start_begin hook that is runs immediately
|
6
|
-
# before Guard::Guard#start, and a :start_end hook that runs immediately after Guard::Guard#start.
|
7
|
-
#
|
8
|
-
# Read more about [hooks and callbacks on the wiki](https://github.com/guard/guard/wiki/Hooks-and-callbacks).
|
9
|
-
#
|
10
|
-
module Hook
|
11
|
-
|
12
|
-
# The Hook module gets included.
|
13
|
-
#
|
14
|
-
# @param [Class] base the class that includes the module
|
15
|
-
#
|
16
|
-
def self.included(base)
|
17
|
-
base.send :include, InstanceMethods
|
18
|
-
end
|
19
|
-
|
20
|
-
# Instance methods that gets included in the base class.
|
21
|
-
#
|
22
|
-
module InstanceMethods
|
23
|
-
|
24
|
-
# When event is a Symbol, {#hook} will generate a hook name
|
25
|
-
# by concatenating the method name from where {#hook} is called
|
26
|
-
# with the given Symbol.
|
27
|
-
#
|
28
|
-
# @example Add a hook with a Symbol
|
29
|
-
#
|
30
|
-
# def run_all
|
31
|
-
# hook :foo
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# Here, when {Guard::Guard#run_all} is called, {#hook} will notify callbacks
|
35
|
-
# registered for the "run_all_foo" event.
|
36
|
-
#
|
37
|
-
# When event is a String, {#hook} will directly turn the String
|
38
|
-
# into a Symbol.
|
39
|
-
#
|
40
|
-
# @example Add a hook with a String
|
41
|
-
#
|
42
|
-
# def run_all
|
43
|
-
# hook "foo_bar"
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# When {Guard::Guard#run_all} is called, {#hook} will notify callbacks
|
47
|
-
# registered for the "foo_bar" event.
|
48
|
-
#
|
49
|
-
# @param [Symbol, String] event the name of the Guard event
|
50
|
-
# @param [Array] args the parameters are passed as is to the callbacks registered for the given event.
|
51
|
-
#
|
52
|
-
def hook(event, *args)
|
53
|
-
hook_name = if event.is_a? Symbol
|
54
|
-
calling_method = caller[0][/`([^']*)'/, 1]
|
55
|
-
"#{ calling_method }_#{ event }"
|
56
|
-
else
|
57
|
-
event
|
58
|
-
end.to_sym
|
59
|
-
|
60
|
-
UI.debug "Hook :#{ hook_name } executed for #{ self.class }"
|
61
|
-
|
62
|
-
Hook.notify(self.class, hook_name, *args)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class << self
|
67
|
-
|
68
|
-
# Get all callbacks.
|
69
|
-
#
|
70
|
-
def callbacks
|
71
|
-
@callbacks ||= Hash.new { |hash, key| hash[key] = [] }
|
72
|
-
end
|
73
|
-
|
74
|
-
# Add a callback.
|
75
|
-
#
|
76
|
-
# @param [Block] listener the listener to notify
|
77
|
-
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
78
|
-
# @param [Array<Symbol>] events the events to register
|
79
|
-
#
|
80
|
-
def add_callback(listener, guard_class, events)
|
81
|
-
_events = events.is_a?(Array) ? events : [events]
|
82
|
-
_events.each do |event|
|
83
|
-
callbacks[[guard_class, event]] << listener
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Checks if a callback has been registered.
|
88
|
-
#
|
89
|
-
# @param [Block] listener the listener to notify
|
90
|
-
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
91
|
-
# @param [Symbol] event the event to look for
|
92
|
-
#
|
93
|
-
def has_callback?(listener, guard_class, event)
|
94
|
-
callbacks[[guard_class, event]].include?(listener)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Notify a callback.
|
98
|
-
#
|
99
|
-
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
100
|
-
# @param [Symbol] event the event to trigger
|
101
|
-
# @param [Array] args the arguments for the listener
|
102
|
-
#
|
103
|
-
def notify(guard_class, event, *args)
|
104
|
-
callbacks[[guard_class, event]].each do |listener|
|
105
|
-
listener.call(guard_class, event, *args)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Reset all callbacks.
|
110
|
-
#
|
111
|
-
def reset_callbacks!
|
112
|
-
@callbacks = nil
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
end
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# Guard has a hook mechanism that allows you to insert callbacks for individual Guards.
|
4
|
+
# By default, each of the Guard instance methods has a "_begin" and an "_end" hook.
|
5
|
+
# For example, the Guard::Guard#start method has a :start_begin hook that is runs immediately
|
6
|
+
# before Guard::Guard#start, and a :start_end hook that runs immediately after Guard::Guard#start.
|
7
|
+
#
|
8
|
+
# Read more about [hooks and callbacks on the wiki](https://github.com/guard/guard/wiki/Hooks-and-callbacks).
|
9
|
+
#
|
10
|
+
module Hook
|
11
|
+
|
12
|
+
# The Hook module gets included.
|
13
|
+
#
|
14
|
+
# @param [Class] base the class that includes the module
|
15
|
+
#
|
16
|
+
def self.included(base)
|
17
|
+
base.send :include, InstanceMethods
|
18
|
+
end
|
19
|
+
|
20
|
+
# Instance methods that gets included in the base class.
|
21
|
+
#
|
22
|
+
module InstanceMethods
|
23
|
+
|
24
|
+
# When event is a Symbol, {#hook} will generate a hook name
|
25
|
+
# by concatenating the method name from where {#hook} is called
|
26
|
+
# with the given Symbol.
|
27
|
+
#
|
28
|
+
# @example Add a hook with a Symbol
|
29
|
+
#
|
30
|
+
# def run_all
|
31
|
+
# hook :foo
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# Here, when {Guard::Guard#run_all} is called, {#hook} will notify callbacks
|
35
|
+
# registered for the "run_all_foo" event.
|
36
|
+
#
|
37
|
+
# When event is a String, {#hook} will directly turn the String
|
38
|
+
# into a Symbol.
|
39
|
+
#
|
40
|
+
# @example Add a hook with a String
|
41
|
+
#
|
42
|
+
# def run_all
|
43
|
+
# hook "foo_bar"
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# When {Guard::Guard#run_all} is called, {#hook} will notify callbacks
|
47
|
+
# registered for the "foo_bar" event.
|
48
|
+
#
|
49
|
+
# @param [Symbol, String] event the name of the Guard event
|
50
|
+
# @param [Array] args the parameters are passed as is to the callbacks registered for the given event.
|
51
|
+
#
|
52
|
+
def hook(event, *args)
|
53
|
+
hook_name = if event.is_a? Symbol
|
54
|
+
calling_method = caller[0][/`([^']*)'/, 1]
|
55
|
+
"#{ calling_method }_#{ event }"
|
56
|
+
else
|
57
|
+
event
|
58
|
+
end.to_sym
|
59
|
+
|
60
|
+
UI.debug "Hook :#{ hook_name } executed for #{ self.class }"
|
61
|
+
|
62
|
+
Hook.notify(self.class, hook_name, *args)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class << self
|
67
|
+
|
68
|
+
# Get all callbacks.
|
69
|
+
#
|
70
|
+
def callbacks
|
71
|
+
@callbacks ||= Hash.new { |hash, key| hash[key] = [] }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Add a callback.
|
75
|
+
#
|
76
|
+
# @param [Block] listener the listener to notify
|
77
|
+
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
78
|
+
# @param [Array<Symbol>] events the events to register
|
79
|
+
#
|
80
|
+
def add_callback(listener, guard_class, events)
|
81
|
+
_events = events.is_a?(Array) ? events : [events]
|
82
|
+
_events.each do |event|
|
83
|
+
callbacks[[guard_class, event]] << listener
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Checks if a callback has been registered.
|
88
|
+
#
|
89
|
+
# @param [Block] listener the listener to notify
|
90
|
+
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
91
|
+
# @param [Symbol] event the event to look for
|
92
|
+
#
|
93
|
+
def has_callback?(listener, guard_class, event)
|
94
|
+
callbacks[[guard_class, event]].include?(listener)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Notify a callback.
|
98
|
+
#
|
99
|
+
# @param [Guard::Guard] guard_class the Guard class to add the callback
|
100
|
+
# @param [Symbol] event the event to trigger
|
101
|
+
# @param [Array] args the arguments for the listener
|
102
|
+
#
|
103
|
+
def notify(guard_class, event, *args)
|
104
|
+
callbacks[[guard_class, event]].each do |listener|
|
105
|
+
listener.call(guard_class, event, *args)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Reset all callbacks.
|
110
|
+
#
|
111
|
+
def reset_callbacks!
|
112
|
+
@callbacks = nil
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|