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; } }