diff --git a/Gemfile b/Gemfile index 3f5f6ce..371875f 100644 --- a/Gemfile +++ b/Gemfile @@ -3,4 +3,6 @@ source "https://rubygems.org" group :test do gem 'rspec' gem 'stud', "~> 0.0.18" + gem 'uuid', "~> 2.3.8" + gem 'ffi-xattr', "~> 0.1.2" end diff --git a/lib/filewatch/watch.rb b/lib/filewatch/watch.rb index 9694eed..c5140a1 100644 --- a/lib/filewatch/watch.rb +++ b/lib/filewatch/watch.rb @@ -2,6 +2,8 @@ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ require "filewatch/winhelper" end +require "ffi-xattr" +require "uuid" module FileWatch class Watch @@ -19,6 +21,9 @@ def initialize(opts={}) @watching = [] @exclude = [] @files = Hash.new { |h, k| h[k] = Hash.new } + + @xattr = opts[:xattr] || 'uuid' + @uuid = UUID.new if @xattr end # def initialize public @@ -46,6 +51,22 @@ def inode(path,stat) if @iswindows fileId = Winhelper.GetWindowsUniqueFileIdentifier(path) inode = [fileId, stat.dev_major, stat.dev_minor] + elsif @xattr + begin + xattr = Xattr.new(path) + + fileId = xattr[@xattr] + + if !fileId + fileId = @uuid.generate + + xattr[@xattr] = fileId + end + + inode = [fileId, stat.dev_major, stat.dev_minor] + rescue + inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] + end else inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] end diff --git a/spec/tail_spec.rb b/spec/tail_spec.rb index 5ed047a..df0fec2 100644 --- a/spec/tail_spec.rb +++ b/spec/tail_spec.rb @@ -1,5 +1,6 @@ require 'filewatch/tail' require 'stud/temporary' +require 'ffi-xattr' describe FileWatch::Tail do @@ -21,6 +22,14 @@ it "reads new lines off the file" do expect { |b| subject.subscribe(&b) }.to yield_successive_args([file_path, "line1"], [file_path, "line2"]) end + + it "file contains xattr 'uuid'" do + subject.subscribe {|_,_| } + stat = File::Stat.new(file_path) + sincedb_id = subject.sincedb_record_uid(file_path,stat)[0] + + expect(Xattr.new(file_path)['uuid']).to eq(sincedb_id) + end end context "when watching a file" do