From 9d3e93fe46182c6d5609898bc9f7ed0685dbabf4 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:21:24 -0400 Subject: [PATCH 1/7] Fix pattern matching code to match specific pkgName.version.nupkg not packageName* to avoid unwanted wildcard clashes --- src/code/LocalServerApiCalls.cs | 54 ++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index c32f3db57..43a1c67c4 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -255,35 +255,55 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu FindResults findResponse = new FindResults(); errRecord = null; - WildcardPattern pkgNamePattern = new WildcardPattern($"{packageName}.*", WildcardOptions.IgnoreCase); + WildcardPattern pkgNamePattern = new WildcardPattern($"{packageName}.", WildcardOptions.IgnoreCase); NuGetVersion latestVersion = new NuGetVersion("0.0.0.0"); String latestVersionPath = String.Empty; string actualPkgName = packageName; + string regexPattern = $"{packageName}" + @".\d+\.\d+\.\d+(?:-\w+|.\d)*.nupkg"; + Regex rx = new Regex(regexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + + _cmdletPassedIn.WriteDebug($"pattern is: {regexPattern}"); + foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath)) { string packageFullName = Path.GetFileName(path); + MatchCollection matches = rx.Matches(packageFullName); + if (matches.Count == 0) + { + continue; + } - if (!String.IsNullOrEmpty(packageFullName) && pkgNamePattern.IsMatch(packageFullName)) + Match match = matches[0]; + + GroupCollection groups = match.Groups; + if (groups.Count == 0) { - NuGetVersion nugetVersion = GetInfoFromFileName(packageFullName: packageFullName, packageName: packageName, actualName: out actualPkgName, out errRecord); - _cmdletPassedIn.WriteDebug($"Version parsed as '{nugetVersion}'"); + continue; + } - if (errRecord != null) - { - return findResponse; - } + Capture group = groups[0]; - if ((!nugetVersion.IsPrerelease || includePrerelease) && (nugetVersion > latestVersion)) + _cmdletPassedIn.WriteDebug($"package name is: {packageFullName}"); + // string pkgFoundName = packageFullName.Substring(0, group.Index); + + NuGetVersion nugetVersion = GetInfoFromFileName(packageFullName: packageFullName, packageName: packageName, actualName: out actualPkgName, out errRecord); + _cmdletPassedIn.WriteDebug($"Version parsed as '{nugetVersion}'"); + + if (errRecord != null) + { + return findResponse; + } + + if ((!nugetVersion.IsPrerelease || includePrerelease) && (nugetVersion > latestVersion)) + { + if (nugetVersion > latestVersion) { - if (nugetVersion > latestVersion) - { - latestVersion = nugetVersion; - latestVersionPath = path; - } + latestVersion = nugetVersion; + latestVersionPath = path; } } - } + } if (String.IsNullOrEmpty(latestVersionPath)) { @@ -880,6 +900,10 @@ private NuGetVersion GetInfoFromFileName(string packageFullName, string packageN // packageFullName will look like package.1.0.0.nupkg errRecord = null; + // Microsoft.Graph.Users + // Microsoft.Graph.Users.Actions + // packageName should contain the pkg name that the user searched for + // actualName will be the name with the casing package.nupkg had, which is the casing we use when returning to the user string[] packageWithoutName = packageFullName.ToLower().Split(new string[]{ $"{packageName.ToLower()}." }, StringSplitOptions.RemoveEmptyEntries); string packageVersionAndExtension = packageWithoutName[0]; string[] originalFileNameParts = packageFullName.Split(new string[]{ $".{packageVersionAndExtension}" }, StringSplitOptions.RemoveEmptyEntries); From 55a7f03a3e18507eea1079ced7f74d8f1ad883a1 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:27:32 -0400 Subject: [PATCH 2/7] remove unused code --- src/code/LocalServerApiCalls.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index 43a1c67c4..bf63e7250 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -255,7 +255,6 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu FindResults findResponse = new FindResults(); errRecord = null; - WildcardPattern pkgNamePattern = new WildcardPattern($"{packageName}.", WildcardOptions.IgnoreCase); NuGetVersion latestVersion = new NuGetVersion("0.0.0.0"); String latestVersionPath = String.Empty; string actualPkgName = packageName; From de1c5aebce50776cc778e2f73b397d8a6490cff5 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:28:36 -0400 Subject: [PATCH 3/7] remove unused code some more --- src/code/LocalServerApiCalls.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index bf63e7250..9494fd2d1 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -283,9 +283,6 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu Capture group = groups[0]; - _cmdletPassedIn.WriteDebug($"package name is: {packageFullName}"); - // string pkgFoundName = packageFullName.Substring(0, group.Index); - NuGetVersion nugetVersion = GetInfoFromFileName(packageFullName: packageFullName, packageName: packageName, actualName: out actualPkgName, out errRecord); _cmdletPassedIn.WriteDebug($"Version parsed as '{nugetVersion}'"); @@ -302,7 +299,7 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu latestVersionPath = path; } } - } + } if (String.IsNullOrEmpty(latestVersionPath)) { From 96c6b5290c783f1739b51cf78c05961a9a50d1c6 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 12 Jun 2024 13:08:48 -0400 Subject: [PATCH 4/7] use Regex instead of WildcardPattern for FindVersion() too --- src/code/LocalServerApiCalls.cs | 46 ++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index 9494fd2d1..e7e4b348c 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -387,29 +387,45 @@ private FindResults FindVersionHelper(string packageName, string version, string return findResponse; } - WildcardPattern pkgNamePattern = new WildcardPattern($"{packageName}.*", WildcardOptions.IgnoreCase); + string regexPattern = $"{packageName}.{requiredVersion.ToNormalizedString()}" + @".nupkg"; + Regex rx = new Regex(regexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + _cmdletPassedIn.WriteDebug($"pattern is: {regexPattern}"); string pkgPath = String.Empty; string actualPkgName = String.Empty; + foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath)) { string packageFullName = Path.GetFileName(path); - if (!String.IsNullOrEmpty(packageFullName) && pkgNamePattern.IsMatch(packageFullName)) + MatchCollection matches = rx.Matches(packageFullName); + if (matches.Count == 0) { - NuGetVersion nugetVersion = GetInfoFromFileName(packageFullName: packageFullName, packageName: packageName, actualName: out actualPkgName, out errRecord); - _cmdletPassedIn.WriteDebug($"'{packageName}' version parsed as '{nugetVersion}'"); + continue; + } - if (errRecord != null) - { - return findResponse; - } + Match match = matches[0]; - if (nugetVersion == requiredVersion) - { - _cmdletPassedIn.WriteDebug("Found matching version"); - string pkgFullName = $"{actualPkgName}.{nugetVersion.ToString()}.nupkg"; - pkgPath = Path.Combine(Repository.Uri.LocalPath, pkgFullName); - break; - } + GroupCollection groups = match.Groups; + if (groups.Count == 0) + { + continue; + } + + Capture group = groups[0]; + + NuGetVersion nugetVersion = GetInfoFromFileName(packageFullName: packageFullName, packageName: packageName, actualName: out actualPkgName, out errRecord); + _cmdletPassedIn.WriteDebug($"Version parsed as '{nugetVersion}'"); + + if (errRecord != null) + { + return findResponse; + } + + if (nugetVersion == requiredVersion) + { + _cmdletPassedIn.WriteDebug("Found matching version"); + string pkgFullName = $"{actualPkgName}.{nugetVersion.ToString()}.nupkg"; + pkgPath = Path.Combine(Repository.Uri.LocalPath, pkgFullName); + break; } } From 61a227e0bbd74bd2e53ad6def4668b990174b1a2 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 17 Jun 2024 12:27:15 -0400 Subject: [PATCH 5/7] add tests --- .../FindPSResourceLocal.Tests.ps1 | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 index dda4ddf50..a61a34b78 100644 --- a/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 @@ -14,6 +14,7 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { $localUNCRepo = 'psgettestlocal3' $testModuleName = "test_local_mod" $testModuleName2 = "test_local_mod2" + $similarTestModuleName = "test_local_mod.similar" $commandName = "cmd1" $dscResourceName = "dsc1" $prereleaseLabel = "" @@ -31,6 +32,9 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { New-TestModule -moduleName $testModuleName2 -repoName $localRepo -packageVersion "5.0.0" -prereleaseLabel "" -tags $tagsEscaped New-TestModule -moduleName $testModuleName2 -repoName $localRepo -packageVersion "5.2.5" -prereleaseLabel $prereleaseLabel -tags $tagsEscaped + + New-TestModule -moduleName $similarTestModuleName -repoName $localRepo -packageVersion "4.0.0" -prereleaseLabel "" -tags $tagsEscaped + New-TestModule -moduleName $similarTestModuleName -repoName $localRepo -packageVersion "5.0.0" -prereleaseLabel "" -tags $tagsEscaped } AfterAll { @@ -74,6 +78,7 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { } It "should not find resource given nonexistant Name" { + # FindName() $res = Find-PSResource -Name NonExistantModule -Repository $localRepo -ErrorVariable err -ErrorAction SilentlyContinue $res | Should -BeNullOrEmpty $err.Count | Should -Not -Be 0 @@ -81,6 +86,17 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { $res | Should -BeNullOrEmpty } + It "find resource given specific Name when another package with similar name (with period) exists" { + # FindName() + $res = Find-PSResource -Name $testModuleName -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "5.0.0" + + $res = Find-PSResource -Name $similarTestModuleName -Repository $localRepo + $res.Name | Should -Be $similarTestModuleName + $res.Version | Should -Be "5.0.0" + } + It "find resource(s) given wildcard Name" { # FindNameGlobbing $res = Find-PSResource -Name "test_local_*" -Repository $localRepo @@ -129,6 +145,22 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { $resPrerelease.Prerelease | Should -Be "alpha001" } + It "find resource given specific Name when another package with similar name (with period) exists" { + # FindVersion() + # Package $testModuleName version 4.0.0 does not exist + # previously if Find-PSResource -Version against local repo did not find that package's version it kept looking at + # similar named packages and would fault. This test is to ensure only the specified package and its version is checked + $res = Find-PSResource -Name $testModuleName -Version "4.0.0" -Repository $localRepo + $res | Should -BeNullOrEmpty + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource" + $res | Should -BeNullOrEmpty + + $res = Find-PSResource -Name $similarTestModuleName -Version "4.0.0" -Repository $localRepo + $res.Name | Should -Be $similarTestModuleName + $res.Version | Should -Be "4.0.0" + } + It "find resources, including Prerelease version resources, when given Prerelease parameter" { # FindVersionGlobbing() $resWithoutPrerelease = Find-PSResource -Name $testModuleName -Version "*" -Repository $localRepo From 450bbb5e593f0dce79bd1ce89c3b22a0a08b3a50 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 17 Jun 2024 12:29:37 -0400 Subject: [PATCH 6/7] remove comment --- src/code/LocalServerApiCalls.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index e7e4b348c..6537edd99 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -912,10 +912,6 @@ private NuGetVersion GetInfoFromFileName(string packageFullName, string packageN // packageFullName will look like package.1.0.0.nupkg errRecord = null; - // Microsoft.Graph.Users - // Microsoft.Graph.Users.Actions - // packageName should contain the pkg name that the user searched for - // actualName will be the name with the casing package.nupkg had, which is the casing we use when returning to the user string[] packageWithoutName = packageFullName.ToLower().Split(new string[]{ $"{packageName.ToLower()}." }, StringSplitOptions.RemoveEmptyEntries); string packageVersionAndExtension = packageWithoutName[0]; string[] originalFileNameParts = packageFullName.Split(new string[]{ $".{packageVersionAndExtension}" }, StringSplitOptions.RemoveEmptyEntries); From a867bcae8ffdcced5072b04549551e37ba324da9 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 9 Oct 2024 19:47:53 -0400 Subject: [PATCH 7/7] add ErrorVariable reference --- test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 index a61a34b78..b6e43716a 100644 --- a/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 @@ -150,7 +150,7 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' { # Package $testModuleName version 4.0.0 does not exist # previously if Find-PSResource -Version against local repo did not find that package's version it kept looking at # similar named packages and would fault. This test is to ensure only the specified package and its version is checked - $res = Find-PSResource -Name $testModuleName -Version "4.0.0" -Repository $localRepo + $res = Find-PSResource -Name $testModuleName -Version "4.0.0" -Repository $localRepo -ErrorVariable err -ErrorAction SilentlyContinue $res | Should -BeNullOrEmpty $err.Count | Should -Not -Be 0 $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource"