RefrEnv
RefrEnv copied to clipboard
Suggested addition to the PowerShell and shell code
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