From 7b0bb7ad2b7a39dbe3ceae21054685ec6ce912b5 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Tue, 19 Apr 2011 19:59:54 -0700 Subject: [PATCH] Change FSSM to a gem dependency instead of vendoring it. Closes GH-343. --- Gemfile | 3 + Gemfile.lock | 6 +- compass.gemspec | 1 + lib/compass/commands/watch_project.rb | 7 +- lib/vendor/fssm/fssm.rb | 33 -- lib/vendor/fssm/fssm/backends/fsevents.rb | 36 -- lib/vendor/fssm/fssm/backends/inotify.rb | 26 - lib/vendor/fssm/fssm/backends/polling.rb | 25 - .../fssm/fssm/backends/rubycocoa/fsevents.rb | 131 ----- lib/vendor/fssm/fssm/monitor.rb | 26 - lib/vendor/fssm/fssm/path.rb | 91 ---- lib/vendor/fssm/fssm/pathname.rb | 502 ------------------ lib/vendor/fssm/fssm/state/directory.rb | 57 -- lib/vendor/fssm/fssm/state/file.rb | 24 - lib/vendor/fssm/fssm/support.rb | 63 --- lib/vendor/fssm/fssm/tree.rb | 176 ------ 16 files changed, 10 insertions(+), 1197 deletions(-) delete mode 100644 lib/vendor/fssm/fssm.rb delete mode 100644 lib/vendor/fssm/fssm/backends/fsevents.rb delete mode 100644 lib/vendor/fssm/fssm/backends/inotify.rb delete mode 100644 lib/vendor/fssm/fssm/backends/polling.rb delete mode 100644 lib/vendor/fssm/fssm/backends/rubycocoa/fsevents.rb delete mode 100644 lib/vendor/fssm/fssm/monitor.rb delete mode 100644 lib/vendor/fssm/fssm/path.rb delete mode 100644 lib/vendor/fssm/fssm/pathname.rb delete mode 100644 lib/vendor/fssm/fssm/state/directory.rb delete mode 100644 lib/vendor/fssm/fssm/state/file.rb delete mode 100644 lib/vendor/fssm/fssm/support.rb delete mode 100644 lib/vendor/fssm/fssm/tree.rb diff --git a/Gemfile b/Gemfile index b1eebc5d..6e0e2b33 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,7 @@ source :rubygems +gemspec + gem "compass", :path => "." gem "cucumber", "~> 0.9.2" gem "rspec", "~>2.0.0" @@ -11,6 +13,7 @@ gem "haml", "~> 3.1.0.alpha" gem "rcov" gem "rubyzip" gem "livereload" +gem "rb-fsevent" gem "ruby-prof" unless RUBY_PLATFORM == "java" diff --git a/Gemfile.lock b/Gemfile.lock index 683be5e6..c6acc53d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,8 +7,9 @@ GIT PATH remote: . specs: - compass (0.11.beta.7.3e013b8) + compass (0.11.beta.7.37998a4) chunky_png (~> 1.1.0) + fssm (~> 0.2) sass (>= 3.1.0.alpha.249) GEM @@ -65,6 +66,7 @@ GEM abstract (>= 1.0.0) eventmachine (0.12.10) eventmachine (0.12.10-java) + fssm (0.2.6.1) gherkin (2.2.9) json (~> 1.4.6) term-ansicolor (~> 1.0.5) @@ -106,6 +108,7 @@ GEM rake (>= 0.8.7) thor (~> 0.14.4) rake (0.8.7) + rb-fsevent (0.4.0) rcov (0.9.9) rcov (0.9.9-java) rspec (2.0.1) @@ -144,6 +147,7 @@ DEPENDENCIES livereload mocha rails (~> 3.0.0.rc) + rb-fsevent rcov rspec (~> 2.0.0) ruby-prof diff --git a/compass.gemspec b/compass.gemspec index deb6344a..bd561598 100644 --- a/compass.gemspec +++ b/compass.gemspec @@ -17,6 +17,7 @@ Gem::Specification.new do |gemspec| gemspec.add_dependency 'sass', '>= 3.1.0.alpha.249' gemspec.add_dependency 'chunky_png', '~> 1.1.0' + gemspec.add_dependency 'fssm', '~> 0.2' gemspec.files = %w(README.markdown LICENSE.markdown VERSION.yml Rakefile) gemspec.files += Dir.glob("bin/*") diff --git a/lib/compass/commands/watch_project.rb b/lib/compass/commands/watch_project.rb index 3d35023a..1a3fd66c 100644 --- a/lib/compass/commands/watch_project.rb +++ b/lib/compass/commands/watch_project.rb @@ -39,12 +39,7 @@ module Compass check_for_sass_files!(new_compiler_instance) recompile - begin - require 'fssm' - rescue LoadError - $: << File.join(Compass.lib_directory, 'vendor', 'fssm') - retry - end + require 'fssm' if options[:poll] require "fssm/backends/polling" diff --git a/lib/vendor/fssm/fssm.rb b/lib/vendor/fssm/fssm.rb deleted file mode 100644 index 058cbf3c..00000000 --- a/lib/vendor/fssm/fssm.rb +++ /dev/null @@ -1,33 +0,0 @@ -dir = File.dirname(__FILE__) -$LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir) - -module FSSM - FileNotFoundError = Class.new(StandardError) - CallbackError = Class.new(StandardError) - - class << self - def dbg(msg=nil) - STDERR.puts(msg) - end - - def monitor(*args, &block) - monitor = FSSM::Monitor.new - FSSM::Support.use_block(args.empty? ? monitor : monitor.path(*args), block) - - monitor.run - end - end -end - -require 'thread' - -require 'fssm/pathname' -require 'fssm/support' -require 'fssm/tree' -require 'fssm/path' -require 'fssm/state/directory' -require 'fssm/state/file' -require 'fssm/monitor' - -require "fssm/backends/#{FSSM::Support.backend.downcase}" -FSSM::Backends::Default = FSSM::Backends.const_get(FSSM::Support.backend) diff --git a/lib/vendor/fssm/fssm/backends/fsevents.rb b/lib/vendor/fssm/fssm/backends/fsevents.rb deleted file mode 100644 index 800cebd1..00000000 --- a/lib/vendor/fssm/fssm/backends/fsevents.rb +++ /dev/null @@ -1,36 +0,0 @@ -require File.join(File.dirname(__FILE__), 'rubycocoa/fsevents') - -module FSSM::Backends - class FSEvents - def initialize - @handlers = {} - @fsevents = [] - end - - def add_handler(handler, preload=true) - @handlers[handler.path.to_s] = handler - - fsevent = Rucola::FSEvents.new(handler.path.to_s, {:latency => 0.5}) do |events| - events.each do |event| - handler.refresh(event.path) - end - end - - fsevent.create_stream - handler.refresh(nil, true) if preload - fsevent.start - @fsevents << fsevent - end - - def run - begin - OSX.CFRunLoopRun - rescue Interrupt - @fsevents.each do |fsev| - fsev.stop - end - end - end - - end -end diff --git a/lib/vendor/fssm/fssm/backends/inotify.rb b/lib/vendor/fssm/fssm/backends/inotify.rb deleted file mode 100644 index 74af1bcf..00000000 --- a/lib/vendor/fssm/fssm/backends/inotify.rb +++ /dev/null @@ -1,26 +0,0 @@ -module FSSM::Backends - class Inotify - def initialize - @notifier = INotify::Notifier.new - end - - def add_handler(handler, preload=true) - @notifier.watch(handler.path.to_s, :recursive, :attrib, :modify, :create, - :delete, :delete_self, :moved_from, :moved_to, :move_self) do |event| - path = FSSM::Pathname.for(event.absolute_name) - path = path.dirname unless event.name == "" # Event on root directory - handler.refresh(path) - end - - handler.refresh(nil, true) if preload - end - - def run - begin - @notifier.run - rescue Interrupt - end - end - - end -end diff --git a/lib/vendor/fssm/fssm/backends/polling.rb b/lib/vendor/fssm/fssm/backends/polling.rb deleted file mode 100644 index 083cf07b..00000000 --- a/lib/vendor/fssm/fssm/backends/polling.rb +++ /dev/null @@ -1,25 +0,0 @@ -module FSSM::Backends - class Polling - def initialize(options={}) - @handlers = [] - @latency = options[:latency] || 1.5 - end - - def add_handler(handler, preload=true) - handler.refresh(nil, true) if preload - @handlers << handler - end - - def run - begin - loop do - start = Time.now.to_f - @handlers.each {|handler| handler.refresh} - nap_time = @latency - (Time.now.to_f - start) - sleep nap_time if nap_time > 0 - end - rescue Interrupt - end - end - end -end diff --git a/lib/vendor/fssm/fssm/backends/rubycocoa/fsevents.rb b/lib/vendor/fssm/fssm/backends/rubycocoa/fsevents.rb deleted file mode 100644 index 7a1dbab7..00000000 --- a/lib/vendor/fssm/fssm/backends/rubycocoa/fsevents.rb +++ /dev/null @@ -1,131 +0,0 @@ -OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework' - -module Rucola - class FSEvents - class FSEvent - attr_reader :fsevents_object - attr_reader :id - attr_reader :path - - def initialize(fsevents_object, id, path) - @fsevents_object, @id, @path = fsevents_object, id, path - end - - # Returns an array of the files/dirs in the path that the event occurred in. - # The files are sorted by the modification time, the first entry is the last modified file. - def files - Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse - end - - # Returns the last modified file in the path that the event occurred in. - def last_modified_file - files.first - end - end - - class StreamError < StandardError; - end - - attr_reader :paths - attr_reader :stream - - attr_accessor :allocator - attr_accessor :context - attr_accessor :since - attr_accessor :latency - attr_accessor :flags - - # Initializes a new FSEvents `watchdog` object and starts watching the directories you specify for events. The - # block is used as a handler for events, which are passed as the block's argument. This method is the easiest - # way to start watching some directories if you don't care about the details of setting up the event stream. - # - # Rucola::FSEvents.start_watching('/tmp') do |events| - # events.each { |event| log.debug("#{event.files.inspect} were changed.") } - # end - # - # Rucola::FSEvents.start_watching('/var/log/system.log', '/var/log/secure.log', :since => last_id, :latency => 5) do - # Growl.notify("Something was added to your log files!") - # end - # - # Note that the method also returns the FSEvents object. This enables you to control the event stream if you want to. - # - # fsevents = Rucola::FSEvents.start_watching('/Volumes') do |events| - # events.each { |event| Growl.notify("Volume changes: #{event.files.to_sentence}") } - # end - # fsevents.stop - def self.start_watching(*params, &block) - fsevents = new(*params, &block) - fsevents.create_stream - fsevents.start - fsevents - end - - # Creates a new FSEvents `watchdog` object. You can specify a list of paths to watch and options to control the - # behaviour of the watchdog. The block you pass serves as a callback when an event is generated on one of the - # specified paths. - # - # fsevents = FSEvents.new('/etc/passwd') { Mailer.send_mail("Someone touched the password file!") } - # fsevents.create_stream - # fsevents.start - # - # fsevents = FSEvents.new('/home/upload', :since => UploadWatcher.last_event_id) do |events| - # events.each do |event| - # UploadWatcher.last_event_id = event.id - # event.files.each do |file| - # UploadWatcher.logfile.append("#{file} was changed") - # end - # end - # end - # - # *:since: The service will report events that have happened after the supplied event ID. Never use 0 because that - # will cause every fsevent since the "beginning of time" to be reported. Use OSX::KFSEventStreamEventIdSinceNow - # if you want to receive events that have happened after this call. (Default: OSX::KFSEventStreamEventIdSinceNow). - # You can find the ID's passed with :since in the events passed to your block. - # *:latency: Number of seconds to wait until an FSEvent is reported, this allows the service to bundle events. (Default: 0.0) - # - # Please refer to the Cocoa documentation for the rest of the options. - def initialize(*params, &block) - raise ArgumentError, 'No callback block was specified.' unless block_given? - - options = params.last.kind_of?(Hash) ? params.pop : {} - @paths = params.flatten - - paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) } - - @allocator = options[:allocator] || OSX::KCFAllocatorDefault - @context = options[:context] || nil - @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow - @latency = options[:latency] || 0.0 - @flags = options[:flags] || 0 - @stream = options[:stream] || nil - - @user_callback = block - @callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids| - paths_pointer.regard_as('*') - events = [] - number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) } - @user_callback.call(events) - end - end - - # Create the stream. - # Raises a Rucola::FSEvents::StreamError if the stream could not be created. - def create_stream - @stream = OSX.FSEventStreamCreate(@allocator, @callback, @context, @paths, @since, @latency, @flags) - raise(StreamError, 'Unable to create FSEvents stream.') unless @stream - OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode) - end - - # Start the stream. - # Raises a Rucola::FSEvents::StreamError if the stream could not be started. - def start - raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream) - end - - # Stop the stream. - # You can resume it by calling `start` again. - def stop - OSX.FSEventStreamStop(@stream) - end - end -end diff --git a/lib/vendor/fssm/fssm/monitor.rb b/lib/vendor/fssm/fssm/monitor.rb deleted file mode 100644 index d7f7468d..00000000 --- a/lib/vendor/fssm/fssm/monitor.rb +++ /dev/null @@ -1,26 +0,0 @@ -class FSSM::Monitor - def initialize(options={}) - @options = options - @backend = FSSM::Backends::Default.new - end - - def path(*args, &block) - path = FSSM::Path.new(*args) - FSSM::Support.use_block(path, block) - - @backend.add_handler(FSSM::State::Directory.new(path)) - path - end - - def file(*args, &block) - path = FSSM::Path.new(*args) - FSSM::Support.use_block(path, block) - - @backend.add_handler(FSSM::State::File.new(path)) - path - end - - def run - @backend.run - end -end diff --git a/lib/vendor/fssm/fssm/path.rb b/lib/vendor/fssm/fssm/path.rb deleted file mode 100644 index 101dd103..00000000 --- a/lib/vendor/fssm/fssm/path.rb +++ /dev/null @@ -1,91 +0,0 @@ -class FSSM::Path - def initialize(path=nil, glob=nil, &block) - set_path(path || '.') - set_glob(glob || '**/*') - init_callbacks - - if block_given? - if block.arity == 1 - block.call(self) - else - self.instance_eval(&block) - end - end - end - - def to_s - @path.to_s - end - - def to_pathname - @path - end - - def glob(value=nil) - return @glob if value.nil? - set_glob(value) - end - - def create(callback_or_path=nil, &block) - callback_action(:create, (block_given? ? block : callback_or_path)) - end - - def update(callback_or_path=nil, &block) - callback_action(:update, (block_given? ? block : callback_or_path)) - end - - def delete(callback_or_path=nil, &block) - callback_action(:delete, (block_given? ? block : callback_or_path)) - end - - private - - def init_callbacks - do_nothing = lambda {|base, relative|} - @callbacks = Hash.new(do_nothing) - end - - def callback_action(type, arg=nil) - if arg.is_a?(Proc) - set_callback(type, arg) - elsif arg.nil? - get_callback(type) - else - run_callback(type, arg) - end - end - - def set_callback(type, arg) - raise ArgumentError, "Proc expected" unless arg.is_a?(Proc) - @callbacks[type] = arg - end - - def get_callback(type) - @callbacks[type] - end - - def run_callback(type, arg) - base, relative = split_path(arg) - - begin - @callbacks[type].call(base, relative) - rescue Exception => e - raise FSSM::CallbackError, "#{type} - #{base.join(relative)}: #{e.message}", e.backtrace - end - end - - def split_path(path) - path = FSSM::Pathname.for(path) - [@path, (path.relative? ? path : path.relative_path_from(@path))] - end - - def set_path(path) - path = FSSM::Pathname.for(path) - raise FSSM::FileNotFoundError, "No such file or directory - #{path}" unless path.exist? - @path = path.expand_path - end - - def set_glob(glob) - @glob = glob.is_a?(Array) ? glob : [glob] - end -end diff --git a/lib/vendor/fssm/fssm/pathname.rb b/lib/vendor/fssm/fssm/pathname.rb deleted file mode 100644 index 58396ac4..00000000 --- a/lib/vendor/fssm/fssm/pathname.rb +++ /dev/null @@ -1,502 +0,0 @@ -require 'fileutils' -require 'find' - -module FSSM - class Pathname < String - SYMLOOP_MAX = 8 - - ROOT = '/'.freeze - DOT = '.'.freeze - DOT_DOT = '..'.freeze - - class << self - def for(path) - path.is_a?(::FSSM::Pathname) ? path : new("#{path}") - end - end - - def initialize(path) - raise ArgumentError, "path cannot contain ASCII NULLs" if path =~ %r{\0} - super(path) - end - - def <=>(other) - self.tr('/', "\0").to_s <=> other.to_str.tr('/', "\0") - rescue NoMethodError - nil - end - - def ==(other) - left = self.cleanpath.tr('/', "\0").to_s - right = self.class.for(other).cleanpath.tr('/', "\0").to_s - - left == right - rescue NoMethodError - false - end - - def +(path) - dup << path - end - - def <<(path) - replace( join(path).cleanpath! ) - end - - def absolute? - self[0, 1].to_s == ROOT - end - - def ascend - parts = to_a - parts.length.downto(1) do |i| - yield self.class.join(parts[0, i]) - end - end - - def children - entries[2..-1] - end - - def cleanpath! - parts = to_a - final = [] - - parts.each do |part| - case part - when DOT then - next - when DOT_DOT then - case final.last - when ROOT then - next - when DOT_DOT then - final.push(DOT_DOT) - when nil then - final.push(DOT_DOT) - else - final.pop - end - else - final.push(part) - end - end - - replace(final.empty? ? DOT : self.class.join(*final)) - end - - def cleanpath - dup.cleanpath! - end - - def descend - parts = to_a - 1.upto(parts.length) { |i| yield self.class.join(parts[0, i]) } - end - - def dot? - self == DOT - end - - def dot_dot? - self == DOT_DOT - end - - def each_filename(&blk) - to_a.each(&blk) - end - - def mountpoint? - stat1 = self.lstat - stat2 = self.parent.lstat - - stat1.dev != stat2.dev || stat1.ino == stat2.ino - rescue Errno::ENOENT - false - end - - def parent - self + '..' - end - - def realpath - path = self - - SYMLOOP_MAX.times do - link = path.readlink - link = path.dirname + link if link.relative? - path = link - end - - raise Errno::ELOOP, self - rescue Errno::EINVAL - path.expand_path - end - - def relative? - !absolute? - end - - def relative_path_from(base) - base = self.class.for(base) - - raise ArgumentError, 'no relative path between a relative and absolute' if self.absolute? != base.absolute? - - return self if base.dot? - return self.class.new(DOT) if self == base - - base = base.cleanpath.to_a - dest = self.cleanpath.to_a - - while !dest.empty? && !base.empty? && dest[0] == base[0] - base.shift - dest.shift - end - - base.shift if base[0] == DOT - dest.shift if dest[0] == DOT - - raise ArgumentError, "base directory may not contain '#{DOT_DOT}'" if base.include?(DOT_DOT) - - path = base.fill(DOT_DOT) + dest - path = self.class.join(*path) - path = self.class.new(DOT) if path.empty? - - path - end - - def root? - !!(self =~ %r{^#{ROOT}+$}) - end - - def to_a - array = to_s.split(File::SEPARATOR) - array.delete('') - array.insert(0, ROOT) if absolute? - array - end - - alias segments to_a - - def to_path - self - end - - def to_s - "#{self}" - end - - alias to_str to_s - - def unlink - Dir.unlink(self) - true - rescue Errno::ENOTDIR - File.unlink(self) - true - end - end - - class Pathname - def self.[](pattern) - Dir[pattern].map! {|d| FSSM::Pathname.new(d) } - end - - def self.pwd - FSSM::Pathname.new(Dir.pwd) - end - - def entries - Dir.entries(self).map! {|e| FSSM::Pathname.new(e) } - end - - def mkdir(mode = 0777) - Dir.mkdir(self, mode) - end - - def opendir(&blk) - Dir.open(self, &blk) - end - - def rmdir - Dir.rmdir(self) - end - - def self.glob(pattern, flags = 0) - dirs = Dir.glob(pattern, flags) - dirs.map! {|path| FSSM::Pathname.new(path) } - - if block_given? - dirs.each {|dir| yield dir } - nil - else - dirs - end - end - - def glob(pattern, flags = 0, &block) - patterns = [pattern].flatten - patterns.map! {|p| self.class.glob(self.to_s + p, flags, &block) } - patterns.flatten - end - - def chdir - blk = lambda { yield self } if block_given? - Dir.chdir(self, &blk) - end - end - - class Pathname - def blockdev? - FileTest.blockdev?(self) - end - - def chardev? - FileTest.chardev?(self) - end - - def directory? - FileTest.directory?(self) - end - - def executable? - FileTest.executable?(self) - end - - def executable_real? - FileTest.executable_real?(self) - end - - def exists? - FileTest.exists?(self) - end - - def file? - FileTest.file?(self) - end - - def grpowned? - FileTest.grpowned?(self) - end - - def owned? - FileTest.owned?(self) - end - - def pipe? - FileTest.pipe?(self) - end - - def readable? - FileTest.readable?(self) - end - - def readable_real? - FileTest.readable_real?(self) - end - - def setgid? - FileTest.setgit?(self) - end - - def setuid? - FileTest.setuid?(self) - end - - def socket? - FileTest.socket?(self) - end - - def sticky? - FileTest.sticky?(self) - end - - def symlink? - FileTest.symlink?(self) - end - - def world_readable? - FileTest.world_readable?(self) - end - - def world_writable? - FileTest.world_writable?(self) - end - - def writable? - FileTest.writable?(self) - end - - def writable_real? - FileTest.writable_real?(self) - end - - def zero? - FileTest.zero?(self) - end - end - - class Pathname - def atime - File.atime(self) - end - - def ctime - File.ctime(self) - end - - def ftype - File.ftype(self) - end - - def lstat - File.lstat(self) - end - - def mtime - File.mtime(self) - end - - def stat - File.stat(self) - end - - def utime(atime, mtime) - File.utime(self, atime, mtime) - end - end - - class Pathname - def self.join(*parts) - last_part = FSSM::Pathname.new(parts.last) - return last_part if last_part.absolute? - FSSM::Pathname.new(File.join(*parts.reject {|p| p.empty? })) - end - - def basename - self.class.new(File.basename(self)) - end - - def chmod(mode) - File.chmod(mode, self) - end - - def chown(owner, group) - File.chown(owner, group, self) - end - - def dirname - self.class.new(File.dirname(self)) - end - - def expand_path(from = nil) - self.class.new(File.expand_path(self, from)) - end - - def extname - File.extname(self) - end - - def fnmatch?(pat, flags = 0) - File.fnmatch(pat, self, flags) - end - - def join(*parts) - self.class.join(self, *parts) - end - - def lchmod(mode) - File.lchmod(mode, self) - end - - def lchown(owner, group) - File.lchown(owner, group, self) - end - - def link(to) - File.link(self, to) - end - - def open(mode = 'r', perm = nil, &blk) - File.open(self, mode, perm, &blk) - end - - def readlink - self.class.new(File.readlink(self)) - end - - def rename(to) - File.rename(self, to) - replace(to) - end - - def size - File.size(self) - end - - def size? - File.size?(self) - end - - def split - File.split(self).map {|part| FSSM::Pathname.new(part) } - end - - def symlink(to) - File.symlink(self, to) - end - - def truncate - File.truncate(self) - end - end - - class Pathname - def mkpath - self.class.new(FileUtils.mkpath(self)) - end - - def rmtree - self.class.new(FileUtils.rmtree(self).first) - end - - def touch - self.class.new(FileUtils.touch(self).first) - end - end - - class Pathname - def each_line(sep = $/, &blk) - IO.foreach(self, sep, &blk) - end - - def read(len = nil, off = 0) - IO.read(self, len, off) - end - - def readlines(sep = $/) - IO.readlines(self, sep) - end - - def sysopen(mode = 'r', perm = nil) - IO.sysopen(self, mode, perm) - end - end - - class Pathname - def find - Find.find(self) {|path| yield FSSM::Pathname.new(path) } - end - end - - class Pathname - class << self - alias getwd pwd - end - - alias absolute expand_path - alias delete unlink - alias exist? exists? - alias fnmatch fnmatch? - end -end diff --git a/lib/vendor/fssm/fssm/state/directory.rb b/lib/vendor/fssm/fssm/state/directory.rb deleted file mode 100644 index de701e6a..00000000 --- a/lib/vendor/fssm/fssm/state/directory.rb +++ /dev/null @@ -1,57 +0,0 @@ -module FSSM::State - class Directory - attr_reader :path - - def initialize(path) - @path = path - @cache = FSSM::Tree::Cache.new - end - - def refresh(base=nil, skip_callbacks=false) - previous, current = recache(base || @path.to_pathname) - - unless skip_callbacks - deleted(previous, current) - created(previous, current) - modified(previous, current) - end - end - - private - - def created(previous, current) - (current.keys - previous.keys).each {|created| @path.create(created)} - end - - def deleted(previous, current) - (previous.keys - current.keys).each {|deleted| @path.delete(deleted)} - end - - def modified(previous, current) - (current.keys & previous.keys).each do |file| - @path.update(file) if (current[file] <=> previous[file]) != 0 - end - end - - def recache(base) - base = FSSM::Pathname.for(base) - previous = @cache.files - snapshot(base) - current = @cache.files - [previous, current] - end - - def snapshot(base) - base = FSSM::Pathname.for(base) - @cache.unset(base) - @path.glob.each {|glob| add_glob(base, glob)} - end - - def add_glob(base, glob) - FSSM::Pathname.glob(base.join(glob).to_s).each do |fn| - @cache.set(fn) - end - end - - end -end diff --git a/lib/vendor/fssm/fssm/state/file.rb b/lib/vendor/fssm/fssm/state/file.rb deleted file mode 100644 index ec601f81..00000000 --- a/lib/vendor/fssm/fssm/state/file.rb +++ /dev/null @@ -1,24 +0,0 @@ -module FSSM::State - class File - attr_reader :path - - def initialize(path) - @path = path - end - - def refresh(base=nil, skip_callbacks=false) - base ||= @path.to_pathname - used_to_exist, @exists = @exists, base.exists? - # this handles bad symlinks without failing. why handle bad symlinks at - # all? well, we could still be interested in their creation and deletion. - old_mtime, @mtime = @mtime, base.symlink? ? Time.at(0) : base.mtime if @exists - - unless skip_callbacks - @path.delete(@path.to_s) if used_to_exist && !@exists - @path.create(@path.to_s) if !used_to_exist && @exists - @path.update(@path.to_s) if used_to_exist && @exists && old_mtime != @mtime - end - end - - end -end diff --git a/lib/vendor/fssm/fssm/support.rb b/lib/vendor/fssm/fssm/support.rb deleted file mode 100644 index e70e793b..00000000 --- a/lib/vendor/fssm/fssm/support.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'rbconfig' - -module FSSM::Support - class << self - def backend - @@backend ||= case - when mac? && !jruby? && carbon_core? - 'FSEvents' - when linux? && rb_inotify? - 'Inotify' - else - 'Polling' - end - end - - def jruby? - defined?(JRUBY_VERSION) - end - - def mac? - Config::CONFIG['target_os'] =~ /darwin/i - end - - def linux? - Config::CONFIG['target_os'] =~ /linux/i - end - - def carbon_core? - begin - require 'osx/foundation' - OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework' - true - rescue LoadError - STDERR.puts("Warning: Unable to load CarbonCore. FSEvents will be unavailable.") - false - end - end - - def rb_inotify? - found = begin - require 'rb-inotify' - if defined?(INotify::VERSION) - version = INotify::VERSION - version[0] > 0 || version[1] >= 6 - end - rescue LoadError - false - end - STDERR.puts("Warning: Unable to load rb-inotify >= 0.5.1. Inotify will be unavailable.") unless found - found - end - - def use_block(context, block) - return if block.nil? - if block.arity == 1 - block.call(context) - else - context.instance_eval(&block) - end - end - - end -end diff --git a/lib/vendor/fssm/fssm/tree.rb b/lib/vendor/fssm/fssm/tree.rb deleted file mode 100644 index 25b17be1..00000000 --- a/lib/vendor/fssm/fssm/tree.rb +++ /dev/null @@ -1,176 +0,0 @@ -module FSSM::Tree - module NodeBase - def initialize - @children = {} - end - - protected - - def child(segment) - @children["#{segment}"] - end - - def child!(segment) - (@children["#{segment}"] ||= Node.new) - end - - def has_child?(segment) - @children.has_key?("#{segment}") - end - - def remove_child(segment) - @children.delete("#{segment}") - end - - def remove_children - @children.clear - end - end - - module NodeEnumerable - include NodeBase - include Enumerable - - def each(prefix=nil, &block) - @children.each do |segment, node| - cprefix = prefix ? - FSSM::Pathname.for(prefix).join(segment) : - FSSM::Pathname.for(segment) - block.call([cprefix, node]) - node.each(cprefix, &block) - end - end - end - - module NodeInsertion - include NodeBase - - def unset(path) - key = key_segments(path) - - if key.empty? - remove_children - return nil - end - - segment = key.pop - node = descendant(key) - - return unless node - - node.remove_child(segment) - - nil - end - - def set(path) - node = descendant!(path) - node.from_path(path).mtime - end - - protected - - def key_segments(key) - return key if key.is_a?(Array) - FSSM::Pathname.for(key).segments - end - - def descendant(path) - recurse(path, false) - end - - def descendant!(path) - recurse(path, true) - end - - def recurse(key, create=false) - key = key_segments(key) - node = self - - until key.empty? - segment = key.shift - node = create ? node.child!(segment) : node.child(segment) - return nil unless node - end - - node - end - end - - module CacheDebug - def set(path) - FSSM.dbg("Cache#set(#{path})") - super - end - - def unset(path) - FSSM.dbg("Cache#unset(#{path})") - super - end - - def ftype(ft) - FSSM.dbg("Cache#ftype(#{ft})") - super - end - end - - class Node - include NodeBase - include NodeEnumerable - - attr_accessor :mtime - attr_accessor :ftype - - def <=>(other) - return unless other.is_a?(::FSSM::Tree::Node) - self.mtime <=> other.mtime - end - - def from_path(path) - path = FSSM::Pathname.for(path) - @ftype = path.ftype - # this handles bad symlinks without failing. why handle bad symlinks at - # all? well, we could still be interested in their creation and deletion. - @mtime = path.symlink? ? Time.at(0) : path.mtime - self - end - end - - class Cache - include NodeBase - include NodeEnumerable - include NodeInsertion - include CacheDebug if $DEBUG - - def set(path) - # all paths set from this level need to be absolute - # realpath will fail on broken links - path = FSSM::Pathname.for(path).expand_path - super(path) - end - - def files - ftype('file') - end - - def directories - ftype('directory') - end - - def links - ftype('link') - end - - alias symlinks links - - private - - def ftype(ft) - inject({}) do |hash, (path, node)| - hash["#{path}"] = node.mtime if node.ftype == ft - hash - end - end - end - -end