diff options
Diffstat (limited to 'moduleHelper.ps1')
-rw-r--r-- | moduleHelper.ps1 | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/moduleHelper.ps1 b/moduleHelper.ps1 new file mode 100644 index 0000000..0bca260 --- /dev/null +++ b/moduleHelper.ps1 @@ -0,0 +1,225 @@ +#!powershell +# vim:syntax=ps1:ts=4 +# Do not remove the shebang or vim lines above. It helps software +# (e.g. Notepad++ or rouge-based, not only vim) identifying the syntax. JUST DON'T. + +# This helps a user creating a base module structure. + +<# + .SYNOPSIS + + Helps a user create a PowerShell module. + + .DESCRIPTION + + This script helps creating a base module structure, creating folders and some + base files. + + .EXAMPLE + + PS> .\moduleHelper.ps1 -ModuleName 'FooBar' -ModuleAuthor 'LaFoo Barson' -ModuleDescription "I foo'ed a bar." + + .LINK + + https://ramblingcookiemonster.github.io/Building-A-PowerShell-Module/ +#> + +Param ( + [Parameter( + Mandatory=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="The name of the module to create inside this folder.", + Position=0 + ) + ] + [ValidateLength(1,64)] + [string] + $ModuleName, + [Parameter( + Mandatory=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="The name of the module author.", + Position=1 + ) + ] + [ValidateLength(1,64)] + [string] + $ModuleAuthor, + [Parameter( + Mandatory=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="A short description of the module. Max. 140 characters.", + Position=2 + ) + ] + [ValidateLength(1,140)] + [string] + $ModuleDescription, + [Parameter( + Mandatory=$false, + ValueFromPipelineByPropertyName=$true, + HelpMessage="The name of the module to create inside this folder.", + Position=3 + ) + ] + [ValidateLength(1,64)] + [string] + $CompanyName, + [Parameter( + Mandatory=$false, + ValueFromPipelineByPropertyName=$true, + HelpMessage="The module's version. Validated against being SemVer. Default: 0.1", + Position=4 + ) + ] + [ValidateLength(1,16)] + [string] + $ModuleVersion = '0.1', + [Parameter( + Mandatory=$false, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Link to the licence. Defaults to a Wikipedia link about proprietary software.", + Position=5 + ) + ] + [ValidateLength(1,64)] + [string] + $LicenseUri = 'https://en.wikipedia.org/wiki/Proprietary_software', + [Parameter( + Mandatory=$false, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Use Formats Process file? If unsure, ignore this option. If so, set to true.", + Position=6 + ) + ] + [boolean] + $FormatsProcess = $false, + [Parameter( + Mandatory=$false, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Minimum PowerShell version this module works on. Validated against being SemVer.", + Position=7 + ) + ] + [ValidateLength(1,16)] + [string] + $PSVersion = '5.1' +) + +$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition +# Based off https://ramblingcookiemonster.github.io/Building-A-PowerShell-Module/, +# here comes the actual "let's do this!". +$ModulePath = "${scriptPath}\$ModuleName" +# $ModuleName = 'PSStackExchange' +# $ModuleAuthor = 'RamblingCookieMonster' +$Description = 'PowerShell module to query the StackExchange API' + +# The RegEx to validate version numbers against. We imply semantiv versioning, with +# or without leading "v". +[regex]$versRex = '^v?[0-9]{1,}(\.[0-9]{1,}){0,2}$' + +# Never accept failures, it will lead to subsequent confusion and errors. +$ErrorActionPreference = 'Stop' + +# Create the module and private function directories +# Write down the array in order of creation, i.e. DIR comes before DIR\SUBDIR. +$ModuleDirs = @( + "$ModulePath" + "${ModulePath}\Private" + "${ModulePath}\Public" + "${ModulePath}\en-US" # For about_Help files + "${ModulePath}\Tests" +) +foreach ($ModuleDir in $ModuleDirs) { + if ( -not (Test-Path "$ModuleDir") ) { + New-Item -ItemType Directory -Path "$ModuleDir" | Out-Null + } +} + +#Create the module and related files +$ModuleFiles = @( + "${ModulePath}\${ModuleName}.psd1" + "${ModulePath}\${ModuleName}.psm1" + "${ModulePath}\en-US\about_${ModuleName}.help.txt" + "${ModulePath}\Tests\${ModuleName}.Tests.ps1" +) +foreach ($ModuleFile in $ModuleFiles) { + if ( -not (Test-Path "$ModuleFile") ) { + New-Item -ItemType File -Path $ModuleFile | Out-Null + } +} +if ($FormatsProcess) { + New-Item -ItemType File -Path "${ModulePath}\${ModuleName}.Format.ps1xml" +} + +# Set some defaults +if ( ($ModuleVersion -eq $null) ) { + $ModuleVersion = '0.1' +} +if ( ($LicenseUri -eq $null) ) { + $LicenseUri = 'https://en.wikipedia.org/wiki/Proprietary_software' +} +if ( ($PSVersion -eq $null) ) { + # Yeah, PS7 is still beta and has lots more features, but consider the conservative + # versions that are rolled on Windows server (alongside Xbox extensions, priorities of this company...) + # Better stick to 5 as a default. Anything earlier implies EOL systems, so NOPE. + $PSVersion = '5.1' +} + +# Input Validation +if ( -not ($ModuleVersion -match $versRex) ) { + throw [System.ArgumentException]::New("Not a version string: ${ModuleVersion}") +} +if ( -not ($PSVersion -match $versRex) ) { + throw [System.ArgumentException]::New("Not a version string: ${PSVersion}") +} + +# The module UUID ("GUID") +# New-Guid produces an object with a single attribute, "Guid", containing the string. Here we go. +$moduleGuid = (New-Guid).Guid + +# Declare the Manifest hash: +$ManifestHash = @{ + RootModule = "${ModuleName}.psm1" + Author = $ModuleAuthor + CompanyName = $CompanyName + ModuleVersion = $ModuleVersion + Guid = $moduleGuid + PowerShellVersion = $PSVersion + Description = $ModuleDescription + PrivateData = @{ + PSData = @{ + LicenseUri = $LicenseUri + # A URL to the main website for this project. + # ProjectUri = '' + # A URL to an icon representing this module. + # IconUri = '' + # ReleaseNotes of this module + # ReleaseNotes = '' + } # End of PSData hashtable + } # End of PrivateData hashtable +} +if ($FormatsProcess) { + $ManifestHash += @{ FormatsToProcess = "${ModuleName}.Format.ps1xml" } +} + +# Create the Module: +# New-ModuleManifest produced a result that does not comply with the standard and fails restricted language settings. +# Lel. Since Microsoft never cared about an actual module creator and this just creates ModuleName.psd1, let's do This +# ourselves, we will not fail :-) +# New-ModuleManifest @ManifestHash +# here we go. Only caveat: ofc PS can only output well-known formats, but they HAD to have a different syntax for +# PowerShell internally. +if ( (Test-Path -Path "${ModulePath}\${ModuleName}.psd1") ) { + Remove-Item -Force -Path "${ModulePath}\${ModuleName}.psd1" +} +($ManifestHash | ConvertTo-Json) -replace '^{','@{' -replace ':',' = ' -replace ',','' -replace '=\ +{', '= @{' | Out-File "${ModulePath}\${ModuleName}.psd1" +# Beware: this will look a bit ugly, but it will work. This is on Windows, we have no sophisticated development environments. If you want that - install Linux ;-) + + +# Test and output the result: +Write-Host "`nRESULT:" +Write-Host "======" +Test-ModuleManifest -Path "${ModulePath}\${ModuleName}.psd1" | Select-Object Name,Path,Description,Guid,ModuleBase,PrivateData,Version,ModuleType,Author,AccessMode,ExportedFormatFiles + +# Copy the public/exported functions into the public folder, private functions into private folder
\ No newline at end of file |