gitpowershellcondaposh-git

Co-Existence of posh-git and miniconda3 on powershell - Prompt function warning


I frequently use posh-git in Powershell 7, and miniconda3 (which adds a conda hook to your powershell profile).

Relevant bits of my profile:

Import-Module posh-git -Force -EA 0

$GitPromptSettings.DefaultPromptPrefix.Text                  = '$(Get-Date -f "yyyy-MM-dd HH:mm") '
$GitPromptSettings.DefaultPromptPrefix.ForegroundColor       = [ConsoleColor]::DarkGray
$GitPromptSettings.DefaultPromptPath.ForegroundColor         = [ConsoleColor]::Gray
$GitPromptSettings.BeforeStatus.ForegroundColor              = [ConsoleColor]::DarkGray
$GitPromptSettings.DelimStatus.ForegroundColor               = [ConsoleColor]::DarkGray
$GitPromptSettings.AfterStatus.ForegroundColor               = [ConsoleColor]::DarkGray
$GitPromptSettings.BranchColor.ForegroundColor               = [ConsoleColor]::Cyan
$GitPromptSettings.WorkingColor.ForegroundColor              = [ConsoleColor]::Red
$GitPromptSettings.LocalWorkingStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
$GitPromptSettings.BranchBehindStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
$GitPromptSettings.IndexColor.ForegroundColor                = [ConsoleColor]::Green

#region conda initialize
# !! Contents within this block are managed by 'conda init' !!
If (Test-Path "C:\Python\miniconda3\Scripts\conda.exe") {
    (& "C:\Python\miniconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | ?{$_} | Invoke-Expression
}
#endregion

With this configuration, I get a warning every time I open a PowerShell console:

WARNING: If your prompt function uses any posh-git commands, it will cause posh-git to be re-imported every time your prompt function is invoked.

posh-git-warning

How are people handling this co-existence of posh-git and miniconda?

In the past, I was able to comment out the conda hook, and miniconda3 would still work and activate/deactivate environments by running conda activate <env_name> despite the hook not being present in my profile. But this is no longer the case (I think some recent update to miniconda changed this behavior).

So I have a few questions for those that work with miniconda and Pwsh7:

  1. Is there a way to remove the automatically added conda hook from my profile and still get conda to work on demand in my scripts? Right now if I remove the conda hook from my profile and run conda activate ENVNAME, nothing happens and the environment isn't activated from what I can tell.
  2. Is the best viable alternative to run the conda hook at a script level when I am using miniconda in a powershell script? I.E: Add the hook at the beginning of any powershell script that utilizes conda: (& "C:\Python\miniconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | ?{$_} | iex
  3. Is there a better overall way to handle this?
  4. Can I keep the conda hook in my profile AND posh-git without generating the WARNING: If your prompt function uses any posh-git commands, it will cause posh-git to be re-imported every time your prompt function is invoked. warning?

I'm just looking for the best way to handle the co-existence of these two tools. As a side-note, keeping the conda hook in my profile adds a 2 second overhead in loading time. (Loading personal and system profiles took 2222ms.). Without the hook, my shell loads instantly.

One thing I tried is the following in my profile:

function ImportPoshGit {
    Import-Module posh-git -Force -EA 0
    $GitPromptSettings.DefaultPromptPrefix.Text                  = '$(Get-Date -f "yyyy-MM-dd HH:mm") '
    $GitPromptSettings.DefaultPromptPrefix.ForegroundColor       = [ConsoleColor]::DarkGray
    $GitPromptSettings.DefaultPromptPath.ForegroundColor         = [ConsoleColor]::Gray
    $GitPromptSettings.BeforeStatus.ForegroundColor              = [ConsoleColor]::DarkGray
    $GitPromptSettings.DelimStatus.ForegroundColor               = [ConsoleColor]::DarkGray
    $GitPromptSettings.AfterStatus.ForegroundColor               = [ConsoleColor]::DarkGray
    $GitPromptSettings.BranchColor.ForegroundColor               = [ConsoleColor]::Cyan
    $GitPromptSettings.WorkingColor.ForegroundColor              = [ConsoleColor]::Red
    $GitPromptSettings.LocalWorkingStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
    $GitPromptSettings.BranchBehindStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
    $GitPromptSettings.IndexColor.ForegroundColor                = [ConsoleColor]::Green
}

ImportPoshGit

Set-Alias -Name 'condahook' -Value EnableConda
Set-Alias -Name 'exitconda' -Value DisableConda

function EnableConda {
    If (Test-Path "C:\Python\miniconda3\Scripts\conda.exe") {
        (& "C:\Python\miniconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | ?{$_} | iex
    }
}
function DisableConda {
    Remove-Module -FullyQualifiedName "$Env:_CONDA_ROOT\shell\condabin\Conda.psm1"
    ImportPoshGit 
    # I have to re-import posh-git, because for some unknown reason when the Remove-Module command
    # above executes, it also resets my prompt and posh-git doesn't work.
}

With this approach, conda is loaded on demand and the condahook alias works as expected. But when I type condaexit, I still get the warning: WARNING: If your prompt function uses any posh-git commands, it will cause posh-git to be re-imported every time your prompt function is invoked., and additionally I get a line below the warning: Suggestion [4,General]: The most similar commands are:

See screenshot:

posh-git-warning and suggestion

Can someone please show me the correct way to handle this?


Solution

  • SOLUTION

    I solved my issue with the following steps:

    1. Commented out the Write-Warning line from posh-git.psm1 in my powershell module directory. (I've opened an issue at the posh-git repository to see if they can implement a way to suppress this warning via some kind of preference variable. Right now it always prints this warning on module unload which is a bit annoying.)

    2. Enabled the PSFeedbackProvider "Experimental Feature" with Enable-ExperimentalFeature -Name PSFeedbackProvider. This suppresses the Suggestion [4,General]: The most similar commands are: output pollution. I don't know why it suppresses this specific output, but it does. If someone can comment on why, that would be great.

    3. Modified my Powershell profile to include the following:

    function Import-PoshGit {
        Import-Module posh-git -Force -ErrorAction 0 | Out-Null
        $GitPromptSettings.DefaultPromptPrefix.Text                  = '$(Get-Date -f "yyyy-MM-dd HH:mm") '
        $GitPromptSettings.DefaultPromptPrefix.ForegroundColor       = [ConsoleColor]::DarkGray
        $GitPromptSettings.DefaultPromptPath.ForegroundColor         = [ConsoleColor]::Gray
        $GitPromptSettings.BeforeStatus.ForegroundColor              = [ConsoleColor]::DarkGray
        $GitPromptSettings.DelimStatus.ForegroundColor               = [ConsoleColor]::DarkGray
        $GitPromptSettings.AfterStatus.ForegroundColor               = [ConsoleColor]::DarkGray
        $GitPromptSettings.BranchColor.ForegroundColor               = [ConsoleColor]::Cyan
        $GitPromptSettings.WorkingColor.ForegroundColor              = [ConsoleColor]::Red
        $GitPromptSettings.LocalWorkingStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
        $GitPromptSettings.BranchBehindStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
        $GitPromptSettings.IndexColor.ForegroundColor                = [ConsoleColor]::Green
    }
    
    Import-PoshGit
    
    Set-Alias -Name 'condahook' -Value EnableConda
    Set-Alias -Name 'condaexit' -Value DisableConda
    
    $env:CONDA_IS_ENABLED = $false
    function EnableConda {
        if($env:CONDA_IS_ENABLED -eq $false){
            If (Test-Path "C:\Python\miniconda3\Scripts\conda.exe") {
                (& "C:\Python\miniconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | ?{$_} | iex
                $env:CONDA_IS_ENABLED = $true
                return
            }
        }
    }
    function DisableConda {
        if($env:CONDA_IS_ENABLED -eq $true){
            Remove-Module -FullyQualifiedName "$Env:_CONDA_ROOT\shell\condabin\Conda.psm1" -ErrorAction Ignore | Out-Null
            Remove-Module posh-git -Force -ErrorAction Ignore | Out-Null
            Import-PoshGit
            $env:CONDA_IS_ENABLED = $false
        }
        return
    }
    
    1. The condahook alias enables miniconda3 functionality on-demand.
    2. The condaexit disables miniconda3 functionality on-demand. (And re-imports posh-git, because for some unknown reason it gets disabled after removing the conda module)
    3. Uses $env:CONDA_IS_ENABLED to track the state of whether the miniconda3 module is loaded or unloaded. This prevents the EnableConda function from executing if the environment variable is true, and prevents the DisableConda function from executing if the environment variable is false.
    4. The WARNING: If your prompt function uses any posh-git commands, it will cause posh-git to be re-imported every time your prompt function is invoked. output no longer appears due to the modification to posh-git.psm1
    5. The Suggestion [4,General]: The most similar commands are: output no longer appears due to enabling the PSFeedbackProvider experimental feature.

    Hopefully this helps someone.

    Edit: New (More efficient) Solution:

    This change doesn't require posh-git to be re-imported after you remove miniconda's module from the session.

    
    # Import posh-git for the first time on load
    
    Import-Module posh-git -Force -ErrorAction 0 | Out-Null
    
    # Set your posh-git customizations here
    
    $GitPromptSettings.DefaultPromptPrefix.Text                  = '$(Get-Date -f "yyyy-MM-dd HH:mm") '
    $GitPromptSettings.DefaultPromptPrefix.ForegroundColor       = [ConsoleColor]::DarkGray
    $GitPromptSettings.DefaultPromptPath.ForegroundColor         = [ConsoleColor]::Gray
    $GitPromptSettings.BeforeStatus.ForegroundColor              = [ConsoleColor]::DarkGray
    $GitPromptSettings.DelimStatus.ForegroundColor               = [ConsoleColor]::DarkGray
    $GitPromptSettings.AfterStatus.ForegroundColor               = [ConsoleColor]::DarkGray
    $GitPromptSettings.BranchColor.ForegroundColor               = [ConsoleColor]::Cyan
    $GitPromptSettings.WorkingColor.ForegroundColor              = [ConsoleColor]::Red
    $GitPromptSettings.LocalWorkingStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
    $GitPromptSettings.BranchBehindStatusSymbol.ForegroundColor  = [ConsoleColor]::Red
    $GitPromptSettings.IndexColor.ForegroundColor                = [ConsoleColor]::Green
    
    # Create aliases for loading and unloading miniconda3 functionality.
    Set-Alias -Name 'condahook' -Value EnableConda
    Set-Alias -Name 'condaexit' -Value DisableConda
    
    # Set a variable to track the state of whether miniconda is active or not
    $env:CONDA_IS_ENABLED = $false
    
    
    # Function that executes the default miniconda powershell hook to modify the prompt with your active environment.
    function EnableConda {
        if($env:CONDA_IS_ENABLED -eq $false){
            If (Test-Path "C:\Python\miniconda3\Scripts\conda.exe") {
                (& "C:\Python\miniconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | ?{$_} | iex
                $env:CONDA_IS_ENABLED = $true
            }
        }
    }
    
    # Function that removes the miniconda module and hook from the session.
    # This time, the major change is that we no longer need to re-import posh-git to get our normal prompt back.
    function DisableConda {
        if($env:CONDA_IS_ENABLED -eq $true){
            Remove-Module -FullyQualifiedName "$Env:_CONDA_ROOT\shell\condabin\Conda.psm1" -ErrorAction Ignore | Out-Null
    
            # Create a blank global prompt
            function global:prompt { ' ' }
    
            # Use posh-git's $GitPromptScriptBlock as the value for our new global prompt
            Set-Item Function:\prompt -Value $GitPromptScriptBlock
            $env:CONDA_IS_ENABLED = $false
        }
    }
    

    This is way better because there is no overhead of re-importing posh-git. I also eliminated the useless return statements.