From 51a3a00e03aa66cc5a8bcce88a72518068ab61ec Mon Sep 17 00:00:00 2001 From: Thomas Nieto <38873752+ThomasNieto@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:03:31 -0500 Subject: [PATCH] Add command not found (#40) --- src/AnyPackage.PSResourceGet.psd1 | 6 ++-- src/AnyPackage.PSResourceGet.psm1 | 50 ++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/AnyPackage.PSResourceGet.psd1 b/src/AnyPackage.PSResourceGet.psd1 index 650f05e..7c653c3 100644 --- a/src/AnyPackage.PSResourceGet.psd1 +++ b/src/AnyPackage.PSResourceGet.psd1 @@ -1,13 +1,15 @@ @{ RootModule = 'AnyPackage.PSResourceGet.psm1' - ModuleVersion = '0.3.0' + ModuleVersion = '0.4.0' CompatiblePSEditions = @('Desktop', 'Core') GUID = '4ffeffd3-7f83-4655-ac94-19eb41ebc792' Author = 'Thomas Nieto' Copyright = '(c) 2023 Thomas Nieto. All rights reserved.' Description = 'PSResourceGet provider for AnyPackage.' PowerShellVersion = '5.1' - RequiredModules = @('AnyPackage', 'Microsoft.PowerShell.PSResourceGet') + RequiredModules = @( + @{ ModuleName = 'AnyPackage'; ModuleVersion = '0.6.0' }, + 'Microsoft.PowerShell.PSResourceGet') FunctionsToExport = @() CmdletsToExport = @() AliasesToExport = @() diff --git a/src/AnyPackage.PSResourceGet.psm1 b/src/AnyPackage.PSResourceGet.psm1 index 07c94ea..06af64d 100644 --- a/src/AnyPackage.PSResourceGet.psm1 +++ b/src/AnyPackage.PSResourceGet.psm1 @@ -6,13 +6,33 @@ using module AnyPackage using module Microsoft.PowerShell.PSResourceGet using namespace System.Collections.Generic +using namespace System.Threading using namespace AnyPackage.Provider +using namespace AnyPackage.Feedback using namespace Microsoft.PowerShell.PSResourceGet.UtilClasses [PackageProvider('PSResourceGet')] class PSResourceGetProvider : PackageProvider, IGetPackage, IFindPackage, IInstallPackage, ISavePackage, IUninstallPackage, -IUpdatePackage, IPublishPackage, IGetSource, ISetSource { +IUpdatePackage, IPublishPackage, IGetSource, ISetSource, ICommandNotFound { + [PackageProviderInfo] Initialize([PackageProviderInfo] $providerInfo) { + return [PSResourceGetProviderInfo]::new($providerInfo) + } + + [IEnumerable[CommandNotFoundFeedback]] FindPackage([CommandNotFoundContext] $context, [CancellationToken] $token) { + $dict = [Dictionary[string, CommandNotFoundFeedback]]::new([StringComparer]::OrdinalIgnoreCase) + $packages = $this.ProviderInfo.CommandCache[$context.Command] + + foreach ($package in $packages) { + if (!$dict.ContainsKey($package.Name)) { + $feedback = [CommandNotFoundFeedback]::new($package.Name, $this.ProviderInfo) + $dict.Add($package.Name, $feedback) + } + } + + return $dict.Values + } + #region GetPackage [void] GetPackage([PackageRequest] $request) { $params = @{ @@ -284,6 +304,34 @@ IUpdatePackage, IPublishPackage, IGetSource, ISetSource { } } +class PSResourceGetProviderInfo : PackageProviderInfo { + [Dictionary[string, List[PSResourceInfo]]] $CommandCache = [Dictionary[string, List[PSResourceInfo]]]::new([StringComparer]::OrdinalIgnoreCase) + + PSResourceGetProviderInfo([PackageProviderInfo] $providerInfo) : base($providerInfo) { + if ([Runspace]::DefaultRunspace.Name -eq $this.FullName) { + $this.SetCommandCache() + } + } + + [void] SetCommandCache() { + $packages = Find-PSResource -Name * -Type Module + + foreach ($package in $packages) { + $commands = $package.Tags | Where-Object { $_ -like "PSCommand*" } | ForEach-Object { $_ -replace 'PSCommand_', '' } + + foreach ($command in $commands) { + if ($this.CommandCache.ContainsKey($command)) { + $this.CommandCache[$command] += $package + } else { + $list = [List[PSResourceInfo]]::new() + $list += $package + $this.CommandCache.Add($command, $package) + } + } + } + } +} + class GetPackageDynamicParameters { [Parameter()] [string] $Path