diff --git a/spec/std/path_spec.cr b/spec/std/path_spec.cr index 2f38cfedca11..eaa609a753a5 100644 --- a/spec/std/path_spec.cr +++ b/spec/std/path_spec.cr @@ -166,10 +166,6 @@ describe Path do assert_paths("foo/bar/./.", [".", "foo", "foo/bar", "foo/bar/."], &.parents) end - describe "#dirname" do - assert_paths_raw("/Users/foo/bar.cr", "/Users/foo", &.dirname) - end - describe "#basename" do assert_paths_raw("/foo/bar/baz.cr", "baz.cr", &.basename) assert_paths_raw("/foo/", "foo", &.basename) diff --git a/src/file.cr b/src/file.cr index 13f303fa1950..c6f0ec2a1e3f 100644 --- a/src/file.cr +++ b/src/file.cr @@ -255,7 +255,7 @@ class File < IO::FileDescriptor # File.dirname("/foo/bar/file.cr") # => "/foo/bar" # ``` def self.dirname(path) : String - Path.new(path).dirname + Path.new(path).parent.to_s end # Returns the last component of the given *path*. diff --git a/src/path.cr b/src/path.cr index 976da6aff347..2955311c12ce 100644 --- a/src/path.cr +++ b/src/path.cr @@ -176,7 +176,25 @@ struct Path # ``` # Path["/foo/bar/file.cr"].dirname # => "/foo/bar" # ``` - def dirname : String + @[Deprecated("Use `Path#parent.to_s` instead")] + def dirname : Path + parent.to_s + end + + # Returns the parent path of this path, all components of this path except the last one. + # + # If the path is empty or `"."`, it returns `"."`. If the path is rooted + # and in the top-most hierarchy, the root path is returned. + # + # ``` + # Path["foo/bar/file.cr"].parent # => Path["foo/bar"] + # Path["foo"].parent # => Path["."] + # Path["/foo"].parent # => Path["/"] + # Path["/"].parent # => Path["/"] + # Path[""].parent # => Path["."] + # Path["foo/bar/."].parent # => Path["foo/bar"] + # ``` + def parent : Path reader = Char::Reader.new(at_end: @name) separators = self.separators @@ -199,39 +217,22 @@ struct Path current = reader.current_char if separators.includes?(current) - return current.to_s + return new_instance current.to_s else # skip windows here for next condition regarding anchor if windows? && reader.has_next? && reader.peek_next_char == ':' reader.next_char else - return "." + return new_instance "." end end end if windows? && reader.current_char == ':' && reader.pos == 1 && (anchor = self.anchor) - return anchor.to_s + return anchor end - @name.byte_slice(0, reader.pos + 1) - end - - # Returns the parent path of this path. - # - # If the path is empty or `"."`, it returns `"."`. If the path is rooted - # and in the top-most hierarchy, the root path is returned. - # - # ``` - # Path["foo/bar/file.cr"].parent # => Path["foo/bar"] - # Path["foo"].parent # => Path["."] - # Path["/foo"].parent # => Path["/"] - # Path["/"].parent # => Path["/"] - # Path[""].parent # => Path["."] - # Path["foo/bar/."].parent # => Path["foo/bar"] - # ``` - def parent : Path - new_instance dirname + new_instance @name.byte_slice(0, reader.pos + 1) end # Returns all parent paths of this path beginning with the topmost path.