module Guard

def add_group(name, options = {})

Returns:
  • (Guard::Group) - the group added (or retrieved from the `@groups` variable if already present)

Options Hash: (**options)
  • halt_on_fail (Boolean) -- if a task execution

Parameters:
  • name (String) -- the group name
def add_group(name, options = {})
  group = groups(name)
  if group.nil?
    group = Group.new(name, options)
    @groups << group
  end
  group
end

def add_guard(name, watchers = [], callbacks = [], options = {})

Returns:
  • (Guard::Guard) - the guard added

Parameters:
  • options (Hash) -- the Guard options (see the given Guard documentation)
  • callbacks (Array) -- the list of callbacks
  • watchers (Array) -- the list of declared watchers
  • name (String) -- the Guard name
def add_guard(name, watchers = [], callbacks = [], options = {})
  if name.to_sym == :ego
    UI.deprecation('Guard::Ego is now part of Guard. You can remove it from your Guardfile.')
  else
    guard_class = get_guard_class(name)
    callbacks.each { |callback| Hook.add_callback(callback[:listener], guard_class, callback[:events]) }
    guard = guard_class.new(watchers, options)
    @guards << guard
    guard
  end
end

def changed_paths(paths)

Returns:
  • (Array) - the changed paths

Parameters:
  • paths (Array) -- the watched paths

Other tags:
    See: Guard::Listener#modified_files -
def changed_paths(paths)
  paths.select { |f| !f.respond_to?(:start_with?) || !f.start_with?('!') }
end

def debug_command_execution


execution functions and logs the executed command before execution.
Adds a command logger in debug mode. This wraps common command
def debug_command_execution
  Kernel.send(:alias_method, :original_system, :system)
  Kernel.send(:define_method, :system) do |command, *args|
    ::Guard::UI.debug "Command execution: #{ command } #{ args.join(' ') }"
    original_system command, *args
  end
  Kernel.send(:alias_method, :original_backtick, :'`')
  Kernel.send(:define_method, :'`') do |command|
    ::Guard::UI.debug "Command execution: #{ command }"
    original_backtick command
  end
end

def deleted_paths(paths)

Returns:
  • (Array) - the deleted paths

Parameters:
  • paths (Array) -- the watched paths

Other tags:
    See: Guard::Listener#modified_files -
def deleted_paths(paths)
  paths.select { |f| f.respond_to?(:start_with?) && f.start_with?('!') }.map { |f| f.slice(1..-1) }
end

def get_guard_class(name, fail_gracefully=false)

Returns:
  • (Class, nil) - the loaded class

Parameters:
  • fail_gracefully (Boolean) -- whether error messages should not be printed
  • name (String) -- the name of the Guard
def get_guard_class(name, fail_gracefully=false)
  name        = name.to_s
  try_require = false
  const_name  = name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.gsub(/(?:^|[_-])(.)/) { $1.upcase }
  begin
    require "guard/#{ name.downcase }" if try_require
    self.const_get(self.constants.find { |c| c.to_s == const_name } || self.constants.find { |c| c.to_s.downcase == const_name.downcase })
  rescue TypeError
    unless try_require
      try_require = true
      retry
    else
      UI.error "Could not find class Guard::#{ const_name.capitalize }"
    end
  rescue LoadError => loadError
    unless fail_gracefully
      UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
      UI.error loadError.to_s
    end
  end
end

def groups(filter = nil)

Returns:
  • (Array) - the filtered groups

Parameters:
  • filter (String, Symbol, Regexp) -- the filter to apply to the Groups

Other tags:
    Example: Filter groups by Regexp -
    Example: Filter groups by String or Symbol -

Other tags:
    See: Guard.guards -
def groups(filter = nil)
  case filter
  when String, Symbol
    @groups.find { |group| group.name == filter.to_sym }
  when Regexp
    @groups.find_all { |group| group.name.to_s =~ filter }
  else
    @groups
  end
end

def guard_gem_names

Returns:
  • (Array) - a list of guard gem names
def guard_gem_names
  if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
    Gem::Specification.find_all.select { |x| x.name =~ /^guard-/ }
  else
    Gem.source_index.find_name(/^guard-/)
  end.map { |x| x.name.sub(/^guard-/, '') }
end

def guard_symbol(guard)

Returns:
  • (Symbol) - the symbol to catch

Parameters:
  • guard (Guard::Guard) -- the Guard to execute

Other tags:
    See: .run_on_guards -
def guard_symbol(guard)
  if guard.group.class == Symbol
    group = groups(guard.group)
    group.options[:halt_on_fail] ? :no_catch : :task_has_failed
  else
    :task_has_failed
  end
end

def guards(filter = nil)

Returns:
  • (Array) - the filtered Guards

Parameters:
  • filter (String, Symbol, Regexp, Hash) -- the filter to apply to the Guards

Other tags:
    Example: Filter Guards by Hash -
    Example: Filter Guards by Regexp -
    Example: Filter Guards by String or Symbol -

Other tags:
    See: Guard.groups -
def guards(filter = nil)
  @guards ||= []
  case filter
  when String, Symbol
    @guards.find { |guard| guard.class.to_s.downcase.sub('guard::', '') == filter.to_s.downcase.gsub('-', '') }
  when Regexp
    @guards.find_all { |guard| guard.class.to_s.downcase.sub('guard::', '') =~ filter }
  when Hash
    filter.inject(@guards) do |matches, (k, v)|
      if k.to_sym == :name
        matches.find_all { |guard| guard.class.to_s.downcase.sub('guard::', '') == v.to_s.downcase.gsub('-', '') }
      else
        matches.find_all { |guard| guard.send(k).to_sym == v.to_sym }
      end
    end
  else
    @guards
  end
end

def initialize_template(guard_name = nil)

Parameters:
  • guard_name (String) -- the name of the Guard or template to initialize

Other tags:
    See: Guard::Guard.init -
def initialize_template(guard_name = nil)
  if !File.exist?('Guardfile')
    ::Guard::UI.info "Writing new Guardfile to #{ Dir.pwd }/Guardfile"
    FileUtils.cp(GUARDFILE_TEMPLATE, 'Guardfile')
  elsif guard_name.nil?
    ::Guard::UI.error "Guardfile already exists at #{ Dir.pwd }/Guardfile"
    exit 1
  end
  if guard_name
    guard_class = ::Guard.get_guard_class(guard_name, true)
    if guard_class
      guard_class.init(guard_name)
    elsif File.exist?(File.join(HOME_TEMPLATES, guard_name))
      content  = File.read('Guardfile')
      template = File.read(File.join(HOME_TEMPLATES, guard_name))
      File.open('Guardfile', 'wb') do |f|
        f.puts(content)
        f.puts("")
        f.puts(template)
      end
      ::Guard::UI.info "#{ guard_name } template added to Guardfile, feel free to edit it"
    else
      const_name  = guard_name.downcase.gsub('-', '')
      UI.error "Could not load 'guard/#{ guard_name.downcase }' or '~/.guard/templates/#{ guard_name.downcase }' or find class Guard::#{ const_name.capitalize }"
    end
  end
end

def locate_guard(name)

Returns:
  • (String) - the full path to the Guard gem

Parameters:
  • name (String) -- the name of the Guard without the prefix `guard-`
def locate_guard(name)
  if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
    Gem::Specification.find_by_name("guard-#{ name }").full_gem_path
  else
    Gem.source_index.find_name("guard-#{ name }").last.full_gem_path
  end
rescue
  UI.error "Could not find 'guard-#{ name }' gem path."
end

def pause


Pause Guard listening to file changes.
def pause
  if listener.paused?
    UI.info 'Un-paused files modification listening', :reset => true
    listener.clear_changed_files
    listener.run
  else
    UI.info 'Paused files modification listening', :reset => true
    listener.pause
  end
end

def reload(scopes)

Parameters:
  • scopes (Hash) -- an hash with a guard or a group scope
def reload(scopes)
  run do
    run_on_guards(scopes) do |guard|
      run_supervised_task(guard, :reload)
    end
  end
end

def reset_groups

Other tags:
    See: Guard.groups -
def reset_groups
  @groups = [Group.new(:default)]
end

def run

Other tags:
    Yield: - the block to run
def run
  UI.clear if options[:clear]
  lock.synchronize do
    begin
      interactor.stop if interactor
      yield
    rescue Interrupt
    end
    interactor.start if interactor
  end
end

def run_all(scopes)

Parameters:
  • scopes (Hash) -- an hash with a guard or a group scope
def run_all(scopes)
  run do
    run_on_guards(scopes) do |guard|
      run_supervised_task(guard, :run_all)
    end
  end
end

def run_on_change(files)


Trigger `run_on_change` on all Guards currently enabled.
def run_on_change(files)
  run do
    run_on_guards do |guard|
      run_on_change_task(files, guard)
    end
  end
end

def run_on_change_task(files, guard)

Raises:
  • (:task_has_failed) - when task has failed

Parameters:
  • guard (Guard::Guard) -- the guard to run
  • files (Array) -- the list of files to pass to the task
def run_on_change_task(files, guard)
  paths = Watcher.match_files(guard, files)
  changes = changed_paths(paths)
  deletions = deleted_paths(paths)
  unless changes.empty?
    UI.debug "#{ guard.class.name }#run_on_change with #{ changes.inspect }"
    run_supervised_task(guard, :run_on_change, changes)
  end
  unless deletions.empty?
    UI.debug "#{ guard.class.name }#run_on_deletion with #{ deletions.inspect }"
    run_supervised_task(guard, :run_on_deletion, deletions)
  end
end

def run_on_guards(scopes = {})

Other tags:
    Yield: - the task to run

Parameters:
  • scopes (Hash) -- an hash with a guard or a group scope
def run_on_guards(scopes = {})
  if scope_guard = scopes[:guard]
    yield(scope_guard)
  else
    groups = scopes[:group] ? [scopes[:group]] : @groups
    groups.each do |group|
      catch :task_has_failed do
        guards(:group => group.name).each do |guard|
          yield(guard)
        end
      end
    end
  end
end

def run_supervised_task(guard, task, *args)

Raises:
  • (:task_has_failed) - when task has failed

Parameters:
  • args (Array) -- the arguments for the task
  • task (Symbol) -- the task to run
  • guard (Guard::Guard) -- the Guard to execute
def run_supervised_task(guard, task, *args)
  catch guard_symbol(guard) do
    guard.hook("#{ task }_begin", *args)
    result = guard.send(task, *args)
    guard.hook("#{ task }_end", result)
    result
  end
rescue Exception => ex
  UI.error("#{ guard.class.name } failed to achieve its <#{ task.to_s }>, exception was:" +
           "\n#{ ex.class }: #{ ex.message }\n#{ ex.backtrace.join("\n") }")
  guards.delete guard
  UI.info("\n#{ guard.class.name } has just been fired")
  ex
end

def setup(options = {})

Options Hash: (**options)
  • watch_all_modifications (Boolean) -- watches all file modifications if true
  • guardfile (String) -- the path to the Guardfile
  • watchdir (String) -- the director to watch
  • group (Array) -- the list of groups to start
  • verbose (Boolean) -- if verbose output should be shown
  • notify (Boolean) -- if system notifications should be shown
  • clear (Boolean) -- if auto clear the UI should be done
def setup(options = {})
  @lock       = Mutex.new
  @options    = options
  @guards     = []
  self.reset_groups
  @listener   = Listener.select_and_init(options)
  UI.clear if @options[:clear]
  debug_command_execution if @options[:verbose]
  self
end

def start(options = {})

Options Hash: (**options)
  • guardfile (String) -- the path to the Guardfile
  • watchdir (String) -- the director to watch
  • group (Array) -- the list of groups to start
  • debug (Boolean) -- if debug output should be shown
  • notify (Boolean) -- if system notifications should be shown
  • clear (Boolean) -- if auto clear the UI should be done
def start(options = {})
  setup(options)
  Dsl.evaluate_guardfile(options)
  UI.error 'No guards found in Guardfile, please add at least one.' if ::Guard.guards.empty?
  options[:notify] && ENV['GUARD_NOTIFY'] != 'false' ? Notifier.turn_on : Notifier.turn_off
  listener.on_change do |files|
    Dsl.reevaluate_guardfile        if Watcher.match_guardfile?(files)
    listener.changed_files += files if Watcher.match_files?(guards, files)
  end
  UI.info "Guard is now watching at '#{ listener.directory }'"
  run_on_guards do |guard|
    run_supervised_task(guard, :start)
  end
  unless options[:no_interactions]
    @interactor = Interactor.fabricate
    @interactor.start if @interactor
  end
  listener.start
end

def stop


Stop Guard listening to file changes
def stop
  UI.info 'Bye bye...', :reset => true
  run_on_guards do |guard|
    run_supervised_task(guard, :stop)
  end
  interactor.stop if interactor
  listener.stop
end