require'set'moduleSassListen# TODO: refactor (turn it into a normal object, cache the stat, etc)classDirectorydefself.scan(snapshot,rel_path,options)record=snapshot.recorddir=Pathname.new(record.root)previous=record.dir_entries(rel_path)record.add_dir(rel_path)# TODO: use children(with_directory: false)path=dir+rel_pathcurrent=Set.new(_children(path))SassListen::Logger.debugdoformat('%s: %s(%s): %s -> %s',(options[:silence]?'Recording':'Scanning'),rel_path,options.inspect,previous.inspect,current.inspect)endbegincurrent.eachdo|full_path|type=::File.lstat(full_path.to_s).directory??:dir::fileitem_rel_path=full_path.relative_path_from(dir).to_s_change(snapshot,type,item_rel_path,options)endrescueErrno::ENOENT# The directory changed meanwhile, so rescan itcurrent=Set.new(_children(path))retryend# TODO: this is not tested properlyprevious=previous.reject{|entry,_|current.include?path+entry}_async_changes(snapshot,Pathname.new(rel_path),previous,options)rescueErrno::ENOENT,Errno::EHOSTDOWNrecord.unset_path(rel_path)_async_changes(snapshot,Pathname.new(rel_path),previous,options)rescueErrno::ENOTDIR# TODO: path not testedrecord.unset_path(rel_path)_async_changes(snapshot,path,previous,options)_change(snapshot,:file,rel_path,options)rescueSassListen::Logger.warndoformat('scan DIED: %s:%s',$ERROR_INFO,$ERROR_POSITION*"\n")endraiseenddefself._async_changes(snapshot,path,previous,options)fail"Not a Pathname: #{path.inspect}"unlesspath.respond_to?(:children)previous.eachdo|entry,data|# TODO: this is a hack with insufficient testingtype=data.key?(:mtime)?:file::dirrel_path_s=(path+entry).to_s_change(snapshot,type,rel_path_s,options)endenddefself._change(snapshot,type,path,options)returnsnapshot.invalidate(type,path,options)iftype==:dir# Minor param cleanup for tests# TODO: use a dedicated Event classopts=options.dupopts.delete(:recursive)snapshot.invalidate(type,path,opts)enddefself._children(path)returnpath.childrenunlessRUBY_ENGINE=='jruby'# JRuby inconsistency workaround, see:# https://github.com/jruby/jruby/issues/3840exists=path.exist?directory=path.directory?returnpath.childrenunless(exists&&!directory)raiseErrno::ENOTDIR,path.to_sendendend