Summary of the new feature/enhancement
Especially in the Unix world, symlinks are often define with relative target paths, which enables you to later move the symlink along with its target to a different directory subtree without breaking the link.
The .Target ETS property we add to FileInfo / DirectoryInfo instances reports a symlink's target path as defined (though there is an open bug regarding the current behavior on Unix: #13365).
However, it would also be convenient to have an easy way to resolve the target path to a full (absolute) path, which is cumbersome to do manually:
# Given $symlink as a FileInfo / DirectoryInfo instance:
$fullTargetPath = [IO.Path]::GetFullPath($symlink.Target, (Split-Path $symLink.FullName))
Proposed technical implementation details (optional)
Add a new .ResolvedTarget ETS property to FileInfo / DirectoryInfo instances that behaves as follows:
-
Resolve the target path to a full path as shown above:
- If the resulting path exists, report it as such.
- Otherwise, report
$null to indicate that the symlink is broken.
-
If the item at hand isn't a symlink / reparse point, simply report its own full path - this allows unified treatment of symlinks and non-symlinks, as a simple way to get an item's full path.
Ideally, the .ResolvedTarget property would return a FileInfo / DirectoryInfo rather than a path string (with $null as the return value if the target doesn't exist), but there are two considerations:
- performance in general
- to be consistent with
Get-Item / Get-ChildItem output, the usual PS provider properties must be added to the output FileInfo / DirectoryInfo instances, such as .PSPath.
To mitigate performance issues, .ResolvedTarget should only be calculated on demand and therefore be implemented as a CodeMethod property (which .Target is too).
Related issues:
Summary of the new feature/enhancement
Especially in the Unix world, symlinks are often define with relative target paths, which enables you to later move the symlink along with its target to a different directory subtree without breaking the link.
The
.TargetETS property we add toFileInfo/DirectoryInfoinstances reports a symlink's target path as defined (though there is an open bug regarding the current behavior on Unix: #13365).However, it would also be convenient to have an easy way to resolve the target path to a full (absolute) path, which is cumbersome to do manually:
Proposed technical implementation details (optional)
Add a new
.ResolvedTargetETS property toFileInfo/DirectoryInfoinstances that behaves as follows:Resolve the target path to a full path as shown above:
$nullto indicate that the symlink is broken.If the item at hand isn't a symlink / reparse point, simply report its own full path - this allows unified treatment of symlinks and non-symlinks, as a simple way to get an item's full path.
Ideally, the
.ResolvedTargetproperty would return aFileInfo/DirectoryInforather than a path string (with$nullas the return value if the target doesn't exist), but there are two considerations:Get-Item/Get-ChildItemoutput, the usual PS provider properties must be added to the outputFileInfo/DirectoryInfoinstances, such as.PSPath.To mitigate performance issues,
.ResolvedTargetshould only be calculated on demand and therefore be implemented as aCodeMethodproperty (which.Targetis too).Related issues:
Proposed API for symbolic links dotnet/runtime#24271 (comment) (.NET Core API suggestion to add a
System.IO.Path.GetFullPath()overload for canonical path resolution).Support getting canonical filesystem paths with symlinks resolved, similar to the Linux realpath utility #10640 (PowerShell-side proposal to implement canonical path resolution via
Convert-Path -Canonical).