Skip to content

Wildcard processing #432

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

Merged
merged 10 commits into from
Aug 3, 2021
19 changes: 17 additions & 2 deletions src/code/FindPSResource.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using Dbg = System.Diagnostics.Debug;
using System.Linq;
Expand Down Expand Up @@ -198,7 +199,8 @@ private void ProcessResourceNameParameterSet()
this));
}

Name = Utils.FilterOutWildcardNames(Name, out string[] errorMsgs);
var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard);

foreach (string error in errorMsgs)
{
WriteError(new ErrorRecord(
Expand All @@ -208,8 +210,21 @@ private void ProcessResourceNameParameterSet()
this));
}

if (Name.Length == 0)
// this catches the case where Name wasn't passed in as null or empty,
// but after filtering out unsupported wildcard names there are no elements left in namesToSearch
if (namesToSearch.Length == 0)
{
return;
}

if (String.Equals(namesToSearch[0], "*", StringComparison.InvariantCultureIgnoreCase))
{
// WriteVerbose("Package names were detected to be (or contain an element equal to): '*', so all packages will be updated");
WriteError(new ErrorRecord(
new PSInvalidOperationException("-Name '*' is not supported for Find-PSResource so all Name entries will be discarded."),
"NameEqualsWildcardIsNotSupported",
ErrorCategory.InvalidArgument,
this));
return;
}

Expand Down
38 changes: 18 additions & 20 deletions src/code/GetInstalledPSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,33 +106,31 @@ protected override void BeginProcessing()
// retrieve all possible paths
_pathsToSearch = Utils.GetAllResourcePaths(this);
}

if (Name == null)
{
Name = new string[] { "*" };
}
// if '*' is passed in as an argument for -Name with other -Name arguments,
// ignore all arguments except for '*' since it is the most inclusive
// eg: -Name ["TestModule, Test*, *"] will become -Name ["*"]
if (Name != null && Name.Length > 1)
{
foreach (var pkgName in Name)
{
if (pkgName.Trim().Equals("*"))
{
Name = new string[] { "*" };
break;
}
}
}
}

protected override void ProcessRecord()
{
WriteDebug("Entering GetInstalledPSResource");

var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _);
foreach (string error in errorMsgs)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException(error),
"ErrorFilteringNamesForUnsupportedWildcards",
ErrorCategory.InvalidArgument,
this));
}

// this catches the case where Name wasn't passed in as null or empty,
// but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in Name
if (namesToSearch.Length == 0)
{
return;
}

GetHelper getHelper = new GetHelper(this);
foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(Name, _versionRange, _pathsToSearch))
foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(namesToSearch, _versionRange, _pathsToSearch))
{
WriteObject(pkg);
}
Expand Down
29 changes: 28 additions & 1 deletion src/code/InstallPSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,35 @@ protected override void ProcessRecord()
switch (ParameterSetName)
{
case NameParameterSet:
var namesToInstall = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard);
if (nameContainsWildcard)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"),
"NameContainsWildcard",
ErrorCategory.InvalidArgument,
this));
return;
}

foreach (string error in errorMsgs)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException(error),
"ErrorFilteringNamesForUnsupportedWildcards",
ErrorCategory.InvalidArgument,
this));
}

// this catches the case where Name wasn't passed in as null or empty,
// but after filtering out unsupported wildcard names there are no elements left in namesToInstall
if (namesToInstall.Length == 0)
{
return;
}

installHelper.InstallPackages(
names: Name,
names: namesToInstall,
versionRange: _versionRange,
prerelease: Prerelease,
repository: Repository,
Expand Down
29 changes: 28 additions & 1 deletion src/code/SavePSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,35 @@ protected override void ProcessRecord()
switch (ParameterSetName)
{
case NameParameterSet:
var namesToSave = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard);
if (nameContainsWildcard)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"),
"NameContainsWildcard",
ErrorCategory.InvalidArgument,
this));
return;
}

foreach (string error in errorMsgs)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException(error),
"ErrorFilteringNamesForUnsupportedWildcards",
ErrorCategory.InvalidArgument,
this));
}

// this catches the case where Name wasn't passed in as null or empty,
// but after filtering out unsupported wildcard names there are no elements left in namesToSave
if (namesToSave.Length == 0)
{
return;
}

installHelper.InstallPackages(
names: Name,
names: namesToSave,
versionRange: _versionRange,
prerelease: Prerelease,
repository: Repository,
Expand Down
21 changes: 20 additions & 1 deletion src/code/UninstallPSResource.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
Expand All @@ -16,7 +17,7 @@ namespace Microsoft.PowerShell.PowerShellGet.Cmdlets
/// <summary>
/// Uninstall-PSResource uninstalls a package found in a module or script installation path.
/// </summary>
[Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true, HelpUri = "<add>")]
[Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true)]
public sealed class UninstallPSResource : PSCmdlet
{
#region Parameters
Expand Down Expand Up @@ -83,6 +84,24 @@ protected override void ProcessRecord()
switch (ParameterSetName)
{
case NameParameterSet:
Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _);

foreach (string error in errorMsgs)
{
WriteError(new ErrorRecord(
new PSInvalidOperationException(error),
"ErrorFilteringNamesForUnsupportedWildcards",
ErrorCategory.InvalidArgument,
this));
}

// this catches the case where Name wasn't passed in as null or empty,
// but after filtering out unsupported wildcard names there are no elements left in Name
if (Name.Length == 0)
{
return;
}

if (!UninstallPkgHelper())
{
// any errors should be caught lower in the stack, this debug statement will let us know if there was an unusual failure
Expand Down
36 changes: 0 additions & 36 deletions src/code/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,42 +111,6 @@ public static string[] ProcessNameWildcards(
errorMsgs = errorMsgsList.ToArray();
return namesWithSupportedWildcards.ToArray();
}

public static string[] FilterOutWildcardNames(
string[] pkgNames,
out string[] errorMsgs)
{
List<string> errorFreeNames = new List<string>();
List<string> errorMsgList = new List<string>();

foreach (string n in pkgNames)
{
bool isNameErrorProne = false;
if (WildcardPattern.ContainsWildcardCharacters(n))
{
if (String.Equals(n, "*", StringComparison.InvariantCultureIgnoreCase))
{
errorMsgList = new List<string>(); // clear prior error messages
errorMsgList.Add("-Name '*' is not supported for Find-PSResource so all Name entries will be discarded.");
errorFreeNames = new List<string>();
break;
}
else if (n.Contains("?") || n.Contains("["))
{
errorMsgList.Add(String.Format("-Name with wildcards '?' and '[' are not supported for Find-PSResource so Name entry: {0} will be discarded.", n));
isNameErrorProne = true;
}
}

if (!isNameErrorProne)
{
errorFreeNames.Add(n);
}
}

errorMsgs = errorMsgList.ToArray();
return errorFreeNames.ToArray();
}

#endregion

Expand Down
6 changes: 6 additions & 0 deletions test/FindPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ Describe 'Test Find-PSResource for Module' {
$foundScript | Should -BeTrue
}

It "should not find resources given Name that equals wildcard, '*'" {
Find-PSResource -Name "*" -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "NameEqualsWildcardIsNotSupported,Microsoft.PowerShell.PowerShellGet.Cmdlets.FindPSResource"
}

It "find resource given Name from V3 endpoint repository (NuGetGallery)" {
$res = Find-PSResource -Name "Serilog" -Repository $NuGetGalleryName
$res.Count | Should -Be 1
Expand Down
12 changes: 11 additions & 1 deletion test/InstallPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ Describe 'Test Install-PSResource for Module' {
Get-RevertPSResourceRepositoryFile
}

$testCases = @{Name="*"; ErrorId="NameContainsWildcard"},
@{Name="TestModule*"; ErrorId="NameContainsWildcard"},
@{Name="Test?Module","Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"}

It "Should not install resource with wildcard in name" -TestCases $testCases {
param($Name, $ErrorId)
Install-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource"
}

It "Install specific module resource by name" {
Install-PSResource -Name "TestModule" -Repository $TestGalleryName
$pkg = Get-Module "TestModule" -ListAvailable
Expand All @@ -43,7 +54,6 @@ Describe 'Test Install-PSResource for Module' {
$pkg.Name | Should -Be $pkgNames
}


It "Should not install resource given nonexistant name" {
Install-PSResource -Name NonExistantModule -Repository $TestGalleryName
$pkg = Get-Module "NonExistantModule" -ListAvailable
Expand Down
6 changes: 6 additions & 0 deletions test/SavePSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ Describe 'Test Save-PSResource for PSResources' {
$pkgDir.Name | Should -BeNullOrEmpty
}

It "Not Save module with Name containing wildcard" {
Save-PSResource -Name "TestModule*" -Repository $TestGalleryName -Path $SaveDir -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "NameContainsWildcard,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource"
}

# Do some version testing, but Find-PSResource should be doing thorough testing
It "Should save resource given name and exact version" {
Save-PSResource -Name "TestModule" -Version "1.2.0" -Repository $TestGalleryName -Path $SaveDir
Expand Down
10 changes: 10 additions & 0 deletions test/UninstallPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ Describe 'Test Uninstall-PSResource for Modules' {
Get-Module ContosoServer -ListAvailable | Should -Be $null
}

$testCases = @{Name="Test?Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"},
@{Name="Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"}

It "not uninstall module given Name with invalid wildcard characters" -TestCases $testCases {
param($Name, $ErrorId)
Uninstall-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.UninstallPSResource"
}

It "Uninstall a list of modules by name" {
$null = Install-PSResource BaseTestPackage -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue

Expand Down