Module: Bunto::Watcher

Extended by:
Watcher
Included in:
Watcher
Defined in:
lib/bunto/watcher.rb

Instance Method Summary collapse

Instance Method Details

#build_listener(site, options) ⇒ Object

TODO: shouldn’t be public API



42
43
44
45
46
47
48
49
# File 'lib/bunto/watcher.rb', line 42

def build_listener(site, options)
  Listen.to(
    options['source'],
    :ignore => listen_ignore_paths(options),
    :force_polling => options['force_polling'],
    &(listen_handler(site))
  )
end

#config_files(options) ⇒ Object



73
74
75
76
77
# File 'lib/bunto/watcher.rb', line 73

def config_files(options)
  %w(yml yaml toml).map do |ext|
    Bunto.sanitized_path(options['source'], "_config.#{ext}")
  end
end

#custom_excludes(options) ⇒ Object



69
70
71
# File 'lib/bunto/watcher.rb', line 69

def custom_excludes(options)
  Array(options['exclude']).map { |e| Bunto.sanitized_path(options['source'], e) }
end

#listen_handler(site) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/bunto/watcher.rb', line 51

def listen_handler(site)
  proc do |modified, added, removed|
    t = Time.now
    c = modified + added + removed
    n = c.length
    print Bunto.logger.message("Regenerating:",
      "#{n} file(s) changed at #{t.strftime("%Y-%m-%d %H:%M:%S")} ")
    begin
      site.process
      puts "...done in #{Time.now - t} seconds."
    rescue => e
      puts "...error:"
      Bunto.logger.warn "Error:", e.message
      Bunto.logger.warn "Error:", "Run bunto build --trace for more information."
    end
  end
end

#listen_ignore_paths(options) ⇒ Object

Paths to ignore for the watch option

options - A Hash of options passed to the command

Returns a list of relative paths from source that should be ignored



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/bunto/watcher.rb', line 92

def listen_ignore_paths(options)
  source       = Pathname.new(options['source']).expand_path
  paths        = to_exclude(options)

  paths.map do |p|
    absolute_path = Pathname.new(p).expand_path
    next unless absolute_path.exist?
    begin
      relative_path = absolute_path.relative_path_from(source).to_s
      unless relative_path.start_with?('../')
        path_to_ignore = Regexp.new(Regexp.escape(relative_path))
        Bunto.logger.debug "Watcher:", "Ignoring #{path_to_ignore}"
        path_to_ignore
      end
    rescue ArgumentError
      # Could not find a relative path
    end
  end.compact + [/\.bunto\-metadata/]
end

#sleep_foreverObject



112
113
114
# File 'lib/bunto/watcher.rb', line 112

def sleep_forever
  loop { sleep 1000 }
end

#to_exclude(options) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/bunto/watcher.rb', line 79

def to_exclude(options)
  [
    config_files(options),
    options['destination'],
    custom_excludes(options)
  ].flatten
end

#watch(options, site = nil) ⇒ Object

Public: Continuously watch for file changes and rebuild the site whenever a change is detected.

If the optional site argument is populated, that site instance will be reused and the options Hash ignored. Otherwise, a new site instance will be instantiated from the options Hash and used.

options - A Hash containing the site configuration site - The current site instance (populated starting with Bunto 3.2)

(optional, default: nil)

Returns nothing.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/bunto/watcher.rb', line 19

def watch(options, site = nil)
  ENV["LISTEN_GEM_DEBUGGING"] ||= "1" if options['verbose']

  site ||= Bunto::Site.new(options)
  listener = build_listener(site, options)
  listener.start

  Bunto.logger.info "Auto-regeneration:", "enabled for '#{options["source"]}'"

  unless options['serving']
    trap("INT") do
      listener.stop
      puts "     Halting auto-regeneration."
      exit 0
    end

    sleep_forever
  end
rescue ThreadError
  # You pressed Ctrl-C, oh my!
end