Private/Helpers/ConvertTo-ModuleInfo.ps1
|
function ConvertTo-ModuleInfo { [CmdletBinding()] param( [Parameter(ValueFromPipeline)] $InputObject, [string]$ProviderType ) process { if ($null -eq $InputObject) { return } function Compare-ModuleVersion { param( [string]$Left, [string]$Right ) $leftSem = $null $rightSem = $null $leftSemOk = [System.Management.Automation.SemanticVersion]::TryParse($Left, [ref]$leftSem) $rightSemOk = [System.Management.Automation.SemanticVersion]::TryParse($Right, [ref]$rightSem) if ($leftSemOk -and $rightSemOk) { return $leftSem.CompareTo($rightSem) } try { $leftSys = [System.Version]$Left $rightSys = [System.Version]$Right return $leftSys.CompareTo($rightSys) } catch { # Final fallback keeps behavior deterministic when providers return non-standard version strings. return [string]::Compare($Left, $Right, [System.StringComparison]::OrdinalIgnoreCase) } } function Get-MetadataExportedCommands { param($RawObject) $commands = @() if ($RawObject.PSObject.Properties['Includes']) { $includes = $RawObject.Includes foreach ($propName in @('Commands', 'Command', 'Cmdlets', 'Cmdlet', 'Functions', 'Function')) { if (-not $includes.PSObject.Properties[$propName]) { continue } $values = @($includes.$propName) foreach ($value in $values) { if ($value -is [string] -and -not [string]::IsNullOrWhiteSpace($value)) { $commands += $value.Trim() } elseif ($null -ne $value -and $value.PSObject.Properties['Name']) { $commands += [string]$value.Name } } } } if ($RawObject.PSObject.Properties['AdditionalMetadata'] -and $RawObject.AdditionalMetadata) { foreach ($key in @('commands', 'Commands', 'cmdlets', 'Cmdlets', 'functions', 'Functions')) { $metaValue = $RawObject.AdditionalMetadata[$key] if (-not $metaValue) { continue } if ($metaValue -is [string]) { $commands += @($metaValue -split '[,;\s]+' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) } else { foreach ($item in @($metaValue)) { if ($item -is [string] -and -not [string]::IsNullOrWhiteSpace($item)) { $commands += $item.Trim() } elseif ($null -ne $item -and $item.PSObject.Properties['Name']) { $commands += [string]$item.Name } } } } } return @($commands | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique) } $info = [GalleryModuleInfo]::new() if ($ProviderType -notin @('PSResourceGet', 'PowerShellGet')) { # Generic fallback $info.Name = $InputObject.Name $info.Version = $InputObject.Version?.ToString() $info.Author = $InputObject.Author $info.Description = $InputObject.Description } else { # Common fields for both known providers $info.Name = $InputObject.Name $info.Version = $InputObject.Version?.ToString() $info.Author = $InputObject.Author $info.Description = $InputObject.Description $info.ProjectUri = $InputObject.ProjectUri?.ToString() $info.LicenseUri = $InputObject.LicenseUri?.ToString() $info.Tags = @($InputObject.Tags) $info.Repository = $InputObject.Repository $info.PublishedDate = if ($InputObject.PublishedDate) { $InputObject.PublishedDate } else { [datetime]::MinValue } $info.Dependencies = if ($InputObject.Dependencies) { @($InputObject.Dependencies | ForEach-Object { if ($_ -is [string]) { $_ } elseif ($null -ne $_ -and $_.PSObject.Properties['Name']) { $_.Name } }) } else { @() } # Provider-specific fields if ($ProviderType -eq 'PSResourceGet') { $info.IsPrerelease = $InputObject.IsPrerelease # PSResourceGet doesn't expose a first-class DownloadCount property; # attempt to read it from AdditionalMetadata (present on NuGet v3 sources). $rawCount = $InputObject.AdditionalMetadata?.downloadCount ?? $InputObject.AdditionalMetadata?.DownloadCount $info.DownloadCount = if ($rawCount) { [long]$rawCount } else { 0L } } else { $info.IsPrerelease = $false $info.DownloadCount = [long]($InputObject.AdditionalMetadata?.downloadCount ?? 0) } } # Determine install status $installed = Get-InstalledModuleInfo -Name $info.Name if ($installed) { $info.InstalledVersion = $installed.Version.ToString() # Compare versions with a semantic-first strategy and resilient fallback behavior. try { $comparison = Compare-ModuleVersion -Left $info.InstalledVersion -Right $info.Version $updateAvailable = ($comparison -lt 0) } catch { # If version comparison fails unexpectedly, keep status conservative and avoid false positives. $updateAvailable = $false } $info.InstallStatus = if ($updateAvailable) { 'UpdateAvailable' } else { 'Installed' } $info.ExportedCommands = @($installed.ExportedCommands.Keys) } else { $info.InstalledVersion = '' $info.InstallStatus = 'NotInstalled' $info.ExportedCommands = @(Get-MetadataExportedCommands -RawObject $InputObject) } return $info } } |