pf-module_publish.ps1


function Update-ModulePsm1($path) {
    $folder = Split-Path $path -Parent
    $ModuleName = Split-Path $path -LeafBase
    $files = Get-ScriptList -path $folder
    $fullnameList = $files.fullname | 
        ForEach-Object { ([string]$_).Substring($folder.Length + 1) }

# The following function defines text to insert at the begining of each module
# this is why is not indented
function DefineModuleHeader {
$ErrorActionPreference = 'stop'
$script:scriptFolder = Split-Path ( Get-PSCallStack )[0].ScriptName -Parent
}

    $content =  $fullnameList | ForEach-Object { "`n" + '. $scriptFolder\' + $_  } 

    $DefineModuleHeader = Get-ContentToInclude -functionName DefineModuleHeader

    $content = $DefineModuleHeader + $content

    Set-Content -Value $content -Path $path
}
function Update-ModulePsm1:::Example {
    Update-ModulePsm1 -path C:\code\PowerFrame\pf-module\pf-module.psm1
}

function Get-Modules_Psd1($Path) {
    function NewModuleManifest_Default {
        New-ModuleManifest -Path $Path -ModuleVersion "1.0.0.1"  -Description 'NewModule' | Out-Null
    }
    if (-not (Test-Path $Path) ) { NewModuleManifest_Default }
    $psd = Import-PowerShellDataFile -Path $path -ErrorAction SilentlyContinue
    if (-not $psd) {
        # psd1 likely to be invalid so recreate one
        NewModuleManifest_Default
    }
    return $psd
}

function Update-ModuleManifest_Revision($Path,$revision) {
    if (-not $Revision) {
        return
    }
    
    $psd = Get-Modules_Psd1 $Path
    $ModuleVersion = if ($psd.ModuleVersion) { [Version]$psd.ModuleVersion } else { "$moduleName" }
    $Revision = if ($Revision) { $Revision } else { [Math]::Max($ModuleVersion.Revision, 1) }
    $ModuleVersion = [Version]::new([Math]::Max(1,$ModuleVersion.Major), 
        [Math]::Max(0,$ModuleVersion.Minor),
        [Math]::Max(0,$ModuleVersion.Build),
        $Revision)
    Update-ModuleManifest -Path $Path -ModuleVersion $ModuleVersion
}

function Import-Module_EnsureManifest {
    [CmdletBinding()]
    param (
        [Parameter()]
        $Path, 
        [string[]]$FunctionsToExport,
        $RequiredModules=@()
    )

    $moduleFolder = Split-Path $Path -Parent
    $moduleName = Split-Path $Path -LeafBase
    
    $psd = Get-Modules_Psd1 $Path

    $description = if ($psd.Description) { $psd.Description } else { "$moduleName" }
    $functionsToExport = if ( $functionsToExport ) { $functionsToExport } else { $psd.functionsToExport }

    $ExternalModuleDependencies = @() + $RequiredModules.ModuleName
    
    Update-ModuleManifest -Path $Path -FunctionsToExport $functionsToExport `
        -Description $description -RootModule "$moduleName.psm1"

    function SetManifestRequiredDependencies {
        Install-Module_BlockScope  -Name $ExternalModuleDependencies -script {
        
            if ($ExternalModuleDependencies) {
                Update-ModuleManifest -Path $Path -RequiredModules $ExternalModuleDependencies `
                    -ExternalModuleDependencies $ExternalModuleDependencies 
            }
       }.GetNewClosure()
    }

    # SetManifestRequiredDependencies
}
function Import-Module_EnsureManifest:::Example {
    Import-Module_EnsureManifest -Path C:\code\PowerFrame\pf-git\pf-git.psd1 -Revision 20
}

function Initialize-Module_Manifest_EnsureFiles {
    param(
        [Parameter(ValueFromPipeline=$true)]$module,
        $Revision
    )
    begin {
        $approvedVerbs = Get-Verb | ForEach-Object { $_.Verb  }
        $approvedVerbsRegEx = [string]::Join( '|', ( $approvedVerbs | ForEach-Object { "$_-" } ) ) 
        $approvedVerbsRegEx += "|Assert"
    }
    process {
        $modulePath = $module.DirectoryName ?? $module
        $moduleName = Split-Path $modulePath -Leaf
        $fullPathNoExtension = "$modulePath\$moduleName"
        $psd1Path = "$fullPathNoExtension.psd1"

        $ModuleDef = [PSCustomObject]@{
            FunctionsToExport = @()
        }

        $scriptList = Get-ScriptList -path $modulePath
        $functionList = $scriptList | Get-Functions
        $functionsToExport = $functionList |
            Where-Object name -NotLike '*:*' |
            Where-Object name -Match $approvedVerbsRegEx |
            Sort-Object name
        
        $ModuleDef.FunctionsToExport += $functionsToExport.Name

        $moduleList = $modulePath | Get-ChildItem -filter *.ps1 -Recurse
            | Get-ModuleDependencies | Sort-Object -Unique
            
        $RequiredModules = @()
        if ($moduleList) {
            $rr = $moduleList | ForEach-Object {
                @{
                    ModuleName = $_.Name.ToString()
                    ModuleVersion = $_.Version.ToString()
                    Guid = $_.Guid.ToString()
                }
            }  
            $RequiredModules += $rr
        }

        function CreateDependenciesPs1 {
            $ExternalModuleDependencies = @() + $RequiredModules.ModuleName
    
            $ManifestExtra = @{
                ExternalModuleDependencies = $ExternalModuleDependencies
            }
            $metadataFunction = "Get-Metadata_$ModuleName"
            $metadataFunction = Get-Function_ValidName -name $metadataFunction

            $metadata = $ManifestExtra | ConvertTo-Pson
            $metadata = '$Script:ModuleMetadata = ' + $metadata 
            $metadata += "`n`nfunction $metadataFunction { return `$Script:ModuleMetadata }"
            $metadata | Set-Content -Path ( join-path $modulePath "$moduleName-Metadata.ps1" ) -Force

            $ModuleDef.FunctionsToExport += $metadataFunction
        }

        Initialize-File_InNotPresent -path "$fullPathNoExtension.Format.ps1xml"
        Initialize-File_InNotPresent -path "$fullPathNoExtension.psm1"

        CreateDependenciesPs1

        Import-Module_EnsureManifest -Path $psd1Path `
            -FunctionsToExport $ModuleDef.FunctionsToExport  `
            -RequiredModules $RequiredModules

        Update-ModulePsm1 -path "$fullPathNoExtension.psm1"

        Update-ModuleManifest_Revision -Path $psd1Path -Revision $Revision

        # Remove comments in order to avoid commit changes because of header containg dates
        Remove-PowershellComments -path $psd1Path
    }
}

function Initialize-Module_Manifest_EnsureFiles:::Example {
    $folderModules = Get-Modulefolders -path C:\code\PowerFrame   
    $folderModules.FullName | Initialize-Module_Manifest_EnsureFiles -Revision 3
}