ps/Modules/Alkami.PowerShell.Common/Public/New-AlkamiModule.ps1
2023-05-30 22:51:22 -07:00

291 lines
9.3 KiB
PowerShell

function New-AlkamiModule {
<#
.SYNOPSIS
This function creates a new module according to the Alkami pattern.
.DESCRIPTION
This function creates a new module according to the Alkami pattern.
This function will create the entire folder structure as well as a default pair of functions for testing.
.PARAMETER ModuleName
[string] The name of the module to be created
.INPUTS
Requires the ModuleName to be provided. Expects a 3 part dotted name, will use the last two parts when split by period
.OUTPUTS
This function creates a folder and files under the current location.
.EXAMPLE
New-AlkamiModule -ModuleName MyModule
New-AlkamiModule -ModuleName MyModule
.EXAMPLE
New-AlkamiModule -ModuleName "Alkami.PowerShell.MyModule"
New-AlkamiModule -ModuleName "Alkami.PowerShell.MyModule"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ModuleName
)
process {
if ([string]::IsNullOrWhiteSpace($ModuleName)) {
throw "ModuleName must be supplied"
}
## If we don't specify a module name, assume we are creating a default Alkami.PowerShell module
if ($ModuleName.IndexOf('.') -eq -1) {
$ModuleName = "Alkami.PowerShell.$ModuleName"
}
$workingRoot = (Get-Location)
$newModuleRootFolder = (Join-Path $workingRoot $ModuleName)
$psd1Path = (Join-Path $newModuleRootFolder "$ModuleName.psd1")
$projectPath = (Join-Path $newModuleRootFolder "$ModuleName.pssproj")
$nuspecPath = (Join-Path $newModuleRootFolder "$ModuleName.nuspec")
$publicFolder = (Join-Path $newModuleRootFolder Public)
$privateFolder = (Join-Path $newModuleRootFolder Private)
$publicDemoFile = (Join-Path $publicFolder "Get-HelloWorld.ps1")
$privateDemoFile = (Join-Path $privateFolder "Get-HelloWorldInternal.ps1")
$toolsFolder = (Join-Path $newModuleRootFolder tools)
$chocoInstallPath = (Join-Path $toolsFolder "chocolateyInstall.ps1")
$chocoUninstallPath = (Join-Path $toolsFolder "chocolateyUninstall.ps1")
if (Test-Path $psd1Path) {
throw "$ModuleName already exists, aborting"
}
$getHelloWorldContent = @"
function Get-HelloWorld {
<#
.SYNOPSIS
This function is just to demonstrate a Hello World in the new module being created
.DESCRIPTION
This function is just to demonstrate a Hello World in the new module being created
.INPUTS
None
.OUTPUTS
Hello World
.EXAMPLE
Get-HelloWorld
Get-HelloWorld
Hello World
#>
[CmdletBinding()]
param(
)
process {
Get-HelloWorldInternal
}
}
"@
$getHelloWorldPrivateContent = @"
function Get-HelloWorldInternal {
return "Hello World"
}
"@
$randomGuid = [guid]::NewGuid()
$author = $env:USERNAME
$copyrightYear = [DateTime]::Now.Year
$moduleContent = @"
@{
RootModule = '$ModuleName.psm1'
ModuleVersion = '1.0.0'
GUID = '$randomGuid'
Author = '$author'
CompanyName = 'Alkami Technologies, Inc.'
Copyright = '(c) $copyrightYear Alkami Technologies, Inc. All rights reserved.'
PowerShellVersion = '5.0'
RequiredModules = 'Alkami.PowerShell.Common'
FunctionsToExport = ''
}
"@
$middlePart = ($ModuleName -split '\.')[-2]
$endPart = ($ModuleName -split '\.')[-1]
$nuspecContent = @"
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>$ModuleName</id>
<version>`$version`$</version>
<title>Alkami Platform Modules - $middlePart - $endPart</title>
<authors>Alkami Technologies</authors>
<owners>Alkami Technologies</owners>
<projectUrl>https://extranet.alkamitech.com/display/ORB/$ModuleName</projectUrl>
<iconUrl>https://www.alkami.com/files/alkamilogo75x75.png</iconUrl>
<licenseUrl>http://alkami.com/files/orblicense.html</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Installs the Alkami $endPart module for use with PowerShell.</description>
<releaseNotes />
<tags>PowerShell</tags>
<copyright>Copyright (c) $copyrightYear Alkami Technologies</copyright>
</metadata>
<files>
<file src="tools\ChocolateyInstall.ps1" target="tools\ChocolateyInstall.ps1" />
<file src="tools\ChocolateyUninstall.ps1" target="tools\ChocolateyUninstall.ps1" />
<!-- <file src="public\*.ps1" target="module\public" /> -->
<!-- <file src="private\*.ps1" target="module\private" /> -->
<file src="*.psd1" target="module\" />
<file src="*.psm1" target="module\" />
</files>
</package>
"@
$chocoInstallContent = @"
[CmdletBinding()]
Param()
process {
`$myCurrentPath = `$PSScriptRoot;
Write-Verbose "Installing the Module from `$myCurrentPath";
`$parentPath = (Split-Path `$myCurrentPath);
`$systemModulePath = "C:\Program Files\WindowsPowerShell\Modules\";
`$myModulePath = (Join-Path `$parentPath "module");
`$metadata = ([Xml](Get-Content (Join-Path `$parentPath "*.nuspec"))).package.metadata;
`$id = `$metadata.id;
`$version = `$metadata.version -replace '-pre.+','';
`$targetModulePath = (Join-Path `$systemModulePath `$id);
`$targetModuleVersionPath = (Join-Path `$targetModulePath `$version);
if (Test-Path `$targetModulePath) {
## If the target folder already existed, remove it, because we are re-installing this package, obviously
if (Test-Path `$targetModuleVersionPath) {
Write-Warning "Found an already existing module at [`$targetModuleVersionPath]!!"
Remove-Item `$targetModuleVersionPath -Recurse -Force;
}
## Clear previous children for name conflicts
(Get-ChildItem `$targetModulePath) | ForEach-Object {
Write-Information "Removing module located at [`$_]";
Remove-Item `$_.FullName -Recurse -Force;
}
}
Write-Host "Copying module `$id to [`$targetModuleVersionPath]";
Copy-Item `$myModulePath -Destination `$targetModuleVersionPath -Recurse -Force;
## Ensure the module was able to load
Import-Module `$id -Global;
}
"@
$chocoUninstallContent = @"
[CmdletBinding()]
Param()
process {
`$myCurrentPath = `$PSScriptRoot;
Write-Verbose "Uninstalling the Module from `$myCurrentPath";
`$parentPath = (Split-Path `$myCurrentPath);
`$systemModulePath = "C:\Program Files\WindowsPowerShell\Modules\";
`$myModulePath = (Join-Path `$parentPath "module");
`$metadata = ([Xml](Get-Content (Join-Path `$parentPath "*.nuspec"))).package.metadata;
`$id = `$metadata.id;
`$version = `$metadata.version -replace '-pre.+','';
`$targetModulePath = (Join-Path `$systemModulePath `$id);
`$targetModuleVersionPath = (Join-Path `$targetModulePath `$version);
if (Test-Path `$targetModuleVersionPath) {
Write-Information "Removing module at [`$targetModuleVersionPath]!!"
Remove-Item `$targetModuleVersionPath -Recurse -Force;
}
}
"@
$projectGuid = [Guid]::NewGuid()
$projectContent = @"
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '`$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{$projectGuid}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>$ModuleName</RootNamespace>
<AssemblyName>$ModuleName</AssemblyName>
<Name>$ModuleName</Name>
<PostBuildScript>Invoke-Pester;</PostBuildScript>
<PreBuildScript>..\build-project.ps1 (Join-Path `$(SolutionDir) "$ModuleName")</PreBuildScript>
</PropertyGroup>
<PropertyGroup Condition=" '`$(Configuration)|`$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Folder Include="Private\" />
<Folder Include="Public\" />
<Folder Include="tools\" />
</ItemGroup>
<ItemGroup>
<Compile Include="$ModuleName.psd1" />
<Compile Include="Public\Get-HelloWorld.ps1" />
<Compile Include="Private\Get-HelloWorldInternal.ps1" />
<Compile Include="tools\chocolateyInstall.ps1" />
<Compile Include="tools\chocolateyUninstall.ps1" />
</ItemGroup>
<ItemGroup>
<Content Include="$ModuleName.nuspec" />
</ItemGroup>
<Import Project="`$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="Build" />
<Import Project="`$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets" Condition="Exists('`$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets')" />
</Project>
"@
if (!(Test-Path $newModuleRootFolder)) {
New-Item -Path $newModuleRootFolder -ItemType Directory -Force
}
if (!(Test-Path $publicFolder)) {
New-Item -Path $publicFolder -ItemType Directory -Force
}
if (!(Test-Path $privateFolder)) {
New-Item -Path $privateFolder -ItemType Directory -Force
}
if (!(Test-Path $toolsFolder)) {
New-Item -Path $toolsFolder -ItemType Directory -Force
}
Set-Content -Path $publicDemoFile -Value $getHelloWorldContent
Set-Content -Path $privateDemoFile -Value $getHelloWorldPrivateContent
Set-Content -Path $psd1Path -Value $moduleContent
Set-Content -Path $nuspecPath -Value $nuspecContent
Set-Content -Path $chocoInstallPath -Value $chocoInstallContent
Set-Content -Path $chocoUninstallPath -Value $chocoUninstallContent
Set-Content -Path $projectPath -Value $projectContent
}
}