From 81b0bb9263e97c8b19bad3d50b7f0fca2ae0fc10 Mon Sep 17 00:00:00 2001 From: Couleur <82747632+couleurm@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:28:25 +0100 Subject: [PATCH] refactor manifest builder --- .github/workflows/main.yml | 2 +- buildManifests.ps1 | 215 ++++++++++++++++++++----------------- 2 files changed, 118 insertions(+), 99 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 569598b..7ea4c12 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: shell: pwsh run: | ./buildMaster.ps1 -Write | Set-Content ./Master.ps1 - ./buildManifests.ps1 + ./buildManifests.ps1 | ConvertTo-Json -Depth 5 | Set-Content ./Manifests.json - name: 🌊 Commit the new 'compiled' build uses: stefanzweifel/git-auto-commit-action@v4 with: diff --git a/buildManifests.ps1 b/buildManifests.ps1 index d9ece98..b7edbc5 100644 --- a/buildManifests.ps1 +++ b/buildManifests.ps1 @@ -1,135 +1,154 @@ -function ParseTable { - <# - - #//Turns: - Hello, this is my parameter's description, - here's some useful info that will get formatted and fed in the manifests separately - Platform: Linux; Windows - Category: Optimizations - #//Into: - @{ - Description = @( - "Hello, this is my parameter's description," - "here's some useful info that will get formatted and fed in the manifests separately" - ) - KeyValues = @{ - Category = 'Optimizations' - Platform = @('Linux', 'Windows') - } - } +<# - #> - param( - $Header - ) + .DESCRIPTION - $Header = $Header -Split "`n" + Splits string-based description from hashtable-based key;values - $ret = [Ordered]@{} + .EXAMPLE + $desc, $value = Get-Metadata @" + Hey this is a description - $KeyValues = $Header | Where-Object {$_ -Like "*: *"} - $Description = $Header | Where-Object {$_ -NotLike "*: *"} - - ForEach($Line in $KeyValues){ - $Key, $Value = $Line -Split ': ' + key1: value1 + key2: value2 + "@ +#> +function Get-Metadata ($string) { + $desc = $string -split "`n" | Where-Object { $_ -NotLike "*: *" -and $_.trim() } | Where-Object { $_ -notlike "//*" } + $values = $string -split "`n" | Where-Object { $_ -Like "*: *" } | Where-Object { $_ -notlike "//*" } - if ((!$Key -or !$Value) -or ($Value -isnot [String])){ - Write-Host "Skipping: $Line" -ForegroundColor Red - continue - } + $value_table = [PSCustomObject]@{} + if ($values) { + + foreach ($line in $values) { + [string]$key, [string]$value = ($line -split ':', 2).trim() + if (!$key -or !$value) { + Write-Error "Failed getting metadata from`n$($string | ConvertTo-Json -Depth 3)" + } - if ($Value -Like '*; *'){ - $Value = $Value -split '; ' + $value_table | Add-Member -MemberType NoteProperty -Name $key -Value $value } - $ret.$Key = $Value } - - return @{ - Description = $Description - KeyValues = $ret + else { + $values = "" } + if (!$desc) { $desc = "" } + return @($desc, $value_table) } -Set-Location $PSScriptRoot +function buildManifests2 { + param( + $Path = (Get-ChildItem ./modules/ -File -Recurse -Include *.ps1) + ) + $ManifestList = [PSCustomObject]::new() -$Manifests = [System.Collections.ArrayList]@() + foreach($i in $Path){ -Get-ChildItem ./modules -Recurse -Include "*.ps1" | ForEach-Object { + $filepath = Get-Item $i -ErrorAction Stop - Remove-Variable -Name Parsed, Failed, HelpInfo, Entries, FuncName, Manifest, Parameters, Description -ErrorAction Ignore - $FuncName = $PSItem.BaseName # E.g 'Optimize-LunarClient' - Try { - . $PSItem -ErrorAction Stop - $HelpInfo = Get-Help $FuncName -ErrorAction Stop - } Catch { - $_ - Write-Warning "Failed to get help info from $FuncName, skipping" - } + $funcName = $filepath.BaseName + . $filepath.FullName -ErrorAction Stop + $HelpInfo = Get-Help $funcName -ErrorAction Stop - if ($HelpInfo.Description){ # .DESCRIPTION - # Then such value has been properly documented and will be added to the Manifests + $Manifest = [PSCustomObject]::new() - $Manifest = [Ordered]@{} - $Manifest += @{ - Name = $FuncName - Description = $HelpInfo.Description.Text - Parameters = [System.Collections.ArrayList]@() - Path = $PSItem.FullName.Replace($PSScriptRoot,'') - } + $relativePath = $filepath.FullName.Replace($PSScriptRoot,'') -replace '\\', '/' - if ($HelpInfo.details){ # .SYNOPSIS + $Manifest | Add-Member -MemberType NoteProperty -Name path -Value $relativePath + + + if ($desc = $HelpInfo.description.Text) { + # .DESCRIPTION + + $Manifest | Add-Member -MemberType NoteProperty -Name description -Value $desc + } + else { + # function is not documented, skip + continue + } - $Parsed = (ParseTable $HelpInfo.details.description.text) - if ($Parsed.KeyValues){ - $Manifest += $Parsed.KeyValues - } - if ($Parsed.Description){ - $Manifest.Description += ($Parsed.Description -join "`n") + if ($null, $values = Get-Metadata $HelpInfo.details.description.Text) { + foreach ($object in $values.psobject.properties) { + $key, $value = $object.name, $object.value + $Manifest | Add-Member -MemberType NoteProperty -Name $key -Value $value } } - if(!$Manifest."Display Name"){ - $Manifest."Display Name" = $FuncName -replace '-',' ' + if (!$Manifest.display) { + $Manifest | Add-Member -MemberType NoteProperty -Name display -Value ($FuncName -replace '-', ' ') } - ForEach($Parameter in $HelpInfo.Parameters.Parameter){ + $Manifest | Add-Member -MemberType NoteProperty -Name parameters -Value ([PSCustomObject]::new()) - $Description = ($Parameter.Description.Text -split "`n" | Where-Object {$PSItem -NotLike "//*"}) -join "`n" + foreach ($parameter in $HelpInfo.parameters.parameter) { - if ($Description){ # Therefore it has been documented and shall be added to the manifest - $ParamToAdd = [Ordered]@{} # Mind it's name, couldn't also have named it Parameter - $ParamToAdd += @{ - Name = $Parameter.Name - Required = $Parameter.required - # Description = $Description - Type = $Parameter.type.name - } - $Parsed = (ParseTable $Description) - if ($Parsed.KeyValues){ - $ParamToAdd.KeyValues = $Parsed.KeyValues + [PSCustomObject]$param = [PSCustomObject]::new() + + # if ($parameter.name -in @('misctweaks')){wait-debugger} + + if ($desc, $values = Get-Metadata $parameter.description.Text) { + + if ($desc) { + $param | Add-Member -MemberType NoteProperty -Name description -Value $desc } - if ($Parsed.Description){ - $ParamToAdd.Description = $Parsed.Description - }else{ - Write-Host "No description for parameter [$($Parameter.Name)] in function [$($Manifest.Name)]" -ForegroundColor Red + + if ($values.PSObject.Properties.Count) { + if ($values -is [String]){ + $values = @($values) + } + $param | Add-Member -MemberType NoteProperty -Name values -Value $values } + } + if (!$param.values) { - $ValidateSets = (Get-Command $FuncName).Parameters.$($Parameter.Name).Attributes.ValidValues - if ($ValidateSets){ - $ParamToAdd += @{ - ValidateSet = $ValidateSets + if ($ValidateSets = (Get-Command $funcName).Parameters.$($Parameter.Name).Attributes.ValidValues) { + if ($ValidateSets -is [String]){ + $ValidateSets = @($ValidateSets) } + $param | Add-Member -MemberType NoteProperty -Name values -Value $ValidateSets } + } + if ($parameter.defaultValue -and $parameter.type.name -ne "Array") { + $param | Add-Member -MemberType NoteProperty -Name default -Value $parameter.defaultValue + } + $param | Add-Member -MemberType NoteProperty -Name type -Value $(switch ($parameter.type.name) { + Array { + if ($param.values) { + "enum[]" + } + else { + Wait-Debugger + } + } + String { + if ($param.values) { + "enum" + } + else { + "String" + } + } + SwitchParameter { + "boolean" + } + default { + Write-Warning "Unknown type $()" + } + }) - $Manifest.Parameters += $ParamToAdd + if ($parameter.required -eq "true") { + $param | Add-Member -MemberType NoteProperty -Name required -Value $true } - } - $Manifests += $Manifest - } -} + + $Manifest.parameters | Add-Member -MemberType NoteProperty -Name $parameter.name -Value $param + } # foreach param -$Manifests | ConvertTo-Json -Depth 15 | Out-File ./Manifests.json + $ManifestList | Add-Member -MemberType NoteProperty -Name $funcName -Value $Manifest + } # foreach file + + return $ManifestList +} +buildManifests2 \ No newline at end of file