Skip to content

Commit

Permalink
file
Browse files Browse the repository at this point in the history
continue file

continue file spec

.

done

renamed helper
  • Loading branch information
moste00 committed Mar 7, 2023
1 parent 49eaf5b commit 4761dc1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 29 deletions.
14 changes: 14 additions & 0 deletions spec/ruby/core/file/dirname_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@
it "raises ArgumentError if the level is negative" do
-> {File.dirname('/home/jason', -1)}.should raise_error(ArgumentError)
end

it "returns the exact same object when passed 0 as the level" do
obj = "path"
File.dirname(obj,0).should .equal?(obj)

obj = mock("to_path")
def obj.to_path
"path"
end
File.dirname(obj,0).should .equal?(obj)

obj = Object.new
File.dirname(obj,0).should .equal?(obj)
end
end

it "returns a String" do
Expand Down
2 changes: 0 additions & 2 deletions spec/tags/core/file/dirname_tags.txt

This file was deleted.

43 changes: 16 additions & 27 deletions src/main/ruby/truffleruby/core/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -415,37 +415,26 @@ def self.last_nonslash(path, start=nil)
# the separator used on the local file system.
#
# File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work"
def self.dirname(path)
path = Truffle::Type.coerce_to_path(path)

# edge case
return +'.' if path.empty?

slash = '/'

# pull off any /'s at the end to ignore
chunk_size = last_nonslash(path)
return +'/' unless chunk_size

if pos = Primitive.find_string_reverse(path, slash, chunk_size)
return +'/' if pos == 0

path = path.byteslice(0, pos)

return +'/' if path == '/'

return path unless path.end_with? slash
def self.dirname(path,num_levels=1)
if num_levels < 0
raise ArgumentError, "level can't be negative"
end
#This must happen before the type coercion to string below, because File.dirname accepts any objects which can respond to a :to_path message
#If path was such an object, File.dirname(obj,0) returns it as-is without conversion to string
#Tricky, but that's how Matz ruby behave
if num_levels == 0
return path
end

# prune any trailing /'s
idx = last_nonslash(path, pos)
path = Truffle::Type.coerce_to_path(path)

# edge case, only /'s, return /
return +'/' unless idx
num_levels.times do
# edge case
return +'.' if path.empty?

return path.byteslice(0, idx - 1)
path = Truffle::FileOperations.remove_last_segment_from_path(path)
end

+'.'
path
end

##
Expand Down
29 changes: 29 additions & 0 deletions src/main/ruby/truffleruby/core/truffle/file_operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,34 @@ def self.expand_path(path, dir, expand_tilde)
def self.exist?(path)
Truffle::POSIX.truffleposix_stat_mode(path) > 0
end

#Helper to File.dirname, extracts the directory of a path (doesn't need to handle the empty string)
#This was the original File.dirname, but ruby 3.1 made File.dirname take an optional number of times to do its logic
def self.remove_last_segment_from_path(path)
slash = '/'
# pull off any /'s at the end to ignore
chunk_size = File.last_nonslash(path)
return +'/' unless chunk_size

if pos = Primitive.find_string_reverse(path, slash, chunk_size)
return +'/' if pos == 0

path = path.byteslice(0, pos)

return +'/' if path == '/'

return path unless path.end_with? slash

# prune any trailing /'s
idx = File.last_nonslash(path, pos)

# edge case, only /'s, return /
return +'/' unless idx

return path.byteslice(0, idx - 1)
end

+'.'
end
end
end

0 comments on commit 4761dc1

Please sign in to comment.