Public/New-PstModuleManifest.ps1
function New-PstModuleManifest { <# .SYNOPSIS Generates a PowerShell module manifest by enumerating all function files in the Public folder and updating the module version. .DESCRIPTION This function automates the process of creating a PowerShell module manifest by scanning the specified Public folder for all .ps1 files, extracting the function names, updating the module version by incrementing the build number, and including them in the manifest. .PARAMETER PublicFolderPath The path to the Public folder containing the function files. .PARAMETER ManifestPath The path where the module manifest will be created. .PARAMETER RootModule The name of the root module file. .EXAMPLE New-PstModuleManifest -PublicFolderPath "C:\MyModule\Public" -ManifestPath "C:\MyModule\MyModule.psd1" -RootModule "MyModule.psm1" #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory = $false, Position = 0, HelpMessage = "The path to the Public folder containing the function files.")] [string]$PublicFolderPath = "$(Get-PublicPath)", [Parameter(Mandatory = $false, Position = 1, HelpMessage = "The path where the module manifest will be created.")] [string]$ManifestPath = "$(Get-ModulePSScriptRoot)", [Parameter(Mandatory = $false, Position = 2, HelpMessage = "The name of the root module file.")] [string]$RootModule = "$([System.IO.Path]::GetFileNameWithoutExtension($(Get-ModuleRootFileName)))" ) begin { Write-Debug -Message "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'" if (-not (Test-Path $PublicFolderPath)) { throw "PublicFolderPath not found: $PublicFolderPath" } else { Write-Verbose "PublicFolderPath found: $PublicFolderPath" } if (-not (Test-Path $ManifestPath)) { throw "ManifestPath not found: $ManifestPath" } else { Write-Verbose "ManifestPath found: $ManifestPath" } $RootModuleFileName = "$($RootModule).psm1" $RootModulePath = Join-Path -Path $ManifestPath -ChildPath $RootModuleFileName if (-not (Test-Path $RootModulePath)) { throw "RootModulePath file not found: $RootModulePath" } else { Write-Verbose "RootModulePath file found: $RootModulePath" } $RootManifestFileName = "$($RootModule).psd1" $ManifestFilePath = Join-Path -Path $ManifestPath -ChildPath $RootManifestFileName } process { try { Write-Verbose -Message "Get all the .ps1 files in the Public folder '$($PublicFolderPath)'" $FunctionFiles = Get-ChildItem -Path $PublicFolderPath -Filter *.ps1 Write-Verbose -Message "Extract the function names from the files" $FunctionNames = foreach ($File in $FunctionFiles) { [System.IO.Path]::GetFileNameWithoutExtension($($File.FullName)) } Write-Verbose -Message "Ensure the FunctionNames array is not empty or null" if (-not $FunctionNames) { Write-Error "No functions found in the Public folder." return } Write-Verbose -Message "Read the module version from the root module file" if (-not (Test-Path -Path $RootModulePath)) { Write-Error "Root module file '$RootModulePath' not found." return } $RootModuleContent = Get-Content -Path $RootModulePath $UpdatedContent = New-Object System.Collections.ArrayList $versionFound = $false $regionDeclarationsFound = $false $ModuleVersion = $null foreach ($Line in $RootModuleContent) { if ($Line -match '\[version\]\$Script:PstModuleVersion\s*=') { # Extract the current version and increment the revision by 1 $currentVersion = [version]($Line -replace '.*?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*', '$1') $ModuleVersion = [version]::new($currentVersion.Major, $currentVersion.Minor, $currentVersion.Build, $currentVersion.Revision + 1) # Replace the existing version line with the new version $UpdatedContent.Add('[version]$Script:PstModuleVersion = "' + $ModuleVersion.ToString() + '"') > $null $versionFound = $true } else { $UpdatedContent.Add($Line) > $null } if ($Line -match '#region Declarations') { $regionDeclarationsFound = $true } } # If the version line was not found, initialize $ModuleVersion and insert it after #region Declarations with version 0.0.0.1 if (-not $versionFound -and $regionDeclarationsFound) { $ModuleVersion = [version]"0.0.0.1" for ($i = 0; $i -lt $UpdatedContent.Count; $i++) { if ($UpdatedContent[$i] -match '#region Declarations') { $UpdatedContent.Insert($i + 1, '[version]$Script:PstModuleVersion = "' + $ModuleVersion.ToString() + '"') > $null break } } } # Write the updated content back to the file $UpdatedContent | Set-Content -Path $RootModulePath New-ModuleManifest -Path $ManifestFilePath ` -RootModule $RootModuleFileName ` -FunctionsToExport $FunctionNames ` -ModuleVersion $ModuleVersion ` -CmdletsToExport @() ` -VariablesToExport @() ` -AliasesToExport @() Write-Output "New Module manifest created '$($ManifestFilePath)' for RootModuleFileName '$($RootModuleFileName)', ModuleVersion '$($ModuleVersion)" } catch { if ($_.Exception -and $_.Exception.Message) { Write-Error "An error occurred: $($_.Exception.Message)" } else { Write-Error "An error occurred, but no additional information is available." } } } end { if ($?) { Write-Debug -Message "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'" } } } |