Skip to content

Commit

Permalink
Package metadata and AllVersions support (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanbergstrom authored Mar 13, 2022
1 parent 916022a commit 655bbb7
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
path: C:\Users\runneradmin\Documents\PowerShell\Modules\WinGet\
- name: Install WinGet
shell: pwsh
run: .\Install-WinGet.ps1
run: Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/ethanbergstrom/Cobalt/master/Install-WinGet.ps1'))
- name: Install Cobalt
run: Install-Module Cobalt -Force
- name: Test with Pester
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## Unreleased

## 0.0.7 - 2022-03-12 - Additional Package Details
### Added
* Include package summary and download URL in package data
* Support for the Find-Package `AllVersions` parameter
* Support for the `RequiredVersion`, `MinimumVersion`, and `MaximumVersion` parameters across multiple cmdlets

## 0.0.6 - 2022-02-06 - Force dependency checks
### Fixed
* Installed package version checks
Expand Down
49 changes: 0 additions & 49 deletions Install-WinGet.ps1

This file was deleted.

5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Find-Package OpenJS.NodeJS -Provider WinGet
Find-Package Mozilla.Firefox -Provider WinGet
```
### Find all available versions of a package
```PowerShell
Find-Package Mozilla.Firefox -Provider WinGet -AllVersions
```

### Install a package
```PowerShell
Expand Down Expand Up @@ -166,7 +170,6 @@ If using the 'latest' functionality, best practice is to either:
WinGet is still in a preview period, with many features not implemented that are required for a PackageManagement provider to be fully implemented.

Unsupported features currently include:
* Searching for packages by version range
* Passing install arguments to packages
* Saving a package

Expand Down
48 changes: 37 additions & 11 deletions Test/WinGet.Unit.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ BeforeAll {
Describe 'basic package search operations' {
Context 'without additional arguments' {
BeforeAll {
$package = 'CPUID.CPU-Z'
$package = 'CPUID.HWMonitor'
$version = '1.44'
}

It 'gets a list of latest installed packages' {
Expand All @@ -18,34 +19,44 @@ Describe 'basic package search operations' {
It 'searches for the latest version of a package' {
Find-Package -Provider $WinGet -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
It 'returns all available versions of a package' {
Find-Package -Provider $WinGet -Name $package -AllVersions | Where-Object {$_.Version -eq $version} | Should -Not -BeNullOrEmpty
}
It 'returns additional package metadata' {
Find-Package -Provider $WinGet -Name $package | Select-Object -ExpandProperty FullPath | Should -Not -BeNullOrEmpty
}
It 'searches for all versions of a package' {
Find-Package -Provider $WinGet -Name $package -AllVersions | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
}
}

Describe 'DSC-compliant package installation and uninstallation' {
Context 'without additional arguments' {
BeforeAll {
$package = 'CPUID.CPU-Z'
$package = 'CPUID.HWMonitor'
$version = '1.44'
}

It 'searches for the latest version of a package' {
Find-Package -Provider $WinGet -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
It 'searches for a specific version of a package' {
Find-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
It 'silently installs the latest version of a package' {
Install-Package -Provider $WinGet -Name $package -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
It 'silently installs a specific version of a package' {
Install-Package -Provider $WinGet -Name $package -RequiredVersion $version -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
It 'finds the locally installed package just installed' {
Get-Package -Provider $WinGet -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
Get-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
It 'silently uninstalls the locally installed package just installed' {
Uninstall-Package -Provider $WinGet -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
Uninstall-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
}
}

Describe 'pipeline-based package installation and uninstallation' {
Context 'without additional arguments' {
BeforeAll {
$package = 'CPUID.CPU-Z'
$package = 'CPUID.HWMonitor'
}

It 'searches for and silently installs the latest version of a package' {
Expand All @@ -57,11 +68,26 @@ Describe 'pipeline-based package installation and uninstallation' {
}
}

Describe 'version tests' {
Context 'without additional arguments' {
BeforeAll {
$package = 'CPUID.HWMonitor'
$minVersion = '1.43'
$maxVersion = '1.44'
}

It 'retrieves and correctly filters versions within a range' {
Find-Package -Provider $WinGet -Name $package -MaximumVersion $maxVersion -MinimumVersion $minVersion -AllVersions | Where-Object {$_.Name -contains $package} | Should -HaveCount 2
}
}
}

Describe "multi-source support" {
BeforeAll {
$altSourceName = 'AltWinGetSource'
$altSourceLocation = 'https://winget.azureedge.net/cache'
$package = 'CPUID.CPU-Z'
$package = 'CPUID.HWMonitor'
$version = '1.44'

Unregister-PackageSource -Name $altSourceName -Provider $WinGet -ErrorAction SilentlyContinue
}
Expand All @@ -76,7 +102,7 @@ Describe "multi-source support" {
Register-PackageSource -Name $altSourceName -Provider $WinGet -Location $altSourceLocation | Where-Object {$_.Name -eq $altSourceName} | Should -Not -BeNullOrEmpty
}
It 'searches for and installs the latest version of a package from an alternate source' {
Find-Package -Provider $WinGet -Name $package -source $altSourceName | Install-Package -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
Find-Package -Provider $WinGet -Name $package -Source $altSourceName -RequiredVersion $version | Install-Package -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty
}
It 'unregisters an alternative package source' {
Unregister-PackageSource -Name $altSourceName -Provider $WinGet
Expand Down
4 changes: 2 additions & 2 deletions src/WinGet.psd1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@{
RootModule = 'WinGet.psm1'
ModuleVersion = '0.0.6'
ModuleVersion = '0.0.7'
GUID = '468ef37a-2557-4c10-92ec-783ec1e41639'
Author = 'Ethan Bergstrom'
Copyright = ''
Expand All @@ -19,7 +19,7 @@
},
@{
ModuleName='Cobalt'
ModuleVersion='0.0.10'
ModuleVersion='0.2.0'
}
)
PrivateData = @{
Expand Down
1 change: 1 addition & 0 deletions src/WinGet.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
$script:AcceptLicense = "AcceptLicense"
$script:Force = "Force"
$script:PackageSource = "WinGet"
$script:AllVersions = "AllVersions"

# Utility variables
# Fast Package References are passed between cmdlets in the format of '<name>#<version>#<source>'
Expand Down
3 changes: 3 additions & 0 deletions src/private/ConvertTo-SoftwareIdentity.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ function ConvertTo-SoftwareIdentity {
)
if ($packageSource) {
Write-Debug "Package identified: $($package.ID), $($package.version), $($packageSource)"
$metadata = Cobalt\Get-WinGetPackageInfo -ID $package.ID -Version $package.Version -Source $packageSource
$swid = @{
FastPackageReference = $package.ID+"#"+ $package.version+"#"+$packageSource
Name = $package.ID
Version = $package.version
versionScheme = "MultiPartNumeric"
FromTrustedSource = $true
Source = $packageSource
Summary = $metadata.Description
FullPath = $metadata.'Download URL'
}
New-SoftwareIdentity @swid
}
Expand Down
20 changes: 18 additions & 2 deletions src/private/Find-WinGetPackage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ function Find-WinGetPackage {

# Convert the PSCustomObject output from Cobalt into PackageManagement SWIDs, then filter results by any version requirements
# We have to specify the source when converting to SWIDs, because WinGet doesn't return source information when the source is specified
Cobalt\Find-WinGetPackage @WinGetParams | ConvertTo-SoftwareIdentity -Source $selectedSource |
Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion -Debug}
Cobalt\Find-WinGetPackage @WinGetParams | ForEach-Object {
# If we need to retrieve all versions, perform an additional query to get all available versions, and create a package object for each version
if ($RequiredVersion -Or $minimumVersion -Or $maximumVersion -Or $options.ContainsKey($script:AllVersions)) {
$package = $_
$package | Get-WinGetPackageInfo -Versions -Source $selectedSource | Select-Object -Property @{
Name = 'ID'
Expression = {$package.ID}
},@{
Name = 'Version'
Expression = {$_}
},@{
Name = 'Source'
Expression = {$package.Source}
}
} else {
$_
}
} | Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion} | ConvertTo-SoftwareIdentity -Source $selectedSource
}
1 change: 0 additions & 1 deletion src/private/Test-PackageVersion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ function Test-PackageVersion {
[OutputType([bool])]
param (
[Parameter(Mandatory=$true)]
[Microsoft.PackageManagement.MetaProvider.PowerShell.SoftwareIdentity]
$Package,

[Parameter()]
Expand Down
7 changes: 4 additions & 3 deletions src/public/Get-InstalledPackage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ function Get-InstalledPackage {

# Convert the PSCustomObject output from Cobalt into PackageManagement SWIDs, then filter results by version requirements
# This provides wildcard search behavior for locally installed packages, which WinGet lacks
Cobalt\Get-WinGetPackage | ConvertTo-SoftwareIdentity |
Where-Object {-Not $Name -Or ($_.Name -Like $Name)} |
Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion}
Cobalt\Get-WinGetPackage |
Where-Object {-Not $Name -Or ($_.ID -Like $Name)} |
Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion} |
ConvertTo-SoftwareIdentity
}
14 changes: 2 additions & 12 deletions src/public/Install-Package.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,8 @@ function Install-Package {
Source = $Matches.source
}

# Convert the PSCustomObject output from Cobalt into PackageManagement SWIDs, then validate what WinGet installed matched what we requested
$swid = $(
$result = Cobalt\Install-WinGetPackage @WinGetParams
# If Cobalt didn't return anything, something went wrong and we need to throw our own exception
if (-Not $result) {
ThrowError -ExceptionName 'System.OperationCanceledException' `
-ExceptionMessage $LocalizedData.WinGetFailure `
-ErrorID 'JobFailure' `
-ErrorCategory InvalidOperation `
}
ConvertTo-SoftwareIdentity -InputObject $result -Source $WinGetParams.Source
) | Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $WinGetParams.version -ErrorAction SilentlyContinue}
# Validate what WinGet installed matched what we requested, then convert the PSCustomObject output from Cobalt into PackageManagement SWIDs
$swid = Cobalt\Install-WinGetPackage @WinGetParams | Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $WinGetParams.version -ErrorAction SilentlyContinue} | ConvertTo-SoftwareIdentity -Source $WinGetParams.Source

if (-Not $swid) {
# Cobalt returned something, but not in the format we expected. Something is amiss.
Expand Down

0 comments on commit 655bbb7

Please sign in to comment.