From 6fea3a6e95a36c3fff49057a8cf67632272ac4d0 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 20 Feb 2019 11:20:34 -0800 Subject: [PATCH] Show error message when activate.sh/ps1 is invoked directly instead of sourced (#7731) Helps users avoid a common mistake which is otherwise not obvious. --- activate.ps1 | 9 ++++++++- activate.sh | 33 +++++++++++++++++++++++++++++---- docs/BuildFromSource.md | 8 ++++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/activate.ps1 b/activate.ps1 index 78e8557fc8..194ac8d349 100644 --- a/activate.ps1 +++ b/activate.ps1 @@ -1,9 +1,16 @@ # # This file must be used by invoking ". .\activate.ps1" from the command line. -# You cannot run it directly. +# You cannot run it directly. See https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scripts#script-scope-and-dot-sourcing +# # To exit from the environment this creates, execute the 'deactivate' function. # +if ($MyInvocation.CommandOrigin -eq 'runspace') { + Write-Host -f Red "This script cannot be invoked directly." + Write-Host -f Red "To function correctly, this script file must be 'dot sourced' by calling `". $PSCommandPath`" (notice the dot at the beginning)." + exit 1 +} + function deactivate ([switch]$init) { # reset old environment variables diff --git a/activate.sh b/activate.sh index 894479a8b9..4986e1b297 100644 --- a/activate.sh +++ b/activate.sh @@ -3,10 +3,35 @@ # You cannot run it directly. # To exit from the environment this creates, execute the 'deactivate' function. +_RED="\033[0;31m" _MAGENTA="\033[0;95m" _YELLOW="\033[0;33m" _RESET="\033[0m" +# This detects if a script was sourced or invoked directly +# See https://stackoverflow.com/a/28776166/2526265 +sourced=0 +if [ -n "$ZSH_EVAL_CONTEXT" ]; then + case $ZSH_EVAL_CONTEXT in *:file) sourced=1;; esac + THIS_SCRIPT="${0:-}" +elif [ -n "$KSH_VERSION" ]; then + [ "$(cd $(dirname -- $0) && pwd -P)/$(basename -- $0)" != "$(cd $(dirname -- ${.sh.file}) && pwd -P)/$(basename -- ${.sh.file})" ] && sourced=1 + THIS_SCRIPT="${0:-}" +elif [ -n "$BASH_VERSION" ]; then + (return 2>/dev/null) && sourced=1 + THIS_SCRIPT="$BASH_SOURCE" +else # All other shells: examine $0 for known shell binary filenames + # Detects `sh` and `dash`; add additional shell filenames as needed. + case ${0##*/} in sh|dash) sourced=1;; esac + THIS_SCRIPT="${0:-}" +fi + +if [ $sourced -eq 0 ]; then + printf "${_RED}This script cannot be invoked directly.${_RESET}\n" + printf "${_RED}To function correctly, this script file must be sourced by calling \"source $0\".${_RESET}\n" + exit 1 +fi + deactivate () { # reset old environment variables @@ -38,7 +63,7 @@ deactivate () { # Cleanup the environment deactivate init -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DIR="$( cd "$( dirname "$THIS_SCRIPT" )" && pwd )" _OLD_PATH="$PATH" # Tell dotnet where to find itself export DOTNET_ROOT="$DIR/.dotnet" @@ -60,10 +85,10 @@ if [ -n "${BASH:-}" ] || [ -n "${ZSH_VERSION:-}" ] ; then hash -r 2>/dev/null fi -echo "${_MAGENTA}Enabled the .NET Core environment. Execute 'deactivate' to exit.${_RESET}" +printf "${_MAGENTA}Enabled the .NET Core environment. Execute 'deactivate' to exit.${_RESET}\n" if [ ! -f "$DOTNET_ROOT/dotnet" ]; then - echo "${_YELLOW}.NET Core has not been installed yet. Run $DIR/restore.sh to install it.${_RESET}" + printf "${_YELLOW}.NET Core has not been installed yet. Run $DIR/restore.sh to install it.${_RESET}\n" else - echo "dotnet = $DOTNET_ROOT/dotnet" + printf "dotnet = $DOTNET_ROOT/dotnet\n" fi diff --git a/docs/BuildFromSource.md b/docs/BuildFromSource.md index 403edbf53c..e48ed6bc69 100644 --- a/docs/BuildFromSource.md +++ b/docs/BuildFromSource.md @@ -101,8 +101,10 @@ Using Visual Studio Code with this repo requires setting environment variables o Use these command to launch VS Code with the right settings. On Windows (requires PowerShell): -``` -. activate.ps1 +```ps1 +# The extra dot at the beginning is required to 'dot source' this file into the right scope. + +. .\activate.ps1 code . ``` @@ -134,6 +136,8 @@ to make the .NET Core command line tool work well. You can set these environment On Windows (requires PowerShell): ```ps1 +# The extra dot at the beginning is required to 'dot source' this file into the right scope. + . .\activate.ps1 ```