From 9bc5cf5e976354190b0d0991eb05ef7497fb3474 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Thu, 16 Mar 2023 23:55:08 +0100 Subject: [PATCH 1/5] Add RelativeBasePath parameter to Resolve-Path --- .../commands/management/ResolvePathCommand.cs | 74 +++++++++++++++++-- .../Resolve-Path.Tests.ps1 | 3 + 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs index 905a82c8e86..0bd1c78c254 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs @@ -75,6 +75,12 @@ public SwitchParameter Relative private SwitchParameter _relative; + /// + /// Gets or sets the path the resolved relative path should be based off. + /// + [Parameter()] + public string RelativeBasePath { get; set; } + #endregion Parameters #region parameter data @@ -84,10 +90,68 @@ public SwitchParameter Relative /// private string[] _paths; + private PSDriveInfo _relativeDrive; + private string _relativeBasePath; + #endregion parameter data #region Command code + /// + /// Finds the path and drive that should be used for relative path resolution + /// represents. + /// + protected override void BeginProcessing() + { + if (_relative) + { + if (!string.IsNullOrEmpty(RelativeBasePath)) + { + 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; + } + + _relativeDrive = SessionState.Path.CurrentLocation.Drive; + _relativeBasePath = SessionState.Path.CurrentLocation.ProviderPath; + return; + } + } + /// /// Resolves the path containing glob characters to the PowerShell paths that it /// represents. @@ -109,10 +173,9 @@ protected override void ProcessRecord() { // When result path and base path is on different PSDrive // (../)*path should not go beyond the root of base path - if (currentPath.Drive != SessionState.Path.CurrentLocation.Drive && - SessionState.Path.CurrentLocation.Drive != null && - !currentPath.ProviderPath.StartsWith( - SessionState.Path.CurrentLocation.Drive.Root, StringComparison.OrdinalIgnoreCase)) + if (currentPath.Drive != _relativeDrive && + _relativeDrive != null && + !currentPath.ProviderPath.StartsWith(_relativeDrive.Root, StringComparison.OrdinalIgnoreCase)) { WriteObject(currentPath.Path, enumerateCollection: false); continue; @@ -127,8 +190,7 @@ protected override void ProcessRecord() } baseCache = basePath; - string adjustedPath = SessionState.Path.NormalizeRelativePath(currentPath.Path, - SessionState.Path.CurrentLocation.ProviderPath); + string adjustedPath = SessionState.Path.NormalizeRelativePath(currentPath.Path, _relativeBasePath); // Do not insert './' if result path is not relative if (!adjustedPath.StartsWith( diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 index 87195c26352..e07b162646b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -48,4 +48,7 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { Pop-Location } } + It 'Resolve-Path -Relative should support user specified base paths' { + Resolve-Path -Path $fakeRoot -Relative -RelativeBasePath $testRoot | Should -BeExactly '.\fakeroot' + } } From 78f688af07beef1836ced343ad2a8ac59febccd1 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Fri, 17 Mar 2023 15:07:15 +0100 Subject: [PATCH 2/5] Fix test issue --- .../Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 index e07b162646b..6dfd5db3d95 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -49,6 +49,7 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } } It 'Resolve-Path -Relative should support user specified base paths' { - Resolve-Path -Path $fakeRoot -Relative -RelativeBasePath $testRoot | Should -BeExactly '.\fakeroot' + $Expected = Join-Path -Path .\ -ChildPath fakeroot + Resolve-Path -Path $fakeRoot -Relative -RelativeBasePath $testRoot | Should -BeExactly $Expected } } From 87ee9f25bc6991bf68821c73931e2ad449ffe5d4 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Mon, 20 Mar 2023 20:08:13 +0100 Subject: [PATCH 3/5] Add new parametersets --- .../commands/management/ResolvePathCommand.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs index 0bd1c78c254..06e8b3f7c69 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs @@ -22,6 +22,8 @@ public class ResolvePathCommand : CoreCommandWithCredentialsBase /// [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 @@ -40,6 +42,8 @@ public string[] Path /// [Parameter(ParameterSetName = "LiteralPath", Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)] + [Parameter(ParameterSetName = "LiteralPathWithRelativeBase", + Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)] [Alias("PSPath", "LP")] public string[] LiteralPath { @@ -59,7 +63,8 @@ public string[] LiteralPath /// Gets or sets the value that determines if the resolved path should /// be resolved to its relative version. /// - [Parameter()] + [Parameter(ParameterSetName = "Path")] + [Parameter(ParameterSetName = "LiteralPath")] public SwitchParameter Relative { get @@ -78,8 +83,21 @@ public SwitchParameter Relative /// /// Gets or sets the path the resolved relative path should be based off. /// - [Parameter()] - public string RelativeBasePath { get; set; } + [Parameter(Mandatory = true, ParameterSetName = "PathWithRelativeBase")] + [Parameter(Mandatory = true, ParameterSetName = "LiteralPathWithRelativeBase")] + public string RelativeBasePath + { + get + { + return _relativeBasePath; + } + + set + { + _relative = true; + _relativeBasePath = value; + } + } #endregion Parameters From 655472897f27c06cfb150cfddd2d309d238bf915 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Mon, 20 Mar 2023 21:16:54 +0100 Subject: [PATCH 4/5] Fix test issue --- .../Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 index 6dfd5db3d95..6403fd89789 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -50,6 +50,6 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } It 'Resolve-Path -Relative should support user specified base paths' { $Expected = Join-Path -Path .\ -ChildPath fakeroot - Resolve-Path -Path $fakeRoot -Relative -RelativeBasePath $testRoot | Should -BeExactly $Expected + Resolve-Path -Path $fakeRoot -RelativeBasePath $testRoot | Should -BeExactly $Expected } } From 090bf7c87e38280d0f556def0d33b2f808c1619b Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Tue, 21 Mar 2023 16:36:42 +0100 Subject: [PATCH 5/5] Update test description to be more accurate with recent changes --- .../Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 index 6403fd89789..91a16eb507b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -48,7 +48,7 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { Pop-Location } } - It 'Resolve-Path -Relative should support user specified base paths' { + It 'Resolve-Path should support user specified base paths' { $Expected = Join-Path -Path .\ -ChildPath fakeroot Resolve-Path -Path $fakeRoot -RelativeBasePath $testRoot | Should -BeExactly $Expected }