• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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