path
path copied to clipboard
Segments that are just a drive letter are dropped on Windows
On Windows, the following code:
final String homeDrive = platform.environment['HOMEDRIVE'];
final String homePath = platform.environment['HOMEPATH'];
print(homeDrive);
print(homePath);
print(fs.path.join(homeDrive, homePath));
Outputs the following:
C:
\Users\danny
\Users\danny
The value of HOMEDRIVE
is something that's provided by Windows (without a trailing slash) and is often joined with HOMEPATH
so maybe it makes sense to support it here.
Windows paths like C:
are a weird case that this package currently doesn't attempt to handle at all, and it's not clear what the correct behavior should be. According to this MSDN article, a path of the form C:foo\bar
refers to foo\bar
relative to "the current directory on drive C". That's all well and good if the current drive is C
, but what does it mean when the current drive is D:
?
According to this Raymond Chen article, cmd.exe
uses environment variables to track a notion of the "current directory" for each drive. We have to figure out a policy for interacting with these separate drive directories in order to provide a correct view of paths on a Windows system.
I see three possibilities:
-
Shell out to
cmd
to check the current directory of a drive if doing so ever becomes necessary. This would require accessingdart:io
frompath
, which we've avoided so far, but which is now feasible due todart:io
being available anywhere.p.absolute("D:foo")
would produce"D:\whatever\dir\foo"
. -
Treat foreign drives' working directories as unknowable in the same way we treat the main working directory as unknowable for
p.windows
and friends.p.absolute("D:foo")
would produce"D:foo"
. -
Treat foreign drives' working directories as the root directory. This is the default behavior for a
cmd.exe
that's spawned outside the context of any other command prompt, and it will be correct a high percentage of the time since presumably most users won't be flipping between drives.
I lean towards option 2. I don't like the performance characteristics of option 1 (or the fact that the subprocess spawn could hypothetically flake), and I don't like even the marginal possibility of incorrectness in option 3.
@munificent I'd appreciate your thoughts on this.
I decided to try this out on dotnetfiddle, figuring .NET might be a good thing to copy since it came from MS... However:
Console.WriteLine(Path.Combine("C:", "\\test\\test"));
Console.WriteLine(Path.Combine("C:", "test\\test"));
Console.WriteLine(Path.Combine("X:", "\\test\\test"));
Console.WriteLine(Path.Combine("X:", "test\\test"));
Outputs:
\test\test
C:test\test
\test\test
X:test\test
So actually it's not doing what I'd want anyway. In my original example I had C:
and \Users\danny
which in .NET would've returned me \Users\danny
regardless of my current drive, which would be incorrect if my current drive wasn't C
!
So, probably the fix isn't going to be usable with HOMEDRIVE
/HOMEPATH
directly anyway, so I'll have to do just concat the strings myself (as I am currently).
I think the right interpretation is that HOMEDRIVE
is not a path on its own, it's a string you can use to build a path.
Yeah, I think that makes sense. I (incorrectly) assumed they would both be in a nice format to use in path.join's etc., but these things are probably as old as me! 😀
@munificent In practice, it seems that listing a string like C:
as a directory does list the working directory, so I think there's a case to be made for considering it a path. But whether you do or not, C:foo
is definitely a path, and we need to decide how to handle it.
Hello, do you consider fixing this issue?
Hello, do you consider fixing this issue?
Please, disregard. I just saw that it is working as expected in 1.8.0-nullsafety.1.