filewatch 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd471cc099285df704d3f28e4241871e1aa666e2
4
- data.tar.gz: dfea4f9a717b2dc2b5d1ef1336091e7af10bf3b6
3
+ metadata.gz: 0e65e9502f748961f239834468650fec44803b49
4
+ data.tar.gz: d0a583f9ca8d394ab0adccda0a843e30ebcf4d40
5
5
  SHA512:
6
- metadata.gz: adbda674e3639e946a0db108e56175a29ac10483cefe1e6ea429d4f1c8e8ca9f4434ea76f6f8db758a79d112b15152936ffddf5dea5446a939ed8be7ef7f0c09
7
- data.tar.gz: 87608be8ee355a10e2e3962712c96254fdc971d0bab352c1a3155226d7bef63b3e9d1105c9abcff75db85a815d2f9f2789d9f19b6dfe89948c7a1015421f1145
6
+ metadata.gz: 2a96dd9971c7bcde08e601a4e6d22c1d4fad2851b9489d79e378302fa819cc2919bb3f2bf83c5a28877d97e022f45ed6b3a53425034d4dd6eac4f04e7325f10b
7
+ data.tar.gz: 5c4eb3f52ed225b541fba0a2adfb5a869072f5473923a3de750d8e5520b4579e05b3af3822b841ed7f262f920e033ef00c2e59f3796ce42048905234fad1c161
@@ -0,0 +1,69 @@
1
+ # code downloaded from Ruby on Rails 4.2.1
2
+ # https://raw.githubusercontent.com/rails/rails/v4.2.1/activesupport/lib/active_support/core_ext/file/atomic.rb
3
+ require 'fileutils'
4
+
5
+ class File
6
+ # Write to a file atomically. Useful for situations where you don't
7
+ # want other processes or threads to see half-written files.
8
+ #
9
+ # File.atomic_write('important.file') do |file|
10
+ # file.write('hello')
11
+ # end
12
+ #
13
+ # If your temp directory is not on the same filesystem as the file you're
14
+ # trying to write, you can provide a different temporary directory.
15
+ #
16
+ # File.atomic_write('/data/something.important', '/data/tmp') do |file|
17
+ # file.write('hello')
18
+ # end
19
+ def self.atomic_write(file_name)
20
+
21
+ if File.exist?(file_name)
22
+ # Get original file permissions
23
+ old_stat = stat(file_name)
24
+ else
25
+ # If not possible, probe which are the default permissions in the
26
+ # destination directory.
27
+ old_stat = probe_stat_in(dirname(file_name))
28
+ end
29
+
30
+ mode = old_stat ? old_stat.mode : nil
31
+
32
+ # Create temporary file with identical permissions
33
+ temp_file = File.new(rand_filename(file_name), "w", mode)
34
+ temp_file.binmode
35
+ return_val = yield temp_file
36
+ temp_file.close
37
+
38
+ # Overwrite original file with temp file
39
+ File.rename(temp_file.path, file_name)
40
+
41
+ # Unable to get permissions of the original file => return
42
+ return return_val if old_stat.nil?
43
+
44
+ # Set correct uid/gid on new file
45
+ chown(old_stat.uid, old_stat.gid, file_name) if old_stat
46
+
47
+ return_val
48
+ end
49
+
50
+ # Private utility method.
51
+ def self.probe_stat_in(dir) #:nodoc:
52
+ basename = rand_filename(".permissions_check")
53
+ file_name = join(dir, basename)
54
+ FileUtils.touch(file_name)
55
+ stat(file_name)
56
+ rescue
57
+ # ...
58
+ ensure
59
+ FileUtils.rm_f(file_name) if File.exist?(file_name)
60
+ end
61
+
62
+ def self.rand_filename(prefix)
63
+ [ prefix, Thread.current.object_id, Process.pid, rand(1000000) ].join('.')
64
+ end
65
+
66
+ def self.device?(file_name)
67
+ chardev?(file_name) || blockdev?(file_name)
68
+ end
69
+ end
@@ -1,3 +1,4 @@
1
+ require "filewatch/helper"
1
2
  require "filewatch/buftok"
2
3
  require "filewatch/watch"
3
4
  if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
@@ -103,7 +104,14 @@ module FileWatch
103
104
  @logger.warn("unknown event type #{event} for #{path}")
104
105
  end
105
106
  end # @watch.subscribe
106
- end # def each
107
+ end # def subscribe
108
+
109
+ public
110
+ def sincedb_record_uid(path, stat)
111
+ inode = @watch.inode(path,stat)
112
+ @statcache[path] = inode
113
+ return inode
114
+ end # def sincedb_record_uid
107
115
 
108
116
  private
109
117
  def _open_file(path, event)
@@ -130,37 +138,28 @@ module FileWatch
130
138
  end
131
139
 
132
140
  stat = File::Stat.new(path)
133
-
134
- if @iswindows
135
- fileId = Winhelper.GetWindowsUniqueFileIdentifier(path)
136
- inode = [fileId, stat.dev_major, stat.dev_minor]
137
- else
138
- inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor]
139
- end
140
-
141
- @statcache[path] = inode
141
+ sincedb_record_uid = sincedb_record_uid(path, stat)
142
142
 
143
- if @sincedb.member?(inode)
144
- last_size = @sincedb[inode]
145
- @logger.debug? && @logger.debug("#{path}: sincedb last value #{@sincedb[inode]}, cur size #{stat.size}")
143
+ if @sincedb.member?(sincedb_record_uid)
144
+ last_size = @sincedb[sincedb_record_uid]
145
+ @logger.debug? && @logger.debug("#{path}: sincedb last value #{@sincedb[sincedb_record_uid]}, cur size #{stat.size}")
146
146
  if last_size <= stat.size
147
147
  @logger.debug? && @logger.debug("#{path}: sincedb: seeking to #{last_size}")
148
148
  @files[path].sysseek(last_size, IO::SEEK_SET)
149
149
  else
150
150
  @logger.debug? && @logger.debug("#{path}: last value size is greater than current value, starting over")
151
- @sincedb[inode] = 0
151
+ @sincedb[sincedb_record_uid] = 0
152
152
  end
153
153
  elsif event == :create_initial && @files[path]
154
- # TODO(sissel): Allow starting at beginning of the file.
155
154
  if @opts[:start_new_files_at] == :beginning
156
155
  @logger.debug? && @logger.debug("#{path}: initial create, no sincedb, seeking to beginning of file")
157
156
  @files[path].sysseek(0, IO::SEEK_SET)
158
- @sincedb[inode] = 0
157
+ @sincedb[sincedb_record_uid] = 0
159
158
  else
160
159
  # seek to end
161
160
  @logger.debug? && @logger.debug("#{path}: initial create, no sincedb, seeking to end #{stat.size}")
162
161
  @files[path].sysseek(stat.size, IO::SEEK_SET)
163
- @sincedb[inode] = stat.size
162
+ @sincedb[sincedb_record_uid] = stat.size
164
163
  end
165
164
  else
166
165
  @logger.debug? && @logger.debug("#{path}: staying at position 0, no sincedb")
@@ -172,7 +171,6 @@ module FileWatch
172
171
  private
173
172
  def _read_file(path, &block)
174
173
  @buffers[path] ||= FileWatch::BufferedTokenizer.new(@opts[:delimiter])
175
-
176
174
  changed = false
177
175
  loop do
178
176
  begin
@@ -219,9 +217,9 @@ module FileWatch
219
217
  @logger.debug? && @logger.debug("_sincedb_open: reading from #{path}")
220
218
  db.each do |line|
221
219
  ino, dev_major, dev_minor, pos = line.split(" ", 4)
222
- inode = [ino, dev_major.to_i, dev_minor.to_i]
223
- @logger.debug? && @logger.debug("_sincedb_open: setting #{inode.inspect} to #{pos.to_i}")
224
- @sincedb[inode] = pos.to_i
220
+ sincedb_record_uid = [ino, dev_major.to_i, dev_minor.to_i]
221
+ @logger.debug? && @logger.debug("_sincedb_open: setting #{sincedb_record_uid.inspect} to #{pos.to_i}")
222
+ @sincedb[sincedb_record_uid] = pos.to_i
225
223
  end
226
224
  db.close
227
225
  end # def _sincedb_open
@@ -229,29 +227,24 @@ module FileWatch
229
227
  private
230
228
  def _sincedb_write
231
229
  path = @opts[:sincedb_path]
232
- tmp = "#{path}.new"
233
- begin
234
- db = File.open(tmp, "w")
235
- rescue => e
236
- @logger.warn("_sincedb_write failed: #{tmp}: #{e}")
237
- return
238
- end
239
-
240
- @sincedb.each do |inode, pos|
241
- db.puts([inode, pos].flatten.join(" "))
242
- end
243
- db.close
244
-
245
- begin
246
- File.rename(tmp, path)
247
- rescue => e
248
- @logger.warn("_sincedb_write rename/sync failed: #{tmp} -> #{path}: #{e}")
230
+ if File.device?(path)
231
+ IO.write(path, serialize_sincedb, 0)
232
+ else
233
+ File.atomic_write(path) {|file| file.write(serialize_sincedb) }
249
234
  end
250
235
  end # def _sincedb_write
251
236
 
252
237
  public
253
238
  def quit
239
+ _sincedb_write
254
240
  @watch.quit
255
241
  end # def quit
242
+
243
+ private
244
+ def serialize_sincedb
245
+ @sincedb.map do |inode, pos|
246
+ [inode, pos].flatten.join(" ")
247
+ end.join("\n") + "\n"
248
+ end
256
249
  end # class Tail
257
250
  end # module FileWatch
@@ -39,7 +39,18 @@ module FileWatch
39
39
  end
40
40
 
41
41
  return true
42
- end # def tail
42
+ end # def watch
43
+
44
+ public
45
+ def inode(path,stat)
46
+ if @iswindows
47
+ fileId = Winhelper.GetWindowsUniqueFileIdentifier(path)
48
+ inode = [fileId, stat.dev_major, stat.dev_minor]
49
+ else
50
+ inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor]
51
+ end
52
+ return inode
53
+ end
43
54
 
44
55
  # Calls &block with params [event_type, path]
45
56
  # event_type can be one of:
@@ -72,13 +83,7 @@ module FileWatch
72
83
  next
73
84
  end
74
85
 
75
- if @iswindows
76
- fileId = Winhelper.GetWindowsUniqueFileIdentifier(path)
77
- inode = [fileId, stat.dev_major, stat.dev_minor]
78
- else
79
- inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor]
80
- end
81
-
86
+ inode = inode(path,stat)
82
87
  if inode != @files[path][:inode]
83
88
  @logger.debug? && @logger.debug("#{path}: old inode was #{@files[path][:inode].inspect}, new is #{inode.inspect}")
84
89
  yield(:delete, path)
@@ -149,20 +154,10 @@ module FileWatch
149
154
  stat = File::Stat.new(file)
150
155
  @files[file] = {
151
156
  :size => 0,
152
- :inode => [stat.ino, stat.dev_major, stat.dev_minor],
157
+ :inode => inode(file,stat),
153
158
  :create_sent => false,
159
+ :initial => initial
154
160
  }
155
-
156
- if @iswindows
157
- fileId = Winhelper.GetWindowsUniqueFileIdentifier(file)
158
- @files[file][:inode] = [fileId, stat.dev_major, stat.dev_minor]
159
- else
160
- @files[file][:inode] = [stat.ino.to_s, stat.dev_major, stat.dev_minor]
161
- end
162
-
163
- if initial
164
- @files[file][:initial] = true
165
- end
166
161
  end
167
162
  end # def _discover_file
168
163
 
metadata CHANGED
@@ -1,18 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filewatch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
8
  - Pete Fritchman
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-19 00:00:00.000000000 Z
12
+ date: 2015-04-14 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: Watch files and directories in ruby. Also supports tailing and glob file
15
- patterns.
14
+ description: Watch files and directories in ruby. Also supports tailing and glob file patterns.
16
15
  email:
17
16
  - jls@semicomplete.com
18
17
  - petef@databits.net
@@ -24,6 +23,7 @@ files:
24
23
  - bin/globtail
25
24
  - lib/JRubyFileExtension.jar
26
25
  - lib/filewatch/buftok.rb
26
+ - lib/filewatch/helper.rb
27
27
  - lib/filewatch/tail.rb
28
28
  - lib/filewatch/watch.rb
29
29
  - lib/filewatch/winhelper.rb
@@ -53,25 +53,25 @@ files:
53
53
  homepage: https://github.com/jordansissel/ruby-filewatch
54
54
  licenses: []
55
55
  metadata: {}
56
- post_install_message:
56
+ post_install_message:
57
57
  rdoc_options: []
58
58
  require_paths:
59
59
  - lib
60
60
  - lib
61
61
  required_ruby_version: !ruby/object:Gem::Requirement
62
62
  requirements:
63
- - - ">="
63
+ - - '>='
64
64
  - !ruby/object:Gem::Version
65
65
  version: '0'
66
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ">="
68
+ - - '>='
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubyforge_project:
73
- rubygems_version: 2.4.5
74
- signing_key:
72
+ rubyforge_project:
73
+ rubygems_version: 2.2.2
74
+ signing_key:
75
75
  specification_version: 4
76
76
  summary: filewatch - file watching for ruby
77
77
  test_files: []