lib/nyara/reload.rb in nyara-0.1.pre.0 vs lib/nyara/reload.rb in nyara-0.1.pre.1

- old
+ new

@@ -1,85 +1,84 @@ require "listen" module Nyara # listen to fs events and reload code / views - # todo add to development env: require 'nyara/reload'; Reload.listen module Reload - # init, should require all files that needs to be reloaded in the given block - def self.init - @new_classes = [] - @trace_point = TracePoint.new :class do |tp| - @new_classes << tp.self.to_s.to_sym - end - @file_list = {} - @first_load = true - yield - @first_load = false - end - # NOTE file should end with '.rb' - def self.load_file file - if consts = @file_list[file] - consts.reverse_each do |const| - Object.send :remove_const, const - end - end + extend self - @trace_point.enable - old_consts = Object.send :constants - if @first_load - require file - else - if l = Nyara.logger - l.info "reloading: #{file}" + # NOTE file should end with '.rb'<br> + # returns last error + def load_file file + verbose = $VERBOSE + $VERBOSE = nil + begin + load file + @last_error = nil + rescue Exception + @last_error = $! + ensure + $VERBOSE = verbose + end + if l = Nyara.logger + if @last_error + l.error @last_error end - begin - load file - @last_error = nil - rescue Exception - @last_error = $! - end end - @trace_point.disable - added_consts = Object.send(:constants) - old_consts - - added_consts.concat @new_classes - @new_classes.clear - added_consts.uniq! - added_consts.sort! - - @file_list[file] = added_consts - @last_error end + attr_reader :last_error # start listening - def self.listen - views_path = Config.views_path('/') - if views_path - if l = Nyara.logger - l.info "watching views change under #{views_path}" + def listen + @port = Config['port'] + app_path = Config['root'] + views_path = Config.views_path('/', false) + if l = Nyara.logger + l.info "watching app and view changes under #{app_path}" + unless views_path.start_with?(app_path) + l.warn "views not under project dir, changes not watched" end - Listen.to Config.views_path('/'), relative_paths: true do |modified, added, removed| - modified.each do |file| - View.on_modified file - end - removed.each do |file| - View.on_removed file - end - end end + @app_listener = hook_app_reload app_path + @views_listener = hook_views_reload views_path + end - return unless Config.development? - if l = Nyara.logger - l.info "watching app change under #{Config['root']}" + # cleanup workers + def stop + if @app_listener.adapter.worker + @app_listener.adapter.worker.stop end - Listen.to Config['root'], filter: /\.rb$/, relative_paths: false do |modified, added, removed| - (added + modified).uniq.each do |file| - load_file file - end - # (1.0) todo send notification on bad files + if @views_listener.adapter.worker + @views_listener.adapter.worker.stop end end - # todo (don't forget wiki doc!) + # --- + # private + # +++ + + def hook_app_reload app_path + l = Listen.to(app_path).relative_paths(false).filter(/\.rb$/).change do |modified, added, removed| + notify 'app-modified', (added + modified).uniq + end + l.start + l + end + + def hook_views_reload views_path + l = Listen.to(views_path).relative_paths(true).change do |modified, added, removed| + notify 'views-modified', (added + modified).uniq + notify 'views-removed', removed + end + l.start + l + end + + def notify leader, files + return if files.empty? + data = files.to_query('files') + s = TCPSocket.new 'localhost', @port + s << "POST /reload:#{leader}\r\nContent-Length: #{data.bytesize}\r\n\r\n" << data + s.close + end end end