[Feature] Validate app manifest property order (with idea to how)
@aliesbelik has corrected me at least twice on the order of items / properties / attributes in app manifests I've contributed, latest example:
* <https://github.com/ScoopInstaller/Extras/pull/13661>
I then thought, this must be feasible to check in a GitHub Action on PR. I then came up with a very simple solution:
1. Store wanted order of items in a string array, say `$WantedKeysOrder`.
2. Sort the keys of a manifest by the index of the item in `$WantedKeysOrder`.
3. Compare order before and after sorting. If different: Throw error / fail test.
```powershell
#Requires -Version 7.4
<#
Idea for validating order of items in JSON for Scoop manifests.
* Manifest: <https://github.com/ScoopInstaller/Scoop/wiki/App-Manifests>
* Contributing: <https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md>
* For Scoop buckets: <https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md#for-scoop-buckets>
* Manifest template: <https://github.com/ScoopInstaller/BucketTemplate/blob/master/bucket/app-name.json.template>
* App manifest schema: <https://github.com/ScoopInstaller/Scoop/blob/master/schema.json>
#>
# Assets
$WantedKeysOrder = [string[]](
'$schema',
'##',
'version',
'description',
'homepage',
'license',
'notes',
'depends',
'suggest',
'architecture',
'url',
'hash',
'innosetup',
'extract_dir',
'extract_to',
'pre_install',
'installer',
'post_install',
'env_add_path',
'env_set',
'bin',
'shortcuts',
'persist',
'pre_uninstall',
'uninstaller',
'post_uninstall',
'psmodule',
'checkver',
'autoupdate',
'cookie'
)
# Test JSON schema
Test-Json -Path (
'{0}\IT\Code\PowerShell\CLI\Scoop\Scoop-ManifestAuthoring\bucket\xl-converter.json' -f $env:OneDriveConsumer
) -Schema (
ConvertTo-Json -Depth 10 -InputObject (
Invoke-RestMethod -Method 'Get' -Uri 'https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json'
)
)
# Validate JSON order
## Get keys
### Local manifest
$KeysCurrently = [string[]](
$(
ConvertFrom-Json -InputObject (
Get-Content -Raw -Path (
'{0}\IT\Code\PowerShell\CLI\Scoop\Scoop-ManifestAuthoring\bucket\xl-converter.json' -f $env:OneDriveConsumer
)
) -AsHashtable
).'Keys'
)
### Public manifest
$KeysCurrently = [string[]](
$(
Invoke-RestMethod -Method 'Get' -Uri 'https://raw.githubusercontent.com/ScoopInstaller/Main/master/bucket/azure-cli.json'
).'PSObject'.'Properties'.'Name'
)
## Order by wanted order
$KeysOrdered = [string[]]($KeysCurrently | Sort-Object -Property @{'Expression' ={[byte]($WantedKeysOrder.IndexOf($_))}})
## Visual compare
$KeysCurrently | ForEach-Object -Begin {$Index = [byte] 1} -Process {
[PSCustomObject]@{
'Index' = [byte] $Index++
'Current' = [string] $_
'Ordered' = [string] $KeysOrdered[$KeysCurrently.IndexOf($_)]
}
} | ForEach-Object -Process {
$null = Add-Member -InputObject $_ -MemberType 'NoteProperty' -Force -Name 'Equal' -Value (
[bool]($_.'Current' -eq $_.'Ordered')
)
$_
} | Format-Table
## Validate order
if ((Compare-Object -ReferenceObject $KeysCurrently -DifferenceObject $KeysOrdered -SyncWindow 0 -PassThru).'Count' -gt 0) {
Throw 'Not following the order defined in CONTRIBUTING.md#for-scoop-buckets'
}
else {
Write-Output -InputObject 'The order looks fine.'
}
```
1 条评论