Class: Listen::Listener

Inherits:
Object
  • Object
show all
Defined in:
lib/listen/listener.rb

Constant Summary collapse

RELATIVE_PATHS_WITH_MULTIPLE_DIRECTORIES_WARNING_MESSAGE =
"The relative_paths option doesn't work when listening to multiple diretories."

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) {|modified, added, removed| ... } ⇒ Listener

Initializes the directories listener.

Parameters:

  • directory (String)

    the directories to listen to

  • options (Hash)

    the listen options (see Listen::Listener::Options)

Yields:

  • (modified, added, removed)

    the changed files

Yield Parameters:

  • modified (Array<String>)

    the list of modified files

  • added (Array<String>)

    the list of added files

  • removed (Array<String>)

    the list of removed files



23
24
25
26
27
28
29
# File 'lib/listen/listener.rb', line 23

def initialize(*args, &block)
  @options     = _init_options(args.last.is_a?(Hash) ? args.pop : {})
  @directories = args.flatten.map { |path| Pathname.new(path).realpath }
  @changes     = []
  @block       = block
  _init_debug
end

Instance Attribute Details

#blockObject

Returns the value of attribute block.



9
10
11
# File 'lib/listen/listener.rb', line 9

def block
  @block
end

#changesObject

Returns the value of attribute changes.



9
10
11
# File 'lib/listen/listener.rb', line 9

def changes
  @changes
end

#directoriesObject

Returns the value of attribute directories.



9
10
11
# File 'lib/listen/listener.rb', line 9

def directories
  @directories
end

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/listen/listener.rb', line 9

def options
  @options
end

#pausedObject

Returns the value of attribute paused.



9
10
11
# File 'lib/listen/listener.rb', line 9

def paused
  @paused
end

#threadObject

Returns the value of attribute thread.



9
10
11
# File 'lib/listen/listener.rb', line 9

def thread
  @thread
end

Instance Method Details

#_init_actorsObject (private)



118
119
120
121
122
123
# File 'lib/listen/listener.rb', line 118

def _init_actors
  Celluloid::Actor[:listen_silencer]    = Silencer.new(options)
  Celluloid::Actor[:listen_change_pool] = Change.pool(args: self)
  Celluloid::Actor[:listen_adapter]     = Adapter.new(self)
  Celluloid::Actor[:listen_record]      = Record.new(self)
end

#_init_debugObject (private)



110
111
112
113
114
115
116
# File 'lib/listen/listener.rb', line 110

def _init_debug
  if options[:debug]
    Celluloid.logger.level = Logger::INFO
  else
    Celluloid.logger = nil
  end
end

#_init_options(options = {}) ⇒ Object (private)



103
104
105
106
107
108
# File 'lib/listen/listener.rb', line 103

def _init_options(options = {})
  { debug: false,
    latency: nil,
    force_polling: false,
    polling_fallback_message: nil }.merge(options)
end

#_pop_changesObject (private)



144
145
146
147
148
149
150
151
# File 'lib/listen/listener.rb', line 144

def _pop_changes
  changes = { modified: [], added: [], removed: [] }
  until @changes.empty?
    change = @changes.pop
    change.each { |k, v| changes[k] << v.to_s }
  end
  changes.each { |_, v| v.uniq! }
end

#_signals_trapObject (private)



125
126
127
128
129
# File 'lib/listen/listener.rb', line 125

def _signals_trap
  if Signal.list.keys.include?('INT')
    Signal.trap('INT') { exit }
  end
end

#_wait_for_changesObject (private)



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/listen/listener.rb', line 131

def _wait_for_changes
  loop do
    changes = _pop_changes
    unless changes.all? { |_,v| v.empty? }
      block.call(changes[:modified], changes[:added], changes[:removed])
    end
    sleep 0.1
  end
rescue => ex
  Kernel.warn "[Listen warning]: Change block raise an execption: #{$!}"
  Kernel.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
end

#ignore(regexps) ⇒ Object

Adds ignore patterns to the existing one (See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer)

Parameters:

  • new (Regexp, Hash<Regexp>)

    ignoring patterns.



86
87
88
89
# File 'lib/listen/listener.rb', line 86

def ignore(regexps)
  options[:ignore] = [options[:ignore], regexps]
  Celluloid::Actor[:listen_silencer] = Silencer.new(options)
end

#ignore!(regexps) ⇒ Object

Overwrites ignore patterns (See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer)

Parameters:

  • new (Regexp, Hash<Regexp>)

    ignoring patterns.



95
96
97
98
99
# File 'lib/listen/listener.rb', line 95

def ignore!(regexps)
  options.delete(:ignore)
  options[:ignore!] = regexps
  Celluloid::Actor[:listen_silencer] = Silencer.new(options)
end

#listen?Boolean

Returns true if Listener is not paused

Returns:

  • (Boolean)


78
79
80
# File 'lib/listen/listener.rb', line 78

def listen?
  @paused == false
end

#pauseObject

Pauses listening callback (adapter still running)



55
56
57
# File 'lib/listen/listener.rb', line 55

def pause
  @paused = true
end

#paused?Boolean

Returns true if Listener is paused

Returns:

  • (Boolean)


70
71
72
# File 'lib/listen/listener.rb', line 70

def paused?
  @paused == true
end

#startObject

Starts the listener by initializing the adapter and building the directory record concurrently, then it starts the adapter to watch for changes. The current thread is not blocked after starting.



35
36
37
38
39
40
41
# File 'lib/listen/listener.rb', line 35

def start
  _signals_trap
  _init_actors
  unpause
  Celluloid::Actor[:listen_adapter].async.start
  @thread = Thread.new { _wait_for_changes }
end

#stopObject

Terminates all Listen actors and kill the adapter.



45
46
47
48
49
50
51
# File 'lib/listen/listener.rb', line 45

def stop
  thread.kill
  Celluloid::Actor.kill(Celluloid::Actor[:listen_adapter])
  Celluloid::Actor[:listen_silencer].terminate
  Celluloid::Actor[:listen_change_pool].terminate
  Celluloid::Actor[:listen_record].terminate
end

#unpauseObject

Unpauses listening callback



61
62
63
64
# File 'lib/listen/listener.rb', line 61

def unpause
  Celluloid::Actor[:listen_record].build
  @paused = false
end