fssm 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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