Permalink
Browse files

minor changes that attempt to make backends a little more flexible

1) autoload code as needed
2) wait until the last possible moment to define FSSM::Backends::Default
3) provide set_backend(symbol, value) to make it easier to opt out and use polling, as well as plug in your own custom backend or backend handling logic
4) handling of platform specific dependencies via spec.extensions + rake

I'm not completely convinced on point number four. Though, if gem install option args get passed to rake along the way, it'd be a non-issue to have it do nothing by default and only install/update backend support if asked.
  • Loading branch information...
1 parent 1a7bada commit 648d772ee3527e56b25b96c24b8c5d4998466f9d @ttilley committed Dec 2, 2011
Showing with 91 additions and 42 deletions.
  1. +14 −0 ext/rakefile.rb
  2. +3 −0 fssm.gemspec
  3. +56 −19 lib/fssm.rb
  4. +17 −22 lib/fssm/support.rb
  5. +1 −1 lib/fssm/version.rb
View
@@ -0,0 +1,14 @@
+# -*- encoding: utf-8 -*-
+$LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
+
+require 'rubygems/dependency_installer'
+require 'fssm'
+
+# semi-elegant solution or hack? *shrug*
+task :default do
+ name, version = FSSM::Support.optimal_backend_dependency
+ if name and version
+ installer = Gem::DependencyInstaller.new({:domain => :both, :env_shebang => true})
+ installer.install name, version
+ end
+end
View
@@ -19,6 +19,9 @@ Gem::Specification.new do |s|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
s.require_paths = ["lib"]
+
+ s.extensions = 'ext/rakefile.rb'
+ s.add_development_dependency "rake"
s.add_development_dependency "rspec", ">= 2.4.0"
end
View
@@ -1,12 +1,62 @@
dir = File.dirname(__FILE__)
$LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
-#noinspection ALL
-module FSSM
- FileNotFoundError = Class.new(StandardError)
- FileNotRealError = Class.new(StandardError)
- CallbackError = Class.new(StandardError)
+require 'thread'
+module FSSM
+
+ FSSMError = Class.new(StandardError)
+ FileNotFoundError = Class.new(FSSMError)
+ FileNotRealError = Class.new(FSSMError)
+ CallbackError = Class.new(FSSMError)
+
+ autoload :VERSION, 'fssm/version'
+ autoload :Pathname, 'fssm/pathname'
+ autoload :Support, 'fssm/support'
+ autoload :Tree, 'fssm/tree'
+ autoload :Path, 'fssm/path'
+ autoload :Monitor, 'fssm/monitor'
+
+ module State
+ autoload :Directory, 'fssm/state/directory'
+ autoload :File, 'fssm/state/file'
+ end
+
+ module Backends
+ autoload :Polling, 'fssm/backends/polling'
+ autoload :FSEvents, 'fssm/backends/fsevents'
+ autoload :RBFSEvent, 'fssm/backends/rbfsevent'
+ autoload :Inotify, 'fssm/backends/inotify'
+
+ class << self
+ def set_backend(const_symbol=nil, value=nil)
+ const_symbol ||= :Default
+ value ||= ::FSSM::Support.backend
+
+ if (value.is_a?(Symbol) || value.is_a?(String))
+ unless const_defined?(value)
+ raise NameError,
+ "uninitialized constant FSSM::Backends::#{value}"
+ end
+ value = const_get(value)
+ end
+
+ unless value.is_a?(Class)
+ raise ArgumentError,
+ "value must be a class or the symbol of an existing backend"
+ end
+
+ remove_const(const_symbol) if const_defined?(const_symbol)
+ const_set(const_symbol, value)
+ end
+
+ def const_missing(symbol)
+ symbol == :Default ? set_backend(symbol, FSSM::Support.backend) : super
+ end
+
+ end
+ end
+
class << self
def dbg(msg=nil)
STDERR.puts("FSSM -> #{msg}")
@@ -20,18 +70,5 @@ def monitor(*args, &block)
monitor.run
end
end
+
end
-
-require 'thread'
-
-require 'fssm/version'
-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)
View
@@ -3,29 +3,24 @@
module FSSM::Support
class << self
def usable_backend
- choice = case
- when mac? && !lion? && !jruby? && carbon_core?
- 'FSEvents'
- when mac? && rb_fsevent?
- 'RBFSEvent'
- when linux? && rb_inotify?
- 'Inotify'
- else
- 'Polling'
- end
-
- if (mac? || linux?) && choice == 'Polling'
- optimal = case
- when mac?
- 'rb-fsevent'
- when linux?
- 'rb-inotify'
- end
- FSSM.dbg("An optimized backend is available for this platform!")
- FSSM.dbg(" gem install #{optimal}")
+ case
+ when mac? && !lion? && !jruby? && carbon_core?
+ 'FSEvents'
+ when mac? && rb_fsevent?
+ 'RBFSEvent'
+ when linux? && rb_inotify?
+ 'Inotify'
+ else
+ 'Polling'
+ end
+ end
+
+ def optimal_backend_dependency
+ return case
+ when mac? then ['rb-fsevent', '>= 0.4.3.1']
+ when linux? then ['rb-inotify', '>= 0.8.8']
+ else [nil, nil]
end
-
- choice
end
def backend
View
@@ -1,3 +1,3 @@
module FSSM
- VERSION = "0.2.7"
+ VERSION = "0.2.8"
end

0 comments on commit 648d772

Please sign in to comment.