=begin attribute absolute and dir return String, method absolute_path(), dirname() return Pa Pa("/home/a").dir #=> "/home" Pa("/home/a").dirname #=> Pa("/home") == methods from String * + * [g]sub[!] match =~ * start_with? end_with? =end class Pa module Path extend Util::Concern DELEGATE_CLASS_METHODS = [:pwd, :dir, :expand, :real, :parent, :relative_to, :shorten, :delete_ext, :add_ext ] module ClassMethods # Return current work directory # # @return [String] path def pwd2 Dir.getwd end # Is path an absolute path ? # # @param [String,Pa] path # @return [Boolean] def absolute?(path) p = get(path) File.absolute_path(p, ".") == p # rbx end # Is path a dangling symlink? # # a dangling symlink is a dead symlink. # # @param [String,Pa] path # @return [Boolean] def dangling?(path) p = get(path) if File.symlink?(p) src = File.readlink(p) not File.exists?(src) else nil end end # Alias from File.expand_path # # @param [String,Pa] path # @return [String] def expand2(name, dir=".") File.expand_path(get(name), dir) end # Alias from Filel.realpath # # @param [String, Pa] path # @return [String] def real2(name, dir=".") File.realpath(get(name), dir) end # Path relative_to? dir # # @example # # Pa.relative_to?("/home/foo", "/home") -> true # Pa.relative_to?("/home1/foo", "/home") -> false # def relative_to?(path, dir) path_parts = Pa.split2(get(path), all: true) dir_parts = Pa.split2(get(dir), all: true) index = -1 dir_parts.all? {|part| index += 1 path_parts[index] == part } end # Delete the head. # # @example # # Pa.relative_to2("/home/foo", "/home") -> "foo" # Pa.relative_to2("/home/foo", "/home/foo") -> "." # Pa.relative_to2("/home/foo", "/bin") -> "/home/foo" # # Pa.relative_to2("/home/foo", "/home/foo/") -> "." # Pa.relative_to2("/home/foo/", "/home/foo") -> "." # # @return [String] def relative_to2(path, dir) p = get(path) if relative_to?(p, dir) path_parts = Pa.split(p, all: true) dir_parts = Pa.split(dir, all: true) ret = File.join(*path_parts[dir_parts.length..-1]) ret == "" ? "." : ret else p end end # Return true if a path has the ext. # # @example # # Pa.has_ext?("foo.txt", ".epub", ".txt") -> true # Pa.has_ext?("foo", ".txt") -> false # def has_ext?(path, *exts) exts.include? Pa.ext2(get(path)) end # Delete the tail. # # @example # # Pa.delete_ext2("foo.txt", ".epub", ".txt") -> "foo" # Pa.delete_ext2("foo", ".txt") -> "foo" # Pa.delete_ext2("foo.epub", ".txt") -> "foo.epub" # def delete_ext2(path, *exts) p = get(path) exts.each {|ext| if has_ext?(p, ext) return p[0...p.rindex(ext)] end } p end # Ensure the tail # # @example # # Pa.add_ext2("foo", ".txt") -> "foo.txt" # Pa.add_ext2("foo.txt", ".txt") -> "foo.txt" # Pa.add_ext2("foo.epub", ".txt") -> "foo.txt.epub" # def add_ext2(path, ext) p = get(path) if Pa.ext2(p) == ext p else "#{p}#{ext}" end end # shorten2 a path, # convert /home/user/file to ~/file # # @param [String,Pa] path # @return [String] def shorten2(path) p = get(path) home = Pa.home2 return p if home.empty? ret = relative_to2(p, home) if ret == p p else ret == "." ? "" : ret File.join("~", ret) end end # get parent path # # @param [String,Pa] path # @param [Fixnum] n up level # @return [String] def parent2(path, n=1) path = get(path) n.times do path = File.dirname(path) end path end DELEGATE_CLASS_METHODS.each { |mth| mth2 = "#{mth}2" eval <<-EOF def #{mth}(*args, &blk) Pa(Pa.#{mth2}(*args, &blk)) end EOF } private end DELEGATE_METHODS2 = [ :parent2, :delete_ext2, :add_ext2 ] DELEGATE_METHODS = [ :parent, :delete_ext, :add_ext] DELEGATE_METHODS2.each do |mth2| class_eval <<-EOF def #{mth2}(*args, &blk) Pa.#{mth2}(path, *args, &blk) end EOF end DELEGATE_METHODS.each do |mth| class_eval <<-EOF def #{mth}(*args, &blk) Pa(#{mth}2(*args, &blk)) end EOF end end end