guard 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +24 -0
- data/README.md +85 -79
- data/lib/guard.rb +6 -3
- data/lib/guard/cli.rb +2 -2
- data/lib/guard/commands/all.rb +34 -0
- data/lib/guard/commands/change.rb +37 -0
- data/lib/guard/commands/notification.rb +27 -0
- data/lib/guard/commands/pause.rb +28 -0
- data/lib/guard/commands/reload.rb +35 -0
- data/lib/guard/commands/show.rb +27 -0
- data/lib/guard/dsl.rb +73 -9
- data/lib/guard/interactor.rb +134 -212
- data/lib/guard/notifier.rb +36 -14
- data/lib/guard/notifiers/emacs.rb +23 -19
- data/lib/guard/notifiers/terminal_title.rb +35 -0
- data/lib/guard/notifiers/tmux.rb +67 -10
- data/lib/guard/runner.rb +6 -2
- data/lib/guard/ui.rb +74 -14
- data/lib/guard/version.rb +1 -1
- metadata +44 -10
- data/lib/guard/interactors/coolline.rb +0 -64
- data/lib/guard/interactors/helpers/completion.rb +0 -32
- data/lib/guard/interactors/helpers/terminal.rb +0 -46
- data/lib/guard/interactors/readline.rb +0 -94
- data/lib/guard/interactors/simple.rb +0 -19
@@ -0,0 +1,35 @@
|
|
1
|
+
module Guard
|
2
|
+
class Interactor
|
3
|
+
|
4
|
+
RELOAD = Pry::CommandSet.new do
|
5
|
+
create_command 'reload' do
|
6
|
+
|
7
|
+
group 'Guard'
|
8
|
+
description 'Reload all plugins.'
|
9
|
+
|
10
|
+
banner <<-BANNER
|
11
|
+
Usage: reload <scope>
|
12
|
+
|
13
|
+
Run the Guard plugin `reload` action.
|
14
|
+
|
15
|
+
You may want to specify an optional scope to the action,
|
16
|
+
either the name of a Guard plugin or a plugin group.
|
17
|
+
BANNER
|
18
|
+
|
19
|
+
def process(*entries)
|
20
|
+
scopes, rest = ::Guard::Interactor.convert_scope(entries)
|
21
|
+
|
22
|
+
if rest.length == 0
|
23
|
+
::Guard.reload scopes
|
24
|
+
else
|
25
|
+
output.puts "Unkown scope #{ rest.join(', ') }"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Pry.commands.import ::Guard::Interactor::RELOAD
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'guard/dsl_describer'
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
class Interactor
|
5
|
+
|
6
|
+
SHOW = Pry::CommandSet.new do
|
7
|
+
create_command 'show' do
|
8
|
+
|
9
|
+
group 'Guard'
|
10
|
+
description 'Show all Guard plugins.'
|
11
|
+
|
12
|
+
banner <<-BANNER
|
13
|
+
Usage: show <scope>
|
14
|
+
|
15
|
+
Show all defined Guard plugins and their options.
|
16
|
+
BANNER
|
17
|
+
|
18
|
+
def process
|
19
|
+
::Guard::DslDescriber.show(::Guard.options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Pry.commands.import ::Guard::Interactor::SHOW
|
data/lib/guard/dsl.rb
CHANGED
@@ -16,7 +16,7 @@ module Guard
|
|
16
16
|
#
|
17
17
|
# A more advanced DSL use is the `callback` keyword that allows you to execute arbitrary
|
18
18
|
# code before or after any of the `start`, `stop`, `reload`, `run_all`, `run_on_changes`,
|
19
|
-
# `run_on_additions`, `run_on_modifications` and `run_on_removals` Guard plugins method.
|
19
|
+
# `run_on_additions`, `run_on_modifications` and `run_on_removals` Guard plugins method.
|
20
20
|
# You can even insert more hooks inside these methods.
|
21
21
|
# Please [checkout the Wiki page](https://github.com/guard/guard/wiki/Hooks-and-callbacks) for more details.
|
22
22
|
#
|
@@ -93,12 +93,21 @@ module Guard
|
|
93
93
|
|
94
94
|
# Deprecation message for the `ignore_paths` method
|
95
95
|
IGNORE_PATHS_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
96
|
-
Starting with Guard v1.1 the use of the 'ignore_paths' Guardfile
|
96
|
+
Starting with Guard v1.1 the use of the 'ignore_paths' Guardfile DSL method is deprecated.
|
97
97
|
|
98
98
|
Please replace that method with the better 'ignore' or/and 'filter' methods.
|
99
99
|
Documentation on the README: https://github.com/guard/guard#guardfile-dsl-ignore
|
100
100
|
EOS
|
101
101
|
|
102
|
+
# Deprecation message for the `ignore_paths` method
|
103
|
+
INTERACTOR_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
104
|
+
Starting with Guard v1.4 the use of the 'interactor' Guardfile DSL method is only used to
|
105
|
+
turn the Pry interactor off. All other usages are deprecated.
|
106
|
+
|
107
|
+
Please make use of the Pry plugin architecture to customize the interactions and place them
|
108
|
+
either in your `~/.guardrc` or the `Guardfile`.
|
109
|
+
EOS
|
110
|
+
|
102
111
|
class << self
|
103
112
|
|
104
113
|
@@options = nil
|
@@ -315,17 +324,15 @@ module Guard
|
|
315
324
|
|
316
325
|
# Sets the interactor to use.
|
317
326
|
#
|
318
|
-
# @example Use the readline interactor
|
319
|
-
# interactor :readline
|
320
|
-
#
|
321
|
-
# @example Use the gets interactor
|
322
|
-
# interactor :gets
|
323
|
-
#
|
324
327
|
# @example Turn off interactions
|
325
328
|
# interactor :off
|
326
329
|
#
|
327
330
|
def interactor(interactor)
|
328
|
-
|
331
|
+
if interactor == :off
|
332
|
+
::Guard.options[:no_interactions] = true
|
333
|
+
else
|
334
|
+
::Guard::UI.deprecation(INTERACTOR_DEPRECATION)
|
335
|
+
end
|
329
336
|
end
|
330
337
|
|
331
338
|
# Declares a group of Guard plugins to be run with `guard start --group group_name`.
|
@@ -465,5 +472,62 @@ module Guard
|
|
465
472
|
::Guard.listener = ::Guard.listener.filter(*regexps)
|
466
473
|
end
|
467
474
|
|
475
|
+
# Configure the Guard logger.
|
476
|
+
#
|
477
|
+
# * Log level must be either `:debug`, `:info`, `:warn` or `:error`.
|
478
|
+
# * Template supports the following placeholders: `:time`, `:severity`, `:progname`, `:pid`, `:unit_of_work_id` and `:message`
|
479
|
+
# * Time format directives are the same as Time#strftime or :milliseconds
|
480
|
+
# * The `:only` and `:except` options must be a RegExp.
|
481
|
+
#
|
482
|
+
# @example Set the log level
|
483
|
+
# logger :level => :warn
|
484
|
+
#
|
485
|
+
# @example Set a custom log template
|
486
|
+
# logger :template => '[Guard - :severity - :progname - :time] :message'
|
487
|
+
#
|
488
|
+
# @example Set a custom time format
|
489
|
+
# logger :time_format => '%h'
|
490
|
+
#
|
491
|
+
# @example Limit logging to a Guard plugin
|
492
|
+
# logger :only => :jasmine
|
493
|
+
#
|
494
|
+
# @example Log all but not the messages from a specific Guard plugin
|
495
|
+
# logger :except => :jasmine
|
496
|
+
#
|
497
|
+
# @param [Hash] options the log options
|
498
|
+
# @option options [String, Symbol] level the log level
|
499
|
+
# @option options [String] template the logger template
|
500
|
+
# @option options [String, Symbol] time_format the time format
|
501
|
+
# @option options [RegExp] only show only messages from the matching Guard plugin
|
502
|
+
# @option options [RegExp] except does not show messages from the matching Guard plugin
|
503
|
+
#
|
504
|
+
def logger(options)
|
505
|
+
if options[:level]
|
506
|
+
options[:level] = options[:level].to_sym
|
507
|
+
|
508
|
+
unless [:debug, :info, :warn, :error].include? options[:level]
|
509
|
+
::Guard::UI.warning "Invalid log level `#{ options[:level] }` ignored. Please use either :debug, :info, :warn or :error."
|
510
|
+
options.delete :level
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
if options[:only] && options[:except]
|
515
|
+
::Guard::UI.warning "You cannot specify the logger options :only and :except at the same time."
|
516
|
+
|
517
|
+
options.delete :only
|
518
|
+
options.delete :except
|
519
|
+
end
|
520
|
+
|
521
|
+
# Convert the :only and :except options to a regular expression
|
522
|
+
[:only, :except].each do |name|
|
523
|
+
if options[name]
|
524
|
+
list = [].push(options[name]).flatten.map { |plugin| Regexp.escape(plugin.to_s) }.join('|')
|
525
|
+
options[name] = Regexp.new(list, Regexp::IGNORECASE)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
::Guard::UI.options = ::Guard::UI.options.merge options
|
530
|
+
end
|
531
|
+
|
468
532
|
end
|
469
533
|
end
|
data/lib/guard/interactor.rb
CHANGED
@@ -1,110 +1,123 @@
|
|
1
1
|
module Guard
|
2
2
|
|
3
|
-
# The interactor
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# Currently the following actions are implemented:
|
7
|
-
#
|
8
|
-
# - h, help => Show help
|
9
|
-
# - e, exit,
|
10
|
-
# q. quit => Exit Guard
|
11
|
-
# - r, reload => Reload Guard
|
12
|
-
# - p, pause => Toggle file modification listener
|
13
|
-
# - n, notification => Toggle notifications
|
14
|
-
# - s, show => Show Guard plugin configuration
|
15
|
-
# - c, change => Trigger a file change
|
16
|
-
# - <enter> => Run all
|
17
|
-
#
|
18
|
-
# It's also possible to scope `reload` and `run all` actions to only a specified group or a guard.
|
19
|
-
#
|
20
|
-
# @example Reload backend group
|
21
|
-
# backend reload
|
22
|
-
# reload backend
|
23
|
-
#
|
24
|
-
# @example Reload rspec guard
|
25
|
-
# spork reload
|
26
|
-
# reload spork
|
27
|
-
#
|
28
|
-
# @example Run all jasmine specs
|
29
|
-
# jasmine
|
30
|
-
#
|
31
|
-
# @abstract
|
3
|
+
# The Guard interactor is a Pry REPL with a Guard
|
4
|
+
# specific command set.
|
32
5
|
#
|
33
6
|
class Interactor
|
34
7
|
|
8
|
+
require 'pry'
|
9
|
+
|
35
10
|
require 'guard'
|
36
11
|
require 'guard/ui'
|
37
|
-
|
38
|
-
require 'guard/
|
39
|
-
require 'guard/
|
40
|
-
require 'guard/
|
41
|
-
require 'guard/
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
}
|
52
|
-
|
53
|
-
# Set the interactor implementation
|
54
|
-
#
|
55
|
-
# @param [Symbol] interactor the name of the interactor
|
12
|
+
|
13
|
+
require 'guard/commands/all'
|
14
|
+
require 'guard/commands/change'
|
15
|
+
require 'guard/commands/notification'
|
16
|
+
require 'guard/commands/pause'
|
17
|
+
require 'guard/commands/reload'
|
18
|
+
require 'guard/commands/show'
|
19
|
+
|
20
|
+
GUARD_RC = '~/.guardrc'
|
21
|
+
HISTORY_FILE = '~/.guard_history'
|
22
|
+
|
23
|
+
# Initialize the interactor. This configures
|
24
|
+
# Pry and creates some custom commands and aliases
|
25
|
+
# for Guard.
|
56
26
|
#
|
57
|
-
def
|
58
|
-
|
27
|
+
def initialize
|
28
|
+
return if ENV['GUARD_ENV'] == 'test'
|
29
|
+
|
30
|
+
Pry.config.history.file = HISTORY_FILE
|
31
|
+
|
32
|
+
load_guard_rc
|
33
|
+
|
34
|
+
create_run_all_command
|
35
|
+
create_command_aliases
|
36
|
+
create_guard_commands
|
37
|
+
create_group_commands
|
38
|
+
|
39
|
+
configure_prompt
|
59
40
|
end
|
60
41
|
|
61
|
-
#
|
62
|
-
# interactor implementation.
|
42
|
+
# Loads the `~/.guardrc` file when pry has started.
|
63
43
|
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
case @interactor
|
68
|
-
when :coolline
|
69
|
-
::Guard::CoollineInteractor.new if ::Guard::CoollineInteractor.available?
|
70
|
-
when :readline
|
71
|
-
::Guard::ReadlineInteractor.new if ::Guard::ReadlineInteractor.available?
|
72
|
-
when :simple
|
73
|
-
::Guard::SimpleInteractor.new
|
74
|
-
when :off
|
75
|
-
nil
|
76
|
-
else
|
77
|
-
auto_detect
|
44
|
+
def load_guard_rc
|
45
|
+
Pry.config.hooks.add_hook :when_started, :load_guard_rc do
|
46
|
+
load GUARD_RC if File.exist? File.expand_path GUARD_RC
|
78
47
|
end
|
79
48
|
end
|
80
49
|
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# It returns the Readline implementation when:
|
85
|
-
#
|
86
|
-
# * rb-readline is installed
|
87
|
-
# * The Ruby implementation is JRuby
|
88
|
-
# * The current OS is not Mac OS X
|
50
|
+
# Creates a command that triggers the `:run_all` action
|
51
|
+
# when the command is empty (just pressing enter on the
|
52
|
+
# beginning of a line).
|
89
53
|
#
|
90
|
-
|
54
|
+
def create_run_all_command
|
55
|
+
Pry.commands.block_command /^$/, 'Hit enter to run all' do
|
56
|
+
Pry.run_command 'all'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates command aliases for the commands
|
61
|
+
# `help`, `reload`, `change`, `show`, `notification`, `pause`, `exit` and `quit`,
|
62
|
+
# which will be the first letter of the command.
|
91
63
|
#
|
92
|
-
|
64
|
+
def create_command_aliases
|
65
|
+
%w(help reload change show notification pause exit quit).each do |command|
|
66
|
+
Pry.commands.alias_command command[0].chr, command
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create a shorthand command to run the `:run_all`
|
71
|
+
# action on a specific Guard plugin. For example,
|
72
|
+
# when guard-rspec is available, then a command
|
73
|
+
# `rspec` is created that runs `all rspec`.
|
93
74
|
#
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
75
|
+
def create_guard_commands
|
76
|
+
::Guard.guards.each do |guard|
|
77
|
+
name = guard.class.to_s.downcase.sub('guard::', '')
|
78
|
+
|
79
|
+
Pry.commands.create_command name, "Run all #{ name }" do
|
80
|
+
group 'Guard'
|
81
|
+
|
82
|
+
def process
|
83
|
+
Pry.run_command "all #{ match }"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
98
87
|
end
|
99
88
|
|
100
|
-
#
|
101
|
-
#
|
89
|
+
# Create a shorthand command to run the `:run_all`
|
90
|
+
# action on a specific Guard group. For example,
|
91
|
+
# when you have a group `frontend`, then a command
|
92
|
+
# `frontend` is created that runs `all frontend`.
|
102
93
|
#
|
103
|
-
|
104
|
-
|
94
|
+
def create_group_commands
|
95
|
+
::Guard.groups.each do |group|
|
96
|
+
name = group.name.to_s
|
97
|
+
next if name == 'default'
|
98
|
+
|
99
|
+
Pry.commands.create_command name, "Run all #{ name }" do
|
100
|
+
group 'Guard'
|
101
|
+
|
102
|
+
def process
|
103
|
+
Pry.run_command "all #{ match }"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Configure the pry prompt to see `guard` instead of
|
110
|
+
# `pry`.
|
105
111
|
#
|
106
|
-
def
|
107
|
-
|
112
|
+
def configure_prompt
|
113
|
+
Pry.config.prompt = [
|
114
|
+
proc do |target_self, nest_level, pry|
|
115
|
+
"[#{ pry.input_array.size }] #{ ::Guard.listener.paused? ? 'pause' : 'guard' }(#{ Pry.view_clip(target_self) })#{":#{ nest_level }" unless nest_level.zero? }> "
|
116
|
+
end,
|
117
|
+
proc do |target_self, nest_level, pry|
|
118
|
+
"[#{ pry.input_array.size }] #{ ::Guard.listener.paused? ? 'pause' : 'guard' }(#{ Pry.view_clip(target_self) })#{":#{ nest_level }" unless nest_level.zero? }* "
|
119
|
+
end
|
120
|
+
]
|
108
121
|
end
|
109
122
|
|
110
123
|
# Start the line reader in its own thread.
|
@@ -112,8 +125,17 @@ module Guard
|
|
112
125
|
def start
|
113
126
|
return if ENV['GUARD_ENV'] == 'test'
|
114
127
|
|
115
|
-
|
116
|
-
|
128
|
+
store_terminal_settings if stty_exists?
|
129
|
+
|
130
|
+
if !@thread || !@thread.alive?
|
131
|
+
::Guard::UI.debug 'Start interactor'
|
132
|
+
|
133
|
+
@thread = Thread.new do
|
134
|
+
Pry.start
|
135
|
+
::Guard.stop
|
136
|
+
exit
|
137
|
+
end
|
138
|
+
end
|
117
139
|
end
|
118
140
|
|
119
141
|
# Kill interactor thread if not current
|
@@ -121,157 +143,57 @@ module Guard
|
|
121
143
|
def stop
|
122
144
|
return if !@thread || ENV['GUARD_ENV'] == 'test'
|
123
145
|
|
124
|
-
::Guard::UI.debug 'Stop interactor'
|
125
146
|
unless Thread.current == @thread
|
147
|
+
::Guard::UI.debug 'Stop interactor'
|
126
148
|
@thread.kill
|
127
149
|
end
|
128
|
-
end
|
129
150
|
|
130
|
-
|
131
|
-
# by each interactor implementation.
|
132
|
-
#
|
133
|
-
# @abstract
|
134
|
-
#
|
135
|
-
def read_line
|
136
|
-
raise NotImplementedError
|
151
|
+
restore_terminal_settings if stty_exists?
|
137
152
|
end
|
138
153
|
|
139
|
-
#
|
140
|
-
#
|
141
|
-
# @param [String] line the input line
|
154
|
+
# Detects whether or not the stty command exists
|
155
|
+
# on the user machine.
|
142
156
|
#
|
143
|
-
|
144
|
-
scopes, action, rest = extract_scopes_and_action(line)
|
145
|
-
|
146
|
-
case action
|
147
|
-
when :help
|
148
|
-
help
|
149
|
-
when :show
|
150
|
-
::Guard::DslDescriber.show(::Guard.options)
|
151
|
-
when :stop
|
152
|
-
::Guard.stop
|
153
|
-
exit
|
154
|
-
when :pause
|
155
|
-
::Guard.pause
|
156
|
-
when :reload
|
157
|
-
::Guard.reload(scopes)
|
158
|
-
when :change
|
159
|
-
::Guard.within_preserved_state do
|
160
|
-
::Guard.runner.run_on_changes(rest, [], [])
|
161
|
-
end
|
162
|
-
when :run_all
|
163
|
-
::Guard.run_all(scopes)
|
164
|
-
when :notification
|
165
|
-
toggle_notification
|
166
|
-
else
|
167
|
-
::Guard::UI.error "Unknown command #{ line }"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Toggle the system notifications on/off
|
157
|
+
# @return [Boolean] the status of stty
|
172
158
|
#
|
173
|
-
def
|
174
|
-
|
175
|
-
::Guard::UI.info 'Turn off notifications'
|
176
|
-
::Guard::Notifier.turn_off
|
177
|
-
else
|
178
|
-
::Guard::Notifier.turn_on
|
179
|
-
end
|
159
|
+
def stty_exists?
|
160
|
+
@stty_exists ||= system('hash', 'stty')
|
180
161
|
end
|
181
162
|
|
182
|
-
#
|
163
|
+
# Stores the terminal settings so we can resore them
|
164
|
+
# when stopping.
|
183
165
|
#
|
184
|
-
def
|
185
|
-
|
186
|
-
puts '[e]xit, [q]uit Exit Guard'
|
187
|
-
puts '[p]ause Toggle file modification listener'
|
188
|
-
puts '[r]eload Reload Guard'
|
189
|
-
puts '[n]otification Toggle notifications'
|
190
|
-
puts '[s]how Show available Guard plugins'
|
191
|
-
puts '[c]hange <file> Trigger a file change'
|
192
|
-
puts '<enter> Run all Guard plugins'
|
193
|
-
puts ''
|
194
|
-
puts 'You can scope the reload action to a specific guard or group:'
|
195
|
-
puts ''
|
196
|
-
puts 'rspec reload Reload the RSpec Guard'
|
197
|
-
puts 'backend reload Reload the backend group'
|
198
|
-
puts ''
|
199
|
-
puts 'You can also run only a specific Guard or all Guard plugins in a specific group:'
|
200
|
-
puts ''
|
201
|
-
puts 'jasmine Run the jasmine Guard'
|
202
|
-
puts 'frontend Run all Guard plugins in the frontend group'
|
203
|
-
puts ''
|
166
|
+
def store_terminal_settings
|
167
|
+
@stty_save = `stty -g 2>/dev/null`.chomp
|
204
168
|
end
|
205
169
|
|
206
|
-
#
|
207
|
-
# input line. There's no strict order for scopes and
|
208
|
-
# actions.
|
209
|
-
#
|
210
|
-
# @example `spork reload` will only reload rspec
|
211
|
-
# @example `jasmine` will only run all jasmine specs
|
170
|
+
# Restore terminal settings
|
212
171
|
#
|
213
|
-
|
214
|
-
|
215
|
-
#
|
216
|
-
def extract_scopes_and_action(line)
|
217
|
-
entries = line.split(' ')
|
218
|
-
|
219
|
-
scopes = extract_scopes(entries)
|
220
|
-
action = extract_action(entries)
|
221
|
-
|
222
|
-
action = :run_all if !action && (!scopes.empty? || entries.empty?)
|
223
|
-
|
224
|
-
[scopes, action, entries]
|
172
|
+
def restore_terminal_settings
|
173
|
+
system("stty #{ @stty_save } 2>/dev/null") if @stty_save
|
225
174
|
end
|
226
175
|
|
227
|
-
|
228
|
-
|
229
|
-
# Extract a guard or group scope from entry if valid.
|
230
|
-
# Any entry found will be removed from the entries.
|
176
|
+
# Converts and validates a plain text scope
|
177
|
+
# to a valid plugin or group scope.
|
231
178
|
#
|
232
|
-
# @param [Array<String>] entries the
|
233
|
-
# @return [Hash]
|
179
|
+
# @param [Array<String>] entries the text scope
|
180
|
+
# @return [Hash, Array<String>] the plugin or group scope, the unknown entries
|
234
181
|
#
|
235
|
-
def
|
236
|
-
scopes
|
182
|
+
def self.convert_scope(entries)
|
183
|
+
scopes = { }
|
184
|
+
unknown = []
|
237
185
|
|
238
|
-
entries.
|
186
|
+
entries.each do |entry|
|
239
187
|
if guard = ::Guard.guards(entry)
|
240
188
|
scopes[:guard] ||= guard
|
241
|
-
true
|
242
|
-
|
243
189
|
elsif group = ::Guard.groups(entry)
|
244
190
|
scopes[:group] ||= group
|
245
|
-
true
|
246
|
-
|
247
191
|
else
|
248
|
-
|
192
|
+
unknown << entry
|
249
193
|
end
|
250
194
|
end
|
251
195
|
|
252
|
-
scopes
|
196
|
+
[scopes, unknown]
|
253
197
|
end
|
254
|
-
|
255
|
-
# Find the action for the given input entry.
|
256
|
-
# Any action found will be removed from the entries.
|
257
|
-
#
|
258
|
-
# @param [Array<String>] entries the user entries
|
259
|
-
# @return [Symbol] a Guard action
|
260
|
-
#
|
261
|
-
def extract_action(entries)
|
262
|
-
action = nil
|
263
|
-
|
264
|
-
entries.delete_if do |entry|
|
265
|
-
if command = ACTIONS.detect { |k, list| list.include?(entry) }
|
266
|
-
action ||= command.first
|
267
|
-
true
|
268
|
-
else
|
269
|
-
false
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
action
|
274
|
-
end
|
275
|
-
|
276
198
|
end
|
277
199
|
end
|