guard 2.10.2 → 2.10.3

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.
@@ -1,3 +1,6 @@
1
+ require "guard"
2
+ require "guard/internals/groups"
3
+
1
4
  module Guard
2
5
  # Base class from which every Guard plugin implementation must inherit.
3
6
  #
@@ -2,7 +2,29 @@
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
4
  ## Uncomment and set this to only include directories you want to watch
5
- # directories %(app lib config test spec feature)
5
+ # directories %w(app lib config test spec feature)
6
6
 
7
7
  ## Uncomment to clear the screen before every task
8
8
  # clearing :on
9
+
10
+ ## Make Guard exit when config is changed so it can be restarted
11
+ #
12
+ ## Note: if you want Guard to automatically start up again, run guard in a
13
+ ## shell loop, e.g.:
14
+ #
15
+ # $ while bundle exec guard; do echo "Restarting Guard..."; done
16
+ #
17
+ ## Note: if you are using the `directories` clause above and you are not
18
+ ## watching the project directory ('.'), the you will want to move the Guardfile
19
+ ## to a watched dir and symlink it back, e.g.
20
+ #
21
+ # $ mkdir config
22
+ # $ mv Guardfile config/
23
+ # $ ln -s config/Guardfile .
24
+ #
25
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
26
+ #
27
+ watch ("Guardfile") do
28
+ UI.info "Exiting because Guard must be restarted for changes to take effect"
29
+ exit 0
30
+ end
@@ -1,10 +1,3 @@
1
- require "lumberjack"
2
-
3
- # TODO: remove this dep!
4
- require "guard/internals/state"
5
-
6
- require "guard/options"
7
-
8
1
  require "guard/ui/colors"
9
2
 
10
3
  require "guard/terminal"
@@ -1,3 +1,3 @@
1
1
  module Guard
2
- VERSION = "2.10.2"
2
+ VERSION = "2.10.3"
3
3
  end
@@ -106,8 +106,8 @@ module Guard
106
106
  def call_action(matches)
107
107
  @action.arity > 0 ? @action.call(matches) : @action.call
108
108
  rescue => ex
109
- ::Guard::UI.error "Problem with watch action!\n#{ ex.message }"
110
- ::Guard::UI.error ex.backtrace.join("\n")
109
+ UI.error "Problem with watch action!\n#{ ex.message }"
110
+ UI.error ex.backtrace.join("\n")
111
111
  end
112
112
  end
113
113
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.2
4
+ version: 2.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibaud Guillaume-Gentil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-08 00:00:00.000000000 Z
11
+ date: 2014-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.2.4
83
+ - !ruby/object:Gem::Dependency
84
+ name: nenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
83
97
  description: Guard is a command line tool to easily handle events on file system modifications.
84
98
  email:
85
99
  - thibaud@thibaud.gg
@@ -97,9 +111,11 @@ files:
97
111
  - images/pending.png
98
112
  - images/success.png
99
113
  - lib/guard.rb
100
- - lib/guard.rb.orig
101
114
  - lib/guard/aruba_adapter.rb
102
115
  - lib/guard/cli.rb
116
+ - lib/guard/cli/environments/bundler.rb
117
+ - lib/guard/cli/environments/evaluate_only.rb
118
+ - lib/guard/cli/environments/valid.rb
103
119
  - lib/guard/commander.rb
104
120
  - lib/guard/commands/all.rb
105
121
  - lib/guard/commands/change.rb
@@ -108,7 +124,6 @@ files:
108
124
  - lib/guard/commands/reload.rb
109
125
  - lib/guard/commands/scope.rb
110
126
  - lib/guard/commands/show.rb
111
- - lib/guard/compat/test/helper.rb.orig
112
127
  - lib/guard/config.rb
113
128
  - lib/guard/deprecated/dsl.rb
114
129
  - lib/guard/deprecated/evaluator.rb
@@ -116,7 +131,6 @@ files:
116
131
  - lib/guard/deprecated/guardfile.rb
117
132
  - lib/guard/deprecated/watcher.rb
118
133
  - lib/guard/dsl.rb
119
- - lib/guard/dsl.rb.orig
120
134
  - lib/guard/dsl_describer.rb
121
135
  - lib/guard/group.rb
122
136
  - lib/guard/guardfile.rb
@@ -124,14 +138,12 @@ files:
124
138
  - lib/guard/guardfile/generator.rb
125
139
  - lib/guard/interactor.rb
126
140
  - lib/guard/internals/debugging.rb
127
- - lib/guard/internals/environment.rb
128
141
  - lib/guard/internals/groups.rb
129
142
  - lib/guard/internals/helpers.rb
130
143
  - lib/guard/internals/plugins.rb
131
144
  - lib/guard/internals/queue.rb
132
145
  - lib/guard/internals/scope.rb
133
146
  - lib/guard/internals/session.rb
134
- - lib/guard/internals/session.rb.orig
135
147
  - lib/guard/internals/state.rb
136
148
  - lib/guard/internals/tracing.rb
137
149
  - lib/guard/internals/traps.rb
@@ -154,18 +166,14 @@ files:
154
166
  - lib/guard/options.rb
155
167
  - lib/guard/plugin.rb
156
168
  - lib/guard/plugin_util.rb
157
- - lib/guard/plugin_util.rb.orig
158
169
  - lib/guard/rake_task.rb
159
- - lib/guard/reevaluator.rb
160
170
  - lib/guard/runner.rb
161
171
  - lib/guard/sheller.rb
162
172
  - lib/guard/templates/Guardfile
163
173
  - lib/guard/terminal.rb
164
174
  - lib/guard/ui.rb
165
- - lib/guard/ui.rb.orig
166
175
  - lib/guard/ui/colors.rb
167
176
  - lib/guard/version.rb
168
- - lib/guard/version.rb.orig
169
177
  - lib/guard/watcher.rb
170
178
  - man/guard.1
171
179
  - man/guard.1.html
@@ -1,174 +0,0 @@
1
- require "thread"
2
- require "listen"
3
-
4
- require "guard/config"
5
- require "guard/deprecated/guard" unless Guard::Config.new.strict?
6
-
7
- require "guard/internals/debugging"
8
- require "guard/internals/traps"
9
- require "guard/internals/helpers"
10
-
11
- require "guard/internals/queue"
12
- require "guard/internals/state"
13
-
14
- require "guard/options"
15
- require "guard/commander"
16
- require "guard/dsl"
17
- require "guard/group"
18
- require "guard/interactor"
19
- require "guard/notifier"
20
- require "guard/plugin_util"
21
- require "guard/runner"
22
- require "guard/sheller"
23
- require "guard/ui"
24
- require "guard/watcher"
25
- require "guard/guardfile/evaluator"
26
-
27
- # Guard is the main module for all Guard related modules and classes.
28
- # Also Guard plugins should use this namespace.
29
- #
30
- module Guard
31
- Deprecated::Guard.add_deprecated(self) unless Config.new.strict?
32
-
33
- class << self
34
- attr_reader :listener
35
-
36
- # @private api
37
- attr_reader :queue
38
-
39
- include Internals::Helpers
40
-
41
- # Initializes the Guard singleton:
42
- #
43
- # * Initialize the internal Guard state;
44
- # * Create the interactor
45
- # * Select and initialize the file change listener.
46
- #
47
- # @option options [Boolean] clear if auto clear the UI should be done
48
- # @option options [Boolean] notify if system notifications should be shown
49
- # @option options [Boolean] debug if debug output should be shown
50
- # @option options [Array<String>] group the list of groups to start
51
- # @option options [Array<String>] watchdir the directories to watch
52
- # @option options [String] guardfile the path to the Guardfile
53
- #
54
- # @return [Guard] the Guard singleton
55
- def setup(cmdline_options = {})
56
- init(cmdline_options)
57
-
58
- @queue = Internals::Queue.new(Guard)
59
-
60
- _evaluate(state.session.evaluator_options)
61
-
62
- # NOTE: this should be *after* evaluate so :directories can work
63
- # TODO: move listener setup to session?
64
- @listener = Listen.send(*state.session.listener_args, &_listener_callback)
65
-
66
- ignores = state.session.guardfile_ignore
67
- @listener.ignore(ignores) unless ignores.empty?
68
-
69
- ignores = state.session.guardfile_ignore_bang
70
- @listener.ignore!(ignores) unless ignores.empty?
71
-
72
- Notifier.connect(state.session.notify_options)
73
-
74
- traps = Internals::Traps
75
- traps.handle("USR1") { async_queue_add([:guard_pause, :paused]) }
76
- traps.handle("USR2") { async_queue_add([:guard_pause, :unpaused]) }
77
-
78
- @interactor = Interactor.new(state.session.interactor_name == :sleep)
79
- traps.handle("INT") { @interactor.handle_interrupt }
80
-
81
- self
82
- end
83
-
84
- def init(cmdline_options)
85
- @state = Internals::State.new(cmdline_options)
86
- end
87
-
88
- attr_reader :state
89
-
90
- attr_reader :interactor
91
-
92
- # Asynchronously trigger changes
93
- #
94
- # Currently supported args:
95
- #
96
- # @example Old style hash:
97
- # async_queue_add(modified: ['foo'], added: ['bar'], removed: [])
98
- #
99
- # @example New style signals with args:
100
- # async_queue_add([:guard_pause, :unpaused ])
101
- #
102
- def async_queue_add(changes)
103
- @queue << changes
104
-
105
- # Putting interactor in background puts guard into foreground
106
- # so it can handle change notifications
107
- Thread.new { interactor.background }
108
- end
109
-
110
- private
111
-
112
- # Check if any of the changes are actually watched for
113
- # TODO: why iterate twice? reuse this info when running tasks
114
- def _relevant_changes?(changes)
115
- # TODO: no coverage!
116
- files = changes.values.flatten(1)
117
- scope = Guard.state.scope
118
- watchers = scope.grouped_plugins.map do |_group, plugins|
119
- plugins.map(&:watchers).flatten
120
- end.flatten
121
- watchers.any? { |watcher| files.any? { |file| watcher.match(file) } }
122
- end
123
-
124
- def _relative_pathnames(paths)
125
- paths.map { |path| _relative_pathname(path) }
126
- end
127
-
128
- def _listener_callback
129
- lambda do |modified, added, removed|
130
- relative_paths = {
131
- modified: _relative_pathnames(modified),
132
- added: _relative_pathnames(added),
133
- removed: _relative_pathnames(removed)
134
- }
135
-
136
- async_queue_add(relative_paths) if _relevant_changes?(relative_paths)
137
- end
138
- end
139
-
140
- # TODO: obsoleted? (move to Dsl?)
141
- def _pluginless_guardfile?
142
- # no Reevaluator means there was no Guardfile configured that could be
143
- # reevaluated, so we don't have a pluginless guardfile, because we don't
144
- # have a Guardfile to begin with...
145
- #
146
- # But, if we have a Guardfile, we'll at least have the built-in
147
- # Reevaluator, so the following will work:
148
-
149
- plugins = state.session.plugins.all
150
- plugins.empty? || plugins.map(&:name) == ["reevaluator"]
151
- end
152
-
153
- def _evaluate(options)
154
- evaluator = Guardfile::Evaluator.new(options)
155
- evaluator.evaluate
156
-
157
- # TODO: remove this workaround when options are removed
158
- state.session.clearing(state.session.options[:clear])
159
-
160
- UI.reset_and_clear
161
-
162
- msg = "No plugins found in Guardfile, please add at least one."
163
- UI.error msg if _pluginless_guardfile?
164
-
165
- if evaluator.inline?
166
- UI.info("Using inline Guardfile.")
167
- elsif evaluator.custom?
168
- UI.info("Using Guardfile at #{ evaluator.path }.")
169
- end
170
- rescue Guardfile::Evaluator::NoPluginsError => e
171
- UI.error(e.message)
172
- end
173
- end
174
- end
File without changes
@@ -1,432 +0,0 @@
1
- require "guard/guardfile/evaluator"
2
- require "guard/interactor"
3
- require "guard/notifier"
4
- require "guard/ui"
5
- require "guard/watcher"
6
-
7
- require "guard/deprecated/dsl" unless Guard::Config.new.strict?
8
-
9
- # TODO: only for listener
10
- require "guard"
11
-
12
- module Guard
13
- # The Dsl class provides the methods that are used in each `Guardfile` to
14
- # describe the behaviour of Guard.
15
- #
16
- # The main keywords of the DSL are {#guard} and {#watch}. These are necessary
17
- # to define the used Guard plugins and the file changes they are watching.
18
- #
19
- # You can optionally group the Guard plugins with the {#group} keyword and
20
- # ignore and filter certain paths with the {#ignore} and {#filter} keywords.
21
- #
22
- # You can set your preferred system notification library with {#notification}
23
- # and pass some optional configuration options for the library. If you don't
24
- # configure a library, Guard will automatically pick one with default options
25
- # (if you don't want notifications, specify `:off` as library). Please see
26
- # {Notifier} for more information about the supported libraries.
27
- #
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#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
- # Guard plugins method.
34
- # You can even insert more hooks inside these methods. Please [checkout the
35
- # Wiki page](https://github.com/guard/guard/wiki/Hooks-and-callbacks) for
36
- # more details.
37
- #
38
- # The DSL will also evaluate normal Ruby code.
39
- #
40
- # There are two possible locations for the `Guardfile`:
41
- #
42
- # * The `Guardfile` in the current directory where Guard has been started
43
- # * The `.Guardfile` in your home directory.
44
- #
45
- # In addition, if a user configuration `.guard.rb` in your home directory is
46
- # found, it will be appended to the current project `Guardfile`.
47
- #
48
- # @see https://github.com/guard/guard/wiki/Guardfile-examples
49
- #
50
- class Dsl
51
- Deprecated::Dsl.add_deprecated(self) unless Config.new.strict?
52
-
53
- # Wrap exceptions during parsing Guardfile
54
- class Error < RuntimeError
55
- end
56
-
57
- WARN_INVALID_LOG_LEVEL = "Invalid log level `%s` ignored. "\
58
- "Please use either :debug, :info, :warn or :error."
59
-
60
- WARN_INVALID_LOG_OPTIONS = "You cannot specify the logger options"\
61
- " :only and :except at the same time."
62
-
63
- # Set notification options for the system notifications.
64
- # You can set multiple notifications, which allows you to show local
65
- # system notifications and remote notifications with separate libraries.
66
- # You can also pass `:off` as library to turn off notifications.
67
- #
68
- # @example Define multiple notifications
69
- # notification :ruby_gntp
70
- # notification :ruby_gntp, host: '192.168.1.5'
71
- #
72
- # @param [Symbol, String] notifier the name of the notifier to use
73
- # @param [Hash] options the notification library options
74
- #
75
- # @see Guard::Notifier for available notifier and its options.
76
- #
77
- def notification(notifier, options = {})
78
- Notifier.add(notifier.to_sym, options.merge(silent: false))
79
- end
80
-
81
- # Sets the interactor options or disable the interactor.
82
- #
83
- # @example Pass options to the interactor
84
- # interactor option1: 'value1', option2: 'value2'
85
- #
86
- # @example Turn off interactions
87
- # interactor :off
88
- #
89
- # @param [Symbol, Hash] options either `:off` or a Hash with interactor
90
- # options
91
- #
92
- def interactor(options)
93
- case options
94
- when :off
95
- Interactor.enabled = false
96
- when Hash
97
- Interactor.options = options
98
- end
99
- end
100
-
101
- # Declares a group of Guard plugins to be run with `guard start --group
102
- # group_name`.
103
- #
104
- # @example Declare two groups of Guard plugins
105
- # group :backend do
106
- # guard :spork
107
- # guard :rspec
108
- # end
109
- #
110
- # group :frontend do
111
- # guard :passenger
112
- # guard :livereload
113
- # end
114
- #
115
- # @param [Symbol, String, Array<Symbol, String>] name the group name called
116
- # from the CLI
117
- # @param [Hash] options the options accepted by the group
118
- # @yield a block where you can declare several Guard plugins
119
- #
120
- # @see Group
121
- # @see Guard.add_group
122
- # @see #guard
123
- #
124
- def group(*args)
125
- options = args.last.is_a?(Hash) ? args.pop : {}
126
- groups = args
127
-
128
- groups.each do |group|
129
- next unless group.to_sym == :all
130
- fail ArgumentError, "'all' is not an allowed group name!"
131
- end
132
-
133
- if block_given?
134
- groups.each do |group|
135
- Guard.state.session.groups.add(group, options)
136
- end
137
-
138
- @current_groups ||= []
139
- @current_groups.push(groups)
140
-
141
- yield
142
-
143
- @current_groups.pop
144
- else
145
- UI.error \
146
- "No Guard plugins found in the group '#{ groups.join(", ") }',"\
147
- " please add at least one."
148
- end
149
- end
150
-
151
- # Declares a Guard plugin to be used when running `guard start`.
152
- #
153
- # The name parameter is usually the name of the gem without
154
- # the 'guard-' prefix.
155
- #
156
- # The available options are different for each Guard implementation.
157
- #
158
- # @example Declare a Guard without `watch` patterns
159
- # guard :rspec
160
- #
161
- # @example Declare a Guard with a `watch` pattern
162
- # guard :rspec do
163
- # watch %r{.*_spec.rb}
164
- # end
165
- #
166
- # @param [String] name the Guard plugin name
167
- # @param [Hash] options the options accepted by the Guard plugin
168
- # @yield a block where you can declare several watch patterns and actions
169
- #
170
- # @see Plugin
171
- # @see Guard.add_plugin
172
- # @see #watch
173
- # @see #group
174
- #
175
- def guard(name, options = {})
176
- @plugin_options = options.merge(watchers: [], callbacks: [])
177
-
178
- yield if block_given?
179
-
180
- @current_groups ||= []
181
- groups = @current_groups && @current_groups.last || [:default]
182
- groups.each do |group|
183
- opts = @plugin_options.merge(group: group)
184
- Guard.state.session.plugins.add(name, opts)
185
- end
186
-
187
- @plugin_options = nil
188
- end
189
-
190
- # Defines a pattern to be watched in order to run actions on file
191
- # modification.
192
- #
193
- # @example Declare watchers for a Guard
194
- # guard :rspec do
195
- # watch('spec/spec_helper.rb')
196
- # watch(%r{^.+_spec.rb})
197
- # watch(%r{^app/controllers/(.+).rb}) do |m|
198
- # 'spec/acceptance/#{m[1]}s_spec.rb'
199
- # end
200
- # end
201
- #
202
- # @example Declare global watchers outside of a Guard
203
- # watch(%r{^(.+)$}) { |m| puts "#{m[1]} changed." }
204
- #
205
- # @param [String, Regexp] pattern the pattern that Guard must watch for
206
- # modification
207
- #
208
- # @yield a block to be run when the pattern is matched
209
- # @yieldparam [MatchData] m matches of the pattern
210
- # @yieldreturn a directory, a filename, an array of
211
- # directories / filenames, or nothing (can be an arbitrary command)
212
- #
213
- # @see Guard::Watcher
214
- # @see #guard
215
- #
216
- def watch(pattern, &action)
217
- # Allow watches in the global scope (to execute arbitrary commands) by
218
- # building a generic Guard::Plugin.
219
- @plugin_options ||= nil
220
- return guard(:plugin) { watch(pattern, &action) } unless @plugin_options
221
-
222
- @plugin_options[:watchers] << Watcher.new(pattern, action)
223
- end
224
-
225
- # Defines a callback to execute arbitrary code before or after any of
226
- # the `start`, `stop`, `reload`, `run_all`, `run_on_changes`,
227
- # `run_on_additions`, `run_on_modifications` and `run_on_removals` plugin
228
- # method.
229
- #
230
- # @example Add callback before the `reload` action.
231
- # callback(:reload_begin) { puts "Let's reload!" }
232
- #
233
- # @example Add callback before the `start` and `stop` actions.
234
- #
235
- # my_lambda = lambda do |plugin, event, *args|
236
- # puts "Let's #{event} #{plugin} with #{args}!"
237
- # end
238
- #
239
- # callback(my_lambda, [:start_begin, :start_end])
240
- #
241
- # @param [Array] args the callback arguments
242
- # @yield a callback block
243
- #
244
- def callback(*args, &block)
245
- @plugin_options ||= nil
246
- fail "callback must be called within a guard block" unless @plugin_options
247
-
248
- block, events = if args.size > 1
249
- # block must be the first argument in that case, the
250
- # yielded block is ignored
251
- args
252
- else
253
- [block, args[0]]
254
- end
255
- @plugin_options[:callbacks] << { events: events, listener: block }
256
- end
257
-
258
- # Ignores certain paths globally.
259
- #
260
- # @example Ignore some paths
261
- # ignore %r{^ignored/path/}, /man/
262
- #
263
- # @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
264
- #
265
- def ignore(*regexps)
266
- # TODO: instead, use Guard.reconfigure(ignore: regexps) or something
267
- Guard.listener.ignore(regexps) if Guard.listener
268
- end
269
-
270
- # TODO: deprecate
271
- alias filter ignore
272
-
273
- # Replaces ignored paths globally
274
- #
275
- # @example Ignore only these paths
276
- # ignore! %r{^ignored/path/}, /man/
277
- #
278
- # @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
279
- #
280
- def ignore!(*regexps)
281
- @ignore_regexps ||= []
282
- @ignore_regexps << regexps
283
- Guard.listener.ignore!(@ignore_regexps) if Guard.listener
284
- end
285
- alias filter! ignore!
286
-
287
- # Configures the Guard logger.
288
- #
289
- # * Log level must be either `:debug`, `:info`, `:warn` or `:error`.
290
- # * Template supports the following placeholders: `:time`, `:severity`,
291
- # `:progname`, `:pid`, `:unit_of_work_id` and `:message`.
292
- # * Time format directives are the same as `Time#strftime` or
293
- # `:milliseconds`.
294
- # * The `:only` and `:except` options must be a `RegExp`.
295
- #
296
- # @example Set the log level
297
- # logger level: :warn
298
- #
299
- # @example Set a custom log template
300
- # logger template: '[Guard - :severity - :progname - :time] :message'
301
- #
302
- # @example Set a custom time format
303
- # logger time_format: '%h'
304
- #
305
- # @example Limit logging to a Guard plugin
306
- # logger only: :jasmine
307
- #
308
- # @example Log all but not the messages from a specific Guard plugin
309
- # logger except: :jasmine
310
- #
311
- # @param [Hash] options the log options
312
- # @option options [String, Symbol] level the log level
313
- # @option options [String] template the logger template
314
- # @option options [String, Symbol] time_format the time format
315
- # @option options [Regexp] only show only messages from the matching Guard
316
- # plugin
317
- # @option options [Regexp] except does not show messages from the matching
318
- # Guard plugin
319
- #
320
- def logger(options)
321
- if options[:level]
322
- options[:level] = options[:level].to_sym
323
-
324
- unless [:debug, :info, :warn, :error].include? options[:level]
325
- UI.warning WARN_INVALID_LOG_LEVEL % [options[:level]]
326
- options.delete :level
327
- end
328
- end
329
-
330
- if options[:only] && options[:except]
331
- UI.warning WARN_INVALID_LOG_OPTIONS
332
-
333
- options.delete :only
334
- options.delete :except
335
- end
336
-
337
- # Convert the :only and :except options to a regular expression
338
- [:only, :except].each do |name|
339
- next unless options[name]
340
-
341
- list = [].push(options[name]).flatten.map do |plugin|
342
- Regexp.escape(plugin.to_s)
343
- end
344
-
345
- options[name] = Regexp.new(list.join("|"), Regexp::IGNORECASE)
346
- end
347
-
348
- UI.options.merge!(options)
349
- end
350
-
351
- # Sets the default scope on startup
352
- #
353
- # @example Scope Guard to a single group
354
- # scope group: :frontend
355
- #
356
- # @example Scope Guard to multiple groups
357
- # scope groups: [:specs, :docs]
358
- #
359
- # @example Scope Guard to a single plugin
360
- # scope plugin: :test
361
- #
362
- # @example Scope Guard to multiple plugins
363
- # scope plugins: [:jasmine, :rspec]
364
- #
365
- # @param [Hash] scopes the scope for the groups and plugins
366
- #
367
- def scope(scope = {})
368
- Guard.state.session.guardfile_scope(scope)
369
- end
370
-
371
- def evaluate(contents, filename, lineno) # :nodoc
372
- instance_eval(contents, filename.to_s, lineno)
373
- rescue StandardError, ScriptError => e
374
- prefix = "\n\t(dsl)> "
375
- cleaned_backtrace = _cleanup_backtrace(e.backtrace)
376
- backtrace = "#{prefix}#{cleaned_backtrace.join(prefix)}"
377
- msg = "Invalid Guardfile, original error is: \n\n%s, \nbacktrace: %s"
378
- raise Error, format(msg, e, backtrace)
379
- end
380
-
381
- # Sets the directories to pass to Listen
382
- #
383
- # @example watch only given directories
384
- # directories %w(lib specs)
385
- #
386
- # @param [Array] directories directories for Listen to watch
387
- #
388
- def directories(directories)
389
- directories.each do |dir|
390
- fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
391
- end
392
- Guard.state.session.watchdirs = directories
393
- end
394
-
395
- # Sets Guard to clear the screen before every task is run
396
- #
397
- # @example switching clearing the screen on
398
- # clearing(:on)
399
- #
400
- # @param [Symbol] on ':on' to turn on, ':off' (default) to turn off
401
- #
402
- def clearing(on)
403
- Guard.state.session.clearing(on == :on)
404
- end
405
-
406
- private
407
-
408
- def _cleanup_backtrace(backtrace)
409
- dirs = { File.realpath(Dir.pwd) => ".", }
410
-
411
- gem_env = ENV["GEM_HOME"] || ""
412
- dirs[gem_env] = "$GEM_HOME" unless gem_env.empty?
413
-
414
- gem_paths = (ENV["GEM_PATH"] || "").split(File::PATH_SEPARATOR)
415
- gem_paths.each_with_index do |path, index|
416
- dirs[path] = "$GEM_PATH[#{index}]"
417
- end
418
-
419
- backtrace.dup.map do |raw_line|
420
- path = nil
421
- symlinked_path = raw_line.split(":").first
422
- begin
423
- path = raw_line.sub(symlinked_path, File.realpath(symlinked_path))
424
- dirs.detect { |dir, name| path.sub!(File.realpath(dir), name) }
425
- path
426
- rescue Errno::ENOENT
427
- path || symlinked_path
428
- end
429
- end
430
- end
431
- end
432
- end