From 07f0798026a1ef612760413682ec90e00a3cbf56 Mon Sep 17 00:00:00 2001 From: Armaan Mcleod Date: Tue, 20 Aug 2024 11:16:32 +1000 Subject: [PATCH] Add `-Force` parameter to `Resolve-Path` and `Convert-Path` cmdlets to support wildcard hidden files (#20981) * Added -Force parameter to Resolve-Path * Added -Force parameter to Convert-Path * Added tests * Handle hidden file prefix for unix * Use OS automatic variables and cleanup test setup code * Add missing file prefix --- .../commands/management/ConvertPathCommand.cs | 10 +++ .../commands/management/ResolvePathCommand.cs | 10 +++ .../Convert-Path.Tests.ps1 | 69 +++++++++++++++++++ .../Resolve-Path.Tests.ps1 | 63 ++++++++++++++++- 4 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs index c32d0f2aa6..33796b2337 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs @@ -55,6 +55,16 @@ namespace Microsoft.PowerShell.Commands } } + /// + /// Gets or sets the force property. + /// + [Parameter] + public override SwitchParameter Force + { + get => base.Force; + set => base.Force = value; + } + #endregion Parameters #region parameter data diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs index b624c6e08c..3d1b66933d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs @@ -93,6 +93,16 @@ namespace Microsoft.PowerShell.Commands } } + /// + /// Gets or sets the force property. + /// + [Parameter] + public override SwitchParameter Force + { + get => base.Force; + set => base.Force = value; + } + #endregion Parameters #region parameter data diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 index 1cc88b36bb..7de1d97dd2 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 @@ -1,6 +1,27 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. Describe "Convert-Path tests" -Tag CI { + BeforeAll { + $hiddenFilePrefix = ($IsLinux -or $IsMacOS) ? '.' : '' + + $hiddenFilePath1 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test1.txt" + $hiddenFilePath2 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test2.txt" + + $hiddenFile1 = New-Item -Path $hiddenFilePath1 -ItemType File + $hiddenFile2 = New-Item -Path $hiddenFilePath2 -ItemType File + + $relativeHiddenFilePath1 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test1.txt" + $relativeHiddenFilePath2 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test2.txt" + + if ($IsWindows) { + $hiddenFile1.Attributes = "Hidden" + $hiddenFile2.Attributes = "Hidden" + } + + $hiddenFileWildcardPath = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test*.txt" + $relativeHiddenFileWildcardPath = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test*.txt" + } + It "Convert-Path should handle provider qualified paths" { Convert-Path -Path "FileSystem::${TestDrive}" | Should -BeExactly "${TestDrive}" } @@ -41,4 +62,52 @@ Describe "Convert-Path tests" -Tag CI { It "Convert-Path should return something which exists" { Convert-Path -Path $TestDrive | Should -Exist } + + It "Convert-Path -Path '' -Force: should return ''" -TestCases @( + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $false + ExpectedResult = $null + } + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $true + ExpectedResult = @($hiddenFilePath1, $hiddenFilePath2) + } + ) { + param($Path, $BasePath, $Force, $ExpectedResult) + try { + Push-Location -Path $BasePath + Convert-Path -Path $Path -Force:$Force | Should -BeExactly $ExpectedResult + } + finally { + Pop-Location + } + } } 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 efd2441e0a..9e38d1f8c2 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -16,6 +16,25 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { @{ wd = $fakeRoot; target = $testRoot; expected = $testRoot } @{ wd = $testRoot; target = Join-Path $fakeRoot "file.txt"; expected = Join-Path "." "fakeroot" "file.txt" } ) + + $hiddenFilePrefix = ($IsLinux -or $IsMacOS) ? '.' : '' + + $hiddenFilePath1 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test1.txt" + $hiddenFilePath2 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test2.txt" + + $hiddenFile1 = New-Item -Path $hiddenFilePath1 -ItemType File + $hiddenFile2 = New-Item -Path $hiddenFilePath2 -ItemType File + + $relativeHiddenFilePath1 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test1.txt" + $relativeHiddenFilePath2 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test2.txt" + + if ($IsWindows) { + $hiddenFile1.Attributes = "Hidden" + $hiddenFile2.Attributes = "Hidden" + } + + $hiddenFileWildcardPath = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test*.txt" + $relativeHiddenFileWildcardPath = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test*.txt" } AfterAll { Remove-PSDrive -Name $driveName -Force @@ -86,7 +105,7 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } ) -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" @@ -114,4 +133,46 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } } } + + It "Resolve-Path -Path '' -RelativeBasePath '' -Force: should return ''" -TestCases @( + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $false + ExpectedResult = $null + } + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $true + ExpectedResult = @($hiddenFilePath1, $hiddenFilePath2) + } + ) { + param($Path, $BasePath, $Force, $ExpectedResult) + (Resolve-Path -Path $Path -RelativeBasePath $BasePath -Force:$Force).Path | Should -BeExactly $ExpectedResult + } }