1# Copyright 2020 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15# Just in case PATH isn't already exported. 16export PATH 17 18# Note: Colors are unfortunately duplicated in several places; and removing the 19# duplication is not easy. Their locations are: 20# 21# - bootstrap.sh 22# - pw_cli/color.py 23# - pw_env_setup/py/pw_env_setup/colors.py 24# 25# So please keep them matching then modifying them. 26pw_none() { 27 echo -e "$*" 28} 29 30pw_red() { 31 echo -e "\033[0;31m$*\033[0m" 32} 33 34pw_bold_red() { 35 echo -e "\033[1;31m$*\033[0m" 36} 37 38pw_yellow() { 39 echo -e "\033[0;33m$*\033[0m" 40} 41 42pw_bold_yellow() { 43 echo -e "\033[1;33m$*\033[0m" 44} 45 46pw_green() { 47 echo -e "\033[0;32m$*\033[0m" 48} 49 50pw_bold_green() { 51 echo -e "\033[1;32m$*\033[0m" 52} 53 54pw_blue() { 55 echo -e "\033[1;34m$*\033[0m" 56} 57 58pw_cyan() { 59 echo -e "\033[1;36m$*\033[0m" 60} 61 62pw_magenta() { 63 echo -e "\033[0;35m$*\033[0m" 64} 65 66pw_bold_white() { 67 echo -e "\033[1;37m$*\033[0m" 68} 69 70pw_eval_sourced() { 71 if [ "$1" -eq 0 ]; then 72 # TODO(pwbug/354) Remove conditional after all downstream projects have 73 # changed to passing in second argument. 74 if [ -n "$2" ]; then 75 _PW_NAME=$(basename "$2" .sh) 76 else 77 _PW_NAME=$(basename "$_BOOTSTRAP_PATH" .sh) 78 fi 79 pw_bold_red "Error: Attempting to $_PW_NAME in a subshell" 80 pw_red " Since $_PW_NAME.sh modifies your shell's environment variables," 81 pw_red " it must be sourced rather than executed. In particular, " 82 pw_red " 'bash $_PW_NAME.sh' will not work since the modified " 83 pw_red " environment will get destroyed at the end of the script. " 84 pw_red " Instead, source the script's contents in your shell:" 85 pw_red "" 86 pw_red " \$ source $_PW_NAME.sh" 87 exit 1 88 fi 89} 90 91pw_check_root() { 92 _PW_ROOT="$1" 93 if [[ "$_PW_ROOT" = *" "* ]]; then 94 pw_bold_red "Error: The Pigweed path contains spaces\n" 95 pw_red " The path '$_PW_ROOT' contains spaces. " 96 pw_red " Pigweed's Python environment currently requires Pigweed to be " 97 pw_red " at a path without spaces. Please checkout Pigweed in a " 98 pw_red " directory without spaces and retry running bootstrap." 99 return 100 fi 101} 102 103pw_get_env_root() { 104 # PW_ENVIRONMENT_ROOT allows developers to specify where the environment 105 # should be installed. bootstrap.sh scripts should not use that variable to 106 # store the result of this function. This separation allows scripts to assume 107 # PW_ENVIRONMENT_ROOT came from the developer and not from a previous 108 # bootstrap possibly from another workspace. 109 if [ -z "$PW_ENVIRONMENT_ROOT" ]; then 110 if [ -n "$PW_PROJECT_ROOT" ]; then 111 echo "$PW_PROJECT_ROOT/.environment" 112 else 113 echo "$PW_ROOT/.environment" 114 fi 115 else 116 echo "$PW_ENVIRONMENT_ROOT" 117 fi 118} 119 120# Note: This banner is duplicated in three places; which is a lesser evil than 121# the contortions that would be needed to share this snippet across shell, 122# batch, and Python. Locations: 123# 124# - pw_env_setup/util.sh 125# - pw_cli/branding.py 126# - pw_env_setup/py/pw_env_setup/windows_env_start.py 127# 128_PW_BANNER=$(cat <<EOF 129 ▒█████▄ █▓ ▄███▒ ▒█ ▒█ ░▓████▒ ░▓████▒ ▒▓████▄ 130 ▒█░ █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█ ▒█ ▀ ▒█ ▀ ▒█ ▀█▌ 131 ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█ ▒███ ▒███ ░█ █▌ 132 ▒█▀ ░█░ ▓█ █▓ ░█░ █ ▒█ ▒█ ▄ ▒█ ▄ ░█ ▄█▌ 133 ▒█ ░█░ ░▓███▀ ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀ 134EOF 135) 136 137_pw_banner() { 138 if [ -z "$PW_ENVSETUP_QUIET" ] && [ -z "$PW_ENVSETUP_NO_BANNER" ]; then 139 pw_magenta "$_PW_BANNER\n" 140 fi 141} 142 143_PW_BANNER_FUNC="_pw_banner" 144 145_pw_hello() { 146 _PW_TEXT="$1" 147 if [ -n "$PW_BANNER_FUNC" ]; then 148 _PW_BANNER_FUNC="$PW_BANNER_FUNC" 149 fi 150 if [ -z "$PW_ENVSETUP_QUIET" ]; then 151 pw_green "\n WELCOME TO...\n" 152 "$_PW_BANNER_FUNC" 153 pw_green "$_PW_TEXT" 154 fi 155} 156 157pw_deactivate() { 158 # Assume PW_ROOT and PW_PROJECT_ROOT have already been set and we need to 159 # preserve their values. 160 _NEW_PW_ROOT="$PW_ROOT" 161 _NEW_PW_PROJECT_ROOT="$PW_PROJECT_ROOT" 162 163 # Find deactivate script, run it, and then delete it. This way if the 164 # deactivate script is doing something wrong subsequent bootstraps still 165 # have a chance to pass. 166 _PW_DEACTIVATE_SH="$_PW_ACTUAL_ENVIRONMENT_ROOT/deactivate.sh" 167 if [ -f "$_PW_DEACTIVATE_SH" ]; then 168 . "$_PW_DEACTIVATE_SH" 169 rm -f "$_PW_DEACTIVATE_SH" &> /dev/null 170 fi 171 172 # If there's a _pw_deactivate function run it. Redirect output to /dev/null 173 # in case _pw_deactivate doesn't exist. Remove _pw_deactivate when complete. 174 if [ -n "$(command -v _pw_deactivate)" ]; then 175 _pw_deactivate > /dev/null 2> /dev/null 176 unset -f _pw_deactivate 177 fi 178 179 # Restore. 180 PW_ROOT="$_NEW_PW_ROOT" 181 export PW_ROOT 182 PW_PROJECT_ROOT="$_NEW_PW_PROJECT_ROOT" 183 export PW_PROJECT_ROOT 184} 185 186deactivate() { 187 pw_deactivate 188 unset -f pw_deactivate 189 unset -f deactivate 190 unset PW_ROOT 191 unset PW_PROJECT_ROOT 192 unset PW_BRANDING_BANNER 193 unset PW_BRANDING_BANNER_COLOR 194} 195 196# The next three functions use the following variables. 197# * PW_BANNER_FUNC: function to print banner 198# * PW_BOOTSTRAP_PYTHON: specific Python interpreter to use for bootstrap 199# * PW_ROOT: path to Pigweed root 200# * PW_ENVSETUP_QUIET: limit output if "true" 201# 202# All arguments passed in are passed on to env_setup.py in pw_bootstrap, 203# pw_activate takes no arguments, and pw_finalize takes the name of the script 204# "bootstrap" or "activate" and the path to the setup script written by 205# bootstrap.sh. 206pw_bootstrap() { 207 _pw_hello " BOOTSTRAP! Bootstrap may take a few minutes; please be patient.\n" 208 209 local _pw_alias_check=0 210 alias python > /dev/null 2> /dev/null || _pw_alias_check=$? 211 if [ "$_pw_alias_check" -eq 0 ]; then 212 pw_bold_red "Error: 'python' is an alias" 213 pw_red "The shell has a 'python' alias set. This causes many obscure" 214 pw_red "Python-related issues both in and out of Pigweed. Please remove" 215 pw_red "the Python alias from your shell init file or at least run the" 216 pw_red "following command before bootstrapping Pigweed." 217 pw_red 218 pw_red " unalias python" 219 pw_red 220 return 221 fi 222 223 # Allow forcing a specific version of Python for testing pursposes. 224 if [ -n "$PW_BOOTSTRAP_PYTHON" ]; then 225 _PW_PYTHON="$PW_BOOTSTRAP_PYTHON" 226 elif command -v python3 > /dev/null 2> /dev/null; then 227 _PW_PYTHON=python3 228 elif command -v python2 > /dev/null 2> /dev/null; then 229 _PW_PYTHON=python2 230 elif command -v python > /dev/null 2> /dev/null; then 231 _PW_PYTHON=python 232 else 233 pw_bold_red "Error: No system Python present\n" 234 pw_red " Pigweed's bootstrap process requires a local system Python." 235 pw_red " Please install Python on your system, add it to your PATH" 236 pw_red " and re-try running bootstrap." 237 return 238 fi 239 240 if [ -n "$_PW_ENV_SETUP" ]; then 241 "$_PW_ENV_SETUP" "$@" 242 _PW_ENV_SETUP_STATUS="$?" 243 else 244 "$_PW_PYTHON" "$PW_ROOT/pw_env_setup/py/pw_env_setup/env_setup.py" "$@" 245 _PW_ENV_SETUP_STATUS="$?" 246 fi 247 248 # Create the environment README file. Use quotes to prevent alias expansion. 249 "cp" "$PW_ROOT/pw_env_setup/destination.md" "$_PW_ACTUAL_ENVIRONMENT_ROOT/README.md" 250} 251 252pw_activate() { 253 _pw_hello " ACTIVATOR! This sets your shell environment variables.\n" 254 _PW_ENV_SETUP_STATUS=0 255} 256 257pw_finalize() { 258 _PW_NAME="$1" 259 _PW_SETUP_SH="$2" 260 261 if [ "$_PW_ENV_SETUP_STATUS" -ne 0 ]; then 262 return 263 fi 264 265 if [ -f "$_PW_SETUP_SH" ]; then 266 . "$_PW_SETUP_SH" 267 268 if [ "$?" -eq 0 ]; then 269 if [ "$_PW_NAME" = "bootstrap" ] && [ -z "$PW_ENVSETUP_QUIET" ]; then 270 echo "To reactivate this environment in the future, run this in your " 271 echo "terminal:" 272 echo 273 pw_green " source ./activate.sh" 274 echo 275 echo "To deactivate this environment, run this:" 276 echo 277 pw_green " deactivate" 278 echo 279 fi 280 else 281 pw_red "Error during $_PW_NAME--see messages above." 282 fi 283 else 284 pw_red "Error during $_PW_NAME--see messages above." 285 fi 286} 287 288pw_cleanup() { 289 unset _PW_BANNER 290 unset _PW_BANNER_FUNC 291 unset PW_BANNER_FUNC 292 unset _PW_ENV_SETUP 293 unset _PW_NAME 294 unset _PW_PYTHON 295 unset _PW_SETUP_SH 296 unset _PW_DEACTIVATE_SH 297 unset _NEW_PW_ROOT 298 unset _PW_ENV_SETUP_STATUS 299 300 unset -f pw_none 301 unset -f pw_red 302 unset -f pw_bold_red 303 unset -f pw_yellow 304 unset -f pw_bold_yellow 305 unset -f pw_green 306 unset -f pw_bold_green 307 unset -f pw_blue 308 unset -f pw_cyan 309 unset -f pw_magenta 310 unset -f pw_bold_white 311 unset -f pw_eval_sourced 312 unset -f pw_check_root 313 unset -f pw_get_env_root 314 unset -f _pw_banner 315 unset -f pw_bootstrap 316 unset -f pw_activate 317 unset -f pw_finalize 318 unset -f pw_cleanup 319 unset -f _pw_hello 320} 321