Class: Ole::Storage::DirClass

Inherits:
Object
  • Object
show all
Defined in:
lib/ole/file_system.rb

Overview

an instance of this class is supposed to provide similar methods to the class methods of Dir itself.

pretty complete. like zip/zipfilesystem’s implementation, i provide everything except chroot and glob. glob could be done with a glob to regex regex, and then simply match in the entries array… although recursive glob complicates that somewhat.

Dir.chroot, Dir.glob, Dir.[], and Dir.tmpdir is the complete list.

Defined Under Namespace

Classes: Dir

Instance Method Summary collapse

Constructor Details

#initialize(ole) ⇒ DirClass

Returns a new instance of DirClass.



268
269
270
271
# File 'lib/ole/file_system.rb', line 268

def initialize ole
  @ole = ole
  @pwd = ''
end

Instance Method Details

#chdir(orig_path) ⇒ Object



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/ole/file_system.rb', line 309

def chdir orig_path
  # make path absolute, squeeze slashes, and remove trailing slash
  path = @ole.file.expand_path(orig_path).gsub(/\/+/, '/').sub(/\/$/, '')
  # this is just for the side effects of the exceptions if invalid
  dirent_from_path path, orig_path
  if block_given?
    old_pwd = @pwd
    begin
      @pwd = path
      yield
    ensure
      @pwd = old_pwd
    end
  else
    @pwd = path
    0
  end
end

#entries(path) ⇒ Object



328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/ole/file_system.rb', line 328

def entries path
  dirent = dirent_from_path path
  # Not sure about adding on the dots...
  entries = %w[. ..] + dirent.children.map(&:name)
  # do some checks about un-reachable files
  seen = {}
  entries.each do |n|
    Log.warn "inaccessible file (filename contains slash) - #{n.inspect}" if n['/']
    Log.warn "inaccessible file (duplicate filename) - #{n.inspect}" if seen[n]
    seen[n] = true
  end
  entries
end

#foreach(path, &block) ⇒ Object



342
343
344
# File 'lib/ole/file_system.rb', line 342

def foreach path, &block
  entries(path).each(&block)
end

#mkdir(path) ⇒ Object

there are some other important ones, like: chroot (!), glob etc etc. for now, i think

Raises:

  • (Errno::EEXIST)


348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/ole/file_system.rb', line 348

def mkdir path
  # as for rmdir below:
  parent_path, basename = File.split @ole.file.expand_path(path)
  # note that we will complain about the full path despite accessing
  # the parent path. this is consistent with ::Dir
  parent = dirent_from_path parent_path, path
  # now, we first should ensure that it doesn't already exist
  # either as a file or a directory.
  raise Errno::EEXIST, path if parent/basename
  parent.children << Dirent.new(@ole, :type => :dir, :name => basename)
  0
end

#new(path) ⇒ Object

as for file, explicit alias to inhibit block



294
295
296
# File 'lib/ole/file_system.rb', line 294

def new path
  open path
end

#open(path) ⇒ Object



284
285
286
287
288
289
290
291
# File 'lib/ole/file_system.rb', line 284

def open path
  dir = Dir.new path, entries(path)
  if block_given?
    yield dir
  else
    dir
  end
end

#pwdObject Also known as: getwd

pwd is always stored without the trailing slash. we handle the root case here



300
301
302
303
304
305
306
# File 'lib/ole/file_system.rb', line 300

def pwd
  if @pwd.empty?
    '/'
  else
    @pwd
  end
end

#rmdir(path) ⇒ Object Also known as: delete, unlink

Raises:

  • (Errno::ENOTEMPTY)


361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/ole/file_system.rb', line 361

def rmdir path
  dirent = dirent_from_path path
  raise Errno::ENOTEMPTY, path unless dirent.children.empty?

  # now delete it, how to do that? the canonical representation that is
  # maintained is the root tree, and the children array. we must remove it
  # from the children array.
  # we need the parent then. this sucks but anyway:
  # we need to split the path. but before we can do that, we need
  # to expand it first. eg. say we need the parent to unlink
  # a/b/../c. the parent should be a, not a/b/.., or a/b.
  parent_path, basename = File.split @ole.file.expand_path(path)
  # this shouldn't be able to fail if the above didn't
  parent = dirent_from_path parent_path
  # note that the way this currently works, on save and repack time this will get
  # reflected. to work properly, ie to make a difference now it would have to re-write
  # the dirent. i think that Ole::Storage#close will handle that. and maybe include a
  # #repack.
  parent.children.delete dirent
  0 # hmmm. as per ::Dir ?
end