Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix - Correctly match package names from local repos #1663

Closed
90 changes: 61 additions & 29 deletions src/code/LocalServerApiCalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,32 +255,48 @@ 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;

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))
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;
}
}
}
Expand Down Expand Up @@ -371,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;
}
}

Expand Down
32 changes: 32 additions & 0 deletions test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""
Expand All @@ -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 {
Expand Down Expand Up @@ -74,13 +78,25 @@ 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
$err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource"
$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
Expand Down Expand Up @@ -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 -ErrorVariable err -ErrorAction SilentlyContinue
$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
Expand Down
Loading