Upgrade the vendored version of FSSM to 0.1.0, this fixes some bugs with jruby and adds inotify support for linux.
This commit is contained in:
parent
6d6e1ca0e3
commit
8006c7854c
3
lib/vendor/fssm.rb
vendored
3
lib/vendor/fssm.rb
vendored
@ -28,9 +28,8 @@ module FSSM
|
|||||||
end
|
end
|
||||||
|
|
||||||
require 'thread'
|
require 'thread'
|
||||||
require 'pathname'
|
|
||||||
|
|
||||||
require 'fssm/ext'
|
require 'fssm/pathname'
|
||||||
require 'fssm/support'
|
require 'fssm/support'
|
||||||
require 'fssm/tree'
|
require 'fssm/tree'
|
||||||
require 'fssm/path'
|
require 'fssm/path'
|
||||||
|
2
lib/vendor/fssm/backends/fsevents.rb
vendored
2
lib/vendor/fssm/backends/fsevents.rb
vendored
@ -1,4 +1,4 @@
|
|||||||
require 'fssm/fsevents'
|
require File.join(File.dirname(__FILE__), 'rubycocoa/fsevents')
|
||||||
|
|
||||||
module FSSM::Backends
|
module FSSM::Backends
|
||||||
class FSEvents
|
class FSEvents
|
||||||
|
25
lib/vendor/fssm/backends/inotify.rb
vendored
Normal file
25
lib/vendor/fssm/backends/inotify.rb
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
module FSSM::Backends
|
||||||
|
class Inotify
|
||||||
|
def initialize
|
||||||
|
@notifier = INotify::Notifier.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_path(path, preload=true)
|
||||||
|
handler = FSSM::State.new(path)
|
||||||
|
|
||||||
|
@notifier.watch(path.to_s, :all_events) do |event|
|
||||||
|
handler.refresh(event.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
handler.refresh(path.to_pathname, true) if preload
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
begin
|
||||||
|
@notifier.run
|
||||||
|
rescue Interrupt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
4
lib/vendor/fssm/backends/polling.rb
vendored
4
lib/vendor/fssm/backends/polling.rb
vendored
@ -1,8 +1,8 @@
|
|||||||
module FSSM::Backends
|
module FSSM::Backends
|
||||||
class Polling
|
class Polling
|
||||||
def initialize(options={})
|
def initialize(options={})
|
||||||
@handlers = []
|
@handlers = []
|
||||||
@latency = options[:latency] || 1
|
@latency = options[:latency] || 1.5
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_path(path, preload=true)
|
def add_path(path, preload=true)
|
||||||
|
@ -6,6 +6,7 @@ module Rucola
|
|||||||
attr_reader :fsevents_object
|
attr_reader :fsevents_object
|
||||||
attr_reader :id
|
attr_reader :id
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
def initialize(fsevents_object, id, path)
|
def initialize(fsevents_object, id, path)
|
||||||
@fsevents_object, @id, @path = fsevents_object, id, path
|
@fsevents_object, @id, @path = fsevents_object, id, path
|
||||||
end
|
end
|
||||||
@ -22,7 +23,8 @@ module Rucola
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class StreamError < StandardError; end
|
class StreamError < StandardError;
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :paths
|
attr_reader :paths
|
||||||
attr_reader :stream
|
attr_reader :stream
|
||||||
@ -91,11 +93,11 @@ module Rucola
|
|||||||
paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
|
paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
|
||||||
|
|
||||||
@allocator = options[:allocator] || OSX::KCFAllocatorDefault
|
@allocator = options[:allocator] || OSX::KCFAllocatorDefault
|
||||||
@context = options[:context] || nil
|
@context = options[:context] || nil
|
||||||
@since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
|
@since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
|
||||||
@latency = options[:latency] || 0.0
|
@latency = options[:latency] || 0.0
|
||||||
@flags = options[:flags] || 0
|
@flags = options[:flags] || 0
|
||||||
@stream = options[:stream] || nil
|
@stream = options[:stream] || nil
|
||||||
|
|
||||||
@user_callback = block
|
@user_callback = block
|
||||||
@callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
|
@callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
|
193
lib/vendor/fssm/cache.rb
vendored
193
lib/vendor/fssm/cache.rb
vendored
@ -1,193 +0,0 @@
|
|||||||
class FSSM::Cache
|
|
||||||
module Common
|
|
||||||
include Enumerable
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@children = Hash.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def each(prefix='./', &block)
|
|
||||||
@children.each do |segment, node|
|
|
||||||
cprefix = Pathname.for(prefix.dup).join(segment)
|
|
||||||
block.call(cprefix, node)
|
|
||||||
node.each(cprefix, &block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def with_lock
|
|
||||||
@mutex.lock
|
|
||||||
yield
|
|
||||||
@mutex.unlock
|
|
||||||
end
|
|
||||||
|
|
||||||
def descendant(path)
|
|
||||||
recurse_on_key(path, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
def descendant!(path)
|
|
||||||
recurse_on_key(path, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def child(segment)
|
|
||||||
has_child?(segment) ? @children["#{segment}"] : nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def child!(segment)
|
|
||||||
(@children["#{segment}"] ||= Node.new)
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_child?(segment)
|
|
||||||
@children.include?("#{segment}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_child(segment)
|
|
||||||
@children.delete("#{segment}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_children
|
|
||||||
@children.clear
|
|
||||||
end
|
|
||||||
|
|
||||||
def recurse_on_key(key, create)
|
|
||||||
key = sanitize_key(key)
|
|
||||||
node = self
|
|
||||||
|
|
||||||
until key.empty?
|
|
||||||
segment = key.shift
|
|
||||||
node = create ? node.child!(segment) : node.child(segment)
|
|
||||||
return nil unless node
|
|
||||||
end
|
|
||||||
|
|
||||||
node
|
|
||||||
end
|
|
||||||
|
|
||||||
def key_for_path(path)
|
|
||||||
Pathname.for(path).names
|
|
||||||
end
|
|
||||||
|
|
||||||
def relative_path(path)
|
|
||||||
sanitize_path(path, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
def absolute_path(path)
|
|
||||||
sanitize_path(path, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sanitize_path(path, absolute)
|
|
||||||
if path.is_a?(Array)
|
|
||||||
first = absolute ? '/' : path.shift
|
|
||||||
path = path.inject(Pathname.new("#{first}")) do |pathname, segment|
|
|
||||||
pathname.join("#{segment}")
|
|
||||||
end
|
|
||||||
path
|
|
||||||
else
|
|
||||||
path = Pathname.for(path)
|
|
||||||
absolute ? path.expand_path : path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Node
|
|
||||||
include Common
|
|
||||||
|
|
||||||
attr_accessor :mtime
|
|
||||||
attr_accessor :ftype
|
|
||||||
|
|
||||||
def <=>(other)
|
|
||||||
self.mtime <=> other.mtime
|
|
||||||
end
|
|
||||||
|
|
||||||
def from_path(path)
|
|
||||||
path = absolute_path(path)
|
|
||||||
@mtime = path.mtime
|
|
||||||
@ftype = path.ftype
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def sanitize_key(key)
|
|
||||||
key_for_path(relative_path(key))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
include Common
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@mutex = Mutex.new
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear
|
|
||||||
@mutex.lock
|
|
||||||
@children.clear
|
|
||||||
@mutex.unlock
|
|
||||||
end
|
|
||||||
|
|
||||||
def set(path)
|
|
||||||
unset(path)
|
|
||||||
node = descendant!(path)
|
|
||||||
node.from_path(path)
|
|
||||||
node.mtime
|
|
||||||
end
|
|
||||||
|
|
||||||
def unset(path='/')
|
|
||||||
key = sanitize_key(path)
|
|
||||||
|
|
||||||
if key.empty?
|
|
||||||
self.clear
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
segment = key.pop
|
|
||||||
node = descendant(key)
|
|
||||||
|
|
||||||
return unless node
|
|
||||||
|
|
||||||
@mutex.lock
|
|
||||||
node.remove_child(segment)
|
|
||||||
@mutex.unlock
|
|
||||||
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def files
|
|
||||||
ftype('file')
|
|
||||||
end
|
|
||||||
|
|
||||||
def directories
|
|
||||||
ftype('directory')
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def each(&block)
|
|
||||||
prefix='/'
|
|
||||||
super(prefix, &block)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ftype(ft)
|
|
||||||
inject({}) do |hash, entry|
|
|
||||||
path, node = entry
|
|
||||||
hash["#{path}"] = node.mtime if node.ftype == ft
|
|
||||||
hash
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def descendant(path)
|
|
||||||
node = recurse_on_key(path, false)
|
|
||||||
node
|
|
||||||
end
|
|
||||||
|
|
||||||
def descendant!(path)
|
|
||||||
@mutex.lock
|
|
||||||
node = recurse_on_key(path, true)
|
|
||||||
@mutex.unlock
|
|
||||||
node
|
|
||||||
end
|
|
||||||
|
|
||||||
def sanitize_key(key)
|
|
||||||
key_for_path(absolute_path(key))
|
|
||||||
end
|
|
||||||
end
|
|
37
lib/vendor/fssm/ext.rb
vendored
37
lib/vendor/fssm/ext.rb
vendored
@ -1,37 +0,0 @@
|
|||||||
class Pathname
|
|
||||||
class << self
|
|
||||||
def for(path)
|
|
||||||
path.is_a?(Pathname) ? path : new(path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# before overwriting chop_basename:
|
|
||||||
# %total - 29.50%
|
|
||||||
# %self - 20.50%
|
|
||||||
# after overwriting chop_basename:
|
|
||||||
# %total - 24.36%
|
|
||||||
# %self - 15.47%
|
|
||||||
CHOP_PAT = /\A#{SEPARATOR_PAT}?\z/
|
|
||||||
def chop_basename(path)
|
|
||||||
base = File.basename(path)
|
|
||||||
# the original version of this method recalculates this regexp
|
|
||||||
# each run, despite the pattern never changing.
|
|
||||||
if CHOP_PAT =~ base
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
return path[0, path.rindex(base)], base
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def segments
|
|
||||||
prefix, names = split_names(@path)
|
|
||||||
names.unshift(prefix) unless prefix.empty?
|
|
||||||
names.shift if names[0] == '.'
|
|
||||||
names
|
|
||||||
end
|
|
||||||
|
|
||||||
def names
|
|
||||||
prefix, names = split_names(@path)
|
|
||||||
names
|
|
||||||
end
|
|
||||||
end
|
|
6
lib/vendor/fssm/path.rb
vendored
6
lib/vendor/fssm/path.rb
vendored
@ -75,14 +75,14 @@ class FSSM::Path
|
|||||||
end
|
end
|
||||||
|
|
||||||
def split_path(path)
|
def split_path(path)
|
||||||
path = Pathname.for(path)
|
path = FSSM::Pathname.for(path)
|
||||||
[@path, (path.relative? ? path : path.relative_path_from(@path))]
|
[@path, (path.relative? ? path : path.relative_path_from(@path))]
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_path(path)
|
def set_path(path)
|
||||||
path = Pathname.for(path)
|
path = FSSM::Pathname.for(path)
|
||||||
raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
|
raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
|
||||||
@path = path.realpath
|
@path = path.expand_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_glob(glob)
|
def set_glob(glob)
|
||||||
|
528
lib/vendor/fssm/pathname.rb
vendored
Normal file
528
lib/vendor/fssm/pathname.rb
vendored
Normal file
@ -0,0 +1,528 @@
|
|||||||
|
# The bundled ruby pathname library is a slow and hideous beast.
|
||||||
|
# There. I said it. This version is based on pathname3.
|
||||||
|
|
||||||
|
module FSSM
|
||||||
|
class Pathname < String
|
||||||
|
|
||||||
|
SEPARATOR = Regexp.quote(File::SEPARATOR)
|
||||||
|
|
||||||
|
if File::ALT_SEPARATOR
|
||||||
|
ALT_SEPARATOR = Regexp.quote(File::ALT_SEPARATOR)
|
||||||
|
SEPARATOR_PAT = Regexp.compile("[#{SEPARATOR}#{ALT_SEPARATOR}]")
|
||||||
|
else
|
||||||
|
SEPARATOR_PAT = Regexp.compile(SEPARATOR)
|
||||||
|
end
|
||||||
|
|
||||||
|
if RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
|
||||||
|
PREFIX_PAT = Regexp.compile("^([A-Za-z]:#{SEPARATOR_PAT})")
|
||||||
|
else
|
||||||
|
PREFIX_PAT = Regexp.compile("^(#{SEPARATOR_PAT})")
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def for(path)
|
||||||
|
path = path.is_a?(::FSSM::Pathname) ? path : new(path)
|
||||||
|
path.dememo
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(path)
|
||||||
|
if path =~ %r{\0}
|
||||||
|
raise ArgumentError, "path cannot contain ASCII NULLs"
|
||||||
|
end
|
||||||
|
|
||||||
|
dememo
|
||||||
|
|
||||||
|
super(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_path
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{self}"
|
||||||
|
end
|
||||||
|
|
||||||
|
alias to_str to_s
|
||||||
|
|
||||||
|
def to_a
|
||||||
|
return @segments if @segments
|
||||||
|
set_prefix_and_names
|
||||||
|
@segments = @names.dup
|
||||||
|
@segments.delete('.')
|
||||||
|
@segments.unshift(@prefix) unless @prefix.empty?
|
||||||
|
@segments
|
||||||
|
end
|
||||||
|
|
||||||
|
alias segments to_a
|
||||||
|
|
||||||
|
def each_filename(&block)
|
||||||
|
to_a.each(&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ascend
|
||||||
|
parts = to_a
|
||||||
|
parts.length.downto(1) do |i|
|
||||||
|
yield self.class.join(parts[0, i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def descend
|
||||||
|
parts = to_a
|
||||||
|
1.upto(parts.length) do |i|
|
||||||
|
yield self.class.join(parts[0, i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def root?
|
||||||
|
set_prefix_and_names
|
||||||
|
@names.empty? && !@prefix.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def parent
|
||||||
|
self + '..'
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative?
|
||||||
|
set_prefix_and_names
|
||||||
|
@prefix.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def absolute?
|
||||||
|
!relative?
|
||||||
|
end
|
||||||
|
|
||||||
|
def +(path)
|
||||||
|
dup << path
|
||||||
|
end
|
||||||
|
|
||||||
|
def <<(path)
|
||||||
|
replace(join(path).cleanpath!)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cleanpath!
|
||||||
|
parts = to_a
|
||||||
|
final = []
|
||||||
|
|
||||||
|
parts.each do |part|
|
||||||
|
case part
|
||||||
|
when '.' then
|
||||||
|
next
|
||||||
|
when '..' then
|
||||||
|
case final.last
|
||||||
|
when '..' then
|
||||||
|
final.push('..')
|
||||||
|
when nil then
|
||||||
|
final.push('..')
|
||||||
|
else
|
||||||
|
final.pop
|
||||||
|
end
|
||||||
|
else
|
||||||
|
final.push(part)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
replace(final.empty? ? Dir.pwd : File.join(*final))
|
||||||
|
end
|
||||||
|
|
||||||
|
def cleanpath
|
||||||
|
dup.cleanpath!
|
||||||
|
end
|
||||||
|
|
||||||
|
def realpath
|
||||||
|
raise unless self.exist?
|
||||||
|
|
||||||
|
if File.symlink?(self)
|
||||||
|
file = self.dup
|
||||||
|
|
||||||
|
while true
|
||||||
|
file = File.join(File.dirname(file), File.readlink(file))
|
||||||
|
break unless File.symlink?(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.class.new(file).clean
|
||||||
|
else
|
||||||
|
self.class.new(Dir.pwd) + self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative_path_from(base)
|
||||||
|
base = self.class.for(base)
|
||||||
|
|
||||||
|
if self.absolute? != base.absolute?
|
||||||
|
raise ArgumentError, 'no relative path between a relative and absolute'
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.prefix != base.prefix
|
||||||
|
raise ArgumentError, "different prefix: #{@prefix.inspect} and #{base.prefix.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
base = base.cleanpath!.segments
|
||||||
|
dest = dup.cleanpath!.segments
|
||||||
|
|
||||||
|
while !dest.empty? && !base.empty? && dest[0] == base[0]
|
||||||
|
base.shift
|
||||||
|
dest.shift
|
||||||
|
end
|
||||||
|
|
||||||
|
base.shift if base[0] == '.'
|
||||||
|
dest.shift if dest[0] == '.'
|
||||||
|
|
||||||
|
if base.include?('..')
|
||||||
|
raise ArgumentError, "base directory may not contain '..'"
|
||||||
|
end
|
||||||
|
|
||||||
|
path = base.fill('..') + dest
|
||||||
|
path = self.class.join(*path)
|
||||||
|
path = self.class.new('.') if path.empty?
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace(path)
|
||||||
|
if path =~ %r{\0}
|
||||||
|
raise ArgumentError, "path cannot contain ASCII NULLs"
|
||||||
|
end
|
||||||
|
|
||||||
|
dememo
|
||||||
|
|
||||||
|
super(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unlink
|
||||||
|
Dir.unlink(self)
|
||||||
|
true
|
||||||
|
rescue Errno::ENOTDIR
|
||||||
|
File.unlink(self)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def prefix
|
||||||
|
set_prefix_and_names
|
||||||
|
@prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
def names
|
||||||
|
set_prefix_and_names
|
||||||
|
@names
|
||||||
|
end
|
||||||
|
|
||||||
|
def dememo
|
||||||
|
@set = nil
|
||||||
|
@segments = nil
|
||||||
|
@prefix = nil
|
||||||
|
@names = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_prefix_and_names
|
||||||
|
return if @set
|
||||||
|
|
||||||
|
@names = []
|
||||||
|
|
||||||
|
if (match = PREFIX_PAT.match(self))
|
||||||
|
@prefix = match[0].to_s
|
||||||
|
@names += match.post_match.split(SEPARATOR_PAT)
|
||||||
|
else
|
||||||
|
@prefix = ''
|
||||||
|
@names += self.split(SEPARATOR_PAT)
|
||||||
|
end
|
||||||
|
|
||||||
|
@names.compact!
|
||||||
|
@names.delete('')
|
||||||
|
|
||||||
|
@set = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class Pathname
|
||||||
|
class << self
|
||||||
|
def glob(pattern, flags=0)
|
||||||
|
dirs = Dir.glob(pattern, flags)
|
||||||
|
dirs.map! {|path| new(path)}
|
||||||
|
|
||||||
|
if block_given?
|
||||||
|
dirs.each {|dir| yield dir}
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
dirs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](pattern)
|
||||||
|
Dir[pattern].map! {|path| new(path)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def pwd
|
||||||
|
new(Dir.pwd)
|
||||||
|
end
|
||||||
|
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 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
|
||||||
|
|
||||||
|
alias exist? exists?
|
||||||
|
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
|
||||||
|
class << self
|
||||||
|
def join(*parts)
|
||||||
|
new(File.join(*parts.reject {|p| p.empty? }))
|
||||||
|
end
|
||||||
|
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 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
|
||||||
|
|
||||||
|
end
|
6
lib/vendor/fssm/state.rb
vendored
6
lib/vendor/fssm/state.rb
vendored
@ -32,7 +32,7 @@ class FSSM::State
|
|||||||
end
|
end
|
||||||
|
|
||||||
def recache(base)
|
def recache(base)
|
||||||
base = Pathname.for(base)
|
base = FSSM::Pathname.for(base)
|
||||||
previous = @cache.files
|
previous = @cache.files
|
||||||
snapshot(base)
|
snapshot(base)
|
||||||
current = @cache.files
|
current = @cache.files
|
||||||
@ -40,13 +40,13 @@ class FSSM::State
|
|||||||
end
|
end
|
||||||
|
|
||||||
def snapshot(base)
|
def snapshot(base)
|
||||||
base = Pathname.for(base)
|
base = FSSM::Pathname.for(base)
|
||||||
@cache.unset(base)
|
@cache.unset(base)
|
||||||
@path.glob.each {|glob| add_glob(base, glob)}
|
@path.glob.each {|glob| add_glob(base, glob)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_glob(base, glob)
|
def add_glob(base, glob)
|
||||||
Pathname.glob(base.join(glob).to_s).each do |fn|
|
FSSM::Pathname.glob(base.join(glob).to_s).each do |fn|
|
||||||
@cache.set(fn)
|
@cache.set(fn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
35
lib/vendor/fssm/support.rb
vendored
35
lib/vendor/fssm/support.rb
vendored
@ -1,19 +1,48 @@
|
|||||||
|
require 'rbconfig'
|
||||||
|
|
||||||
module FSSM::Support
|
module FSSM::Support
|
||||||
class << self
|
class << self
|
||||||
def backend
|
def backend
|
||||||
(mac? && carbon_core?) ? 'FSEvents' : 'Polling'
|
@@backend ||= case
|
||||||
|
when mac? && !jruby? && carbon_core?
|
||||||
|
'FSEvents'
|
||||||
|
when linux? && rb_inotify?
|
||||||
|
'Inotify'
|
||||||
|
else
|
||||||
|
'Polling'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def jruby?
|
||||||
|
defined?(JRUBY_VERSION)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mac?
|
def mac?
|
||||||
@@mac ||= RUBY_PLATFORM =~ /darwin/i
|
Config::CONFIG['target_os'] =~ /darwin/i
|
||||||
|
end
|
||||||
|
|
||||||
|
def linux?
|
||||||
|
Config::CONFIG['target_os'] =~ /linux/i
|
||||||
end
|
end
|
||||||
|
|
||||||
def carbon_core?
|
def carbon_core?
|
||||||
@@carbon_core ||= begin
|
begin
|
||||||
require 'osx/foundation'
|
require 'osx/foundation'
|
||||||
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
||||||
true
|
true
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
|
STDERR.puts("Warning: Unable to load CarbonCore. FSEvents will be unavailable.")
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rb_inotify?
|
||||||
|
begin
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rb-inotify'
|
||||||
|
true
|
||||||
|
rescue LoadError, Gem::LoadError
|
||||||
|
STDERR.puts("Warning: Unable to load rb-inotify. Inotify will be unavailable.")
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
16
lib/vendor/fssm/tree.rb
vendored
16
lib/vendor/fssm/tree.rb
vendored
@ -34,9 +34,9 @@ module FSSM::Tree
|
|||||||
def each(prefix=nil, &block)
|
def each(prefix=nil, &block)
|
||||||
@children.each do |segment, node|
|
@children.each do |segment, node|
|
||||||
cprefix = prefix ?
|
cprefix = prefix ?
|
||||||
Pathname.for(prefix).join(segment) :
|
FSSM::Pathname.for(prefix).join(segment) :
|
||||||
Pathname.for(segment)
|
FSSM::Pathname.for(segment)
|
||||||
block.call(cprefix, node)
|
block.call([cprefix, node])
|
||||||
node.each(cprefix, &block)
|
node.each(cprefix, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -72,7 +72,7 @@ module FSSM::Tree
|
|||||||
|
|
||||||
def key_segments(key)
|
def key_segments(key)
|
||||||
return key if key.is_a?(Array)
|
return key if key.is_a?(Array)
|
||||||
Pathname.for(key).segments
|
FSSM::Pathname.for(key).segments
|
||||||
end
|
end
|
||||||
|
|
||||||
def descendant(path)
|
def descendant(path)
|
||||||
@ -127,7 +127,7 @@ module FSSM::Tree
|
|||||||
end
|
end
|
||||||
|
|
||||||
def from_path(path)
|
def from_path(path)
|
||||||
path = Pathname.for(path)
|
path = FSSM::Pathname.for(path)
|
||||||
@ftype = path.ftype
|
@ftype = path.ftype
|
||||||
# this handles bad symlinks without failing. why handle bad symlinks at
|
# this handles bad symlinks without failing. why handle bad symlinks at
|
||||||
# all? well, we could still be interested in their creation and deletion.
|
# all? well, we could still be interested in their creation and deletion.
|
||||||
@ -145,7 +145,7 @@ module FSSM::Tree
|
|||||||
def set(path)
|
def set(path)
|
||||||
# all paths set from this level need to be absolute
|
# all paths set from this level need to be absolute
|
||||||
# realpath will fail on broken links
|
# realpath will fail on broken links
|
||||||
path = Pathname.for(path).expand_path
|
path = FSSM::Pathname.for(path).expand_path
|
||||||
super(path)
|
super(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -160,13 +160,13 @@ module FSSM::Tree
|
|||||||
def links
|
def links
|
||||||
ftype('link')
|
ftype('link')
|
||||||
end
|
end
|
||||||
|
|
||||||
alias symlinks links
|
alias symlinks links
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ftype(ft)
|
def ftype(ft)
|
||||||
inject({}) do |hash, entry|
|
inject({}) do |hash, (path, node)|
|
||||||
path, node = entry
|
|
||||||
hash["#{path}"] = node.mtime if node.ftype == ft
|
hash["#{path}"] = node.mtime if node.ftype == ft
|
||||||
hash
|
hash
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user