From fd2e9f6dd65430c678c9645aff5d909fd3ffc0c0 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:21:24 -0400 Subject: [PATCH 1/9] 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 484ed351b..1f3036218 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)) { @@ -881,6 +901,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 235665a5bc5261512bf678799febff8977451838 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:27:32 -0400 Subject: [PATCH 2/9] 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 1f3036218..a4379aec6 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 e2769c9768815e13342157430bb767e918d9c087 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 11 Jun 2024 12:28:36 -0400 Subject: [PATCH 3/9] 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 a4379aec6..84cd6471b 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 20b8cbad3ba4332447c641a58a7f13400489437b Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 12 Jun 2024 13:08:48 -0400 Subject: [PATCH 4/9] 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 84cd6471b..06a319ed2 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 ce5d36a96e5d3e8400166e9eb79aa5a7ef11a621 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 17 Jun 2024 12:27:15 -0400 Subject: [PATCH 5/9] 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 d45bb921c2052e1ef4eb395077d305877d777ba2 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 17 Jun 2024 12:29:37 -0400 Subject: [PATCH 6/9] 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 06a319ed2..6ffd7b24c 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -913,10 +913,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 d3b060980881137adaab71c5823b3051151f050b Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 9 Oct 2024 19:47:53 -0400 Subject: [PATCH 7/9] 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" From 9cdc095c0ecb5527043705cb4368eb1b0436d816 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 21 Oct 2024 17:52:45 -0400 Subject: [PATCH 8/9] addres PR feedback about comments and debug message --- src/code/LocalServerApiCalls.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index 6ffd7b24c..be1f330bc 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -259,10 +259,10 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu String latestVersionPath = String.Empty; string actualPkgName = packageName; + // this regex pattern matches packageName followed by a version (4 digit or 3 with prerelease word) string regexPattern = $"{packageName}" + @".\d+\.\d+\.\d+(?:-\w+|.\d)*.nupkg"; Regex rx = new Regex(regexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); - - _cmdletPassedIn.WriteDebug($"pattern is: {regexPattern}"); + _cmdletPassedIn.WriteDebug($"package file name pattern to be searched for is: {regexPattern}"); foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath)) { From 98c6809d9299bd6bde4b0bf540d25d5e5ce3b17e Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 21 Oct 2024 18:07:58 -0400 Subject: [PATCH 9/9] add comment --- src/code/LocalServerApiCalls.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/code/LocalServerApiCalls.cs b/src/code/LocalServerApiCalls.cs index be1f330bc..b22b3efb6 100644 --- a/src/code/LocalServerApiCalls.cs +++ b/src/code/LocalServerApiCalls.cs @@ -387,6 +387,7 @@ private FindResults FindVersionHelper(string packageName, string version, string return findResponse; } + // this regex pattern matches packageName followed by the requested version string regexPattern = $"{packageName}.{requiredVersion.ToNormalizedString()}" + @".nupkg"; Regex rx = new Regex(regexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); _cmdletPassedIn.WriteDebug($"pattern is: {regexPattern}");