Class: RSpactor::Listener

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

Overview

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Listener

Options examples:

{:extensions => ['rb', 'haml'], :relative_paths => true, :latency => .5}


11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/rspactor/listener.rb', line 11

def initialize(options = {})
  @options = options
  timestamp_checked
  @force_changed = []
  
  @callback = lambda do |stream, ctx, num_events, paths, marks, event_ids|
    changed_files = extract_changed_files_from_paths(split_paths(paths, num_events))
    timestamp_checked
    changed_files = relativize_path_names(changed_files) if options[:relative_paths]
    yield changed_files unless changed_files.empty?
  end
end

Instance Attribute Details

#callbackObject (readonly)

Returns the value of attribute callback.



7
8
9
# File 'lib/rspactor/listener.rb', line 7

def callback
  @callback
end

#dirsObject (readonly)

Returns the value of attribute dirs.



7
8
9
# File 'lib/rspactor/listener.rb', line 7

def dirs
  @dirs
end

#force_changedObject (readonly)

Returns the value of attribute force_changed.



7
8
9
# File 'lib/rspactor/listener.rb', line 7

def force_changed
  @force_changed
end

#last_checkObject (readonly)

Returns the value of attribute last_check.



7
8
9
# File 'lib/rspactor/listener.rb', line 7

def last_check
  @last_check
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/rspactor/listener.rb', line 7

def options
  @options
end

Instance Method Details

#enter_run_loopObject



51
52
53
54
55
56
57
# File 'lib/rspactor/listener.rb', line 51

def enter_run_loop
  begin
    OSX::CFRunLoopRun()
  rescue Interrupt
    stop
  end
end

#extract_changed_files_from_paths(paths) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rspactor/listener.rb', line 76

def extract_changed_files_from_paths(paths)
  changed_files = []
  paths.each do |path|
    next if ignore_path?(path)
    Dir.glob(path + "*").each do |file|
      next if ignore_file?(file)
      changed_files << file if file_changed?(file)
    end
  end
  changed_files
end

#file_changed?(file) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
91
92
93
94
# File 'lib/rspactor/listener.rb', line 88

def file_changed?(file)
  return true if force_changed.delete(file)
  file_mtime = File.stat(file).mtime
  file_mtime > last_check
rescue Errno::ENOENT
  false
end

#file_extension(file) ⇒ Object



104
105
106
# File 'lib/rspactor/listener.rb', line 104

def file_extension(file)
  file =~ /\.(\w+)$/ and $1
end

#ignore_file?(file) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/rspactor/listener.rb', line 100

def ignore_file?(file)
  File.basename(file).index('.') == 0 or not valid_extension?(file)
end

#ignore_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/rspactor/listener.rb', line 96

def ignore_path?(path)
  path =~ /(?:^|\/)\.(git|svn)/
end

#relativize_path_names(files) ⇒ Object



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

def relativize_path_names(files)
  for file in files
    if dir = @dirs.find { |p| file.index(p) == 0 }
      file.sub!(dir + '/', '')
    end
  end
end

#split_paths(paths, num_events) ⇒ Object



69
70
71
72
73
74
# File 'lib/rspactor/listener.rb', line 69

def split_paths(paths, num_events)
  paths.regard_as('*')
  rpaths = []
  num_events.times { |i| rpaths << paths[i] }
  rpaths
end

#start(directories) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rspactor/listener.rb', line 32

def start(directories)
  @dirs = Array(directories)
  since = OSX::KFSEventStreamEventIdSinceNow
  
  @stream = OSX::FSEventStreamCreate(OSX::KCFAllocatorDefault, callback, nil, @dirs, since, options[:latency] || 0.0, 0)
  unless @stream
    $stderr.puts "Failed to create stream"
    exit(1)
  end

  OSX::FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
  unless OSX::FSEventStreamStart(@stream)
    $stderr.puts "Failed to start stream"
    exit(1)
  end
  
  return self
end

#stopObject



59
60
61
62
63
# File 'lib/rspactor/listener.rb', line 59

def stop
  OSX::FSEventStreamStop(@stream)
  OSX::FSEventStreamInvalidate(@stream)
  OSX::FSEventStreamRelease(@stream)
end

#timestamp_checkedObject



65
66
67
# File 'lib/rspactor/listener.rb', line 65

def timestamp_checked
  @last_check = Time.now
end

#valid_extension?(file) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/rspactor/listener.rb', line 108

def valid_extension?(file)
  options[:extensions].nil? or options[:extensions].include?(file_extension(file))
end