Class: Guard::Dsl

Inherits:
Object
  • Object
show all
Defined in:
lib/guard/dsl.rb

Overview

The Dsl class provides the methods that are used in each `Guardfile` to describe the behaviour of Guard.

The main keywords of the DSL are #guard and #watch. These are necessary to define the used Guard plugins and the file changes they are watching.

You can optionally group the Guard plugins with the #group keyword and ignore and filter certain paths with the #ignore and #filter keywords.

You can set your preferred system notification library with #notification and pass some optional configuration options for the library. If you don't configure a library, Guard will automatically pick one with default options (if you don't want notifications, specify `:off` as library). Please see Notifier for more information about the supported libraries.

A more advanced DSL use is the #callback keyword that allows you to execute arbitrary code before or after any of the Plugin::Base#start, Plugin::Base#stop, Plugin::Base#reload, Plugin::Base#run_all, Plugin::Base#run_on_changes, Plugin::Base#run_on_additions, Plugin::Base#run_on_modifications and Plugin::Base#run_on_removals Guard plugins method. You can even insert more hooks inside these methods. Please [checkout the Wiki page](github.com/guard/guard/wiki/Hooks-and-callbacks) for more details.

The DSL will also evaluate normal Ruby code.

There are two possible locations for the `Guardfile`:

  • The `Guardfile` in the current directory where Guard has been started

  • The `.Guardfile` in your home directory.

In addition, if a user configuration `.guard.rb` in your home directory is found, it will be appended to the current project `Guardfile`.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.evaluate_guardfile(options = {}) ⇒ Object

Deprecated.

Use `Guard::Guardfile::Evaluator.new(options).evaluate_guardfile` instead.



54
55
56
57
# File 'lib/guard/dsl.rb', line 54

def self.evaluate_guardfile(options = {})
  ::Guard::UI.deprecation(::Guard::Deprecator::EVALUATE_GUARDFILE_DEPRECATION)
  ::Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
end

Instance Method Details

#callback(*args) { ... } ⇒ Object

Defines a callback to execute arbitrary code before or after any of the `start`, `stop`, `reload`, `run_all`, `run_on_changes`, `run_on_additions`, `run_on_modifications` and `run_on_removals` plugin method.

Examples:

Define a callback that'll be called before the `reload` action.

callback(:reload_begin) { puts "Let's reload!" }

Define a callback that'll be called before the `start` and `stop` actions.

my_lambda = lambda { |plugin, event, *args| puts "Let's #{event} #{plugin} with #{args}!" }
callback(my_lambda, [:start_begin, :start_end])

Parameters:

  • args (Array)

    the callback arguments

Yields:

  • a callback block

See Also:

  • Hooker


225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/guard/dsl.rb', line 225

def callback(*args, &block)
  fail "callback must be called within a guard block" unless @plugin_options

  block, events = if args.size > 1
    # block must be the first argument in that case, the yielded block is
    # ignored
    args
  else
    [block, args[0]]
  end
  @plugin_options[:callbacks] << { events: events, listener: block }
end

#group(*args) { ... } ⇒ Object

Declares a group of Guard plugins to be run with `guard start –group

group_name`.

Examples:

Declare two groups of Guard plugins

group :backend do
  guard :spork
  guard :rspec
end

group :frontend do
  guard :passenger
  guard :livereload
end

Parameters:

  • name (Symbol, String, Array<Symbol, String>)

    the group name called from the CLI

  • options (Hash)

    the options accepted by the group

Yields:

  • a block where you can declare several Guard plugins

See Also:



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/guard/dsl.rb', line 119

def group(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  groups = args

  groups.each do |group|
    raise ArgumentError, "'all' is not an allowed group name!" if group.to_sym == :all
  end

  if block_given?
    groups.each do |group|
      ::Guard.add_group(group, options)
    end

    @current_groups ||= []
    @current_groups.push(groups)

    yield

    @current_groups.pop
  else
    ::Guard::UI.error "No Guard plugins found in the group '#{ groups.join(', ') }', please add at least one."
  end
end

#guard(name, options = {}) { ... } ⇒ Object

Declares a Guard plugin to be used when running `guard start`.

The name parameter is usually the name of the gem without the 'guard-' prefix.

The available options are different for each Guard implementation.

Examples:

Declare a Guard without `watch` patterns

guard :rspec

Declare a Guard with a `watch` pattern

guard :rspec do
  watch %r{.*_spec.rb}
end

Parameters:

  • name (String)

    the Guard plugin name

  • options (Hash) (defaults to: {})

    the options accepted by the Guard plugin

Yields:

  • a block where you can declare several watch patterns and actions

See Also:



167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/guard/dsl.rb', line 167

def guard(name, options = {})
  @plugin_options = options.merge(watchers: [], callbacks: [])

  yield if block_given?

  groups = @current_groups && @current_groups.last || [:default]
  groups.each do |group|
    ::Guard.add_plugin(name, @plugin_options.merge(group: group))
  end

  @plugin_options = nil
end

#ignore(*regexps) ⇒ Object Also known as: filter

Ignores certain paths globally.

Examples:

Ignore some paths

ignore %r{^ignored/path/}, /man/

Parameters:

  • regexps (Regexp)

    a pattern (or list of patterns) for ignoring paths



245
246
247
# File 'lib/guard/dsl.rb', line 245

def ignore(*regexps)
  ::Guard.listener.ignore(regexps) if ::Guard.listener
end

#ignore!(*regexps) ⇒ Object Also known as: filter!

Replaces ignored paths globally

Examples:

Ignore only these paths

ignore! %r{^ignored/path/}, /man/

Parameters:

  • regexps (Regexp)

    a pattern (or list of patterns) for ignoring paths



257
258
259
260
261
# File 'lib/guard/dsl.rb', line 257

def ignore!(*regexps)
  @ignore_regexps ||= []
  @ignore_regexps << regexps
  ::Guard.listener.ignore!(@ignore_regexps) if ::Guard.listener
end

#interactor(options) ⇒ Object

Sets the interactor options or disable the interactor.

Examples:

Pass options to the interactor

interactor option1: 'value1', option2: 'value2'

Turn off interactions

interactor :off

Parameters:

  • options (Symbol, Hash)

    either `:off` or a Hash with interactor options



88
89
90
91
92
93
94
95
# File 'lib/guard/dsl.rb', line 88

def interactor(options)
  case options
  when :off
    ::Guard::Interactor.enabled = false
  when Hash
    ::Guard::Interactor.options = options
  end
end

#logger(options) ⇒ Object

Configures the Guard logger.

  • Log level must be either `:debug`, `:info`, `:warn` or `:error`.

  • Template supports the following placeholders: `:time`, `:severity`, `:progname`, `:pid`, `:unit_of_work_id` and `:message`.

  • Time format directives are the same as `Time#strftime` or `:milliseconds`.

  • The `:only` and `:except` options must be a `RegExp`.

Examples:

Set the log level

logger level: :warn

Set a custom log template

logger template: '[Guard - :severity - :progname - :time] :message'

Set a custom time format

logger time_format: '%h'

Limit logging to a Guard plugin

logger only: :jasmine

Log all but not the messages from a specific Guard plugin

logger except: :jasmine

Parameters:

  • options (Hash)

    the log options

Options Hash (options):

  • level (String, Symbol)

    the log level

  • template (String)

    the logger template

  • time_format (String, Symbol)

    the time format

  • only (Regexp)

    show only messages from the matching Guard plugin

  • except (Regexp)

    does not show messages from the matching Guard plugin



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/guard/dsl.rb', line 297

def logger(options)
  if options[:level]
    options[:level] = options[:level].to_sym

    unless [:debug, :info, :warn, :error].include? options[:level]
      ::Guard::UI.warning "Invalid log level `#{ options[:level] }` ignored. Please use either :debug, :info, :warn or :error."
      options.delete :level
    end
  end

  if options[:only] && options[:except]
    ::Guard::UI.warning 'You cannot specify the logger options :only and :except at the same time.'

    options.delete :only
    options.delete :except
  end

  # Convert the :only and :except options to a regular expression
  [:only, :except].each do |name|
    if options[name]
      list = [].push(options[name]).flatten.map { |plugin| Regexp.escape(plugin.to_s) }.join('|')
      options[name] = Regexp.new(list, Regexp::IGNORECASE)
    end
  end

  ::Guard::UI.options.merge!(options)
end

#notification(notifier, options = {}) ⇒ Object

Set notification options for the system notifications. You can set multiple notifications, which allows you to show local system notifications and remote notifications with separate libraries. You can also pass `:off` as library to turn off notifications.

Examples:

Define multiple notifications

notification :growl_notify
notification :ruby_gntp, host: '192.168.1.5'

Parameters:

  • notifier (Symbol, String)

    the name of the notifier to use

  • options (Hash) (defaults to: {})

    the notification library options

See Also:



73
74
75
# File 'lib/guard/dsl.rb', line 73

def notification(notifier, options = {})
  ::Guard::Notifier.add_notifier(notifier.to_sym, options.merge(silent: false))
end

#scope(scope = {}) ⇒ Object

Sets the default scope on startup

Examples:

Scope Guard to a single group

scope group: :frontend

Scope Guard to multiple groups

scope groups: [:specs, :docs]

Scope Guard to a single plugin

scope plugin: :test

Scope Guard to multiple plugins

scope plugins: [:jasmine, :rspec]

Parameters:

  • scopes (Hash)

    the scope for the groups and plugins



341
342
343
344
345
# File 'lib/guard/dsl.rb', line 341

def scope(scope = {})
  scope[:plugins] = Array(scope[:plugins] || scope[:plugin] || [])
  scope[:groups] = Array(scope[:groups] || scope[:group] || [])
  ::Guard.setup_scope(scope)
end

#watch(pattern) {|m| ... } ⇒ Object

Defines a pattern to be watched in order to run actions on file modification.

Examples:

Declare watchers for a Guard

guard :rspec do
  watch('spec/spec_helper.rb')
  watch(%r{^.+_spec.rb})
  watch(%r{^app/controllers/(.+).rb}) { |m| 'spec/acceptance/#{m[1]}s_spec.rb' }
end

Declare global watchers outside of a Guard

watch(%r{^(.+)$}) { |m| puts "#{m[1]} changed." }

Parameters:

  • pattern (String, Regexp)

    the pattern that Guard must watch for modification

Yields:

  • a block to be run when the pattern is matched

Yield Parameters:

  • m (MatchData)

    matches of the pattern

Yield Returns:

  • a directory, a filename, an array of directories / filenames, or nothing (can be an arbitrary command)

See Also:



200
201
202
203
204
205
206
# File 'lib/guard/dsl.rb', line 200

def watch(pattern, &action)
  # Allow watches in the global scope (to execute arbitrary commands) by
  # building a generic Guard::Plugin.
  return guard(:plugin) { watch(pattern, &action) } unless @plugin_options

  @plugin_options[:watchers] << ::Guard::Watcher.new(pattern, action)
end