module Guard
def add_group(name, options = {})
-
(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 = {})
-
(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)
-
(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)
-
(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)
-
(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)
-
(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
-
(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)
-
(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)
-
(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)
-
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)
-
(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)
-
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
- See: Guard.groups -
def reset_groups @groups = [Group.new(:default)] end
def run
- 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)
-
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)
-
(: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 = {})
- 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)
-
(: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)
-
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)
-
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