A canonical path should have all existing components canonicalized
Currently, AbsolutePath::Canonicalize will mostly do nothing for a non-existing path, it will be returned as-is.
Which is mostly fine, but might cause misinterpretation on the user's side: e.g. while myPath.Canonicalize() is okay-ish and follows the spec "canonical if exists", myPath.Canonicalize().Parent is not okay — if myPath doesn't exist then this will not be canonicalized, even if existing.
We should think about this situation, perhaps let's introduce two more methods?
-
CanonicalIfExists(): AbsolutePath? -
CanonicalRecursive(): AbsolutePath— which will essentially doCanonicalIfExists() ?? Parent.CanonicalRecursive() / FileName— e.g. will try to canonicalize existing parent chain whenever possible
Note I lean towards not following the parent chain solution in default implementation of .Canonicalize(), because of its less predictable IO performance impact and potential pathological cases (technically a malicious program could cause it to loop endlessly and/or eat all the available memory by exploiting a race condition and updating several symlinks by point to each other during its execution).