require "ftools" class Dir def self.mkdirrec(dir) pdir = File.dirname(dir) if not pdir.empty? and not File.directory?(pdir) Dir.mkdirrec(pdir) end Dir.mkdir(dir) rescue nil end def self.copy(from, to) if File.directory?(from) pdir = Dir.pwd todir = File.expand_path(to) mkdirrec(todir) Dir.chdir(from) Dir.new(".").each do |e| Dir.copy(e, todir+"/"+e) if not [".", ".."].include?(e) end Dir.chdir(pdir) else todir = File.dirname(File.expand_path(to)) mkdirrec(todir) File.copy(from, to) end end def self.move(from, to) Dir.copy(from, to) Dir.rm_rf(from) end def self.rm_rf(entry) if File.ftype(entry) == "directory" pdir = Dir.pwd Dir.chdir(entry) Dir.new(".").each do |e| Dir.rm_rf(e) if not [".", ".."].include?(e) end Dir.chdir(pdir) Dir.delete(entry) else File.delete(entry) end end def self.find(entry=nil, mask=nil) entry = "." if entry.nil? entry = entry.gsub!(/[\/\\]*$/, "") unless entry.nil? mask = /^#{mask}$/i if mask.kind_of?(String) res = [] if File.directory?(entry) pdir = Dir.pwd res += ["%s/" % entry] if mask.nil? or entry =~ mask begin Dir.chdir(entry) begin Dir.new(".").each do |e| res += Dir.find(e, mask).collect{|e| entry+"/"+e} unless [".", ".."].include?(e) end ensure Dir.chdir(pdir) end rescue Errno::EACCES => error puts error end else res += [entry] if mask.nil? or entry =~ mask end res end end class File def self.rollbackup(file, mode=nil) backupfile = file + ".RB.BACKUP" controlfile = file + ".RB.CONTROL" res = nil File.touch(file) unless File.file?(file) # Rollback if File.file?(backupfile) and File.file?(controlfile) $stdout.puts "Restoring #{file}..." File.copy(backupfile, file) # Rollback from phase 3 end # Reset File.delete(backupfile) if File.file?(backupfile) # Reset from phase 2 or 3 File.delete(controlfile) if File.file?(controlfile) # Reset from phase 3 or 4 # Backup File.copy(file, backupfile) # Enter phase 2 File.touch(controlfile) # Enter phase 3 # The real thing if block_given? if mode.nil? res = yield else File.open(file, mode) do |f| res = yield(f) end end end # Cleanup File.delete(backupfile) # Enter phase 4 File.delete(controlfile) # Enter phase 5 # Return, like File.open res = File.open(file, (mode or "r")) unless block_given? res end def self.touch(file) File.open(file, "a"){|f|} end def self.which(file) res = nil if windows? file = file.gsub(/\.exe$/i, "") + ".exe" sep = ";" else sep = ":" end catch :stop do ENV["PATH"].split(/#{sep}/).reverse.each do |d| if File.directory?(d) Dir.new(d).each do |e| if e.downcase == file.downcase res = File.expand_path(e, d) throw :stop end end end end end res end end