From 40eb3b3e13d8c9694e3c66e738f66cde75687562 Mon Sep 17 00:00:00 2001 From: Chunqing Chen Date: Wed, 7 Feb 2018 16:30:14 -0800 Subject: [PATCH] Get-ChildItem /* -file should include as search directory (#5431) * get-childitem /* -file should include as search directory * [Feature] Added check for -Directory and more tests * [Feature] Added check for the dynamic parameter type --- .../engine/SessionStateContainer.cs | 19 +++++++++-- .../Get-ChildItem.Tests.ps1 | 33 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/SessionStateContainer.cs b/src/System.Management.Automation/engine/SessionStateContainer.cs index 3541a1d9bf..687f1be639 100644 --- a/src/System.Management.Automation/engine/SessionStateContainer.cs +++ b/src/System.Management.Automation/engine/SessionStateContainer.cs @@ -1499,6 +1499,22 @@ namespace System.Management.Automation // expectations: if (recurse) { + string childName = GetChildName(path, context); + + // If -File or -Directory is specified and path is ended with '*', we should include the parent path as search path + + bool isFileOrDirectoryPresent = false; + + if(context.DynamicParameters is Microsoft.PowerShell.Commands.GetChildDynamicParameters dynParam) + { + isFileOrDirectoryPresent = dynParam.File.IsPresent || dynParam.Directory.IsPresent; + } + + if (String.Equals(childName, "*", StringComparison.OrdinalIgnoreCase) && isFileOrDirectoryPresent) + { + string parentName = path.Substring(0, path.Length - childName.Length); + path = parentName; + } // dir c:\tem* -include *.ps1 -rec => No change if ((context.Include == null) || (context.Include.Count == 0)) { @@ -1509,9 +1525,8 @@ namespace System.Management.Automation // Should glob paths and files that match tem*, but then // recurse into all subdirectories and do the same for // those directories. - if ((!String.IsNullOrEmpty(path)) && (!IsItemContainer(path))) + if (!String.IsNullOrEmpty(path) && !IsItemContainer(path)) { - string childName = GetChildName(path, context); if (!String.Equals(childName, "*", StringComparison.OrdinalIgnoreCase)) { if (context.Include != null) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 index 1956a558f9..5979d64562 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 @@ -10,7 +10,7 @@ Describe "Get-ChildItem" -Tags "CI" { $item_D = "D39B4FD9-3E1D-4DD5-8718-22FE2C934CE3" $item_E = "EE150FEB-0F21-4AFF-8066-AF59E925810C" $item_F = ".F81D8514-8862-4227-B041-0529B1656A43" - $item_G = "5560A62F-74F1-4FAE-9A23-F4EBD90D2676" + $item_G = "5560A62F-74F1-4FAE-9A23-F4EBD90D2676" $null = New-Item -Path $TestDrive -Name $item_a -ItemType "File" -Force $null = New-Item -Path $TestDrive -Name $item_B -ItemType "File" -Force $null = New-Item -Path $TestDrive -Name $item_c -ItemType "File" -Force @@ -18,6 +18,18 @@ Describe "Get-ChildItem" -Tags "CI" { $null = New-Item -Path $TestDrive -Name $item_E -ItemType "Directory" -Force $null = New-Item -Path $TestDrive -Name $item_F -ItemType "File" -Force | ForEach-Object {$_.Attributes = "hidden"} $null = New-Item -Path (Join-Path -Path $TestDrive -ChildPath $item_E) -Name $item_G -ItemType "File" -Force + + $searchRoot = Join-Path $TestDrive -ChildPath "TestPS" + $file1 = Join-Path $searchRoot -ChildPath "D1" -AdditionalChildPath "File1.txt" + $file2 = Join-Path $searchRoot -ChildPath "File1.txt" + + $PathWildCardTestCases = @( + @{Parameters = @{Path = $searchRoot; Recurse = $true; Directory = $true }; ExpectedCount = 1; Title = "directory without wildcard"}, + @{Parameters = @{Path = (Join-Path $searchRoot '*'); Recurse = $true; Directory = $true }; ExpectedCount = 1; Title = "directory with wildcard"}, + @{Parameters = @{Path = $searchRoot; Recurse = $true; File = $true }; ExpectedCount = 1; Title = "file without wildcard"}, + @{Parameters = @{Path = (Join-Path $searchRoot '*'); Recurse = $true; File = $true }; ExpectedCount = 1; Title = "file with wildcard"}, + @{Parameters = @{Path = (Join-Path $searchRoot 'F*.txt'); Recurse = $true; File = $true }; ExpectedCount = 1; Title = "file with wildcard filename"} + ) } It "Should list the contents of the current folder" { @@ -80,6 +92,25 @@ Describe "Get-ChildItem" -Tags "CI" { (Get-ChildItem -Path $TestDrive -Depth 1 -Include $item_G).Count | Should Be 1 (Get-ChildItem -Path $TestDrive -Depth 1 -Exclude $item_a).Count | Should Be 5 } + + It "get-childitem path wildcard - " -TestCases $PathWildCardTestCases { + param($Parameters, $ExpectedCount) + + $null = New-Item $file1 -Force -ItemType File + + (Get-ChildItem @Parameters).Count | Should Be $ExpectedCount + } + + It "get-childitem with and without file in search root" { + $null = New-Item $file2 -Force -ItemType File + + (Get-ChildItem -Path $searchRoot -File -Recurse).Count | Should be 2 + (Get-ChildItem -Path $searchRoot -Directory -Recurse).Count | Should be 1 + + Remove-Item $file2 -ErrorAction SilentlyContinue -Force + (Get-ChildItem -Path $searchRoot -File -Recurse).Count | Should be 1 + (Get-ChildItem -Path $searchRoot -Directory -Recurse).Count | Should be 1 + } } Context 'Env: Provider' {