RefrEnv icon indicating copy to clipboard operation
RefrEnv copied to clipboard

Suggested addition to the PowerShell and shell code

Open Lockszmith-GH opened this issue 7 months ago • 0 comments

Hi, great project!

May I suggest an addition to the top of the scripts - a detection whether the script is called or sourced, and display a message if it is not sourced.

I've developed this for myself a while back, and use it with function libraries that I want to load (even in powershell, there are times I don't want to bake stuff into a module)

PowerShell version

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

$local:VerboseSourcing = $VerboseSourcing ?? ($PSBoundParameters.ContainsKey("Verbose") -and $PSBoundParameters['Verbose'] ? 'Continue' : 'Ignore')
if( $SourceMe ) {
    $local:PSScript = Get-Item -LiteralPath $PSCommandPath

    "Write-Verbose `"Sourcing from $($PSScript.Name)$(($PSBoundParameters.Count ? (@(' Called with:') + $PSBoundParameters.Keys) : '') -join ' -')`""
    "`$local:VerboseSourcing = '$VerboseSourcing'"
    "`$local:PSScript = Get-Item -LiteralPath '$($PSScript.FullName)'"
    Get-Content -LiteralPath $PSCommandPath -Raw
    return
} else {
    $local:tmpVP = $VerbosePreference

    $local:IsLoadMyGitUtilFuncsSourced = $IsLoadMyGitUtilFuncsSourced ?? $false

    $local:VerbosePreference = $VerboseSourcing
    if( -not $IsLoadMyGitUtilFuncsSourced )
    {
        $local:tmpEA = $ErrorActionPreference
        $ErrorActionPreference = 'Ignore'
        $local:MyPSInvocationStatement = "$(try{
            ( Get-Variable -Name:MyInvocation -Scope:1 -ValueOnly -ErrorAction Ignore |
            Where-Object Statement -match $PSScript.BaseName |
            # ForEach-Object Statement) + (
            # Get-Variable -Name:MyInvocation -Scope:0 -ValueOnly -ErrorAction Ignore |
            #     Where-Object Statement -match $PSScript.BaseName |
                ForEach-Object Statement
            )
        }finally{})"
        $IsLoadMyGitUtilFuncsSourced = [string]::IsNullOrEmpty($MyPSInvocationCommand ?? "")

        $ErrorActionPreference = $tmpEA
    }
    if( -not $IsLoadMyGitUtilFuncsSourced ) {
        $VerbosePreference = $tmpVP
    }
    Write-Verbose "IsLoadMyGitUtilFuncsSourced = $IsLoadMyGitUtilFuncsSourced"
    Write-Verbose "MyInvokation.Statement      = $MyPSInvocationStatement"
    Write-Verbose "PSScriptPath                = $PSScriptPath"
    Write-Verbose "PSCommandPath               = $PSCommandPath"
    Write-Verbose "PSScript.Name               = $($PSScript.BaseName)"

    $VerbosePreference = $tmpVP
    try {
        if( -not $IsLoadMyGitUtilFuncsSourced ) {

            Write-Error ("This code should be sourced by running:`n" +
            "`t$($PSScript.BaseName) -SourceMe | Invoke-Expression`n" +
            "or`n" +
            "`t. `$($($PSScript.BaseName) -SourceMe)")
            return
        }
    } finally {
        Remove-Variable IsLoadMyGitUtilFuncsSourced,tmpVP
    }
}
Remove-Variable VerboseSourcing

$script:IsVerbose = $VerbosePreference -eq 'Continue'
## Code that needs to be sourced -- BEGIN

## Code that needs to be sourced -- END

bash/zsh version

#! /usr/bin/env bash

# Helper function
is_sourced() {
    if [ -n "$ZSH_VERSION" ]; then
        case $ZSH_EVAL_CONTEXT in *:file:*) return 0;; esac
    else  # Add additional POSIX-compatible shell names here, if needed.
        case ${0##*/} in dash|-dash|bash|-bash|ksh|-ksh|sh|-sh) return 0;; esac
    fi
    return 1; # NOT sourced.
}

BASE_0=${BASE_0:-$0}
BASE_SHELL=$(basename "$SHELL")

if is_sourced; then
  ## Code that needs to be sourced -- BEGIN

  ## Code that needs to be sourced -- END
elif [[ "$1" == '-' ]]; then
    cat "${BASH_SOURCE[0]}"
else
    SCRIPT_NAME="$BASE_0"
    printf '%s\n' \
        "It seems $SCRIPT_NAME was invoked as a script. It should be sourced instead." \
        'The easiest way is to call it would probably be like this:' \
        "    $ . <( $SCRIPT_NAME - ) # Note the '-' after the script's name" \
        ''
fi

Lockszmith-GH avatar Jul 23 '24 19:07 Lockszmith-GH