private/Confirm-WtwSessionModuleCurrent.ps1

function Test-WtwTruthyEnvFlag {
    <#
    .SYNOPSIS
        True when an env var is set to a non-empty value other than 0/false/no.
    #>

    [CmdletBinding()]
    param(
        [string] $Value
    )

    if ([string]::IsNullOrWhiteSpace($Value)) {
        return $false
    }

    return $Value.Trim() -notin @('0', 'false', 'no')
}

function Test-WtwIsPesterRun {
    <#
    .SYNOPSIS
        True when the current call stack is inside Pester.
    .DESCRIPTION
        Auto-reload must not replace the checkout under test with ``~/.wtw/module``.
        Matching Pester's own scripts on the call stack is enough, and is cheap.
    #>

    [CmdletBinding()]
    param()

    try {
        foreach ($frame in Get-PSCallStack) {
            $src = [string]$frame.ScriptName
            if ([string]::IsNullOrWhiteSpace($src)) { continue }
            if ($src -match '[\\/]Pester[\\/]' -or $src -match 'Pester\.psm1$') {
                return $true
            }
        }
    } catch {
        return $false
    }

    return $false
}

function Get-WtwSessionModuleStatus {
    <#
    .SYNOPSIS
        Compare the version this session loaded with the copies on disk.
    .DESCRIPTION
        ``$script:WtwLoadedManifestVersion`` is snapped when the module imports.
        After ``wtw update``, ``wtw install``, or an in-place overwrite, the
        files on disk can be newer than the functions still in memory.
 
        ReloadRoot is the copy this session should be running:
        the loaded checkout when ``WTW_USE_REPO_MODULE`` is set, otherwise the
        newer of that checkout and ``~/.wtw/module``.
    #>

    [CmdletBinding()]
    param(
        [string] $ModuleRoot,

        [string] $InstallRoot,

        $LoadedVersion
    )

    if ([string]::IsNullOrWhiteSpace($ModuleRoot)) {
        $ModuleRoot = $script:WtwModuleRoot
    }
    if ([string]::IsNullOrWhiteSpace($InstallRoot)) {
        $InstallRoot = Join-Path $HOME '.wtw' 'module'
    }
    if (-not $PSBoundParameters.ContainsKey('LoadedVersion')) {
        $LoadedVersion = $script:WtwLoadedManifestVersion
    }

    $loaded = $null
    if ($LoadedVersion -is [version]) {
        $loaded = $LoadedVersion
    } elseif ($null -ne $LoadedVersion) {
        [void][version]::TryParse([string]$LoadedVersion, [ref] $loaded)
    }

    $resolvedRoot = try { [IO.Path]::GetFullPath($ModuleRoot) } catch { $ModuleRoot }
    $resolvedInstall = try { [IO.Path]::GetFullPath($InstallRoot) } catch { $InstallRoot }
    $diskVersion = Get-WtwManifestVersion -ModuleRoot $resolvedRoot
    $installModule = Join-Path $resolvedInstall 'wtw.psm1'
    $installPresent = Test-Path -LiteralPath $installModule -PathType Leaf
    $installVersion = if ($installPresent) { Get-WtwManifestVersion -ModuleRoot $resolvedInstall } else { $null }
    $sameRoot = [string]::Equals($resolvedRoot, $resolvedInstall, [StringComparison]::OrdinalIgnoreCase)
    # Same truthiness as Restore-WtwInstalledModule: any non-empty value opts in.
    $useRepo = -not [string]::IsNullOrWhiteSpace([string]$env:WTW_USE_REPO_MODULE)

    $reloadRoot = $resolvedRoot
    $reloadVersion = $diskVersion
    $reason = 'loaded-root'
    if (-not $useRepo -and $installPresent -and -not $sameRoot) {
        if ($null -ne $installVersion -and ($null -eq $diskVersion -or $installVersion -gt $diskVersion)) {
            $reloadRoot = $resolvedInstall
            $reloadVersion = $installVersion
            $reason = 'install'
        }
    }

    $stale = $null -ne $loaded -and $null -ne $reloadVersion -and $reloadVersion -gt $loaded

    [pscustomobject]@{
        LoadedVersion     = $loaded
        LoadedRoot        = $resolvedRoot
        DiskVersion       = $diskVersion
        InstallRoot       = $resolvedInstall
        InstallVersion    = $installVersion
        InstallPresent    = $installPresent
        ReloadRoot        = $reloadRoot
        ReloadVersion     = $reloadVersion
        ReloadModulePath  = Join-Path $reloadRoot 'wtw.psm1'
        SameRoot          = $sameRoot
        UseRepoModule     = $useRepo
        Reason            = $reason
        Stale             = $stale
    }
}

function Import-WtwSessionModule {
    <#
    .SYNOPSIS
        Force-import a wtw.psm1 into the current session.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string] $ModulePath
    )

    Import-Module $ModulePath -Global -Force -DisableNameChecking -Verbose:$false -Debug:$false 1>$null 4>$null 5>$null 6>$null
}

function Write-WtwSessionReloadNotice {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        $Status,

        [switch] $Reloaded
    )

    $from = if ($null -ne $Status.LoadedVersion) { $Status.LoadedVersion.ToString() } else { 'unknown' }
    $to = if ($null -ne $Status.ReloadVersion) { $Status.ReloadVersion.ToString() } else { 'unknown' }
    if ($Reloaded) {
        if ($from -ne $to) {
            Write-Host (" Reloaded wtw {0} → {1} in this session." -f $from, $to) -ForegroundColor DarkGray
        } else {
            Write-Host (" Reloaded wtw {0} in this session." -f $to) -ForegroundColor DarkGray
        }
        return
    }

    Write-Host ''
    Write-Host (" This session loaded wtw {0}; {1} is on disk." -f $from, $to) -ForegroundColor Yellow
    Write-Host ' Reload: wtw reload' -ForegroundColor DarkGray
}

function Confirm-WtwSessionModuleCurrent {
    <#
    .SYNOPSIS
        Reload wtw in this session when the imported copy is older than disk.
    .DESCRIPTION
        Same-folder updates (``wtw update`` / an overwrite of ``~/.wtw/module``
        while this shell still holds the old functions) are imported automatically
        and the original command is re-run against the new functions.
 
        A checkout-imported session that is older than ``~/.wtw/module`` is not
        yanked automatically (that would surprise ``WTW_USE_REPO_MODULE`` and
        Pester). It prints ``wtw reload`` once instead.
 
        Returns ``$true`` when the original command was already re-dispatched
        (the caller must return). ``wtw reload`` passes ``-Force`` and does not
        re-dispatch.
    #>

    [CmdletBinding()]
    param(
        [object[]] $OriginalArgs = @(),

        [switch] $Force
    )

    try {
        if (-not $Force) {
            if (Test-WtwTruthyEnvFlag -Value $env:WTW_SESSION_RELOADING) {
                return $false
            }
            if (Test-WtwTruthyEnvFlag -Value $env:WTW_NO_SESSION_RELOAD) {
                return $false
            }
            if (Test-WtwTruthyEnvFlag -Value $env:CI) {
                return $false
            }
            if (Test-WtwIsPesterRun) {
                return $false
            }
        }

        $status = Get-WtwSessionModuleStatus
        if (-not $Force -and -not $status.Stale) {
            return $false
        }

        $reloadPath = [string]$status.ReloadModulePath
        if (-not (Test-Path -LiteralPath $reloadPath -PathType Leaf)) {
            return $false
        }

        $quiet = $false
        try { $quiet = [Console]::IsOutputRedirected } catch { $quiet = $false }

        # Auto-import only the copy this session already loaded. Switching to
        # ~/.wtw/module from a checkout is `wtw reload` / Restore-WtwInstalledModule.
        $samePath = [string]::Equals(
            $status.LoadedRoot,
            $status.ReloadRoot,
            [StringComparison]::OrdinalIgnoreCase
        )
        if (-not $Force -and -not $samePath) {
            if (-not $quiet -and -not $script:WtwSessionStaleHintShown) {
                $script:WtwSessionStaleHintShown = $true
                Write-WtwSessionReloadNotice -Status $status
            }
            return $false
        }

        Import-WtwSessionModule -ModulePath $reloadPath

        if ($Force -or -not $quiet) {
            Write-WtwSessionReloadNotice -Status $status -Reloaded
        }

        if ($Force) {
            return $true
        }

        $env:WTW_SESSION_RELOADING = '1'
        try {
            $invoke = Get-Command Invoke-Wtw -ErrorAction Stop
            if (@($OriginalArgs).Count -eq 0) {
                & $invoke
            } else {
                & $invoke @OriginalArgs
            }
        } finally {
            Remove-Item Env:WTW_SESSION_RELOADING -ErrorAction SilentlyContinue
        }

        return $true
    } catch {
        # A failed reload must not block the command the user typed.
        return $false
    }
}

function Invoke-WtwReloadSession {
    <#
    .SYNOPSIS
        Reload the wtw module in this PowerShell session.
    .DESCRIPTION
        Force-imports the copy this session should be running (the newer of the
        loaded checkout and ``~/.wtw/module``, unless ``WTW_USE_REPO_MODULE``).
        ``-Check`` only reports loaded vs disk vs install.
    #>

    [CmdletBinding()]
    param(
        [switch] $Check
    )

    $status = Get-WtwSessionModuleStatus

    if ($Check) {
        $loaded = if ($null -ne $status.LoadedVersion) { $status.LoadedVersion.ToString() } else { 'unknown' }
        $disk = if ($null -ne $status.DiskVersion) { $status.DiskVersion.ToString() } else { 'unknown' }
        $installed = if ($status.InstallPresent -and $null -ne $status.InstallVersion) {
            $status.InstallVersion.ToString()
        } elseif ($status.InstallPresent) {
            'unknown'
        } else {
            'none'
        }
        Write-Host ''
        Write-Host ' wtw session' -ForegroundColor Cyan
        Write-Host (" loaded {0}" -f $loaded)
        Write-Host (" this copy {0} {1}" -f $disk, $status.LoadedRoot)
        Write-Host (" installed {0} {1}" -f $installed, $status.InstallRoot)
        if ($status.Stale) {
            Write-Host ' stale yes — run: wtw reload' -ForegroundColor Yellow
        } else {
            Write-Host ' stale no' -ForegroundColor DarkGray
        }
        Write-Host ''
        return
    }

    Confirm-WtwSessionModuleCurrent -Force | Out-Null
}