lib/nanoc/cli/commands/watch.rb in nanoc-3.4.3 vs lib/nanoc/cli/commands/watch.rb in nanoc-3.5.0b1
- old
+ new
@@ -9,25 +9,25 @@
module Nanoc::CLI::Commands
class Watch < ::Nanoc::CLI::CommandRunner
def run
- require 'fssm'
+ require 'listen'
require 'pathname'
require_site
watcher_config = self.site.config[:watcher] || {}
@notifier = Notifier.new
# Define rebuilder
- rebuilder = lambda do |base, relative|
+ rebuilder = lambda do |file_path|
# Determine filename
- if base.nil? || relative.nil?
+ if file_path.nil?
filename = nil
else
- filename = ::Pathname.new(File.join([ base, relative ])).relative_path_from(::Pathname.new(Dir.getwd)).to_s
+ filename = ::Pathname.new(file_path).relative_path_from(::Pathname.new(Dir.getwd)).to_s
end
# Notify
if filename
print "Change detected to #{filename}; recompiling… "
@@ -61,28 +61,37 @@
puts
end
end
# Rebuild once
- rebuilder.call(nil, nil)
+ rebuilder.call(nil)
# Get directories to watch
- dirs_to_watch = watcher_config[:dirs_to_watch] || %w( content layouts lib )
- files_to_watch = watcher_config[:files_to_watch] || %w( config.yaml Rules rules Rules.rb rules.rb' )
- files_to_watch.delete_if { |f| !File.file?(f) }
+ dirs_to_watch = watcher_config[:dirs_to_watch] || ['content', 'layouts', 'lib']
+ files_to_watch = watcher_config[:files_to_watch] || ['config.yaml', 'Rules', 'rules', 'Rules.rb', 'rules.rb']
+ files_to_watch = Regexp.new(files_to_watch.map { |name| "#{Regexp.quote(name)}$"}.join("|"))
+ ignore_dir = Regexp.new(Dir.glob("*").map{|dir| dir if File::ftype(dir) == "directory" }.compact.join("|"))
# Watch
puts "Watching for changes…"
- watcher = lambda do |*args|
- update(&rebuilder)
- delete(&rebuilder)
- create(&rebuilder)
- end
- monitor = FSSM::Monitor.new
- dirs_to_watch.each { |dir| monitor.path(dir, '**/*', &watcher) }
- files_to_watch.each { |filename| monitor.file(filename, &watcher) }
- monitor.run
+
+ callback = Proc.new do |modified, added, removed|
+ rebuilder.call(modified[0]) if modified[0]
+ rebuilder.call(added[0]) if added[0]
+ rebuilder.call(removed[0]) if removed[0]
+ end
+
+ listener = Listen::MultiListener.new(*dirs_to_watch).change(&callback)
+ listener_root = Listen::MultiListener.new('', :filter => files_to_watch, :ignore => ignore_dir).change(&callback)
+
+ begin
+ listener_root.start(false)
+ listener.start
+ rescue Interrupt
+ listener.stop
+ listener_root.stop
+ end
end
# Allows sending user notifications in a cross-platform way.
class Notifier
@@ -103,13 +112,22 @@
private
def tool
@tool ||= begin
- TOOLS.find { |t| !`#{FIND_BINARY_COMMAND} #{t}`.empty? }
- rescue Errno::ENOENT
- nil
+ require 'terminal-notifier'
+ 'terminal-notify'
+ rescue LoadError
+ begin
+ TOOLS.find { |t| !`#{FIND_BINARY_COMMAND} #{t}`.empty? }
+ rescue Errno::ENOENT
+ nil
+ end
end
+ end
+
+ def terminal_notify(message)
+ TerminalNotifier.notify(message, :title => "nanoc")
end
def growlnotify(message)
system('growlnotify', '-m', message)
end