mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Change how relative paths in Resolve-Path are handled when using the RelativeBasePath parameter (#19755)
This commit is contained in:
+58
-48
@@ -22,8 +22,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
[Parameter(Position = 0, ParameterSetName = "Path",
|
||||
Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[Parameter(Position = 0, ParameterSetName = "PathWithRelativeBase",
|
||||
Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
public string[] Path
|
||||
{
|
||||
get
|
||||
@@ -42,8 +40,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = "LiteralPath",
|
||||
Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)]
|
||||
[Parameter(ParameterSetName = "LiteralPathWithRelativeBase",
|
||||
Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)]
|
||||
[Alias("PSPath", "LP")]
|
||||
public string[] LiteralPath
|
||||
{
|
||||
@@ -83,8 +79,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// <summary>
|
||||
/// Gets or sets the path the resolved relative path should be based off.
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, ParameterSetName = "PathWithRelativeBase")]
|
||||
[Parameter(Mandatory = true, ParameterSetName = "LiteralPathWithRelativeBase")]
|
||||
[Parameter]
|
||||
public string RelativeBasePath
|
||||
{
|
||||
get
|
||||
@@ -94,7 +89,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
set
|
||||
{
|
||||
_relative = true;
|
||||
_relativeBasePath = value;
|
||||
}
|
||||
}
|
||||
@@ -121,52 +115,50 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
if (_relative)
|
||||
if (!string.IsNullOrEmpty(RelativeBasePath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(RelativeBasePath))
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
_relativeBasePath = SessionState.Internal.Globber.GetProviderPath(RelativeBasePath, CmdletProviderContext, out _, out _relativeDrive);
|
||||
}
|
||||
catch (ProviderNotFoundException providerNotFound)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
providerNotFound.ErrorRecord,
|
||||
providerNotFound));
|
||||
}
|
||||
catch (DriveNotFoundException driveNotFound)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
driveNotFound.ErrorRecord,
|
||||
driveNotFound));
|
||||
}
|
||||
catch (ProviderInvocationException providerInvocation)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
providerInvocation.ErrorRecord,
|
||||
providerInvocation));
|
||||
}
|
||||
catch (NotSupportedException notSupported)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(notSupported, "ProviderIsNotNavigationCmdletProvider", ErrorCategory.InvalidArgument, RelativeBasePath));
|
||||
}
|
||||
catch (InvalidOperationException invalidOperation)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(invalidOperation, "InvalidHomeLocation", ErrorCategory.InvalidOperation, RelativeBasePath));
|
||||
}
|
||||
|
||||
return;
|
||||
_relativeBasePath = SessionState.Internal.Globber.GetProviderPath(RelativeBasePath, CmdletProviderContext, out _, out _relativeDrive);
|
||||
}
|
||||
catch (ProviderNotFoundException providerNotFound)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
providerNotFound.ErrorRecord,
|
||||
providerNotFound));
|
||||
}
|
||||
catch (DriveNotFoundException driveNotFound)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
driveNotFound.ErrorRecord,
|
||||
driveNotFound));
|
||||
}
|
||||
catch (ProviderInvocationException providerInvocation)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(
|
||||
providerInvocation.ErrorRecord,
|
||||
providerInvocation));
|
||||
}
|
||||
catch (NotSupportedException notSupported)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(notSupported, "ProviderIsNotNavigationCmdletProvider", ErrorCategory.InvalidArgument, RelativeBasePath));
|
||||
}
|
||||
catch (InvalidOperationException invalidOperation)
|
||||
{
|
||||
ThrowTerminatingError(
|
||||
new ErrorRecord(invalidOperation, "InvalidHomeLocation", ErrorCategory.InvalidOperation, RelativeBasePath));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (_relative)
|
||||
{
|
||||
_relativeDrive = SessionState.Path.CurrentLocation.Drive;
|
||||
_relativeBasePath = SessionState.Path.CurrentLocation.ProviderPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +173,25 @@ namespace Microsoft.PowerShell.Commands
|
||||
Collection<PathInfo> result = null;
|
||||
try
|
||||
{
|
||||
result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
|
||||
if (MyInvocation.BoundParameters.ContainsKey("RelativeBasePath"))
|
||||
{
|
||||
// Pushing and popping the location is done because GetResolvedPSPathFromPSPath uses the current path to resolve relative paths.
|
||||
// It's important that we pop the location before writing an object to the pipeline to avoid affecting downstream commands.
|
||||
try
|
||||
{
|
||||
SessionState.Path.PushCurrentLocation(string.Empty);
|
||||
_ = SessionState.Path.SetLocation(_relativeBasePath);
|
||||
result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = SessionState.Path.PopLocation(string.Empty);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
|
||||
}
|
||||
|
||||
if (_relative)
|
||||
{
|
||||
|
||||
@@ -48,8 +48,70 @@ Describe "Resolve-Path returns proper path" -Tag "CI" {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
It 'Resolve-Path should support user specified base paths' {
|
||||
$Expected = Join-Path -Path .\ -ChildPath fakeroot
|
||||
Resolve-Path -Path $fakeRoot -RelativeBasePath $testRoot | Should -BeExactly $Expected
|
||||
It 'Resolve-Path RelativeBasePath should handle <Scenario>' -TestCases @(
|
||||
@{
|
||||
Scenario = "Absolute Path, Absolute ReleativeBasePath"
|
||||
Path = $root
|
||||
Basepath = $testRoot
|
||||
Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
|
||||
CD = $null
|
||||
}
|
||||
@{
|
||||
Scenario = "Relative Path, Absolute ReleativeBasePath"
|
||||
Path = ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
|
||||
Basepath = $testRoot
|
||||
Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
|
||||
CD = $null
|
||||
}
|
||||
@{
|
||||
Scenario = "Relative Path, Relative ReleativeBasePath"
|
||||
Path = ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
|
||||
Basepath = ".$([System.IO.Path]::DirectorySeparatorChar)"
|
||||
Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
|
||||
CD = $testRoot
|
||||
}
|
||||
@{
|
||||
Scenario = "Invalid Path, Absolute ReleativeBasePath"
|
||||
Path = Join-Path $testRoot ThisPathDoesNotExist
|
||||
Basepath = $root
|
||||
Expected = $null
|
||||
CD = $null
|
||||
}
|
||||
@{
|
||||
Scenario = "Invalid Path, Invalid ReleativeBasePath"
|
||||
Path = Join-Path $testRoot ThisPathDoesNotExist
|
||||
Basepath = Join-Path $testRoot ThisPathDoesNotExist
|
||||
Expected = $null
|
||||
CD = $null
|
||||
}
|
||||
) -Test {
|
||||
param($Path, $BasePath, $Expected, $CD)
|
||||
|
||||
if ($null -eq $Expected)
|
||||
{
|
||||
{Resolve-Path -Path $Path -RelativeBasePath $BasePath -ErrorAction Stop} | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand"
|
||||
{Resolve-Path -Path $Path -RelativeBasePath $BasePath -ErrorAction Stop -Relative} | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand"
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$OldLocation = if ($null -ne $CD)
|
||||
{
|
||||
$PWD
|
||||
Set-Location $CD
|
||||
}
|
||||
|
||||
(Resolve-Path -Path $Path -RelativeBasePath $BasePath).ProviderPath | Should -BeExactly $Expected[0]
|
||||
Resolve-Path -Path $Path -RelativeBasePath $BasePath -Relative | Should -BeExactly $Expected[1]
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($null -ne $OldLocation)
|
||||
{
|
||||
Set-Location $OldLocation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user