Background and motivation
I see a lot of folks implementing their own path normalization schemes so that they can compare paths as strings. Its understood that this does not handle symlinks or hardlinks - there are other methods for that.
Just search the codebase for normalizepath to see all the instances https://source.dot.net/#q=[NormalizePath](https://source.dot.net/#q=NormalizePath)
I recently addressed a bug in one implementation where we assumed TrimEndingDirectorySeparator would trim all separators but it only trims one.
microsoft/component-detection#1475
Simply trimming doesn't work since it doesn't handle the root separator.
Using GetFullPath doesn't work since it leaks the working directory for non-rooted paths.
Multiple directory separators need to be resolved to a single one, and normalized on the default separator.
Relative portions need to be removed when possible.
API Proposal
namespace System.IO;
public static class Path
{
public string NormalizePath(string Path, bool includeDirectorySeparator = false);
}
API Usage
var normalized1 = Path.Normalize(path1);
var normalized2 = Path.Normalize(path2);
var samePath = normalized1 == normalized2;
Alternative Designs
GetFullPath - leaks working directory, expensive.
Resolve to physical file, get normalized path from filesystem - same drawbacks as GetFullPath plus it requires a resolvable path which may not be the case for diagnostic scenarios.
Risks
Callers need to understand that even different normalized paths might point to the same object due to symlinks, hardlinks, mounted file-systems, network shares, etc.
Background and motivation
I see a lot of folks implementing their own path normalization schemes so that they can compare paths as strings. Its understood that this does not handle symlinks or hardlinks - there are other methods for that.
Just search the codebase for normalizepath to see all the instances https://source.dot.net/#q=[NormalizePath](https://source.dot.net/#q=NormalizePath)
I recently addressed a bug in one implementation where we assumed TrimEndingDirectorySeparator would trim all separators but it only trims one.
microsoft/component-detection#1475
Simply trimming doesn't work since it doesn't handle the root separator.
Using GetFullPath doesn't work since it leaks the working directory for non-rooted paths.
Multiple directory separators need to be resolved to a single one, and normalized on the default separator.
Relative portions need to be removed when possible.
API Proposal
API Usage
Alternative Designs
GetFullPath - leaks working directory, expensive.
Resolve to physical file, get normalized path from filesystem - same drawbacks as GetFullPath plus it requires a resolvable path which may not be the case for diagnostic scenarios.
Risks
Callers need to understand that even different normalized paths might point to the same object due to symlinks, hardlinks, mounted file-systems, network shares, etc.