Skip to content

Commit 33f68b6

Browse files
authored
Add support for Uninstall-PSResource (#593)
Add support for Uninstall -Prerelease parameter uninstalling only prerelease versions
1 parent 6fea187 commit 33f68b6

File tree

8 files changed

+113
-15
lines changed

8 files changed

+113
-15
lines changed

help/Get-PSResource.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ The Get-PSResource cmdlet combines the Get-InstalledModule, Get-InstalledScript
2626
PS C:\> Get-PSResource Az
2727
```
2828

29-
This will return versions of the Az module installed via PowerShellGet.
29+
This will return versions (stable and prerelease) of the Az module installed via PowerShellGet.
3030

3131
### Example 2
3232
```powershell
@@ -44,12 +44,32 @@ This will return all versions of the Az module within the specified range.
4444

4545
### Example 4
4646
```powershell
47+
PS C:\> Get-PSResource Az -version "4.0.1-preview"
48+
```
49+
50+
Assume that the package Az version 4.0.1-preview is already installed. This will return version 4.0.1-preview of the Az module.
51+
52+
```powershell
53+
PS C:\> Get-PSResource Az -version "4.0.1"
54+
```
55+
Assume that the package Az version 4.0.1-preview is already installed. This will not return Az version 4.0.1-preview as the full version (including prerelease label, i.e "4.0.1-preview") was not specified.
56+
57+
### Example 5
58+
```powershell
59+
PS C:\> Get-PSResource Az -Version "[4.0.1, 4.0.2-preview]
60+
```
61+
62+
Assume that the following versions are already installed for package Az: 4.0.1-preview and 4.0.2-preview. This will only return version 4.0.2-preview as it is the only one which falls within the specified version range. Per NuGetVersion rules, a prerelease version is less than a stable version, so 4.0.1-preview is less than the 4.0.1 specified version so 4.0.1-preview does not fall within the specified version range and won't be returned.
63+
64+
65+
### Example 6
66+
```powershell
4767
PS C:\> Get-PSResource Az -Path .
4868
```
4969

5070
This will return all versions of the Az module that have been installed in the current directory.
5171

52-
### Example 5
72+
### Example 7
5373
```powershell
5474
PS C:\> Get-PSResource
5575
```

help/Uninstall-PSResource.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,24 @@ Uninstalls version 1.0.0 of the Az module.
4747
### Example 3
4848
```powershell
4949
PS C:\> Uninstall-PSResource -name Az -version "(1.0.0, 3.0.0)"
50+
```
5051

5152
Uninstalls all versions within the specified version range.
53+
54+
### Example 4
55+
```powershell
56+
PS C:\> Uninstall-PSResource -name Az -version "[4.0.1, 4.1.0]"
5257
```
5358

54-
Uninstalls version 1.0.0 of the Az module.
59+
Assume that the following versions are already installed for package Az: 4.0.1-preview, 4.1.0, 4.0.2-preview installed, this will uninstall all versions (stable and prerelease) which fall within the specified version range. Per NuGetVersion rules, a prerelease version is less than a stable version, so 4.0.1-preview is actually less than the 4.0.1 specified version so 4.0.1-preview does not fall within the specified version range and won't be removed. Versions 4.1.0 and 4.0.2-preview do fall in the range and will both be removed.
60+
61+
### Example 4
62+
```powershell
63+
PS C:\> Uninstall-PSResource -name Az -version "[4.0.1, 4.1.0]" -Prerelease
64+
```
65+
66+
Assume that the following versions are already installed for package Az: 4.0.1-preview, 4.1.0, 4.0.2-preview installed. This is the same example as above, except the added `-Prerelease` parameter means only prerelease versions which fall within this range will be removed. Again, per NuGetVersion rules, a prerelease version is less than a stable version, so 4.0.1-preview is actually less than the 4.0.1 specified version. Therefore 4.0.1-preview does not fall within the specified version range and won't be removed. Version 4.1.0 does fall in range however it is not a prerelease version so it will remain installed. Version 4.0.2-preview does fall in the range and is prerelease so it will be removed.
67+
5568

5669
## PARAMETERS
5770

src/code/GetHelper.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ public GetHelper(PSCmdlet cmdletPassedIn)
3939
public IEnumerable<PSResourceInfo> GetPackagesFromPath(
4040
string[] name,
4141
VersionRange versionRange,
42-
List<string> pathsToSearch)
42+
List<string> pathsToSearch,
43+
bool selectPrereleaseOnly)
4344
{
44-
List<string> pgkPathsByName = FilterPkgPathsByName(name, pathsToSearch);
45+
List<string> pkgPathsByName = FilterPkgPathsByName(name, pathsToSearch);
4546

46-
foreach (string pkgPath in FilterPkgPathsByVersion(versionRange, pgkPathsByName))
47+
foreach (string pkgPath in FilterPkgPathsByVersion(versionRange, pkgPathsByName, selectPrereleaseOnly))
4748
{
4849
PSResourceInfo pkg = OutputPackageObject(pkgPath, _scriptDictionary);
4950
if (pkg != null)
@@ -77,7 +78,7 @@ public List<string> FilterPkgPathsByName(string[] names, List<string> dirsToSear
7778
}
7879

7980
// Filter by user provided version
80-
public IEnumerable<String> FilterPkgPathsByVersion(VersionRange versionRange, List<string> dirsToSearch)
81+
public IEnumerable<String> FilterPkgPathsByVersion(VersionRange versionRange, List<string> dirsToSearch, bool selectPrereleaseOnly)
8182
{
8283
Dbg.Assert(versionRange != null, "Version Range cannot be null");
8384

@@ -121,11 +122,15 @@ public IEnumerable<String> FilterPkgPathsByVersion(VersionRange versionRange, Li
121122

122123
_cmdletPassedIn.WriteVerbose(string.Format("Package version parsed as NuGet version: '{0}'", pkgNugetVersion));
123124

125+
// For Uninstall-PSResource Prerelease parameter equates to selecting prerelease versions only to uninstall.
126+
// For other cmdlets (Find-PSResource, Install-PSResource) Prerelease parmater equates to selecting stable and prerelease versions.
127+
// We will not just select prerelase versions. For Get-PSResource, there is no Prerelease parameter.
124128
if (versionRange.Satisfies(pkgNugetVersion))
125129
{
126-
// This will be one version or a version range.
127-
// yield results then continue with this iteration of the loop
128-
yield return versionPath;
130+
if (!selectPrereleaseOnly || pkgNugetVersion.IsPrerelease)
131+
{
132+
yield return versionPath;
133+
}
129134
}
130135
}
131136
}

src/code/GetPSResource.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@ protected override void ProcessRecord()
128128
}
129129

130130
GetHelper getHelper = new GetHelper(this);
131-
foreach (PSResourceInfo pkg in getHelper.GetPackagesFromPath(namesToSearch, _versionRange, _pathsToSearch))
131+
// selectPrereleaseOnly is false because we want both stable and prerelease versions all the time.
132+
foreach (PSResourceInfo pkg in getHelper.GetPackagesFromPath(
133+
name: namesToSearch,
134+
versionRange: _versionRange,
135+
pathsToSearch: _pathsToSearch,
136+
selectPrereleaseOnly: false))
132137
{
133138
WriteObject(pkg);
134139
}

src/code/InstallHelper.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,12 @@ private IEnumerable<PSResourceInfo> FilterByInstalledPkgs(IEnumerable<PSResource
279279

280280
GetHelper getHelper = new GetHelper(_cmdletPassedIn);
281281
// Get currently installed packages.
282+
// selectPrereleaseOnly is false because even if Prerelease is true we want to include both stable and prerelease, never select prerelease only.
282283
IEnumerable<PSResourceInfo> pkgsAlreadyInstalled = getHelper.GetPackagesFromPath(
283284
name: filteredPackages.Keys.ToArray(),
284285
versionRange: _versionRange,
285-
pathsToSearch: _pathsToSearch);
286+
pathsToSearch: _pathsToSearch,
287+
selectPrereleaseOnly: false);
286288
if (!pkgsAlreadyInstalled.Any())
287289
{
288290
return packages;
@@ -666,7 +668,12 @@ private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable)
666668
// Get installed modules, then get all possible paths
667669
bool foundClobber = false;
668670
GetHelper getHelper = new GetHelper(_cmdletPassedIn);
669-
IEnumerable<PSResourceInfo> pkgsAlreadyInstalled = getHelper.GetPackagesFromPath(new string[] { "*" }, VersionRange.All, _pathsToSearch);
671+
// selectPrereleaseOnly is false because even if Prerelease is true we want to include both stable and prerelease, never select prerelease only.
672+
IEnumerable<PSResourceInfo> pkgsAlreadyInstalled = getHelper.GetPackagesFromPath(
673+
name: new string[] { "*" },
674+
versionRange: VersionRange.All,
675+
pathsToSearch: _pathsToSearch,
676+
selectPrereleaseOnly: false);
670677
// user parsed metadata hash
671678
List<string> listOfCmdlets = new List<string>();
672679
foreach (var cmdletName in parsedMetadataHashtable["CmdletsToExport"] as object[])

src/code/UninstallPSResource.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ public sealed class UninstallPSResource : PSCmdlet
3535
[ValidateNotNullOrEmpty]
3636
public string Version { get; set; }
3737

38+
/// <summary>
39+
/// When specified, only uninstalls prerelease versions.
40+
/// </summary>
41+
[Parameter]
42+
public SwitchParameter Prerelease { get; set; }
43+
3844
/// <summary>
3945
/// Used for pipeline input.
4046
/// </summary>
@@ -163,7 +169,7 @@ private bool UninstallPkgHelper()
163169
// note that the xml file is located in ./Scripts/InstalledScriptInfos, eg: ./Scripts/InstalledScriptInfos/TestScript_InstalledScriptInfo.xml
164170

165171
string pkgName;
166-
foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete))
172+
foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete, selectPrereleaseOnly: Prerelease))
167173
{
168174
pkgName = Utils.GetInstalledPackageName(pkgPath);
169175

src/code/UpdatePSResource.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,13 @@ private string[] ProcessPackageNames(
246246
// Get all installed packages selected for updating.
247247
GetHelper getHelper = new GetHelper(cmdletPassedIn: this);
248248
var installedPackages = new Dictionary<string, PSResourceInfo>(StringComparer.InvariantCultureIgnoreCase);
249+
250+
// selectPrereleaseOnly is false because even if Prerelease is true we want to include both stable and prerelease, not select prerelease only.
249251
foreach (var installedPackage in getHelper.GetPackagesFromPath(
250252
name: namesToProcess,
251253
versionRange: VersionRange.All,
252-
pathsToSearch: Utils.GetAllResourcePaths(this, Scope)))
254+
pathsToSearch: Utils.GetAllResourcePaths(this, Scope),
255+
selectPrereleaseOnly: false))
253256
{
254257
if (!installedPackages.ContainsKey(installedPackage.Name))
255258
{

test/UninstallPSResource.Tests.ps1

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
1313
$testScriptName = "test_script"
1414
Get-NewPSResourceRepositoryFile
1515
Uninstall-PSResource -name ContosoServer -Version "*"
16+
Uninstall-PSResource -Name $testModuleName -Version "*"
1617
}
1718

1819
BeforeEach {
@@ -183,6 +184,44 @@ Describe 'Test Uninstall-PSResource for Modules' {
183184
$res.Version | Should -Be "2.5.0.0"
184185
}
185186

187+
It "uninstall all prerelease versions (which satisfy the range) when -Version '*' and -Prerelease parameter is specified" {
188+
Install-PSResource -Name $testModuleName -Version "3.0.0" -Repository $TestGalleryName
189+
Install-PSResource -Name $testModuleName -Version "3.5.2-beta001" -Repository $TestGalleryName
190+
Install-PSResource -Name $testModuleName -Version "4.0.0" -Repository $TestGalleryName
191+
Install-PSResource -Name $testModuleName -Version "4.5.2-alpha001" -Repository $TestGalleryName
192+
Install-PSResource -Name $testModuleName -Version "5.0.0" -Repository $TestGalleryName
193+
$res = Get-PSResource -Name $testModuleName
194+
$prereleaseVersionPkgs = $res | Where-Object {$_.IsPrerelease -eq $true}
195+
$prereleaseVersionPkgs.Count | Should -Be 2
196+
197+
Uninstall-PSResource -Name $testModuleName -Version "*" -Prerelease
198+
$res = Get-PSResource -Name $testModuleName
199+
$prereleaseVersionPkgs = $res | Where-Object {$_.IsPrerelease -eq $true}
200+
$prereleaseVersionPkgs.Count | Should -Be 0
201+
$stableVersionPkgs = $res | Where-Object {$_.IsPrerelease -ne $true}
202+
$stableVersionPkgs.Count | Should -Be 3
203+
}
204+
205+
It "uninstall all prerelease versions (which satisfy the range) when -Version range and -Prerelease parameter is specified" {
206+
Install-PSResource -Name $testModuleName -Version "3.0.0" -Repository $TestGalleryName
207+
Install-PSResource -Name $testModuleName -Version "3.5.2-beta001" -Repository $TestGalleryName
208+
Install-PSResource -Name $testModuleName -Version "4.0.0" -Repository $TestGalleryName
209+
Install-PSResource -Name $testModuleName -Version "4.5.2-alpha001" -Repository $TestGalleryName
210+
Install-PSResource -Name $testModuleName -Version "5.0.0" -Repository $TestGalleryName
211+
$res = Get-PSResource -Name $testModuleName
212+
$prereleaseVersionPkgs = $res | Where-Object {$_.IsPrerelease -eq $true}
213+
$prereleaseVersionPkgs.Count | Should -Be 2
214+
215+
Uninstall-PSResource -Name $testModuleName -Version "[3.0.0, 4.0.0]" -Prerelease
216+
$res = Get-PSResource -Name $testModuleName
217+
# should only uninstall 3.5.2-beta001, 4.5.2-alpha001 is out of range and should remain installed
218+
$prereleaseVersionPkgs = $res | Where-Object {$_.IsPrerelease -eq $true}
219+
$prereleaseVersionPkgs.Count | Should -Be 1
220+
$stableVersionPkgs = $res | Where-Object {$_.IsPrerelease -ne $true}
221+
# versions 3.0.0 and 4.0.0 fall in range but should not be uninstalled as Prerelease parameter only selects prerelease versions for uninstallation
222+
$stableVersionPkgs.Count | Should -Be 3
223+
}
224+
186225
It "Uninstall module using -WhatIf, should not uninstall the module" {
187226
Uninstall-PSResource -Name "ContosoServer" -WhatIf
188227
$pkg = Get-Module ContosoServer -ListAvailable

0 commit comments

Comments
 (0)