chriseppstein-compass 0.8.13 → 0.8.14

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.markdown CHANGED
@@ -1,6 +1,11 @@
1
1
  COMPASS CHANGELOG
2
2
  =================
3
3
 
4
+ 0.8.14 (September 2, 2009)
5
+ --------------------------
6
+
7
+ * Upgrade the FSSM library to 0.0.4 to fix bugs and enable FS Events on Mac OS.
8
+
4
9
  0.8.13 (August 30, 2009)
5
10
  ------------------------
6
11
 
data/REVISION CHANGED
@@ -1 +1 @@
1
- 3ce66e278b2a7a526151bc7c1ab5b344d398f451
1
+ 65e5b122f2d5c0022e65a519342adb2cc4a27907
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 13
2
+ :patch: 14
3
3
  :major: 0
4
4
  :minor: 8
data/lib/vendor/fssm.rb CHANGED
@@ -1,30 +1,37 @@
1
+ dir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
3
+
1
4
  module FSSM
2
5
  FileNotFoundError = Class.new(StandardError)
3
6
  CallbackError = Class.new(StandardError)
4
-
7
+
5
8
  class << self
6
9
  def monitor(*args, &block)
7
10
  monitor = FSSM::Monitor.new
8
11
  context = args.empty? ? monitor : monitor.path(*args)
9
- if block && block.arity == 0
10
- context.instance_eval(&block)
11
- elsif block && block.arity == 1
12
- block.call(context)
12
+
13
+ if block_given?
14
+ if block.arity == 1
15
+ block.call(context)
16
+ else
17
+ context.instance_eval(&block)
18
+ end
13
19
  end
20
+
14
21
  monitor.run
15
22
  end
16
23
  end
17
24
  end
18
25
 
19
- $:.unshift(File.dirname(__FILE__))
26
+ require 'thread'
20
27
  require 'pathname'
28
+
21
29
  require 'fssm/ext'
22
30
  require 'fssm/support'
31
+ require 'fssm/cache'
23
32
  require 'fssm/path'
24
33
  require 'fssm/state'
25
34
  require 'fssm/monitor'
26
35
 
27
36
  require "fssm/backends/#{FSSM::Support.backend.downcase}"
28
37
  FSSM::Backends::Default = FSSM::Backends.const_get(FSSM::Support.backend)
29
- $:.shift
30
-
@@ -1,78 +1,36 @@
1
+ require 'fssm/fsevents'
2
+
1
3
  module FSSM::Backends
2
- class FSEvents
3
- def initialize(options={})
4
- @streams = []
5
- @handlers = {}
6
- @allocator = options[:allocator] || OSX::KCFAllocatorDefault
7
- @context = options[:context] || nil
8
- @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
9
- @latency = options[:latency] || 0.0
10
- @flags = options[:flags] || 0
4
+ class FSEvents
5
+ def initialize
6
+ @handlers = {}
7
+ @fsevents = []
11
8
  end
12
9
 
13
10
  def add_path(path, preload=true)
14
- @handlers["#{path}"] = FSSM::State.new(path, preload)
11
+ handler = FSSM::State.new(path, preload)
12
+ @handlers["#{path}"] = handler
15
13
 
16
- cb = lambda do |stream, context, number, paths, flags, ids|
17
- paths.regard_as('*')
18
- watched = OSX.FSEventStreamCopyPathsBeingWatched(stream).first
19
- @handlers["#{watched}"].refresh
20
- # TODO: support this level of granularity
21
- # number.times do |n|
22
- # @handlers["#{watched}"].refresh_path(paths[n])
23
- # end
14
+ fsevent = Rucola::FSEvents.new("#{path}") do |events|
15
+ events.each do |event|
16
+ handler.refresh(event.path)
17
+ end
24
18
  end
25
19
 
26
- @streams << create_stream(cb, "#{path}")
20
+ fsevent.create_stream
21
+ fsevent.start
22
+ @fsevents << fsevent
27
23
  end
28
24
 
29
25
  def run
30
- @streams.each do |stream|
31
- schedule_stream(stream)
32
- start_stream(stream)
33
- end
34
-
35
26
  begin
36
27
  OSX.CFRunLoopRun
37
28
  rescue Interrupt
38
- @streams.each do |stream|
39
- stop_stream(stream)
40
- invalidate_stream(stream)
41
- release_stream(stream)
29
+ @fsevents.each do |fsev|
30
+ fsev.stop
42
31
  end
43
32
  end
44
-
45
- end
46
-
47
- private
48
-
49
- def create_stream(callback, paths)
50
- paths = [paths] unless paths.is_a?(Array)
51
- OSX.FSEventStreamCreate(@allocator, callback, @context, paths, @since, @latency, @flags)
52
- end
53
-
54
- def schedule_stream(stream, options={})
55
- run_loop = options[:run_loop] || OSX.CFRunLoopGetCurrent
56
- loop_mode = options[:loop_mode] || OSX::KCFRunLoopDefaultMode
57
-
58
- OSX.FSEventStreamScheduleWithRunLoop(stream, run_loop, loop_mode)
59
33
  end
60
-
61
- def start_stream(stream)
62
- OSX.FSEventStreamStart(stream)
63
- end
64
-
65
- def stop_stream(stream)
66
- OSX.FSEventStreamStop(stream)
67
- end
68
-
69
- def invalidate_stream(stream)
70
- OSX.FSEventStreamInvalidate(stream)
71
- end
72
-
73
- def release_stream(stream)
74
- OSX.FSEventStreamRelease(stream)
75
- end
76
-
34
+
77
35
  end
78
36
  end
@@ -1,24 +1,24 @@
1
1
  module FSSM::Backends
2
2
  class Polling
3
- def initialize(options={})
4
- @handlers = []
5
- @latency = options[:latency] || 1
6
- end
7
-
8
- def add_path(path, preload=true)
9
- @handlers << FSSM::State.new(path, preload)
10
- end
11
-
12
- def run
13
- begin
14
- loop do
15
- start = Time.now.to_f
16
- @handlers.each {|handler| handler.refresh}
17
- nap_time = @latency - (Time.now.to_f - start)
18
- sleep nap_time if nap_time > 0
3
+ def initialize(options={})
4
+ @handlers = []
5
+ @latency = options[:latency] || 1
6
+ end
7
+
8
+ def add_path(path, preload=true)
9
+ @handlers << FSSM::State.new(path, preload)
10
+ end
11
+
12
+ def run
13
+ begin
14
+ loop do
15
+ start = Time.now.to_f
16
+ @handlers.each {|handler| handler.refresh}
17
+ nap_time = @latency - (Time.now.to_f - start)
18
+ sleep nap_time if nap_time > 0
19
+ end
20
+ rescue Interrupt
19
21
  end
20
- rescue Interrupt
21
22
  end
22
23
  end
23
24
  end
24
- end
@@ -0,0 +1,193 @@
1
+ class FSSM::Cache
2
+ module Common
3
+ include Enumerable
4
+
5
+ def initialize
6
+ @children = Hash.new
7
+ end
8
+
9
+ def each(prefix='./', &block)
10
+ @children.each do |segment, node|
11
+ cprefix = Pathname.for(prefix.dup).join(segment)
12
+ block.call(cprefix, node)
13
+ node.each(cprefix, &block)
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def with_lock
20
+ @mutex.lock
21
+ yield
22
+ @mutex.unlock
23
+ end
24
+
25
+ def descendant(path)
26
+ recurse_on_key(path, false)
27
+ end
28
+
29
+ def descendant!(path)
30
+ recurse_on_key(path, true)
31
+ end
32
+
33
+ def child(segment)
34
+ has_child?(segment) ? @children["#{segment}"] : nil
35
+ end
36
+
37
+ def child!(segment)
38
+ (@children["#{segment}"] ||= Node.new)
39
+ end
40
+
41
+ def has_child?(segment)
42
+ @children.include?("#{segment}")
43
+ end
44
+
45
+ def remove_child(segment)
46
+ @children.delete("#{segment}")
47
+ end
48
+
49
+ def remove_children
50
+ @children.clear
51
+ end
52
+
53
+ def recurse_on_key(key, create)
54
+ key = sanitize_key(key)
55
+ node = self
56
+
57
+ until key.empty?
58
+ segment = key.shift
59
+ node = create ? node.child!(segment) : node.child(segment)
60
+ return nil unless node
61
+ end
62
+
63
+ node
64
+ end
65
+
66
+ def key_for_path(path)
67
+ Pathname.for(path).names
68
+ end
69
+
70
+ def relative_path(path)
71
+ sanitize_path(path, false)
72
+ end
73
+
74
+ def absolute_path(path)
75
+ sanitize_path(path, true)
76
+ end
77
+
78
+ def sanitize_path(path, absolute)
79
+ if path.is_a?(Array)
80
+ first = absolute ? '/' : path.shift
81
+ path = path.inject(Pathname.new("#{first}")) do |pathname, segment|
82
+ pathname.join("#{segment}")
83
+ end
84
+ path
85
+ else
86
+ path = Pathname.for(path)
87
+ absolute ? path.expand_path : path
88
+ end
89
+ end
90
+ end
91
+
92
+ class Node
93
+ include Common
94
+
95
+ attr_accessor :mtime
96
+ attr_accessor :ftype
97
+
98
+ def <=>(other)
99
+ self.mtime <=> other.mtime
100
+ end
101
+
102
+ def from_path(path)
103
+ path = absolute_path(path)
104
+ @mtime = path.mtime
105
+ @ftype = path.ftype
106
+ end
107
+
108
+ protected
109
+
110
+ def sanitize_key(key)
111
+ key_for_path(relative_path(key))
112
+ end
113
+ end
114
+
115
+ include Common
116
+
117
+ def initialize
118
+ @mutex = Mutex.new
119
+ super
120
+ end
121
+
122
+ def clear
123
+ @mutex.lock
124
+ @children.clear
125
+ @mutex.unlock
126
+ end
127
+
128
+ def set(path)
129
+ unset(path)
130
+ node = descendant!(path)
131
+ node.from_path(path)
132
+ node.mtime
133
+ end
134
+
135
+ def unset(path='/')
136
+ key = sanitize_key(path)
137
+
138
+ if key.empty?
139
+ self.clear
140
+ return nil
141
+ end
142
+
143
+ segment = key.pop
144
+ node = descendant(key)
145
+
146
+ return unless node
147
+
148
+ @mutex.lock
149
+ node.remove_child(segment)
150
+ @mutex.unlock
151
+
152
+ nil
153
+ end
154
+
155
+ def files
156
+ ftype('file')
157
+ end
158
+
159
+ def directories
160
+ ftype('directory')
161
+ end
162
+
163
+ protected
164
+
165
+ def each(&block)
166
+ prefix='/'
167
+ super(prefix, &block)
168
+ end
169
+
170
+ def ftype(ft)
171
+ inject({}) do |hash, entry|
172
+ path, node = entry
173
+ hash["#{path}"] = node.mtime if node.ftype == ft
174
+ hash
175
+ end
176
+ end
177
+
178
+ def descendant(path)
179
+ node = recurse_on_key(path, false)
180
+ node
181
+ end
182
+
183
+ def descendant!(path)
184
+ @mutex.lock
185
+ node = recurse_on_key(path, true)
186
+ @mutex.unlock
187
+ node
188
+ end
189
+
190
+ def sanitize_key(key)
191
+ key_for_path(absolute_path(key))
192
+ end
193
+ end
@@ -4,4 +4,9 @@ class Pathname
4
4
  path.is_a?(Pathname) ? path : new(path)
5
5
  end
6
6
  end
7
+
8
+ def names
9
+ prefix, names = split_names(@path)
10
+ names
11
+ end
7
12
  end
@@ -0,0 +1,129 @@
1
+ OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
2
+
3
+ module Rucola
4
+ class FSEvents
5
+ class FSEvent
6
+ attr_reader :fsevents_object
7
+ attr_reader :id
8
+ attr_reader :path
9
+ def initialize(fsevents_object, id, path)
10
+ @fsevents_object, @id, @path = fsevents_object, id, path
11
+ end
12
+
13
+ # Returns an array of the files/dirs in the path that the event occurred in.
14
+ # The files are sorted by the modification time, the first entry is the last modified file.
15
+ def files
16
+ Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
17
+ end
18
+
19
+ # Returns the last modified file in the path that the event occurred in.
20
+ def last_modified_file
21
+ files.first
22
+ end
23
+ end
24
+
25
+ class StreamError < StandardError; end
26
+
27
+ attr_reader :paths
28
+ attr_reader :stream
29
+
30
+ attr_accessor :allocator
31
+ attr_accessor :context
32
+ attr_accessor :since
33
+ attr_accessor :latency
34
+ attr_accessor :flags
35
+
36
+ # Initializes a new FSEvents `watchdog` object and starts watching the directories you specify for events. The
37
+ # block is used as a handler for events, which are passed as the block's argument. This method is the easiest
38
+ # way to start watching some directories if you don't care about the details of setting up the event stream.
39
+ #
40
+ # Rucola::FSEvents.start_watching('/tmp') do |events|
41
+ # events.each { |event| log.debug("#{event.files.inspect} were changed.") }
42
+ # end
43
+ #
44
+ # Rucola::FSEvents.start_watching('/var/log/system.log', '/var/log/secure.log', :since => last_id, :latency => 5) do
45
+ # Growl.notify("Something was added to your log files!")
46
+ # end
47
+ #
48
+ # Note that the method also returns the FSEvents object. This enables you to control the event stream if you want to.
49
+ #
50
+ # fsevents = Rucola::FSEvents.start_watching('/Volumes') do |events|
51
+ # events.each { |event| Growl.notify("Volume changes: #{event.files.to_sentence}") }
52
+ # end
53
+ # fsevents.stop
54
+ def self.start_watching(*params, &block)
55
+ fsevents = new(*params, &block)
56
+ fsevents.create_stream
57
+ fsevents.start
58
+ fsevents
59
+ end
60
+
61
+ # Creates a new FSEvents `watchdog` object. You can specify a list of paths to watch and options to control the
62
+ # behaviour of the watchdog. The block you pass serves as a callback when an event is generated on one of the
63
+ # specified paths.
64
+ #
65
+ # fsevents = FSEvents.new('/etc/passwd') { Mailer.send_mail("Someone touched the password file!") }
66
+ # fsevents.create_stream
67
+ # fsevents.start
68
+ #
69
+ # fsevents = FSEvents.new('/home/upload', :since => UploadWatcher.last_event_id) do |events|
70
+ # events.each do |event|
71
+ # UploadWatcher.last_event_id = event.id
72
+ # event.files.each do |file|
73
+ # UploadWatcher.logfile.append("#{file} was changed")
74
+ # end
75
+ # end
76
+ # end
77
+ #
78
+ # *:since: The service will report events that have happened after the supplied event ID. Never use 0 because that
79
+ # will cause every fsevent since the "beginning of time" to be reported. Use OSX::KFSEventStreamEventIdSinceNow
80
+ # if you want to receive events that have happened after this call. (Default: OSX::KFSEventStreamEventIdSinceNow).
81
+ # You can find the ID's passed with :since in the events passed to your block.
82
+ # *:latency: Number of seconds to wait until an FSEvent is reported, this allows the service to bundle events. (Default: 0.0)
83
+ #
84
+ # Please refer to the Cocoa documentation for the rest of the options.
85
+ def initialize(*params, &block)
86
+ raise ArgumentError, 'No callback block was specified.' unless block_given?
87
+
88
+ options = params.last.kind_of?(Hash) ? params.pop : {}
89
+ @paths = params.flatten
90
+
91
+ paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
92
+
93
+ @allocator = options[:allocator] || OSX::KCFAllocatorDefault
94
+ @context = options[:context] || nil
95
+ @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
96
+ @latency = options[:latency] || 0.0
97
+ @flags = options[:flags] || 0
98
+ @stream = options[:stream] || nil
99
+
100
+ @user_callback = block
101
+ @callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
102
+ paths_pointer.regard_as('*')
103
+ events = []
104
+ number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) }
105
+ @user_callback.call(events)
106
+ end
107
+ end
108
+
109
+ # Create the stream.
110
+ # Raises a Rucola::FSEvents::StreamError if the stream could not be created.
111
+ def create_stream
112
+ @stream = OSX.FSEventStreamCreate(@allocator, @callback, @context, @paths, @since, @latency, @flags)
113
+ raise(StreamError, 'Unable to create FSEvents stream.') unless @stream
114
+ OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
115
+ end
116
+
117
+ # Start the stream.
118
+ # Raises a Rucola::FSEvents::StreamError if the stream could not be started.
119
+ def start
120
+ raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream)
121
+ end
122
+
123
+ # Stop the stream.
124
+ # You can resume it by calling `start` again.
125
+ def stop
126
+ OSX.FSEventStreamStop(@stream)
127
+ end
128
+ end
129
+ end
@@ -3,18 +3,22 @@ class FSSM::Monitor
3
3
  @options = options
4
4
  @backend = FSSM::Backends::Default.new
5
5
  end
6
-
6
+
7
7
  def path(*args, &block)
8
8
  path = FSSM::Path.new(*args)
9
- if block && block.arity == 0
10
- path.instance_eval(&block)
11
- elsif block && block.arity == 1
12
- block.call(path)
9
+
10
+ if block_given?
11
+ if block.arity == 1
12
+ block.call(path)
13
+ else
14
+ path.instance_eval(&block)
15
+ end
13
16
  end
17
+
14
18
  @backend.add_path(path)
15
19
  path
16
20
  end
17
-
21
+
18
22
  def run
19
23
  @backend.run
20
24
  end
@@ -3,45 +3,48 @@ class FSSM::Path
3
3
  set_path(path || '.')
4
4
  set_glob(glob || '**/*')
5
5
  init_callbacks
6
- if block && block.arity == 0
7
- self.instance_eval(&block)
8
- elsif block && block.arity == 1
9
- block.call(self)
6
+
7
+ if block_given?
8
+ if block.arity == 1
9
+ block.call(self)
10
+ else
11
+ self.instance_eval(&block)
12
+ end
10
13
  end
11
14
  end
12
-
15
+
13
16
  def to_s
14
17
  @path.to_s
15
18
  end
16
-
19
+
17
20
  def to_pathname
18
21
  @path
19
22
  end
20
-
23
+
21
24
  def glob(value=nil)
22
25
  return @glob if value.nil?
23
26
  set_glob(value)
24
27
  end
25
-
28
+
26
29
  def create(callback_or_path=nil, &block)
27
30
  callback_action(:create, (block_given? ? block : callback_or_path))
28
31
  end
29
-
32
+
30
33
  def update(callback_or_path=nil, &block)
31
34
  callback_action(:update, (block_given? ? block : callback_or_path))
32
35
  end
33
-
36
+
34
37
  def delete(callback_or_path=nil, &block)
35
38
  callback_action(:delete, (block_given? ? block : callback_or_path))
36
39
  end
37
-
40
+
38
41
  private
39
-
42
+
40
43
  def init_callbacks
41
44
  do_nothing = lambda {|base, relative|}
42
45
  @callbacks = Hash.new(do_nothing)
43
46
  end
44
-
47
+
45
48
  def callback_action(type, arg=nil)
46
49
  if arg.is_a?(Proc)
47
50
  set_callback(type, arg)
@@ -51,37 +54,37 @@ class FSSM::Path
51
54
  run_callback(type, arg)
52
55
  end
53
56
  end
54
-
57
+
55
58
  def set_callback(type, arg)
56
59
  raise ArgumentError, "Proc expected" unless arg.is_a?(Proc)
57
60
  @callbacks[type] = arg
58
61
  end
59
-
62
+
60
63
  def get_callback(type)
61
64
  @callbacks[type]
62
65
  end
63
-
66
+
64
67
  def run_callback(type, arg)
65
68
  base, relative = split_path(arg)
66
-
69
+
67
70
  begin
68
71
  @callbacks[type].call(base, relative)
69
72
  rescue Exception => e
70
73
  raise FSSM::CallbackError, "#{type} - #{base.join(relative)}: #{e.message}", e.backtrace
71
74
  end
72
75
  end
73
-
76
+
74
77
  def split_path(path)
75
78
  path = Pathname.for(path)
76
- [@path, (path.relative? ? path : path.relative_path_from(@path))]
79
+ [@path, (path.relative? ? path : path.relative_path_from(@path))]
77
80
  end
78
-
81
+
79
82
  def set_path(path)
80
83
  path = Pathname.for(path)
81
84
  raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
82
85
  @path = path.realpath
83
86
  end
84
-
87
+
85
88
  def set_glob(glob)
86
89
  @glob = glob.is_a?(Array) ? glob : [glob]
87
90
  end
@@ -1,46 +1,53 @@
1
+ require 'yaml'
1
2
  class FSSM::State
2
3
  def initialize(path, preload=true)
3
4
  @path = path
4
- @snapshot = {}
5
- snapshot if preload
6
- end
7
-
8
- def refresh
9
- previous = @snapshot
10
- current = snapshot
11
-
5
+ @cache = FSSM::Cache.new
6
+ snapshot(@path.to_pathname) if preload
7
+ end
8
+
9
+ def refresh(base=nil)
10
+ previous, current = recache(base || @path.to_pathname)
11
+
12
12
  deleted(previous, current)
13
13
  created(previous, current)
14
- modified(previous, current)
14
+ modified(previous, current)
15
15
  end
16
-
16
+
17
17
  private
18
-
18
+
19
19
  def created(previous, current)
20
20
  (current.keys - previous.keys).each {|created| @path.create(created)}
21
21
  end
22
-
22
+
23
23
  def deleted(previous, current)
24
24
  (previous.keys - current.keys).each {|deleted| @path.delete(deleted)}
25
25
  end
26
-
26
+
27
27
  def modified(previous, current)
28
28
  (current.keys & previous.keys).each do |file|
29
29
  @path.update(file) if (current[file] <=> previous[file]) != 0
30
30
  end
31
31
  end
32
-
33
- def snapshot
34
- snap = {}
35
- @path.glob.each {|glob| add_glob(snap, glob)}
36
- @snapshot = snap
37
- end
38
-
39
- def add_glob(snap, glob)
40
- Pathname.glob(@path.to_pathname.join(glob)).each do |fn|
41
- next unless fn.file?
42
- snap["#{fn}"] = fn.mtime
32
+
33
+ def recache(base)
34
+ base = Pathname.for(base)
35
+ previous = @cache.files
36
+ snapshot(base)
37
+ current = @cache.files
38
+ [previous, current]
39
+ end
40
+
41
+ def snapshot(base)
42
+ base = Pathname.for(base)
43
+ @cache.unset(base)
44
+ @path.glob.each {|glob| add_glob(base, glob)}
45
+ end
46
+
47
+ def add_glob(base, glob)
48
+ Pathname.glob(base.join(glob)).each do |fn|
49
+ @cache.set(fn)
43
50
  end
44
51
  end
45
-
52
+
46
53
  end
@@ -1,17 +1,13 @@
1
1
  module FSSM::Support
2
2
  class << self
3
- # def backend
4
- # (mac? && carbon_core?) ? 'FSEvents' : 'Polling'
5
- # end
6
-
7
3
  def backend
8
- 'Polling'
4
+ (mac? && carbon_core?) ? 'FSEvents' : 'Polling'
9
5
  end
10
-
6
+
11
7
  def mac?
12
8
  @@mac ||= RUBY_PLATFORM =~ /darwin/i
13
9
  end
14
-
10
+
15
11
  def carbon_core?
16
12
  @@carbon_core ||= begin
17
13
  require 'osx/foundation'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chriseppstein-compass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.13
4
+ version: 0.8.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Eppstein
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-30 00:00:00 -07:00
12
+ date: 2009-09-02 00:00:00 -07:00
13
13
  default_executable: compass
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -263,7 +263,9 @@ files:
263
263
  - lib/vendor/fssm.rb
264
264
  - lib/vendor/fssm/backends/fsevents.rb
265
265
  - lib/vendor/fssm/backends/polling.rb
266
+ - lib/vendor/fssm/cache.rb
266
267
  - lib/vendor/fssm/ext.rb
268
+ - lib/vendor/fssm/fsevents.rb
267
269
  - lib/vendor/fssm/monitor.rb
268
270
  - lib/vendor/fssm/path.rb
269
271
  - lib/vendor/fssm/state.rb