ps/Modules/Alkami.PowerShell.Configuration/Public/Test-AlkamiManifest.ps1

170 lines
6.3 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
function Test-AlkamiManifest {
<#
.SYNOPSIS
Test an AlkamiManifest.xml to ensure the file seems valid.
.DESCRIPTION
Test and AlkamiManifest.xml to ensure the file seems valid.
This will return any of a number of errors, and a code.
The message should have all the remediation information you need to resolve the error.
The code should be supplied to an SDK/Tools team member for bug reporting or more detailed help.
.PARAMETER Source
[string] The folder that has the AlkamiManifest.xml file to be validated. Alternately, the path to the file. Defaults to looking in the current folder.
.PARAMETER TargetObject
[object] Used to bypass file loading. Most useful when combined with Get-PackageManifest -Path for ultimate power
.INPUTS
An AlkamiManifest.xml file for evaluation
.OUTPUTS
Either a successful message or a thrown error about what is broken.
.EXAMPLE
Test-AlkamiManifest
[Test-AlkamiManifest] : The file at C:\my\test\AlkamiManifest.xml appears to be valid for processing.
.EXAMPLE
Test-AlkamiManifest C:\my\test\
[Test-AlkamiManifest] : The file at C:\my\test\AlkamiManifest.xml appears to be valid for processing.
.EXAMPLE
Test-AlkamiManifest C:\my\test\AlkamiManifest.xml
[Test-AlkamiManifest] : The file at C:\my\test\AlkamiManifest.xml appears to be valid for processing.
#>
[CmdletBinding(DefaultParameterSetName = 'PassedPath')]
[OutputType([bool])]
Param(
[Parameter(Mandatory = $false, ParameterSetName = 'PassedPath')]
[ValidateNotNullOrEmpty()]
[ValidateScript( {Test-Path (Resolve-Path $_)})]
[Alias('Path', 'Folder', 'Target')]
[String]$Source = ".",
[Parameter(Mandatory = $true, ParameterSetName = 'PassedObject')]
[object]$TargetObject
)
$logLead = (Get-LogLeadName)
$resultMessages = @()
$success = $true
$validateManifestNodes = @()
#region parse/simplify parameterset
if ($PSCmdlet.ParameterSetName -eq 'PassedPath') {
$filename = (Get-AlkamiManifestFilename)
$targetPath = Resolve-Path $Source
if ((Split-Path $targetPath -Leaf) -ne $filename) {
$targetPath = (Join-Path $targetPath $filename)
}
if (-not (Test-Path $targetPath)) {
throw "$logLead : There is no file at $targetPath - Did you want to New-AlkamiManifest this file instead?"
}
$xmlContent = [Xml](Get-Content $targetPath)
if ($null -eq $xmlContent.packageManifest) {
throw "$logLead : There is no packageManifest tag in this file. It is invalid."
}
$TargetObject = $xmlContent.packageManifest
}
#endregion parse/simplify parameterset
#region parse/validate version
## Add additional recognized version codes here.
$recognizedVersionCodes = @('1.0')
if (-not $TargetObject.version) {
$resultMessages += 'There is no version tag in this file. It is invalid.'
$success = $false
} else {
$version = $TargetObject.Version -replace '\.',''
}
if (-not ($recognizedVersionCodes -contains $TargetObject.version)) {
$resultMessages += "The version tag in this file is unrecognized or unsupported. It is invalid. Valid values are [$($recognizedComponentTypes -join ',')]"
$success = $false
}
#endregion parse/validate version
# If we have gotten this far, we recognize the version and can test this manifest set
if ($success) {
#region parse/validate general
if ($null -eq $TargetObject.general) {
$resultMessages += 'There is no packageManifest/general tag in this file. It is invalid.'
$success = $false
} else {
$validateManifestNodes += "General"
}
$recognizedComponentTypes = @(
'Widget'
'Service'
'FluentMigration'
'WebApplication'
'WebExtension'
'Repository'
'Provider'
'WebSite'
'Installer'
'SREModule'
'LegacyUtility'
'Hotfix'
'ApiComponent'
)
$componentType = $TargetObject.general.componentType
if ([string]::IsNullOrWhiteSpace($componentType)) {
$resultMessages += 'The packageManifest/general/componentType tag in this file is missing or empty. It is invalid.'
$success = $false
} else {
if (-not ($recognizedComponentTypes -contains $componentType)) {
$resultMessages += "The packageManifest/general/componentType tag in this file is unrecognized or unsupported. Valid values are $($recognizedComponentTypes -join ',')"
$success = $false
} else {
if ($componentType) {
$validateManifestNodes += "$($componentType)Manifest"
}
}
}
#endregion parse/validate general
foreach ($manifestNode in $validateManifestNodes) {
$manifestFunctionName = $manifestNode
if ($manifestNode -eq 'General') {
# This is due to function name grouping so that they all appear together
$manifestFunctionName = 'ManifestGeneral'
}
if ($manifestNode -eq "SREModuleManifest") {
# This is due to Cole making a mistake in naming things
$manifestFunctionName = 'SREModuleManifest'
$manifestNode = 'moduleManifest'
}
if ($null -eq $TargetObject.$manifestNode) {
$resultMessages += "The expected manifest type subnode [$manifestNode] was not found"
$success = $false
}
# Create a simplified scriptblock that takes a param and executes a built-string against the provided object
$dynamicString = "param (`$manifestObject) Test-Alkami$manifestFunctionName$version `$manifestObject"
$sb = [scriptblock]::Create($dynamicString)
$results = Invoke-Command -ScriptBlock $sb -ArgumentList @( $TargetObject.$manifestNode )
$resultMessages += @($results.results)
$success = $success -and $results.Success
}
}
foreach($resultMessage in $resultMessages) {
if (-not [string]::IsNullOrWhiteSpace($resultMessage)) {
Write-Warning $resultMessage
}
}
return $success
}