pw_env_setup: Bootstrap fish-shell support

Change-Id: I6d9838b0010ee34c8e50571439f71ecba00cfc3b
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/56840
Reviewed-by: Chad Norvell <chadnorvell@google.com>
Reviewed-by: Rob Mohr <mohrr@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
This commit is contained in:
Anthony DiGirolamo 2024-06-04 03:32:33 +00:00 committed by CQ Bot Account
parent d91003238d
commit d988f7027f
10 changed files with 673 additions and 14 deletions

1
activate.fish Symbolic link
View File

@ -0,0 +1 @@
bootstrap.fish

90
bootstrap.fish Normal file
View File

@ -0,0 +1,90 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# This script must be tested on fish 3.6.0
# Get the absolute path of the bootstrap script.
set _PW_BOOTSTRAP_PATH (path resolve (status current-filename))
# Check if this file is being executed or sourced.
set _pw_sourced 0
if string match --quiet '*from sourcing file*' (status)
set _pw_sourced 1
end
# Downstream projects need to set something other than PW_ROOT here, like
# YOUR_PROJECT_ROOT. Please also set PW_PROJECT_ROOT and PW_ROOT before
# invoking pw_bootstrap or pw_activate.
######### BEGIN PROJECT-SPECIFIC CODE #########
set --export PW_ROOT (path resolve (dirname $_PW_BOOTSTRAP_PATH))
# Please also set PW_PROJECT_ROOT to YOUR_PROJECT_ROOT.
set --export PW_PROJECT_ROOT $PW_ROOT
# Downstream projects may wish to set PW_BANNER_FUNC to a function that prints
# an ASCII art banner here. For example:
#
# set --export PW_BANNER_FUNC banner_function_name
#
########## END PROJECT-SPECIFIC CODE ##########
source $PW_ROOT/pw_env_setup/util.fish
# Check environment properties
pw_deactivate
pw_eval_sourced $_pw_sourced $_PW_BOOTSTRAP_PATH
if not pw_check_root $PW_ROOT
return
end
set --export _PW_ACTUAL_ENVIRONMENT_ROOT (pw_get_env_root)
set SETUP_SH "$_PW_ACTUAL_ENVIRONMENT_ROOT/activate.fish"
# Run full bootstrap when invoked as bootstrap, or env file is missing/empty.
if test (status basename) = "bootstrap.fish"
or not test -e $SETUP_SH
or not test -s $SETUP_SH
######### BEGIN PROJECT-SPECIFIC CODE #########
pw_bootstrap --shell-file "$SETUP_SH" --install-dir "$_PW_ACTUAL_ENVIRONMENT_ROOT"
########## END PROJECT-SPECIFIC CODE ##########
set finalize_mode bootstrap
else
pw_activate_message
set finalize_mode activate
end
# NOTE: Sourced scripts in fish cannot be sourced within a fuction if
# variables should be exported to the calling shell. So activate.fish
# must be sourced here instead of within pw_finalize or another
# function.
pw_finalize_pre_check $finalize_mode "$SETUP_SH"
source $SETUP_SH
pw_finalize_post_check $finalize_mode "$SETUP_SH"
if set --query _PW_ENV_SETUP_STATUS; and test "$_PW_ENV_SETUP_STATUS" -eq 0
# This is where any additional checks about the environment should go.
######### BEGIN PROJECT-SPECIFIC CODE #########
echo -n
########## END PROJECT-SPECIFIC CODE ##########
end
set -e _pw_sourced
set -e _PW_BOOTSTRAP_PATH
set -e SETUP_SH
# TODO(tonymd): Source fish pw_cli shell completion.
pw_cleanup
git -C "$PW_ROOT" config blame.ignoreRevsFile .git-blame-ignore-revs

View File

@ -45,6 +45,11 @@ To get setup:
$ bootstrap.bat (On Windows)
...
.. tip::
If you use the `Fish shell <https://fishshell.com/>`_ run `source
./bootstrap.fish` instead.
#. Configure the GN build.
.. code-block:: bash

View File

@ -40,8 +40,13 @@ runs bootstrap.
.. note::
On Windows the scripts used to set up the environment are ``bootstrap.bat``
and ``activate.bat``. For simplicity they will be referred to with the
``.sh`` endings unless the distinction is relevant.
and ``activate.bat``.
``bootstrap.fish`` and ``activate.fish`` are also available for `Fish shell
<https://fishshell.com/>`_ users.
For simplicity they will be referred to with the ``.sh`` endings unless the
distinction is relevant.
On POSIX systems, the environment can be deactivated by running ``deactivate``.

View File

@ -60,8 +60,8 @@ def _evaluate_env_in_shell(env):
delete=False,
mode='w+',
) as temp:
env.write(temp)
temp_name = temp.name
env.write(temp, shell_file=temp_name)
# Evaluate env sourcing script and capture output of 'env'.
if os.name == 'nt':
@ -164,7 +164,7 @@ class EnvironmentTest(unittest.TestCase):
self.env.set(self.var_not_set, '/foo/bar/baz')
self.env.add_replacement('FOOBAR', '/foo/bar')
buf = six.StringIO()
self.env.write(buf)
self.env.write(buf, shell_file='test.sh')
assert '/foo/bar' not in buf.getvalue()
def test_variable_replacement(self):
@ -172,7 +172,7 @@ class EnvironmentTest(unittest.TestCase):
self.env.set(self.var_not_set, '/foo/bar/baz')
self.env.add_replacement('FOOBAR')
buf = six.StringIO()
self.env.write(buf)
self.env.write(buf, shell_file='test.sh')
print(buf.getvalue())
assert '/foo/bar/baz' not in buf.getvalue()

View File

@ -200,6 +200,7 @@ class EnvSetup(object):
)
self._cipd_cache_dir = cipd_cache_dir
self._shell_file = shell_file
self._env._shell_file = shell_file
self._is_windows = os.name == 'nt'
self._quiet = quiet
self._install_dir = install_dir
@ -628,14 +629,14 @@ Then use `set +x` to go back to normal.
return 0
with open(self._shell_file, 'w') as outs:
self._env.write(outs)
self._env.write(outs, shell_file=self._shell_file)
deactivate = os.path.join(
self._install_dir,
'deactivate{}'.format(os.path.splitext(self._shell_file)[1]),
)
with open(deactivate, 'w') as outs:
self._env.write_deactivate(outs)
self._env.write_deactivate(outs, shell_file=deactivate)
config = {
# Skipping sysname and nodename in os.uname(). nodename could change

View File

@ -333,6 +333,7 @@ class Environment(object):
self.replacements = []
self._join = Join(pathsep)
self._finalized = False
self._shell_file = ''
def add_replacement(self, variable, value=None):
self.replacements.append((variable, value))
@ -440,7 +441,7 @@ class Environment(object):
if not self._windows:
buf = StringIO()
self.write_deactivate(buf)
self.write_deactivate(buf, shell_file=self._shell_file)
self._actions.append(Function('_pw_deactivate', buf.getvalue()))
self._blankline()
@ -457,17 +458,27 @@ class Environment(object):
def json(self, outs):
json_visitor.JSONVisitor().serialize(self, outs)
def write(self, outs):
def write(self, outs, shell_file):
if self._windows:
visitor = batch_visitor.BatchVisitor(pathsep=self._pathsep)
else:
visitor = shell_visitor.ShellVisitor(pathsep=self._pathsep)
if shell_file.endswith('.fish'):
visitor = shell_visitor.FishShellVisitor()
else:
visitor = shell_visitor.ShellVisitor(pathsep=self._pathsep)
visitor.serialize(self, outs)
def write_deactivate(self, outs):
def write_deactivate(self, outs, shell_file):
if self._windows:
return
visitor = shell_visitor.DeactivateShellVisitor(pathsep=self._pathsep)
if shell_file.endswith('.fish'):
visitor = shell_visitor.DeactivateFishShellVisitor(
pathsep=self._pathsep
)
else:
visitor = shell_visitor.DeactivateShellVisitor(
pathsep=self._pathsep
)
visitor.serialize(self, outs)
@contextlib.contextmanager

View File

@ -54,7 +54,7 @@ class _BaseShellVisitor(object): # pylint: disable=useless-object-inheritance
class ShellVisitor(_BaseShellVisitor):
"""Serializes an Environment into a shell file."""
"""Serializes an Environment into a bash-like shell file."""
def __init__(self, *args, **kwargs):
super(ShellVisitor, self).__init__(*args, **kwargs)
@ -174,7 +174,7 @@ class ShellVisitor(_BaseShellVisitor):
class DeactivateShellVisitor(_BaseShellVisitor):
"""Removes values from an Environment."""
"""Removes values from a bash-like shell environment."""
def __init__(self, *args, **kwargs):
pathsep = kwargs.pop('pathsep', ':')
@ -227,3 +227,132 @@ class DeactivateShellVisitor(_BaseShellVisitor):
def visit_function(self, function):
pass # Not relevant.
class FishShellVisitor(ShellVisitor):
"""Serializes an Environment into a fish shell file."""
def __init__(self, *args, **kwargs):
super(FishShellVisitor, self).__init__(*args, **kwargs)
self._pathsep = ' '
def _remove_value_from_path(self, variable, value):
return 'set PATH (string match -v {value} ${variable})\n'.format(
variable=variable, value=value
)
def visit_set(self, set): # pylint: disable=redefined-builtin
value = self._apply_replacements(set)
self._outs.write(
'set -x {name} {value}\n'.format(name=set.name, value=value)
)
def visit_clear(self, clear):
self._outs.write('set -e {name}\n'.format(**vars(clear)))
def visit_remove(self, remove):
value = self._apply_replacements(remove)
self._remove_value_from_path(remove.name, value)
def visit_prepend(self, prepend):
value = self._apply_replacements(prepend)
self._outs.write(
'set -x --prepend {name} {value}\n'.format(
name=prepend.name, value=value
)
)
def visit_append(self, append):
value = self._apply_replacements(append)
self._outs.write(
'set -x --append {name} {value}\n'.format(
name=append.name, value=value
)
)
def visit_echo(self, echo):
self._outs.write('if not set -q PW_ENVSETUP_QUIET\n')
if echo.newline:
self._outs.write(' echo "{}"\n'.format(echo.value))
else:
self._outs.write(' echo -n "{}"\n'.format(echo.value))
self._outs.write('end\n')
def visit_hash(self, hash): # pylint: disable=redefined-builtin
del hash
def visit_function(self, function):
self._outs.write(
'function {name}\n{body}\nend\n'.format(
name=function.name, body=function.body
)
)
def visit_command(self, command):
self._outs.write('{}\n'.format(' '.join(command.command)))
if not command.exit_on_error:
return
# Assume failing command produced relevant output.
self._outs.write('if test $status -ne 0\n return 1\nend\n')
def visit_doctor(self, doctor):
self._outs.write('if not set -q PW_ACTIVATE_SKIP_CHECKS\n')
self.visit_command(doctor)
self._outs.write('else\n')
self._outs.write(
'echo Skipping environment check because '
'PW_ACTIVATE_SKIP_CHECKS is set\n'
)
self._outs.write('end\n')
class DeactivateFishShellVisitor(FishShellVisitor):
"""Removes values from a fish shell environment."""
def serialize(self, env, outs):
try:
self._outs = outs
env.accept(self)
finally:
self._outs = None
def visit_set(self, set): # pylint: disable=redefined-builtin
if set.deactivate:
self._outs.write('set -e {name}\n'.format(name=set.name))
def visit_clear(self, clear):
pass # Not relevant.
def visit_remove(self, remove):
pass # Not relevant.
def visit_prepend(self, prepend):
self._outs.write(
self._remove_value_from_path(prepend.name, prepend.value)
)
def visit_append(self, append):
self._outs.write(
self._remove_value_from_path(append.name, append.value)
)
def visit_echo(self, echo):
pass # Not relevant.
def visit_comment(self, comment):
pass # Not relevant.
def visit_command(self, command):
pass # Not relevant.
def visit_doctor(self, doctor):
pass # Not relevant.
def visit_blank_line(self, blank_line):
pass # Not relevant.
def visit_function(self, function):
pass # Not relevant.

410
pw_env_setup/util.fish Normal file
View File

@ -0,0 +1,410 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# This script must be tested on fish 3.6.0
# Note: Colors are unfortunately duplicated in several places; and removing the
# duplication is not easy. Their locations are:
#
# - bootstrap.sh
# - pw_cli/color.py
# - pw_env_setup/py/pw_env_setup/colors.py
# - pw_env_setup/util.fish
# - pw_env_setup/util.sh
#
# So please keep them matching then modifying them.
function pw_none
set_color normal
echo -e $argv
end
function pw_red
set_color red
echo -e $argv
set_color normal
end
function pw_bold_red
set_color --bold red
echo -e $argv
set_color normal
end
function pw_yellow
set_color yellow
echo -e $argv
set_color normal
end
function pw_bold_yellow
set_color --bold yellow
echo -e $argv
set_color normal
end
function pw_green
set_color green
echo -e $argv
set_color normal
end
function pw_bold_green
set_color --bold green
echo -e $argv
set_color normal
end
function pw_blue
set_color blue
echo -e $argv
set_color normal
end
function pw_cyan
set_color cyan
echo -e $argv
set_color normal
end
function pw_magenta
set_color magenta
echo -e $argv
set_color normal
end
function pw_bold_white
set_color --bold white
echo -e $argv
set_color normal
end
function pw_error
set_color --bold brred
echo -e $argv 1>&2
set_color normal
end
function pw_error_info
set_color red
echo -e $argv 1>&2
set_color normal
end
# Print an error and exit if $is_sourced == 0 (the first argument).
function pw_eval_sourced --argument-names is_sourced bootstrap_path
if test $is_sourced -eq 0
set _PW_NAME (basename $bootstrap_path)
pw_error "Error: Attempting to $_PW_NAME in a subshell"
pw_error_info " Since $_PW_NAME modifies your shell's environment"
pw_error_info " variables, it must be sourced rather than executed. In"
pw_error_info " particular, 'fish $_PW_NAME' will not work since the "
pw_error_info " modified environment will get destroyed at the end of the"
pw_error_info " script. Instead, source the script's contents in your"
pw_error_info " shell:"
pw_error_info ""
pw_error_info " \$ source $_PW_NAME"
exit 1
end
end
# Check for spaces in $_PW_ROOT (the first argument).
function pw_check_root --argument-names _PW_ROOT
if string match --quiet '* *' $_PW_ROOT
pw_error "Error: The Pigweed path contains spaces"
pw_error_info " The path '$_PW_ROOT' contains spaces. "
pw_error_info " Pigweed's Python environment currently requires Pigweed to"
pw_error_info " be at a path without spaces. Please checkout Pigweed in a"
pw_error_info " directory without spaces and retry running bootstrap."
return -1
end
end
# Check for and return the environment directory location.
function pw_get_env_root
# PW_ENVIRONMENT_ROOT allows callers to specify where the environment should
# be installed. bootstrap.sh scripts should not use that variable to store the
# result of this function. This separation allows scripts to assume
# PW_ENVIRONMENT_ROOT came from the caller and not from a previous bootstrap
# possibly from another workspace. PW_ENVIRONMENT_ROOT will be cleared after
# environment setup completes.
if set --query PW_ENVIRONMENT_ROOT
echo $PW_ENVIRONMENT_ROOT
return
end
# Determine project-level root directory.
if set --query PW_PROJECT_ROOT
set _PW_ENV_PREFIX $PW_PROJECT_ROOT
else
set _PW_ENV_PREFIX $PW_ROOT
end
# If <root>/environment exists, use it. Otherwise, if <root>/.environment
# exists, use it. Finally, use <root>/environment.
set _PW_DOTENV $_PW_ENV_PREFIX/.environment
set _PW_ENV $_PW_ENV_PREFIX/environment
if test -d $_PW_DOTENV
if test -d $_PW_ENV
pw_error "Error: both possible environment directories exist."
pw_error_info " $_PW_DOTENV"
pw_error_info " $_PW_ENV"
pw_error_info " If only one of these folders exists it will be used for"
pw_error_info " the Pigweed environment. If neither exists"
pw_error_info " '<...>/environment' will be used. Since both exist,"
pw_error_info " bootstrap doesn't know which to use. Please delete one"
pw_error_info " or both and rerun bootstrap."
exit 1
end
end
if test -d $_PW_ENV
echo $_PW_ENV
else if test -d $_PW_DOTENV
echo $_PW_DOTENV
else
echo $_PW_ENV
end
end
set --export _PW_BANNER "\
▒█████▄ █▓ ▄███▒ ▒█ ▒█ ░▓████▒ ░▓████▒ ▒▓████▄
▒█░ █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█ ▒█ ▀ ▒█ ▀ ▒█ ▀█▌
▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█ ▒███ ▒███ ░█ █▌
▒█▀ ░█░ ▓█ █▓ ░█░ █ ▒█ ▒█ ▄ ▒█ ▄ ░█ ▄█▌
▒█ ░█░ ░▓███▀ ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀
"
function _default_pw_banner_func
pw_magenta $_PW_BANNER
end
set --export _PW_BANNER_FUNC _default_pw_banner_func
function _pw_hello --argument-names _PW_TEXT
# If $PW_BANNER_FUNC is defined, use that as the banner function
# instead of the default.
if set --query PW_BANNER_FUNC
set _PW_BANNER_FUNC $PW_BANNER_FUNC
end
# Display the banner unless PW_ENVSETUP_QUIET or
# PW_ENVSETUP_NO_BANNER is set.
if test -z "$PW_ENVSETUP_QUIET" && test -z "$PW_ENVSETUP_NO_BANNER"
pw_green "\n WELCOME TO...\n"
set_color normal
$_PW_BANNER_FUNC
set_color normal
pw_green $_PW_TEXT
end
end
function pw_deactivate
# Assume PW_ROOT and PW_PROJECT_ROOT have already been set and we need to
# preserve their values.
set _NEW_PW_ROOT $PW_ROOT
set _NEW_PW_PROJECT_ROOT $PW_PROJECT_ROOT
# Find deactivate script, run it, and then delete it. This way if the
# deactivate script is doing something wrong subsequent bootstraps still
# have a chance to pass.
set _PW_DEACTIVATE_SH $_PW_ACTUAL_ENVIRONMENT_ROOT/deactivate.fish
if test -f $_PW_DEACTIVATE_SH
. $_PW_DEACTIVATE_SH
rm -f $_PW_DEACTIVATE_SH &>/dev/null
end
# If there's a _pw_deactivate function run it. Redirect output to /dev/null
# in case _pw_deactivate doesn't exist. Remove _pw_deactivate when complete.
if functions --query _pw_deactivate
_pw_deactivate >/dev/null 2>/dev/null
functions -e _pw_deactivate
end
# Restore.
set --export PW_ROOT $_NEW_PW_ROOT
set --export PW_PROJECT_ROOT $_NEW_PW_PROJECT_ROOT
end
function deactivate
pw_deactivate
functions -e pw_deactivate
functions -e deactivate
set -e PW_ROOT
set -e PW_PROJECT_ROOT
set -e PW_BRANDING_BANNER
set -e PW_BRANDING_BANNER_COLOR
end
# The next three functions use the following variables.
# * PW_BANNER_FUNC: function to print banner
# * PW_BOOTSTRAP_PYTHON: specific Python interpreter to use for bootstrap
# * PW_ROOT: path to Pigweed root
# * PW_ENVSETUP_QUIET: limit output if "true"
#
# All arguments passed in are passed on to env_setup.py in pw_bootstrap,
# pw_activate takes no arguments, and pw_finalize takes the name of the script
# "bootstrap" or "activate" and the path to the setup script written by
# bootstrap.fish.
function pw_bootstrap
_pw_hello " BOOTSTRAP! Bootstrap may take a few minutes; please be patient.\n"
if functions --query python
pw_error "Error: 'python' is an alias"
pw_error_info "The shell has a 'python' alias set. This causes many obscure"
pw_error_info "Python-related issues both in and out of Pigweed. Please"
pw_error_info "remove the Python alias from your shell init file or at"
pw_error_info "least run the following command before bootstrapping"
pw_error_info "Pigweed."
pw_error_info
pw_error_info " functions --erase python"
pw_error_info
return
end
# Allow forcing a specific version of Python for testing pursposes.
if test -n "$PW_BOOTSTRAP_PYTHON"
set _PW_PYTHON "$PW_BOOTSTRAP_PYTHON"
else if command -v python3 >/dev/null 2>/dev/null
set _PW_PYTHON python3
else if command -v python2 >/dev/null 2>/dev/null
set _PW_PYTHON python2
else if command -v python >/dev/null 2>/dev/null
set _PW_PYTHON python
else
pw_error "Error: No system Python present\n"
pw_error_info " Pigweed's bootstrap process requires a local system"
pw_error_info " Python. Please install Python on your system, add it to "
pw_error_info " your PATH and re-try running bootstrap."
return
end
if test -n "$_PW_ENV_SETUP"
$_PW_ENV_SETUP $argv
set _PW_ENV_SETUP_STATUS $status
else
$_PW_PYTHON $PW_ROOT/pw_env_setup/py/pw_env_setup/env_setup.py $argv
set _PW_ENV_SETUP_STATUS $status
end
# Write the directory path at bootstrap time into the directory. This helps
# us double-check things are still in the same space when calling activate.
set _PW_ENV_ROOT_TXT $_PW_ACTUAL_ENVIRONMENT_ROOT/env_root.txt
echo $_PW_ACTUAL_ENVIRONMENT_ROOT >$_PW_ENV_ROOT_TXT 2>/dev/null
# Create the environment README file. Use quotes to prevent alias expansion.
cp $PW_ROOT/pw_env_setup/destination.md $_PW_ACTUAL_ENVIRONMENT_ROOT/README.md &>/dev/null
end
function pw_activate_message
_pw_hello " ACTIVATOR! This sets your shell environment variables.\n"
set _PW_ENV_SETUP_STATUS 0
end
function pw_finalize_pre_check --argument-names _PW_NAME _PW_SETUP_SH
# Check that the environment directory agrees that the path it's at matches
# where it thinks it should be. If not, bail.
set _PW_ENV_ROOT_TXT "$_PW_ACTUAL_ENVIRONMENT_ROOT/env_root.txt"
if test -f $_PW_ENV_ROOT_TXT
set _PW_PREV_ENV_ROOT (cat $_PW_ENV_ROOT_TXT)
if test "$_PW_ACTUAL_ENVIRONMENT_ROOT" != "$_PW_PREV_ENV_ROOT"
pw_error "Error: Environment directory moved"
pw_error_info "This Pigweed environment was created at"
pw_error_info
pw_error_info " $_PW_PREV_ENV_ROOT"
pw_error_info
pw_error_info "But it is now being activated from"
pw_error_info
pw_error_info " $_PW_ACTUAL_ENVIRONMENT_ROOT"
pw_error_info
pw_error_info "This is likely because the checkout moved. After moving "
pw_error_info "the checkout a full '. ./bootstrap.fish' is required."
pw_error_info
set _PW_ENV_SETUP_STATUS 1
end
end
if test -n "$_PW_ENV_SETUP_STATUS" && test "$_PW_ENV_SETUP_STATUS" -ne 0
return
end
if not test -f "$_PW_SETUP_SH"
pw_error "Error during $_PW_NAME--see messages above."
end
end
function pw_finalize_post_check --argument-names _PW_NAME _PW_SETUP_SH
if test "$status" -eq 0
if test "$_PW_NAME" = bootstrap && test -z "$PW_ENVSETUP_QUIET"
echo "To reactivate this environment in the future, run this in your "
echo "terminal:"
echo
pw_green " source ./activate.fish"
echo
echo "To deactivate this environment, run this:"
echo
pw_green " deactivate"
echo
end
else
pw_error "Error during $_PW_NAME--see messages above."
end
end
function pw_install_post_checkout_hook
cp $PW_ROOT/pw_env_setup/post-checkout-hook.sh $PW_PROJECT_ROOT/.git/hooks/post-checkout
end
function pw_cleanup
set -e _PW_BANNER
set -e _PW_BANNER_FUNC
set -e PW_BANNER_FUNC
set -e _PW_ENV_SETUP
set -e _PW_NAME
set -e PW_ENVIRONMENT_ROOT
set -e _PW_PYTHON
set -e _PW_ENV_ROOT_TXT
set -e _PW_PREV_ENV_ROOT
set -e _PW_SETUP_SH
set -e _PW_DEACTIVATE_SH
set -e _NEW_PW_ROOT
set -e _PW_ENV_SETUP_STATUS
set -e _PW_ENV_PREFIX
set -e _PW_ENV
set -e _PW_DOTENV
functions -e pw_none
functions -e pw_red
functions -e pw_bold_red
functions -e pw_yellow
functions -e pw_bold_yellow
functions -e pw_green
functions -e pw_bold_green
functions -e pw_blue
functions -e pw_cyan
functions -e pw_magenta
functions -e pw_bold_white
functions -e pw_eval_sourced
functions -e pw_check_root
functions -e pw_get_env_root
functions -e _pw_banner
functions -e pw_bootstrap
functions -e pw_activate
functions -e pw_finalize
functions -e pw_install_post_checkout_hook
functions -e pw_cleanup
functions -e _pw_hello
functions -e pw_error
functions -e pw_error_info
end

View File

@ -21,6 +21,8 @@ export PATH
# - bootstrap.sh
# - pw_cli/color.py
# - pw_env_setup/py/pw_env_setup/colors.py
# - pw_env_setup/util.fish
# - pw_env_setup/util.sh
#
# So please keep them matching then modifying them.
pw_none() {
@ -160,6 +162,7 @@ pw_get_env_root() {
# the contortions that would be needed to share this snippet across shell,
# batch, and Python. Locations:
#
# - pw_env_setup/util.fish
# - pw_env_setup/util.sh
# - pw_cli/branding.py
# - pw_env_setup/py/pw_env_setup/windows_env_start.py
@ -181,9 +184,13 @@ _PW_BANNER_FUNC="_pw_banner"
_pw_hello() {
_PW_TEXT="$1"
# If $PW_BANNER_FUNC is defined, use that as the banner function
# instead of the default.
if [ -n "$PW_BANNER_FUNC" ]; then
_PW_BANNER_FUNC="$PW_BANNER_FUNC"
fi
# Display the banner unless PW_ENVSETUP_QUIET or
# PW_ENVSETUP_NO_BANNER is set.
if [ -z "$PW_ENVSETUP_QUIET" ] && [ -z "$PW_ENVSETUP_NO_BANNER" ]; then
pw_green "\n WELCOME TO...\n"
"$_PW_BANNER_FUNC"