chriseppstein-compass 0.8.13 → 0.8.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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