Class: Guard::Watcher

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

Overview

The watcher defines a RegExp that will be matched against file system modifications. When a watcher matches a change, an optional action block is executed to enable processing the file system change result.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pattern, action = nil) ⇒ Watcher

Initializes a file watcher.

Parameters:

  • pattern (String, Regexp)

    the pattern to be watched by the Guard plugin

  • action (Block) (defaults to: nil)

    the action to execute before passing the result to the Guard plugin



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/guard/watcher.rb', line 21

def initialize(pattern, action = nil)
  @pattern, @action = pattern, action
  @@warning_printed ||= false

  # deprecation warning
  if @pattern.is_a?(String) && @pattern =~ /(^(\^))|(>?(\\\.)|(\.\*))|(\(.*\))|(\[.*\])|(\$$)/
    unless @@warning_printed
      ::Guard::UI.info "*"*20 + "\nDEPRECATION WARNING!\n" + "*"*20
      ::Guard::UI.info <<-MSG
        You have a string in your Guardfile watch patterns that seem to represent a Regexp.
        Guard matches String with == and Regexp with Regexp#match.
        You should either use plain String (without Regexp special characters) or real Regexp.
      MSG
      @@warning_printed = true
    end

    ::Guard::UI.info "\"#{@pattern}\" has been converted to #{ Regexp.new(@pattern).inspect }\n"
    @pattern = Regexp.new(@pattern)
  end
end

Instance Attribute Details

#actionObject

Returns the value of attribute action



12
13
14
# File 'lib/guard/watcher.rb', line 12

def action
  @action
end

#patternObject

Returns the value of attribute pattern



12
13
14
# File 'lib/guard/watcher.rb', line 12

def pattern
  @pattern
end

Class Method Details

.match_files(guard, files) ⇒ Array<Object>

Finds the files that matches a Guard plugin.

Parameters:

  • guard (Guard::Plugin)

    the Guard plugin which watchers are used

  • files (Array<String>)

    the changed files

Returns:

  • (Array<Object>)

    the matched watcher response



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/guard/watcher.rb', line 48

def self.match_files(guard, files)
  return [] if files.empty?

  guard.watchers.inject([]) do |paths, watcher|
    files.each do |file|
      if matches = watcher.match(file)
        if watcher.action
          result = watcher.call_action(matches)
          if guard.options[:any_return]
            paths << result
          elsif result.respond_to?(:empty?) && !result.empty?
            paths << Array(result)
          end
        else
          paths << matches[0]
        end
      end
    end

    guard.options[:any_return] ? paths : paths.flatten.map { |p| p.to_s }
  end
end

.match_files?(plugins, files) ⇒ Boolean

Tests if a file would be matched by any of the Guard plugin watchers.

Parameters:

  • plugins (Array<Guard::Plugin>)

    the Guard plugins to use the watchers from

  • files (Array<String>)

    the files to test

Returns:

  • (Boolean)

    Whether a file matches



78
79
80
81
82
83
84
# File 'lib/guard/watcher.rb', line 78

def self.match_files?(plugins, files)
  plugins.any? do |plugin|
    plugin.watchers.any? do |watcher|
      files.any? { |file| watcher.match(file) }
    end
  end
end

.match_guardfile?(files) ⇒ Boolean

Tests if any of the files is the Guardfile.

Parameters:

  • files (Array<String>)

    the files to test

Returns:

  • (Boolean)

    whether one of these files is the Guardfile



91
92
93
# File 'lib/guard/watcher.rb', line 91

def self.match_guardfile?(files)
  files.any? { |file| File.expand_path(file) == ::Guard.evaluator.guardfile_path }
end

Instance Method Details

#call_action(matches) ⇒ String

Executes a watcher action.

Parameters:

  • matches (String, MatchData)

    the matched path or the match from the Regex

Returns:

  • (String)

    the final paths



122
123
124
125
126
127
128
129
# File 'lib/guard/watcher.rb', line 122

def call_action(matches)
  begin
    @action.arity > 0 ? @action.call(matches) : @action.call
  rescue Exception => ex
    ::Guard::UI.error "Problem with watch action!\n#{ ex.message }"
    ::Guard::UI.error ex.backtrace.join("\n")
  end
end

#match(file) ⇒ Array<String>

Test the watchers pattern against a file.

Parameters:

  • file (String)

    the file to test

Returns:

  • (Array<String>)

    an array of matches (or containing a single path if the pattern is a string)



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/guard/watcher.rb', line 101

def match(file)
  f = file
  deleted = file.start_with?('!')
  f = deleted ? f[1..-1] : f
  if @pattern.is_a?(Regexp)
    if m = f.match(@pattern)
      m = m.to_a
      m[0] = file
      m
    end
  else
    f == @pattern ? [file] : nil
  end
end