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