Noveris.Build.psm1

<#
#>


#Requires -modules @{ ModuleName = "Noveris.Logger" ; ModuleVersion = "0.1.0" }
#Requires -modules @{ ModuleName = "Noveris.Version" ; ModuleVersion = "0.1.0" }
#Requires -modules @{ ModuleName = "Noveris.Tasker" ; ModuleVersion = "0.1.0" }

using module Noveris.Tasker
using module Noveris.Version
using module Noveris.Logger

################
# Global settings
$ErrorActionPreference = "Stop"
Set-StrictMode -Version 2.0

################
# Script variables

Class BuildManager
{
    [TaskerSettings]$Tasker

    [LoggerType]$LogDefault
    [LoggerType]$LogInfo
    [LoggerType]$LogWarn
    [LoggerType]$LogError
    [LoggerType]$LogDebug
    [LoggerType]$LogVerbose

    Build()
    {
    }
}

<#
#>

Function New-BuildManager
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Project,

        [Parameter(Mandatory=$true)]
        [string]$Organisation,

        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [AllowNull()]
        [string[]]$VersionSources
    )

    process
    {
        ################
        # Configure loggers
        $logInfo = New-LoggerType -WriteHost -Color White -FormatBlock {
            ([string]::Format("{0} (INFO): {1}", [DateTime]::Now.ToString("yyyyMMdd HH:mm:ss"), $_))
        }

        $logWarn = New-LoggerType -WriteHost -Color Yellow -FormatBlock {
            ([string]::Format("{0} (WARN): {1}", [DateTime]::Now.ToString("yyyyMMdd HH:mm:ss"), $_))
        }

        $logError = New-LoggerType -WriteHost -Color Red -FormatBlock {
            ([string]::Format("{0} (ERROR): {1}", [DateTime]::Now.ToString("yyyyMMdd HH:mm:ss"), $_))
        }

        $logDebug = New-LoggerType -WriteHost -Color Cyan -FormatBlock {
            ([string]::Format("{0} (DEBUG): {1}", [DateTime]::Now.ToString("yyyyMMdd HH:mm:ss"), $_))
        }

        $logVerbose = New-LoggerType -WriteHost -Color Yellow -FormatBlock {
            ([string]::Format("{0} (VERBOSE): {1}", [DateTime]::Now.ToString("yyyyMMdd HH:mm:ss"), $_))
        }

        ################
        # Configure build version
        $version = $VersionSources | ConvertTo-VersionStore -MatchFirst -MatchRequired -AddMissingBuildNumber

        Write-Logger -Type $logVerbose ("SemVer: " + $version.SemVer)
        Write-Logger -Type $logVerbose ("FullVer: " + $version.FullVer)

        ################
        # Configure tasker settings
        $tasker = New-TaskerSettings

        Update-TaskerSettings -Settings $tasker -InformationPreference Continue -ErrorActionPreference Stop

        Update-TaskerSettings -Settings $tasker -SetVariable Organisation -Value $Organisation
        Update-TaskerSettings -Settings $tasker -SetVariable Project -Value $Project

        Update-TaskerSettings -Settings $tasker -SetVariable Version -Value $version
        Update-TaskerSettings -Settings $tasker -SetVariable SemVer -Value $version.SemVer
        Update-TaskerSettings -Settings $tasker -SetVariable FullVer -Value $version.FullVer

        Update-TaskerSettings -Settings $tasker -InformationBlock { Write-Logger -Type $logInfo $_ }.GetNewClosure()
        Update-TaskerSettings -Settings $tasker -DebugBlock { Write-Logger -Type $logDebug $_ }.GetNewClosure()
        Update-TaskerSettings -Settings $tasker -WarningBlock { Write-Logger -Type $logWarn $_ }.GetNewClosure()
        Update-TaskerSettings -Settings $tasker -VerboseBlock { Write-Logger -Type $logVerbose $_ }.GetNewClosure()
        Update-TaskerSettings -Settings $tasker -ErrorBlock { Write-Logger -Type $logError $_ }.GetNewClosure()

        ################
        # Create build manager
        $manager = New-Object BuildManager

        $manager.LogInfo = $logInfo
        $manager.LogWarn = $logWarn
        $manager.LogError = $logError
        $manager.LogDebug = $logDebug
        $manager.LogVerbose = $logVerbose

        $manager.Tasker = $tasker

        $manager
    }
}

<#
#>

Function Format-BuildStep
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline)]
        $Content,

        [Parameter(Mandatory=$true)]
        [BuildManager]$Manager,

        [Parameter(Mandatory=$true)]
        [string]$Name,

        [Parameter(Mandatory=$false)]
        [switch]$IgnoreError = $false
    )

    begin
    {
        Write-Logger -Type $manager.LogInfo ""
        Write-Logger -Type $manager.LogInfo ([string]::Empty.PadRight(70, "="))
        Write-Logger -Type $manager.LogInfo ("Task Begin: {0} " -f $Name)
        Write-Logger -Type $manager.LogInfo ([string]::Empty.PadRight(70, "="))
        Write-Logger -Type $manager.LogInfo ""
        $start = [DateTime]::Now
        $errors = 0
    }

    process
    {
        if ([System.Management.Automation.ErrorRecord].IsAssignableFrom($Content.GetType()))
        {
            $errors++
        }

        $content | Format-TaskerRun -Settings $Manager.Tasker
    }

    end
    {
        Write-Logger -Type $manager.LogInfo ""
        Write-Logger -Type $manager.LogInfo ([string]::Empty.PadRight(70, "="))
        Write-Logger -Type $manager.LogInfo ("Task End: {0} " -f $Name)
        $finish = [DateTime]::Now
        $duration = $finish - $start
        Write-Logger -Type $manager.LogInfo ("Duration: {0} minutes " -f [Math]::Round($duration.TotalMinutes, 2))
        Write-Logger -Type $manager.LogInfo ("Errors: {0} " -f $errors)
        Write-Logger -Type $manager.LogInfo ([string]::Empty.PadRight(70, "="))
        Write-Logger -Type $manager.LogInfo ""

        if (!$IgnoreError -and $errors -gt 0)
        {
            throw New-Object Exception -ArgumentList "Errors found during processing"
        }
    }
}

<#
#>

Function Format-TemplateFile
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Template,

        [Parameter(Mandatory=$true)]
        [string]$Target,

        [Parameter(Mandatory=$true)]
        [Hashtable]$Content
    )

    process
    {
        if ([String]::IsNullOrEmpty($Template))
        {
            throw New-Object ArgumentException -ArgumentList "Null or empty Template passed to Expand-Template"
        }

        if ([String]::IsNullOrEmpty($Target))
        {
            throw New-Object ArgumentException -ArgumentList "Null or empty Template passed to Expand-Template"
        }

        Get-Content $Template -Encoding UTF8 | Format-TemplateString -Content $Content | Out-File -Encoding UTF8 $Target
    }
}

<#
#>

Function Format-TemplateString
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline)]
        [AllowEmptyString()]
        [string]$TemplateString,

        [Parameter(Mandatory=$true)]
        [Hashtable]$Content
    )

    process
    {
        $working = $TemplateString

        foreach ($key in $Content.Keys)
        {
            $working = $working.Replace($key, $Content[$key])
        }

        $working
    }
}