Methods

Class/Module Index [+]

Quicksearch

Nanoc::CLI::Commands::Watch

Public Instance Methods

run() click to toggle source
# File lib/nanoc/cli/commands/watch.rb, line 12
def run
  require 'listen'
  require 'pathname'

  require_site
  watcher_config = self.site.config[:watcher] || {}

  @notifier = Notifier.new

  # Define rebuilder
  rebuilder = lambda do |file_path|
    # Determine filename
    if file_path.nil?
      filename = nil
    else
      filename = ::Pathname.new(file_path).relative_path_from(::Pathname.new(Dir.getwd)).to_s
    end

    # Notify
    if filename
      print "Change detected to #{filename}; recompiling… "
    else
      print "Watcher started; compiling the entire site… "
    end

    # Recompile
    start = Time.now
    site = Nanoc::Site.new('.')
    begin
      site.compile

      # TODO include icon (--image misc/success-icon.png)
      notify_on_compilation_success = watcher_config.fetch(:notify_on_compilation_success) { true }
      if notify_on_compilation_success
        @notifier.notify('Compilation complete')
      end

      time_spent = ((Time.now - start)*1000.0).round
      puts "done in #{format '%is %ims', *(time_spent.divmod(1000))}"
    rescue Exception => e
      # TODO include icon (--image misc/error-icon.png)
      notify_on_compilation_failure = watcher_config.fetch(:notify_on_compilation_failure) { true }
      if notify_on_compilation_failure
        @notifier.notify('Compilation failed')
      end

      puts
      Nanoc::CLI::ErrorHandler.print_error(e)
      puts
    end
  end

  # Rebuild once
  rebuilder.call(nil)

  # Get directories to watch
  dirs_to_watch  = watcher_config[:dirs_to_watch]  || ['content', 'layouts', 'lib']
  files_to_watch = watcher_config[:files_to_watch] || ['nanoc.yaml', '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…"

    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::Listener.new(*dirs_to_watch).change(&callback)
    listener_root = Listen::Listener.new('.', :filter => files_to_watch, :ignore => ignore_dir).change(&callback)

    begin
      listener_root.start
      listener.start!
    rescue Interrupt
      listener.stop
      listener_root.stop
    end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.