Class | Ole::Storage::DirClass |
In: |
lib/ole/storage/file_system.rb
|
Parent: | Object |
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.
# File lib/ole/storage/file_system.rb, line 256 256: def initialize ole 257: @ole = ole 258: @pwd = '' 259: end
# File lib/ole/storage/file_system.rb, line 297 297: def chdir orig_path 298: # make path absolute, squeeze slashes, and remove trailing slash 299: path = @ole.file.expand_path(orig_path).gsub(/\/+/, '/').sub(/\/$/, '') 300: # this is just for the side effects of the exceptions if invalid 301: dirent_from_path path, orig_path 302: if block_given? 303: old_pwd = @pwd 304: begin 305: @pwd = path 306: yield 307: ensure 308: @pwd = old_pwd 309: end 310: else 311: @pwd = path 312: 0 313: end 314: end
# File lib/ole/storage/file_system.rb, line 316 316: def entries path 317: dirent = dirent_from_path path 318: # Not sure about adding on the dots... 319: entries = %w[. ..] + dirent.children.map(&:name) 320: # do some checks about un-reachable files 321: seen = {} 322: entries.each do |n| 323: Log.warn "inaccessible file (filename contains slash) - #{n.inspect}" if n['/'] 324: Log.warn "inaccessible file (duplicate filename) - #{n.inspect}" if seen[n] 325: seen[n] = true 326: end 327: entries 328: end
# File lib/ole/storage/file_system.rb, line 330 330: def foreach path, &block 331: entries(path).each(&block) 332: end
there are some other important ones, like: chroot (!), glob etc etc. for now, i think
# File lib/ole/storage/file_system.rb, line 336 336: def mkdir path 337: # as for rmdir below: 338: parent_path, basename = File.split @ole.file.expand_path(path) 339: # note that we will complain about the full path despite accessing 340: # the parent path. this is consistent with ::Dir 341: parent = dirent_from_path parent_path, path 342: # now, we first should ensure that it doesn't already exist 343: # either as a file or a directory. 344: raise Errno::EEXIST, path if parent/basename 345: parent.children << Dirent.new(@ole, :type => :dir, :name => basename) 346: 0 347: end
as for file, explicit alias to inhibit block
# File lib/ole/storage/file_system.rb, line 282 282: def new path 283: open path 284: end
# File lib/ole/storage/file_system.rb, line 272 272: def open path 273: dir = Dir.new path, entries(path) 274: if block_given? 275: yield dir 276: else 277: dir 278: end 279: end
# File lib/ole/storage/file_system.rb, line 349 349: def rmdir path 350: dirent = dirent_from_path path 351: raise Errno::ENOTEMPTY, path unless dirent.children.empty? 352: 353: # now delete it, how to do that? the canonical representation that is 354: # maintained is the root tree, and the children array. we must remove it 355: # from the children array. 356: # we need the parent then. this sucks but anyway: 357: # we need to split the path. but before we can do that, we need 358: # to expand it first. eg. say we need the parent to unlink 359: # a/b/../c. the parent should be a, not a/b/.., or a/b. 360: parent_path, basename = File.split @ole.file.expand_path(path) 361: # this shouldn't be able to fail if the above didn't 362: parent = dirent_from_path parent_path 363: # note that the way this currently works, on save and repack time this will get 364: # reflected. to work properly, ie to make a difference now it would have to re-write 365: # the dirent. i think that Ole::Storage#close will handle that. and maybe include a 366: # #repack. 367: parent.children.delete dirent 368: 0 # hmmm. as per ::Dir ? 369: end
orig_path is just so that we can use the requested path in the error messages even if it has been already modified
# File lib/ole/storage/file_system.rb, line 263 263: def dirent_from_path path, orig_path=nil 264: orig_path ||= path 265: dirent = @ole.dirent_from_path path 266: raise Errno::ENOENT, orig_path unless dirent 267: raise Errno::ENOTDIR, orig_path unless dirent.dir? 268: dirent 269: end