fssm 0.0.9 → 0.1.0

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.
data/.gitignore CHANGED
@@ -1,7 +1,9 @@
1
1
  *.sw?
2
2
  .DS_Store
3
+ .idea
4
+ /*.gem
3
5
  coverage
4
- rdoc
5
- pkg
6
6
  nbproject
7
+ pkg
8
+ rdoc
7
9
 
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 0
4
- :patch: 9
3
+ :minor: 1
4
+ :patch: 0
5
5
  :build:
data/example.rb CHANGED
@@ -3,7 +3,7 @@ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
3
3
  require 'fssm'
4
4
 
5
5
  FSSM.monitor('.', '**/*') do
6
- update {|b,r| puts "Update in #{b} to #{r}"}
7
- delete {|b,r| puts "Delete in #{b} to #{r}"}
8
- create {|b,r| puts "Create in #{b} to #{r}"}
6
+ update {|b, r| puts "Update in #{b} to #{r}"}
7
+ delete {|b, r| puts "Delete in #{b} to #{r}"}
8
+ create {|b, r| puts "Create in #{b} to #{r}"}
9
9
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fssm}
8
- s.version = "0.0.9"
8
+ s.version = "0.1.0"
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"]
@@ -27,8 +27,9 @@ Gem::Specification.new do |s|
27
27
  "fssm.gemspec",
28
28
  "lib/fssm.rb",
29
29
  "lib/fssm/backends/fsevents.rb",
30
+ "lib/fssm/backends/inotify.rb",
30
31
  "lib/fssm/backends/polling.rb",
31
- "lib/fssm/fsevents.rb",
32
+ "lib/fssm/backends/rubycocoa/fsevents.rb",
32
33
  "lib/fssm/monitor.rb",
33
34
  "lib/fssm/path.rb",
34
35
  "lib/fssm/pathname.rb",
@@ -4,13 +4,13 @@ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
4
4
  module FSSM
5
5
  FileNotFoundError = Class.new(StandardError)
6
6
  CallbackError = Class.new(StandardError)
7
-
7
+
8
8
  class << self
9
9
  def dbg(msg=nil)
10
10
  STDERR.puts(msg)
11
11
  end
12
12
 
13
- def monitor(*args, &block)
13
+ def monitor(*args, &block)
14
14
  monitor = FSSM::Monitor.new
15
15
  context = args.empty? ? monitor : monitor.path(*args)
16
16
 
@@ -1,4 +1,4 @@
1
- require 'fssm/fsevents'
1
+ require File.join(File.dirname(__FILE__), 'rubycocoa/fsevents')
2
2
 
3
3
  module FSSM::Backends
4
4
  class FSEvents
@@ -6,23 +6,23 @@ module FSSM::Backends
6
6
  @handlers = {}
7
7
  @fsevents = []
8
8
  end
9
-
9
+
10
10
  def add_path(path, preload=true)
11
11
  handler = FSSM::State.new(path)
12
12
  @handlers["#{path}"] = handler
13
-
13
+
14
14
  fsevent = Rucola::FSEvents.new("#{path}", {:latency => 0.5}) do |events|
15
15
  events.each do |event|
16
16
  handler.refresh(event.path)
17
17
  end
18
18
  end
19
-
19
+
20
20
  fsevent.create_stream
21
21
  handler.refresh(path.to_pathname, true) if preload
22
22
  fsevent.start
23
23
  @fsevents << fsevent
24
24
  end
25
-
25
+
26
26
  def run
27
27
  begin
28
28
  OSX.CFRunLoopRun
@@ -0,0 +1,25 @@
1
+ module FSSM::Backends
2
+ class Inotify
3
+ def initialize
4
+ @notifier = INotify::Notifier.new
5
+ end
6
+
7
+ def add_path(path, preload=true)
8
+ handler = FSSM::State.new(path)
9
+
10
+ @notifier.watch(path.to_s, :all_events) do |event|
11
+ handler.refresh(event.name)
12
+ end
13
+
14
+ handler.refresh(path.to_pathname, true) if preload
15
+ end
16
+
17
+ def run
18
+ begin
19
+ @notifier.run
20
+ rescue Interrupt
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -1,8 +1,8 @@
1
1
  module FSSM::Backends
2
2
  class Polling
3
3
  def initialize(options={})
4
- @handlers = []
5
- @latency = options[:latency] || 1.5
4
+ @handlers = []
5
+ @latency = options[:latency] || 1.5
6
6
  end
7
7
 
8
8
  def add_path(path, preload=true)
@@ -6,33 +6,35 @@ module Rucola
6
6
  attr_reader :fsevents_object
7
7
  attr_reader :id
8
8
  attr_reader :path
9
+
9
10
  def initialize(fsevents_object, id, path)
10
11
  @fsevents_object, @id, @path = fsevents_object, id, path
11
12
  end
12
-
13
+
13
14
  # Returns an array of the files/dirs in the path that the event occurred in.
14
15
  # The files are sorted by the modification time, the first entry is the last modified file.
15
16
  def files
16
17
  Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
17
18
  end
18
-
19
+
19
20
  # Returns the last modified file in the path that the event occurred in.
20
21
  def last_modified_file
21
22
  files.first
22
23
  end
23
24
  end
24
-
25
- class StreamError < StandardError; end
26
-
25
+
26
+ class StreamError < StandardError;
27
+ end
28
+
27
29
  attr_reader :paths
28
30
  attr_reader :stream
29
-
31
+
30
32
  attr_accessor :allocator
31
33
  attr_accessor :context
32
34
  attr_accessor :since
33
35
  attr_accessor :latency
34
36
  attr_accessor :flags
35
-
37
+
36
38
  # Initializes a new FSEvents `watchdog` object and starts watching the directories you specify for events. The
37
39
  # block is used as a handler for events, which are passed as the block's argument. This method is the easiest
38
40
  # way to start watching some directories if you don't care about the details of setting up the event stream.
@@ -57,7 +59,7 @@ module Rucola
57
59
  fsevents.start
58
60
  fsevents
59
61
  end
60
-
62
+
61
63
  # Creates a new FSEvents `watchdog` object. You can specify a list of paths to watch and options to control the
62
64
  # behaviour of the watchdog. The block you pass serves as a callback when an event is generated on one of the
63
65
  # specified paths.
@@ -84,19 +86,19 @@ module Rucola
84
86
  # Please refer to the Cocoa documentation for the rest of the options.
85
87
  def initialize(*params, &block)
86
88
  raise ArgumentError, 'No callback block was specified.' unless block_given?
87
-
89
+
88
90
  options = params.last.kind_of?(Hash) ? params.pop : {}
89
91
  @paths = params.flatten
90
-
92
+
91
93
  paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
92
-
94
+
93
95
  @allocator = options[:allocator] || OSX::KCFAllocatorDefault
94
- @context = options[:context] || nil
95
- @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
96
- @latency = options[:latency] || 0.0
97
- @flags = options[:flags] || 0
98
- @stream = options[:stream] || nil
99
-
96
+ @context = options[:context] || nil
97
+ @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
98
+ @latency = options[:latency] || 0.0
99
+ @flags = options[:flags] || 0
100
+ @stream = options[:stream] || nil
101
+
100
102
  @user_callback = block
101
103
  @callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
102
104
  paths_pointer.regard_as('*')
@@ -105,7 +107,7 @@ module Rucola
105
107
  @user_callback.call(events)
106
108
  end
107
109
  end
108
-
110
+
109
111
  # Create the stream.
110
112
  # Raises a Rucola::FSEvents::StreamError if the stream could not be created.
111
113
  def create_stream
@@ -113,13 +115,13 @@ module Rucola
113
115
  raise(StreamError, 'Unable to create FSEvents stream.') unless @stream
114
116
  OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
115
117
  end
116
-
118
+
117
119
  # Start the stream.
118
120
  # Raises a Rucola::FSEvents::StreamError if the stream could not be started.
119
121
  def start
120
122
  raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream)
121
123
  end
122
-
124
+
123
125
  # Stop the stream.
124
126
  # You can resume it by calling `start` again.
125
127
  def stop
@@ -3,16 +3,16 @@
3
3
 
4
4
  module FSSM
5
5
  class Pathname < String
6
-
6
+
7
7
  SEPARATOR = Regexp.quote(File::SEPARATOR)
8
-
8
+
9
9
  if File::ALT_SEPARATOR
10
10
  ALT_SEPARATOR = Regexp.quote(File::ALT_SEPARATOR)
11
11
  SEPARATOR_PAT = Regexp.compile("[#{SEPARATOR}#{ALT_SEPARATOR}]")
12
12
  else
13
13
  SEPARATOR_PAT = Regexp.compile(SEPARATOR)
14
14
  end
15
-
15
+
16
16
  if RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
17
17
  PREFIX_PAT = Regexp.compile("^([A-Za-z]:#{SEPARATOR_PAT})")
18
18
  else
@@ -26,27 +26,28 @@ module FSSM
26
26
  path
27
27
  end
28
28
  end
29
-
29
+
30
30
  def initialize(path)
31
31
  if path =~ %r{\0}
32
32
  raise ArgumentError, "path cannot contain ASCII NULLs"
33
33
  end
34
-
34
+
35
35
  dememo
36
-
36
+
37
37
  super(path)
38
38
  end
39
-
39
+
40
40
  def to_path
41
41
  self
42
42
  end
43
-
43
+
44
44
  def to_s
45
45
  "#{self}"
46
46
  end
47
+
47
48
  alias to_str to_s
48
-
49
- def to_a
49
+
50
+ def to_a
50
51
  return @segments if @segments
51
52
  set_prefix_and_names
52
53
  @segments = @names.dup
@@ -54,136 +55,142 @@ module FSSM
54
55
  @segments.unshift(@prefix) unless @prefix.empty?
55
56
  @segments
56
57
  end
58
+
57
59
  alias segments to_a
58
-
60
+
59
61
  def each_filename(&block)
60
62
  to_a.each(&block)
61
63
  end
62
-
64
+
63
65
  def ascend
64
66
  parts = to_a
65
67
  parts.length.downto(1) do |i|
66
68
  yield self.class.join(parts[0, i])
67
69
  end
68
70
  end
69
-
71
+
70
72
  def descend
71
73
  parts = to_a
72
74
  1.upto(parts.length) do |i|
73
75
  yield self.class.join(parts[0, i])
74
76
  end
75
77
  end
76
-
78
+
77
79
  def root?
78
80
  set_prefix_and_names
79
81
  @names.empty? && !@prefix.empty?
80
82
  end
81
-
83
+
82
84
  def parent
83
85
  self + '..'
84
86
  end
85
-
87
+
86
88
  def relative?
87
89
  set_prefix_and_names
88
90
  @prefix.empty?
89
91
  end
90
-
92
+
91
93
  def absolute?
92
94
  !relative?
93
95
  end
94
-
96
+
95
97
  def +(path)
96
98
  dup << path
97
99
  end
98
-
100
+
99
101
  def <<(path)
100
102
  replace(join(path).cleanpath!)
101
103
  end
102
-
104
+
103
105
  def cleanpath!
104
106
  parts = to_a
105
107
  final = []
106
108
 
107
109
  parts.each do |part|
108
110
  case part
109
- when '.' then next
110
- when '..' then
111
+ when '.' then
112
+ next
113
+ when '..' then
111
114
  case final.last
112
- when '..' then final.push('..')
113
- when nil then final.push('..')
114
- else final.pop
115
+ when '..' then
116
+ final.push('..')
117
+ when nil then
118
+ final.push('..')
119
+ else
120
+ final.pop
115
121
  end
116
- else final.push(part)
122
+ else
123
+ final.push(part)
117
124
  end
118
125
  end
119
126
 
120
127
  replace(final.empty? ? Dir.pwd : File.join(*final))
121
128
  end
122
-
129
+
123
130
  def cleanpath
124
131
  dup.cleanpath!
125
132
  end
126
-
133
+
127
134
  def realpath
128
- raise unless self.exist?
135
+ raise unless self.exist?
129
136
 
130
- if File.symlink?(self)
131
- file = self.dup
137
+ if File.symlink?(self)
138
+ file = self.dup
132
139
 
133
- while true
134
- file = File.join(File.dirname(file), File.readlink(file))
135
- break unless File.symlink?(file)
136
- end
140
+ while true
141
+ file = File.join(File.dirname(file), File.readlink(file))
142
+ break unless File.symlink?(file)
143
+ end
137
144
 
138
- self.class.new(file).clean
139
- else
140
- self.class.new(Dir.pwd) + self
141
- end
145
+ self.class.new(file).clean
146
+ else
147
+ self.class.new(Dir.pwd) + self
148
+ end
142
149
  end
143
-
150
+
144
151
  def relative_path_from(base)
145
152
  base = self.class.for(base)
146
-
153
+
147
154
  if self.absolute? != base.absolute?
148
155
  raise ArgumentError, 'no relative path between a relative and absolute'
149
156
  end
150
-
157
+
151
158
  if self.prefix != base.prefix
152
159
  raise ArgumentError, "different prefix: #{@prefix.inspect} and #{base.prefix.inspect}"
153
160
  end
154
-
161
+
155
162
  base = base.cleanpath!.segments
156
163
  dest = dup.cleanpath!.segments
157
-
164
+
158
165
  while !dest.empty? && !base.empty? && dest[0] == base[0]
159
166
  base.shift
160
167
  dest.shift
161
168
  end
162
-
169
+
163
170
  base.shift if base[0] == '.'
164
171
  dest.shift if dest[0] == '.'
165
-
172
+
166
173
  if base.include?('..')
167
174
  raise ArgumentError, "base directory may not contain '..'"
168
175
  end
169
-
176
+
170
177
  path = base.fill('..') + dest
171
178
  path = self.class.join(*path)
172
179
  path = self.class.new('.') if path.empty?
173
-
180
+
174
181
  path
175
182
  end
176
-
177
- def replace(path)
183
+
184
+ def replace(path)
178
185
  if path =~ %r{\0}
179
186
  raise ArgumentError, "path cannot contain ASCII NULLs"
180
187
  end
181
-
188
+
182
189
  dememo
183
-
190
+
184
191
  super(path)
185
192
  end
186
-
193
+
187
194
  def unlink
188
195
  Dir.unlink(self)
189
196
  true
@@ -191,31 +198,31 @@ module FSSM
191
198
  File.unlink(self)
192
199
  true
193
200
  end
194
-
201
+
195
202
  def prefix
196
203
  set_prefix_and_names
197
204
  @prefix
198
205
  end
199
-
206
+
200
207
  def names
201
208
  set_prefix_and_names
202
209
  @names
203
210
  end
204
-
211
+
205
212
  def dememo
206
- @set = nil
207
- @segments = nil
208
- @prefix = nil
209
- @names = nil
213
+ @set = nil
214
+ @segments = nil
215
+ @prefix = nil
216
+ @names = nil
210
217
  end
211
-
218
+
212
219
  private
213
-
220
+
214
221
  def set_prefix_and_names
215
222
  return if @set
216
-
223
+
217
224
  @names = []
218
-
225
+
219
226
  if (match = PREFIX_PAT.match(self))
220
227
  @prefix = match[0].to_s
221
228
  @names += match.post_match.split(SEPARATOR_PAT)
@@ -223,10 +230,10 @@ module FSSM
223
230
  @prefix = ''
224
231
  @names += self.split(SEPARATOR_PAT)
225
232
  end
226
-
233
+
227
234
  @names.compact!
228
235
  @names.delete('')
229
-
236
+
230
237
  @set = true
231
238
  end
232
239
 
@@ -237,7 +244,7 @@ module FSSM
237
244
  def glob(pattern, flags=0)
238
245
  dirs = Dir.glob(pattern, flags)
239
246
  dirs.map! {|path| new(path)}
240
-
247
+
241
248
  if block_given?
242
249
  dirs.each {|dir| yield dir}
243
250
  nil
@@ -245,62 +252,158 @@ module FSSM
245
252
  dirs
246
253
  end
247
254
  end
248
-
255
+
249
256
  def [](pattern)
250
257
  Dir[pattern].map! {|path| new(path)}
251
258
  end
252
-
259
+
253
260
  def pwd
254
261
  new(Dir.pwd)
255
262
  end
256
263
  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
264
 
263
- def chdir
265
+ def entries
266
+ Dir.entries(self).map! {|e| FSSM::Pathname.new(e) }
267
+ end
268
+
269
+ def mkdir(mode = 0777)
270
+ Dir.mkdir(self, mode)
271
+ end
272
+
273
+ def opendir(&blk)
274
+ Dir.open(self, &blk)
275
+ end
276
+
277
+ def rmdir
278
+ Dir.rmdir(self)
279
+ end
280
+
281
+ def chdir
264
282
  blk = lambda { yield self } if block_given?
265
283
  Dir.chdir(self, &blk)
266
284
  end
267
285
  end
268
286
 
269
287
  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
-
288
+ def blockdev?
289
+ FileTest.blockdev?(self)
290
+ end
291
+
292
+ def chardev?
293
+ FileTest.chardev?(self)
294
+ end
295
+
296
+ def directory?
297
+ FileTest.directory?(self)
298
+ end
299
+
300
+ def executable?
301
+ FileTest.executable?(self)
302
+ end
303
+
304
+ def executable_real?
305
+ FileTest.executable_real?(self)
306
+ end
307
+
308
+ def exists?
309
+ FileTest.exists?(self)
310
+ end
311
+
312
+ def file?
313
+ FileTest.file?(self)
314
+ end
315
+
316
+ def grpowned?
317
+ FileTest.grpowned?(self)
318
+ end
319
+
320
+ def owned?
321
+ FileTest.owned?(self)
322
+ end
323
+
324
+ def pipe?
325
+ FileTest.pipe?(self)
326
+ end
327
+
328
+ def readable?
329
+ FileTest.readable?(self)
330
+ end
331
+
332
+ def readable_real?
333
+ FileTest.readable_real?(self)
334
+ end
335
+
336
+ def setgid?
337
+ FileTest.setgit?(self)
338
+ end
339
+
340
+ def setuid?
341
+ FileTest.setuid?(self)
342
+ end
343
+
344
+ def socket?
345
+ FileTest.socket?(self)
346
+ end
347
+
348
+ def sticky?
349
+ FileTest.sticky?(self)
350
+ end
351
+
352
+ def symlink?
353
+ FileTest.symlink?(self)
354
+ end
355
+
356
+ def world_readable?
357
+ FileTest.world_readable?(self)
358
+ end
359
+
360
+ def world_writable?
361
+ FileTest.world_writable?(self)
362
+ end
363
+
364
+ def writable?
365
+ FileTest.writable?(self)
366
+ end
367
+
368
+ def writable_real?
369
+ FileTest.writable_real?(self)
370
+ end
371
+
372
+ def zero?
373
+ FileTest.zero?(self)
374
+ end
375
+
293
376
  alias exist? exists?
294
377
  end
295
378
 
296
379
  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
380
+ def atime
381
+ File.atime(self)
382
+ end
383
+
384
+ def ctime
385
+ File.ctime(self)
386
+ end
387
+
388
+ def ftype
389
+ File.ftype(self)
390
+ end
391
+
392
+ def lstat
393
+ File.lstat(self)
394
+ end
395
+
396
+ def mtime
397
+ File.mtime(self)
398
+ end
399
+
400
+ def stat
401
+ File.stat(self)
402
+ end
403
+
404
+ def utime(atime, mtime)
405
+ File.utime(self, atime, mtime)
406
+ end
304
407
  end
305
408
 
306
409
  class Pathname
@@ -309,42 +412,117 @@ module FSSM
309
412
  new(File.join(*parts.reject {|p| p.empty? }))
310
413
  end
311
414
  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
415
+
416
+ def basename
417
+ self.class.new(File.basename(self))
418
+ end
419
+
420
+ def chmod(mode)
421
+ File.chmod(mode, self)
422
+ end
423
+
424
+ def chown(owner, group)
425
+ File.chown(owner, group, self)
426
+ end
427
+
428
+ def dirname
429
+ self.class.new(File.dirname(self))
430
+ end
431
+
432
+ def expand_path(from = nil)
433
+ self.class.new(File.expand_path(self, from))
434
+ end
435
+
436
+ def extname
437
+ File.extname(self)
438
+ end
439
+
440
+ def fnmatch?(pat, flags = 0)
441
+ File.fnmatch(pat, self, flags)
442
+ end
443
+
444
+ def join(*parts)
445
+ self.class.join(self, *parts)
446
+ end
447
+
448
+ def lchmod(mode)
449
+ File.lchmod(mode, self)
450
+ end
451
+
452
+ def lchown(owner, group)
453
+ File.lchown(owner, group, self)
454
+ end
455
+
456
+ def link(to)
457
+ File.link(self, to)
458
+ end
459
+
460
+ def open(mode = 'r', perm = nil, &blk)
461
+ File.open(self, mode, perm, &blk)
462
+ end
463
+
464
+ def readlink
465
+ self.class.new(File.readlink(self))
466
+ end
467
+
468
+ def rename(to)
469
+ File.rename(self, to)
470
+ replace(to)
471
+ end
472
+
473
+ def size
474
+ File.size(self)
475
+ end
476
+
477
+ def size?
478
+ File.size?(self)
479
+ end
480
+
481
+ def symlink(to)
482
+ File.symlink(self, to)
483
+ end
484
+
485
+ def truncate
486
+ File.truncate(self)
487
+ end
331
488
  end
332
489
 
333
490
  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
491
+ def mkpath
492
+ self.class.new(FileUtils.mkpath(self))
493
+ end
494
+
495
+ def rmtree
496
+ self.class.new(FileUtils.rmtree(self).first)
497
+ end
498
+
499
+ def touch
500
+ self.class.new(FileUtils.touch(self).first)
501
+ end
337
502
  end
338
503
 
339
504
  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
505
+ def each_line(sep = $/, &blk)
506
+ IO.foreach(self, sep, &blk)
507
+ end
508
+
509
+ def read(len = nil, off = 0)
510
+ IO.read(self, len, off)
511
+ end
512
+
513
+ def readlines(sep = $/)
514
+ IO.readlines(self, sep)
515
+ end
516
+
517
+ def sysopen(mode = 'r', perm = nil)
518
+ IO.sysopen(self, mode, perm)
519
+ end
344
520
  end
345
521
 
346
522
  class Pathname
347
- def find; Find.find(self) {|path| yield FSSM::Pathname.new(path) }; end
523
+ def find
524
+ Find.find(self) {|path| yield FSSM::Pathname.new(path) }
525
+ end
348
526
  end
349
527
 
350
528
  end