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