function New-AlkamiManifest {
<#
.SYNOPSIS
Create a new AlkamiManifest.xml (v 1.0) in a specified location for a known type.
.PARAMETER Type
The type of manifest to be created
.PARAMETER Destination
The target folder location where the manifest is going to be created. Defaults to the current folder.
.PARAMETER ProjectLocation
The location of the project file to use for manifest creation. Defaults to looking in the current folder.
.PARAMETER FileType
Create files in xml or json format
.PARAMETER Force
Used to overwrite existing files
#>
[CmdletBinding()]
Param(
[Parameter(Position = 0, Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Widget', 'Service', 'Migration', 'Theme', 'WebApplication', 'WebExtension', 'Repository', 'Provider', 'WebSite', 'LegacyUtility', 'Hotfix', 'ApiComponent')]
[String]$Type,
[Parameter(Position = 1, Mandatory = $false)]
[Alias('Path', 'Folder', 'Target')]
[String]$Destination,
[Parameter(Position = 2, Mandatory = $false)]
[String]$ProjectLocation,
[Parameter(Position = 3, Mandatory = $false)]
[ValidateSet('Xml', 'Json')]
[string]$FileType = 'Xml',
[Switch]$Force
)
process {
$logLead = (Get-LogLeadName)
$widgetType = 'Widget'
$serviceType = 'Service'
$migrationType = 'Migration'
$themeType = 'Theme'
$webApplicationType = 'WebApplication'
$webExtensionType = 'WebExtension'
$repositoryType = 'Repository'
$providerType = 'Provider'
$websiteType = 'WebSite'
$legacyUtilityType = 'LegacyUtility'
$hotfixType = 'Hotfix'
$apiComponentType = 'ApiComponent'
# Get the current folder so we can put/look for things in the working folder if not specified
$CurrentWorkingFolder = (Get-Location).Path
# The base name is like C:\git\Alkami.Services.Permissions\ <- I want "Alkami.Services.Permissions"
# The base name can also be derived from the csproj name later
# So if the folder is C:\git\perms with an Alkami.Services.Permissions.csproj we can absorb that as the basename later
# The reason for a basename is when we start supporting node or ruby, etc, they don't have an assemblyInfo
$baseName = (Split-Path $CurrentWorkingFolder -Leaf)
if ([string]::IsNullOrWhiteSpace($Destination)) {
$Destination = $CurrentWorkingFolder
}
# Target path is where we store the final file at
# Easier to work with non-relative paths. This gives us a full path.
$targetPath = (Resolve-Path $Destination).Path
# Determine where we want to drop the file when we're done
# Ensure that our target path ends in the manifest filename
$defaultFilename = "AlkamiManifest.$($FileType.ToLower())"
$targetItemIsContainer = (Get-Item $targetPath).PSIsContainer
if (!$targetItemIsContainer -and ((Split-Path $targetPath -Leaf) -ne $defaultFilename)) {
Write-Warning "$logLead : The specified filename is not the expected filename. Matching to required filename."
$targetPath = (Join-Path (Split-Path $targetPath -Parent) $defaultFilename)
}
# if the target path is a container (is not a file)
# append the filename
if ($targetItemIsContainer) {
$targetPath = (Join-Path $targetPath $defaultFilename)
}
# Target path is now a file that we want to target
if (!$Force -and (Test-Path $targetPath)) {
Write-Warning "$logLead : There's already a file at $targetPath - Did you want to Test-AlkamiManifest this file instead? Use -Force to overwrite the existing file."
return
}
Write-Verbose "$logLead : Getting CSProj"
if ([string]::IsNullOrWhiteSpace($ProjectLocation)) {
$ProjectLocation = $CurrentWorkingFolder
}
if (!(Test-Path $ProjectLocation)) {
Write-Warning "$logLead : Project location does not exist, looking in current folder for a csproj"
$ProjectLocation = $CurrentWorkingFolder
}
# If it's a folder, look in the folder
if ((Get-Item $ProjectLocation).PSIsContainer) {
$csprojFile = ((Get-ChildItem (Join-Path $ProjectLocation "*.csproj") -Recurse) | Sort-Object -Unique | Select-Object -First 1)
} else {
# Test path did exist, it wasn't a folder, use that
$csprojFile = (Get-Item $ProjectLocation)
}
# This could be a node project, or just an empty folder with no content yet
if ($null -ne $csprojFile) {
$baseName = (Get-Item $csprojFile).BaseName
}
$assemblyName = $baseName
$rootNamespace = $baseName
$creatorCode = ""
$areaName = ""
$framework = "framework"
$splitRoots = @()
# If we have a csproj file then let's collect information from it
if ((![string]::IsNullOrWhiteSpace($csprojFile)) -and (Test-Path $csprojFile)) {
$xml = [xml](Get-Content $csprojFile.FullName)
$rootNamespaces = @($xml.Project.PropertyGroup.RootNamespace)
if (![string]::IsNullOrWhiteSpace($rootNamespaces[0])) {
$rootNamespace = $rootNamespaces[0]
}
$assemblyNames = @($xml.Project.PropertyGroup.AssemblyName)
if (![string]::IsNullOrWhiteSpace($assemblyNames[0])) {
$assemblyName = $assemblyNames[0]
}
$targetFrameworks = @($xml.Project.PropertyGroup.TargetFramework)
if (![string]::IsNullOrWhiteSpace($targetFrameworks[0])) {
$targetFramework = $targetFrameworks[0]
}
if ($targetFramework -match "core") {
$framework = "dotnetcore"
} else {
$framework = "framework"
}
$splitRoots = $rootNamespace.Split('.')
$creatorCode = $splitRoots[0]
} else {
# Refactor when we have node project examples to emit something more generic
Write-Warning "$logLead : There is no csproj file at [$ProjectLocation|$csprojFile]. Please run this from within a project code folder, or supply a valid ProjectLocation"
}
if ([string]::IsNullOrWhiteSpace($assemblyName) -and ![string]::IsNullOrWhiteSpace($rootNamespace)) {
$assemblyName = $rootNamespace
}
if ([string]::IsNullOrWhiteSpace($rootNamespace) -and ![string]::IsNullOrWhiteSpace($assemblyName)) {
$rootNamespace = $assemblyName
}
$sectionManifest = ""
if ($Type -eq $hotfixType) {
Write-Verbose "Building Hotfix Section"
$sectionManifest = @"
REPLACEME
REPLACESERVERTIER
"@
}
if($Type -eq $apiComponentType){
Write-Verbose "Building ApiComponent Section"
$sectionManifest = @"
REPLACEME
"@
}
if ($Type -eq $widgetType) {
Write-Verbose "Building Widget Section"
if (!!$splitRoots) {
# Widget area names are always the last part of the project name
# Alkami.Client.Widgets.Lending = Lending
$areaName = $splitRoots[-1]
# In the case of SDK they are actually:
# BCU.Client.Widgets.Lending = BCULending
$areaName = $splitRoots[0] + $splitRoots[-1]
}
$sectionManifest = @"
This is a displayable widget name for the UI
This is a displayable widget description for the UI
Client
$areaName
$rootNamespace
Desktop
"@
}
if ($Type -eq $serviceType) {
Write-Verbose "$logLead : Building Service Section"
$jsonServiceManifestChunk = @"
$assemblyName.Migrations
my_service_role
"@
$xmlServiceManifestChunk = @"
"@
$useChunk = $xmlServiceManifestChunk
if ($FileType -eq 'Json') {
$useChunk = $jsonServiceManifestChunk
}
$sectionManifest = @"
$framework
$assemblyName
$useChunk
"@
}
if ($Type -eq $legacyUtilityType) {
Write-Verbose "Building LegacyUtility Section"
$sectionManifest = @"
true
"@
}
if ($Type -eq $migrationType) {
Write-Verbose "Building Migration Section"
$sectionManifest = @"
FluentMigrator|Fluent
REPLACEME
$assemblyName
"@
}
if ($Type -eq $themeType) {
Write-Verbose "Building Theme Section"
$sectionManifest = @"
"@
}
if ($Type -eq $webApplicationType) {
Write-Verbose "Building Web Application Section"
$sectionManifest = @"
$areaName
false
"@
}
if ($Type -eq $webExtensionType) {
Write-Verbose "Building Web Extension Section"
$sectionManifest = @"
Client
"@
}
if ($Type -eq $repositoryType) {
Write-Verbose "Building Repository Section"
$sectionManifest = @"
Client
"@
}
if ($Type -eq $websiteType) {
Write-Verbose "Building WebSite Section"
$sectionManifest = @"
$baseName
"@
}
if ($Type -eq $providerType) {
Write-Verbose "Building Provider Section"
$sectionManifest = @"
BankService|Bank|SchedulerService|CoreService|Core|NotificationService|SecurityManagementService|SecurityManagement|Security|Radium|Nag|NagConfigurationService|NagConfig|NagConfiguration|All
$rootNamespace
Connector
"@
}
Write-Verbose "Building Manifest"
$sdkSection = @"
DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF
"@
# Special case for SDK clients to get extra help
if ($creatorCode -eq "Alkami") {
$sdkSection = ""
}
$manifestPayload = @"
1.0
$creatorCode
$assemblyName
$Type$sdkSection
$sectionManifest
"@
Write-Host "$logLead : Creating a new manifest file for a $FileType [$Type] at [$targetPath]"
if ($FileType -eq 'Json') {
$manifestPayload = ([xml]$manifestPayload | ConvertFrom-Xml).PackageManifest | Format-Json
}
Set-Content -Path $targetPath -Value $manifestPayload;
}
}