Skip to content
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