Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions spec/std/path_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/file.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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*.
Expand Down
45 changes: 23 additions & 22 deletions src/path.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
Expand Down