ttilley-fssm 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 0
3
- :patch: 6
3
+ :patch: 7
4
4
  :major: 0
data/fssm.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fssm}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Travis Tilley"]
12
- s.date = %q{2009-09-05}
12
+ s.date = %q{2009-09-07}
13
13
  s.description = %q{file system state monitor}
14
14
  s.email = %q{ttilley@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -28,14 +28,18 @@ Gem::Specification.new do |s|
28
28
  "lib/fssm.rb",
29
29
  "lib/fssm/backends/fsevents.rb",
30
30
  "lib/fssm/backends/polling.rb",
31
- "lib/fssm/ext.rb",
32
31
  "lib/fssm/fsevents.rb",
33
32
  "lib/fssm/monitor.rb",
34
33
  "lib/fssm/path.rb",
34
+ "lib/fssm/pathname.rb",
35
35
  "lib/fssm/state.rb",
36
36
  "lib/fssm/support.rb",
37
37
  "lib/fssm/tree.rb",
38
- "prof-cache.rb",
38
+ "profile/prof-cache.rb",
39
+ "profile/prof-fssm-pathname.html",
40
+ "profile/prof-pathname.rb",
41
+ "profile/prof-plain-pathname.html",
42
+ "profile/prof.html",
39
43
  "spec/path_spec.rb",
40
44
  "spec/root/duck/quack.txt",
41
45
  "spec/root/file.css",
@@ -2,7 +2,7 @@ module FSSM::Backends
2
2
  class Polling
3
3
  def initialize(options={})
4
4
  @handlers = []
5
- @latency = options[:latency] || 1
5
+ @latency = options[:latency] || 1.5
6
6
  end
7
7
 
8
8
  def add_path(path, preload=true)
data/lib/fssm/path.rb CHANGED
@@ -75,12 +75,12 @@ class FSSM::Path
75
75
  end
76
76
 
77
77
  def split_path(path)
78
- path = Pathname.for(path)
78
+ path = FSSM::Pathname.for(path)
79
79
  [@path, (path.relative? ? path : path.relative_path_from(@path))]
80
80
  end
81
81
 
82
82
  def set_path(path)
83
- path = Pathname.for(path)
83
+ path = FSSM::Pathname.for(path)
84
84
  raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
85
85
  @path = path.realpath
86
86
  end
@@ -0,0 +1,350 @@
1
+ # The bundled ruby pathname library is a slow and hideous beast.
2
+ # There. I said it. This version is based on pathname3.
3
+
4
+ module FSSM
5
+ class Pathname < String
6
+
7
+ SEPARATOR = Regexp.quote(File::SEPARATOR)
8
+
9
+ if File::ALT_SEPARATOR
10
+ ALT_SEPARATOR = Regexp.quote(File::ALT_SEPARATOR)
11
+ SEPARATOR_PAT = Regexp.compile("[#{SEPARATOR}#{ALT_SEPARATOR}]")
12
+ else
13
+ SEPARATOR_PAT = Regexp.compile(SEPARATOR)
14
+ end
15
+
16
+ if RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
17
+ PREFIX_PAT = Regexp.compile("^([A-Za-z]:#{SEPARATOR_PAT})")
18
+ else
19
+ PREFIX_PAT = Regexp.compile("^(#{SEPARATOR_PAT})")
20
+ end
21
+
22
+ class << self
23
+ def for(path)
24
+ path = path.is_a?(::FSSM::Pathname) ? path : new(path)
25
+ path.dememo
26
+ path
27
+ end
28
+ end
29
+
30
+ def initialize(path)
31
+ if path =~ %r{\0}
32
+ raise ArgumentError, "path cannot contain ASCII NULLs"
33
+ end
34
+
35
+ dememo
36
+
37
+ super(path)
38
+ end
39
+
40
+ def to_path
41
+ self
42
+ end
43
+
44
+ def to_s
45
+ "#{self}"
46
+ end
47
+ alias to_str to_s
48
+
49
+ def to_a
50
+ return @segments if @segments
51
+ set_prefix_and_names
52
+ @segments = @names.dup
53
+ @segments.delete('.')
54
+ @segments.unshift(@prefix) unless @prefix.empty?
55
+ @segments
56
+ end
57
+ alias segments to_a
58
+
59
+ def each_filename(&block)
60
+ to_a.each(&block)
61
+ end
62
+
63
+ def ascend
64
+ parts = to_a
65
+ parts.length.downto(1) do |i|
66
+ yield self.class.join(parts[0, i])
67
+ end
68
+ end
69
+
70
+ def descend
71
+ parts = to_a
72
+ 1.upto(parts.length) do |i|
73
+ yield self.class.join(parts[0, i])
74
+ end
75
+ end
76
+
77
+ def root?
78
+ set_prefix_and_names
79
+ @names.empty? && !@prefix.empty?
80
+ end
81
+
82
+ def parent
83
+ self + '..'
84
+ end
85
+
86
+ def relative?
87
+ set_prefix_and_names
88
+ @prefix.empty?
89
+ end
90
+
91
+ def absolute?
92
+ !relative?
93
+ end
94
+
95
+ def +(path)
96
+ dup << path
97
+ end
98
+
99
+ def <<(path)
100
+ replace(join(path).cleanpath!)
101
+ end
102
+
103
+ def cleanpath!
104
+ parts = to_a
105
+ final = []
106
+
107
+ parts.each do |part|
108
+ case part
109
+ when '.' then next
110
+ when '..' then
111
+ case final.last
112
+ when '..' then final.push('..')
113
+ when nil then final.push('..')
114
+ else final.pop
115
+ end
116
+ else final.push(part)
117
+ end
118
+ end
119
+
120
+ replace(final.empty? ? Dir.pwd : File.join(*final))
121
+ end
122
+
123
+ def cleanpath
124
+ dup.cleanpath!
125
+ end
126
+
127
+ def realpath
128
+ raise unless self.exist?
129
+
130
+ if File.symlink?(self)
131
+ file = self.dup
132
+
133
+ while true
134
+ file = File.join(File.dirname(file), File.readlink(file))
135
+ break unless File.symlink?(file)
136
+ end
137
+
138
+ self.class.new(file).clean
139
+ else
140
+ self.class.new(Dir.pwd) + self
141
+ end
142
+ end
143
+
144
+ def relative_path_from(base)
145
+ base = self.class.for(base)
146
+
147
+ if self.absolute? != base.absolute?
148
+ raise ArgumentError, 'no relative path between a relative and absolute'
149
+ end
150
+
151
+ if self.prefix != base.prefix
152
+ raise ArgumentError, "different prefix: #{@prefix.inspect} and #{base.prefix.inspect}"
153
+ end
154
+
155
+ base = base.cleanpath!.segments
156
+ dest = dup.cleanpath!.segments
157
+
158
+ while !dest.empty? && !base.empty? && dest[0] == base[0]
159
+ base.shift
160
+ dest.shift
161
+ end
162
+
163
+ base.shift if base[0] == '.'
164
+ dest.shift if dest[0] == '.'
165
+
166
+ if base.include?('..')
167
+ raise ArgumentError, "base directory may not contain '..'"
168
+ end
169
+
170
+ path = base.fill('..') + dest
171
+ path = self.class.join(*path)
172
+ path = self.class.new('.') if path.empty?
173
+
174
+ path
175
+ end
176
+
177
+ def replace(path)
178
+ if path =~ %r{\0}
179
+ raise ArgumentError, "path cannot contain ASCII NULLs"
180
+ end
181
+
182
+ dememo
183
+
184
+ super(path)
185
+ end
186
+
187
+ def unlink
188
+ Dir.unlink(self)
189
+ true
190
+ rescue Errno::ENOTDIR
191
+ File.unlink(self)
192
+ true
193
+ end
194
+
195
+ def prefix
196
+ set_prefix_and_names
197
+ @prefix
198
+ end
199
+
200
+ def names
201
+ set_prefix_and_names
202
+ @names
203
+ end
204
+
205
+ def dememo
206
+ @set = nil
207
+ @segments = nil
208
+ @prefix = nil
209
+ @names = nil
210
+ end
211
+
212
+ private
213
+
214
+ def set_prefix_and_names
215
+ return if @set
216
+
217
+ @names = []
218
+
219
+ if (match = PREFIX_PAT.match(self))
220
+ @prefix = match[0].to_s
221
+ @names += match.post_match.split(SEPARATOR_PAT)
222
+ else
223
+ @prefix = ''
224
+ @names += self.split(SEPARATOR_PAT)
225
+ end
226
+
227
+ @names.compact!
228
+ @names.delete('')
229
+
230
+ @set = true
231
+ end
232
+
233
+ end
234
+
235
+ class Pathname
236
+ class << self
237
+ def glob(pattern, flags=0)
238
+ dirs = Dir.glob(pattern, flags)
239
+ dirs.map! {|path| new(path)}
240
+
241
+ if block_given?
242
+ dirs.each {|dir| yield dir}
243
+ nil
244
+ else
245
+ dirs
246
+ end
247
+ end
248
+
249
+ def [](pattern)
250
+ Dir[pattern].map! {|path| new(path)}
251
+ end
252
+
253
+ def pwd
254
+ new(Dir.pwd)
255
+ end
256
+ end
257
+
258
+ def entries; Dir.entries(self).map! {|e| FSSM::Pathname.new(e) }; end
259
+ def mkdir(mode = 0777); Dir.mkdir(self, mode); end
260
+ def opendir(&blk); Dir.open(self, &blk); end
261
+ def rmdir; Dir.rmdir(self); end
262
+
263
+ def chdir
264
+ blk = lambda { yield self } if block_given?
265
+ Dir.chdir(self, &blk)
266
+ end
267
+ end
268
+
269
+ class Pathname
270
+ def blockdev?; FileTest.blockdev?(self); end
271
+ def chardev?; FileTest.chardev?(self); end
272
+ def directory?; FileTest.directory?(self); end
273
+ def executable?; FileTest.executable?(self); end
274
+ def executable_real?; FileTest.executable_real?(self); end
275
+ def exists?; FileTest.exists?(self); end
276
+ def file?; FileTest.file?(self); end
277
+ def grpowned?; FileTest.grpowned?(self); end
278
+ def owned?; FileTest.owned?(self); end
279
+ def pipe?; FileTest.pipe?(self); end
280
+ def readable?; FileTest.readable?(self); end
281
+ def readable_real?; FileTest.readable_real?(self); end
282
+ def setgid?; FileTest.setgit?(self); end
283
+ def setuid?; FileTest.setuid?(self); end
284
+ def socket?; FileTest.socket?(self); end
285
+ def sticky?; FileTest.sticky?(self); end
286
+ def symlink?; FileTest.symlink?(self); end
287
+ def world_readable?; FileTest.world_readable?(self); end
288
+ def world_writable?; FileTest.world_writable?(self); end
289
+ def writable?; FileTest.writable?(self); end
290
+ def writable_real?; FileTest.writable_real?(self); end
291
+ def zero?; FileTest.zero?(self); end
292
+
293
+ alias exist? exists?
294
+ end
295
+
296
+ class Pathname
297
+ def atime; File.atime(self); end
298
+ def ctime; File.ctime(self); end
299
+ def ftype; File.ftype(self); end
300
+ def lstat; File.lstat(self); end
301
+ def mtime; File.mtime(self); end
302
+ def stat; File.stat(self); end
303
+ def utime(atime, mtime); File.utime(self, atime, mtime); end
304
+ end
305
+
306
+ class Pathname
307
+ class << self
308
+ def join(*parts)
309
+ new(File.join(*parts.reject {|p| p.empty? }))
310
+ end
311
+ end
312
+
313
+ def basename; self.class.new(File.basename(self)); end
314
+ def chmod(mode); File.chmod(mode, self); end
315
+ def chown(owner, group); File.chown(owner, group, self); end
316
+ def dirname; self.class.new(File.dirname(self)); end
317
+ def expand_path(from = nil); self.class.new(File.expand_path(self, from)); end
318
+ def extname; File.extname(self); end
319
+ def fnmatch?(pat, flags = 0); File.fnmatch(pat, self, flags); end
320
+ def join(*parts); self.class.join(self, *parts); end
321
+ def lchmod(mode); File.lchmod(mode, self); end
322
+ def lchown(owner, group); File.lchown(owner, group, self); end
323
+ def link(to); File.link(self, to); end
324
+ def open(mode = 'r', perm = nil, &blk); File.open(self, mode, perm, &blk); end
325
+ def readlink; self.class.new(File.readlink(self)); end
326
+ def rename(to); File.rename(self, to); replace(to); end
327
+ def size; File.size(self); end
328
+ def size?; File.size?(self); end
329
+ def symlink(to); File.symlink(self, to); end
330
+ def truncate; File.truncate(self); end
331
+ end
332
+
333
+ class Pathname
334
+ def mkpath; self.class.new(FileUtils.mkpath(self)); end
335
+ def rmtree; self.class.new(FileUtils.rmtree(self).first); end
336
+ def touch; self.class.new(FileUtils.touch(self).first); end
337
+ end
338
+
339
+ class Pathname
340
+ def each_line(sep = $/, &blk); IO.foreach(self, sep, &blk); end
341
+ def read(len = nil, off = 0); IO.read(self, len, off); end
342
+ def readlines(sep = $/); IO.readlines(self, sep); end
343
+ def sysopen(mode = 'r', perm = nil); IO.sysopen(self, mode, perm); end
344
+ end
345
+
346
+ class Pathname
347
+ def find; Find.find(self) {|path| yield FSSM::Pathname.new(path) }; end
348
+ end
349
+
350
+ end
data/lib/fssm/state.rb CHANGED
@@ -32,7 +32,7 @@ class FSSM::State
32
32
  end
33
33
 
34
34
  def recache(base)
35
- base = Pathname.for(base)
35
+ base = FSSM::Pathname.for(base)
36
36
  previous = @cache.files
37
37
  snapshot(base)
38
38
  current = @cache.files
@@ -40,13 +40,13 @@ class FSSM::State
40
40
  end
41
41
 
42
42
  def snapshot(base)
43
- base = Pathname.for(base)
43
+ base = FSSM::Pathname.for(base)
44
44
  @cache.unset(base)
45
45
  @path.glob.each {|glob| add_glob(base, glob)}
46
46
  end
47
47
 
48
48
  def add_glob(base, glob)
49
- Pathname.glob(base.join(glob)).each do |fn|
49
+ FSSM::Pathname.glob(base.join(glob)).each do |fn|
50
50
  @cache.set(fn)
51
51
  end
52
52
  end
data/lib/fssm/tree.rb CHANGED
@@ -34,8 +34,8 @@ module FSSM::Tree
34
34
  def each(prefix=nil, &block)
35
35
  @children.each do |segment, node|
36
36
  cprefix = prefix ?
37
- Pathname.for(prefix).join(segment) :
38
- Pathname.for(segment)
37
+ FSSM::Pathname.for(prefix).join(segment) :
38
+ FSSM::Pathname.for(segment)
39
39
  block.call(cprefix, node)
40
40
  node.each(cprefix, &block)
41
41
  end
@@ -72,7 +72,7 @@ module FSSM::Tree
72
72
 
73
73
  def key_segments(key)
74
74
  return key if key.is_a?(Array)
75
- Pathname.for(key).segments
75
+ FSSM::Pathname.for(key).segments
76
76
  end
77
77
 
78
78
  def descendant(path)
@@ -127,7 +127,7 @@ module FSSM::Tree
127
127
  end
128
128
 
129
129
  def from_path(path)
130
- path = Pathname.for(path)
130
+ path = FSSM::Pathname.for(path)
131
131
  @ftype = path.ftype
132
132
  # this handles bad symlinks without failing. why handle bad symlinks at
133
133
  # all? well, we could still be interested in their creation and deletion.
@@ -145,7 +145,7 @@ module FSSM::Tree
145
145
  def set(path)
146
146
  # all paths set from this level need to be absolute
147
147
  # realpath will fail on broken links
148
- path = Pathname.for(path).expand_path
148
+ path = FSSM::Pathname.for(path).expand_path
149
149
  super(path)
150
150
  end
151
151
 
data/lib/fssm.rb CHANGED
@@ -28,9 +28,8 @@ module FSSM
28
28
  end
29
29
 
30
30
  require 'thread'
31
- require 'pathname'
32
31
 
33
- require 'fssm/ext'
32
+ require 'fssm/pathname'
34
33
  require 'fssm/support'
35
34
  require 'fssm/tree'
36
35
  require 'fssm/path'
@@ -1,12 +1,12 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
 
3
3
  require 'fssm'
4
4
 
5
5
  require 'rubygems'
6
6
  require 'ruby-prof'
7
7
 
8
- $test_path = Pathname.new('.')
9
- $test_files = Pathname.glob(File.join($test_path, '**', '*'))
8
+ $test_path = FSSM::Pathname.new('..').expand_path
9
+ $test_files = FSSM::Pathname.glob(File.join($test_path, '**', '*'))
10
10
 
11
11
  RubyProf.start
12
12
  RubyProf.pause