From 251c5dd36f72bcdea210909321430e4d856ab28c Mon Sep 17 00:00:00 2001 From: Mustafa Mohamad Date: Fri, 2 Apr 2021 16:25:31 -0400 Subject: [PATCH 1/2] Fix relpath when path and startpath are in the same drive When startpath == ".", assume the startpath is in the same drive. This subsequently required tweaking the existing logic to then canonicalize the drive casing in instances where the drive casing differs. --- base/path.jl | 18 +++++++++++++----- test/path.jl | 4 ++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/base/path.jl b/base/path.jl index 449085c00f26d..c11a5767c455e 100644 --- a/base/path.jl +++ b/base/path.jl @@ -517,12 +517,20 @@ function relpath(path::String, startpath::String = ".") curdir = "." pardir = ".." path == startpath && return curdir - path_drive, path_without_drive = splitdrive(path) - startpath_drive, startpath_without_drive = splitdrive(startpath) - path_arr = split(abspath(path_without_drive), path_separator_re) - start_arr = split(abspath(startpath_without_drive), path_separator_re) if Sys.iswindows() - lowercase(path_drive) != lowercase(startpath_drive) && return abspath(path) + path_drive, path_without_drive = splitdrive(path) + startpath_drive, startpath_without_drive = splitdrive(startpath) + isempty(startpath_drive) && (startpath_drive = path_drive) # by default assume same as path drive + + path_drive = uppercase(path_drive) # canonicalize drive letters to uppercasing for comparison + startpath_drive = uppercase(startpath_drive) + + path_drive != startpath_drive && return abspath(path) # if drives differ return first path + path_arr = split(abspath(path_drive * path_without_drive), path_separator_re) + start_arr = split(abspath(startpath_drive * startpath_without_drive), path_separator_re) + else + path_arr = split(abspath(path), path_separator_re) + start_arr = split(abspath(startpath), path_separator_re) end i = 0 while i < min(length(path_arr), length(start_arr)) diff --git a/test/path.jl b/test/path.jl index ca772e24d41de..e263b7c7db917 100644 --- a/test/path.jl +++ b/test/path.jl @@ -290,6 +290,10 @@ # Additional cases @test_throws ArgumentError relpath(S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)"), "") @test_throws ArgumentError relpath(S(""), S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)")) + + # issue 40237 + path = "..$(sep)a$(sep)b$(sep)c" + @test relpath(abspath(path)) == path end test_relpath() end From a8036f53668be61cce1c2fd403aa06bfa4d7c19f Mon Sep 17 00:00:00 2001 From: Mustafa Mohamad Date: Sat, 3 Apr 2021 01:45:22 -0400 Subject: [PATCH 2/2] Address code review --- base/path.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/base/path.jl b/base/path.jl index c11a5767c455e..88d050e750118 100644 --- a/base/path.jl +++ b/base/path.jl @@ -521,13 +521,9 @@ function relpath(path::String, startpath::String = ".") path_drive, path_without_drive = splitdrive(path) startpath_drive, startpath_without_drive = splitdrive(startpath) isempty(startpath_drive) && (startpath_drive = path_drive) # by default assume same as path drive - - path_drive = uppercase(path_drive) # canonicalize drive letters to uppercasing for comparison - startpath_drive = uppercase(startpath_drive) - - path_drive != startpath_drive && return abspath(path) # if drives differ return first path + uppercase(path_drive) == uppercase(startpath_drive) || return abspath(path) # if drives differ return first path path_arr = split(abspath(path_drive * path_without_drive), path_separator_re) - start_arr = split(abspath(startpath_drive * startpath_without_drive), path_separator_re) + start_arr = split(abspath(path_drive * startpath_without_drive), path_separator_re) else path_arr = split(abspath(path), path_separator_re) start_arr = split(abspath(startpath), path_separator_re)