1# Copyright 2024 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# This script must be tested on fish 3.6.0 16 17# Note: Colors are unfortunately duplicated in several places; and removing the 18# duplication is not easy. Their locations are: 19# 20# - bootstrap.sh 21# - pw_cli/color.py 22# - pw_env_setup/py/pw_env_setup/colors.py 23# - pw_env_setup/util.fish 24# - pw_env_setup/util.sh 25# 26# So please keep them matching then modifying them. 27function pw_none 28 set_color normal 29 echo -e $argv 30end 31 32function pw_red 33 set_color red 34 echo -e $argv 35 set_color normal 36end 37 38function pw_bold_red 39 set_color --bold red 40 echo -e $argv 41 set_color normal 42end 43 44function pw_yellow 45 set_color yellow 46 echo -e $argv 47 set_color normal 48end 49 50function pw_bold_yellow 51 set_color --bold yellow 52 echo -e $argv 53 set_color normal 54end 55 56function pw_green 57 set_color green 58 echo -e $argv 59 set_color normal 60end 61 62function pw_bold_green 63 set_color --bold green 64 echo -e $argv 65 set_color normal 66end 67 68function pw_blue 69 set_color blue 70 echo -e $argv 71 set_color normal 72end 73 74function pw_cyan 75 set_color cyan 76 echo -e $argv 77 set_color normal 78end 79 80function pw_magenta 81 set_color magenta 82 echo -e $argv 83 set_color normal 84end 85 86function pw_bold_white 87 set_color --bold white 88 echo -e $argv 89 set_color normal 90end 91 92function pw_error 93 set_color --bold brred 94 echo -e $argv 1>&2 95 set_color normal 96end 97 98function pw_error_info 99 set_color red 100 echo -e $argv 1>&2 101 set_color normal 102end 103 104# Print an error and exit if $is_sourced == 0 (the first argument). 105function pw_eval_sourced --argument-names is_sourced bootstrap_path 106 if test $is_sourced -eq 0 107 set _PW_NAME (basename $bootstrap_path) 108 pw_error "Error: Attempting to $_PW_NAME in a subshell" 109 pw_error_info " Since $_PW_NAME modifies your shell's environment" 110 pw_error_info " variables, it must be sourced rather than executed. In" 111 pw_error_info " particular, 'fish $_PW_NAME' will not work since the " 112 pw_error_info " modified environment will get destroyed at the end of the" 113 pw_error_info " script. Instead, source the script's contents in your" 114 pw_error_info " shell:" 115 pw_error_info "" 116 pw_error_info " \$ source $_PW_NAME" 117 exit 1 118 end 119end 120 121# Check for spaces in $_PW_ROOT (the first argument). 122function pw_check_root --argument-names _PW_ROOT 123 if string match --quiet '* *' $_PW_ROOT 124 pw_error "Error: The Pigweed path contains spaces" 125 pw_error_info " The path '$_PW_ROOT' contains spaces. " 126 pw_error_info " Pigweed's Python environment currently requires Pigweed to" 127 pw_error_info " be at a path without spaces. Please checkout Pigweed in a" 128 pw_error_info " directory without spaces and retry running bootstrap." 129 return -1 130 end 131end 132 133# Check for and return the environment directory location. 134function pw_get_env_root 135 # PW_ENVIRONMENT_ROOT allows callers to specify where the environment should 136 # be installed. bootstrap.sh scripts should not use that variable to store the 137 # result of this function. This separation allows scripts to assume 138 # PW_ENVIRONMENT_ROOT came from the caller and not from a previous bootstrap 139 # possibly from another workspace. PW_ENVIRONMENT_ROOT will be cleared after 140 # environment setup completes. 141 if set --query PW_ENVIRONMENT_ROOT 142 echo $PW_ENVIRONMENT_ROOT 143 return 144 end 145 146 # Determine project-level root directory. 147 if set --query PW_PROJECT_ROOT 148 set _PW_ENV_PREFIX $PW_PROJECT_ROOT 149 else 150 set _PW_ENV_PREFIX $PW_ROOT 151 end 152 153 # If <root>/environment exists, use it. Otherwise, if <root>/.environment 154 # exists, use it. Finally, use <root>/environment. 155 set _PW_DOTENV $_PW_ENV_PREFIX/.environment 156 set _PW_ENV $_PW_ENV_PREFIX/environment 157 158 if test -d $_PW_DOTENV 159 if test -d $_PW_ENV 160 pw_error "Error: both possible environment directories exist." 161 pw_error_info " $_PW_DOTENV" 162 pw_error_info " $_PW_ENV" 163 pw_error_info " If only one of these folders exists it will be used for" 164 pw_error_info " the Pigweed environment. If neither exists" 165 pw_error_info " '<...>/environment' will be used. Since both exist," 166 pw_error_info " bootstrap doesn't know which to use. Please delete one" 167 pw_error_info " or both and rerun bootstrap." 168 exit 1 169 end 170 end 171 172 if test -d $_PW_ENV 173 echo $_PW_ENV 174 else if test -d $_PW_DOTENV 175 echo $_PW_DOTENV 176 else 177 echo $_PW_ENV 178 end 179end 180 181 182set --export _PW_BANNER "\ 183 ▒█████▄ █▓ ▄███▒ ▒█ ▒█ ░▓████▒ ░▓████▒ ▒▓████▄ 184 ▒█░ █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█ ▒█ ▀ ▒█ ▀ ▒█ ▀█▌ 185 ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█ ▒███ ▒███ ░█ █▌ 186 ▒█▀ ░█░ ▓█ █▓ ░█░ █ ▒█ ▒█ ▄ ▒█ ▄ ░█ ▄█▌ 187 ▒█ ░█░ ░▓███▀ ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀ 188" 189 190function _default_pw_banner_func 191 pw_magenta $_PW_BANNER 192end 193 194set --export _PW_BANNER_FUNC _default_pw_banner_func 195 196function _pw_hello --argument-names _PW_TEXT 197 # If $PW_BANNER_FUNC is defined, use that as the banner function 198 # instead of the default. 199 if set --query PW_BANNER_FUNC 200 set _PW_BANNER_FUNC $PW_BANNER_FUNC 201 end 202 # Display the banner unless PW_ENVSETUP_QUIET or 203 # PW_ENVSETUP_NO_BANNER is set. 204 if test -z "$PW_ENVSETUP_QUIET" && test -z "$PW_ENVSETUP_NO_BANNER" 205 pw_green "\n WELCOME TO...\n" 206 set_color normal 207 $_PW_BANNER_FUNC 208 set_color normal 209 pw_green $_PW_TEXT 210 end 211end 212 213function pw_deactivate 214 # Assume PW_ROOT and PW_PROJECT_ROOT have already been set and we need to 215 # preserve their values. 216 set _NEW_PW_ROOT $PW_ROOT 217 set _NEW_PW_PROJECT_ROOT $PW_PROJECT_ROOT 218 219 # Find deactivate script, run it, and then delete it. This way if the 220 # deactivate script is doing something wrong subsequent bootstraps still 221 # have a chance to pass. 222 set _PW_DEACTIVATE_SH $_PW_ACTUAL_ENVIRONMENT_ROOT/deactivate.fish 223 if test -f $_PW_DEACTIVATE_SH 224 . $_PW_DEACTIVATE_SH 225 rm -f $_PW_DEACTIVATE_SH &>/dev/null 226 end 227 228 # If there's a _pw_deactivate function run it. Redirect output to /dev/null 229 # in case _pw_deactivate doesn't exist. Remove _pw_deactivate when complete. 230 if functions --query _pw_deactivate 231 _pw_deactivate >/dev/null 2>/dev/null 232 functions -e _pw_deactivate 233 end 234 235 # Restore. 236 set --export PW_ROOT $_NEW_PW_ROOT 237 set --export PW_PROJECT_ROOT $_NEW_PW_PROJECT_ROOT 238end 239 240function deactivate 241 pw_deactivate 242 functions -e pw_deactivate 243 functions -e deactivate 244 set -e PW_ROOT 245 set -e PW_PROJECT_ROOT 246 set -e PW_BRANDING_BANNER 247 set -e PW_BRANDING_BANNER_COLOR 248end 249 250# The next three functions use the following variables. 251# * PW_BANNER_FUNC: function to print banner 252# * PW_BOOTSTRAP_PYTHON: specific Python interpreter to use for bootstrap 253# * PW_ROOT: path to Pigweed root 254# * PW_ENVSETUP_QUIET: limit output if "true" 255# 256# All arguments passed in are passed on to env_setup.py in pw_bootstrap, 257# pw_activate takes no arguments, and pw_finalize takes the name of the script 258# "bootstrap" or "activate" and the path to the setup script written by 259# bootstrap.fish. 260function pw_bootstrap 261 _pw_hello " BOOTSTRAP! Bootstrap may take a few minutes; please be patient.\n" 262 263 if functions --query python 264 pw_error "Error: 'python' is an alias" 265 pw_error_info "The shell has a 'python' alias set. This causes many obscure" 266 pw_error_info "Python-related issues both in and out of Pigweed. Please" 267 pw_error_info "remove the Python alias from your shell init file or at" 268 pw_error_info "least run the following command before bootstrapping" 269 pw_error_info "Pigweed." 270 pw_error_info 271 pw_error_info " functions --erase python" 272 pw_error_info 273 return 274 end 275 276 # Allow forcing a specific version of Python for testing pursposes. 277 if test -n "$PW_BOOTSTRAP_PYTHON" 278 set _PW_PYTHON "$PW_BOOTSTRAP_PYTHON" 279 else if command -v python3 >/dev/null 2>/dev/null 280 set _PW_PYTHON python3 281 else if command -v python >/dev/null 2>/dev/null 282 set _PW_PYTHON python 283 else 284 pw_error "Error: No system Python present\n" 285 pw_error_info " Pigweed's bootstrap process requires a local system" 286 pw_error_info " Python. Please install Python on your system, add it to " 287 pw_error_info " your PATH and re-try running bootstrap." 288 return 289 end 290 291 if test -n "$_PW_ENV_SETUP" 292 $_PW_ENV_SETUP $argv 293 set _PW_ENV_SETUP_STATUS $status 294 else 295 $_PW_PYTHON $PW_ROOT/pw_env_setup/py/pw_env_setup/env_setup.py $argv 296 set _PW_ENV_SETUP_STATUS $status 297 end 298 299 # Write the directory path at bootstrap time into the directory. This helps 300 # us double-check things are still in the same space when calling activate. 301 set _PW_ENV_ROOT_TXT $_PW_ACTUAL_ENVIRONMENT_ROOT/env_root.txt 302 echo $_PW_ACTUAL_ENVIRONMENT_ROOT >$_PW_ENV_ROOT_TXT 2>/dev/null 303 304 # Create the environment README file. Use quotes to prevent alias expansion. 305 cp $PW_ROOT/pw_env_setup/destination.md $_PW_ACTUAL_ENVIRONMENT_ROOT/README.md &>/dev/null 306end 307 308function pw_activate_message 309 _pw_hello " ACTIVATOR! This sets your shell environment variables.\n" 310 set _PW_ENV_SETUP_STATUS 0 311end 312 313function pw_finalize_pre_check --argument-names _PW_NAME _PW_SETUP_SH 314 # Check that the environment directory agrees that the path it's at matches 315 # where it thinks it should be. If not, bail. 316 set _PW_ENV_ROOT_TXT "$_PW_ACTUAL_ENVIRONMENT_ROOT/env_root.txt" 317 if test -f $_PW_ENV_ROOT_TXT 318 set _PW_PREV_ENV_ROOT (cat $_PW_ENV_ROOT_TXT) 319 if test "$_PW_ACTUAL_ENVIRONMENT_ROOT" != "$_PW_PREV_ENV_ROOT" 320 pw_error "Error: Environment directory moved" 321 pw_error_info "This Pigweed environment was created at" 322 pw_error_info 323 pw_error_info " $_PW_PREV_ENV_ROOT" 324 pw_error_info 325 pw_error_info "But it is now being activated from" 326 pw_error_info 327 pw_error_info " $_PW_ACTUAL_ENVIRONMENT_ROOT" 328 pw_error_info 329 pw_error_info "This is likely because the checkout moved. After moving " 330 pw_error_info "the checkout a full '. ./bootstrap.fish' is required." 331 pw_error_info 332 set _PW_ENV_SETUP_STATUS 1 333 end 334 end 335 336 if test -n "$_PW_ENV_SETUP_STATUS" && test "$_PW_ENV_SETUP_STATUS" -ne 0 337 return 338 end 339 340 if not test -f "$_PW_SETUP_SH" 341 pw_error "Error during $_PW_NAME--see messages above." 342 end 343end 344 345function pw_finalize_post_check --argument-names _PW_NAME _PW_SETUP_SH 346 if test "$status" -eq 0 347 if test "$_PW_NAME" = bootstrap && test -z "$PW_ENVSETUP_QUIET" 348 echo "To reactivate this environment in the future, run this in your " 349 echo "terminal:" 350 echo 351 pw_green " source ./activate.fish" 352 echo 353 echo "To deactivate this environment, run this:" 354 echo 355 pw_green " deactivate" 356 echo 357 end 358 else 359 pw_error "Error during $_PW_NAME--see messages above." 360 end 361end 362 363function pw_install_post_checkout_hook 364 cp $PW_ROOT/pw_env_setup/post-checkout-hook.sh $PW_PROJECT_ROOT/.git/hooks/post-checkout 365end 366 367function pw_cleanup 368 set -e _PW_BANNER 369 set -e _PW_BANNER_FUNC 370 set -e PW_BANNER_FUNC 371 set -e _PW_ENV_SETUP 372 set -e _PW_NAME 373 set -e PW_ENVIRONMENT_ROOT 374 set -e _PW_PYTHON 375 set -e _PW_ENV_ROOT_TXT 376 set -e _PW_PREV_ENV_ROOT 377 set -e _PW_SETUP_SH 378 set -e _PW_DEACTIVATE_SH 379 set -e _NEW_PW_ROOT 380 set -e _PW_ENV_SETUP_STATUS 381 set -e _PW_ENV_PREFIX 382 set -e _PW_ENV 383 set -e _PW_DOTENV 384 385 functions -e pw_none 386 functions -e pw_red 387 functions -e pw_bold_red 388 functions -e pw_yellow 389 functions -e pw_bold_yellow 390 functions -e pw_green 391 functions -e pw_bold_green 392 functions -e pw_blue 393 functions -e pw_cyan 394 functions -e pw_magenta 395 functions -e pw_bold_white 396 functions -e pw_eval_sourced 397 functions -e pw_check_root 398 functions -e pw_get_env_root 399 functions -e _pw_banner 400 functions -e pw_bootstrap 401 functions -e pw_activate 402 functions -e pw_finalize 403 functions -e pw_install_post_checkout_hook 404 functions -e pw_cleanup 405 functions -e _pw_hello 406 functions -e pw_error 407 functions -e pw_error_info 408end 409