mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-09-09 04:29:36 +00:00
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:
parent
d91003238d
commit
d988f7027f
1
activate.fish
Symbolic link
1
activate.fish
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
bootstrap.fish
|
90
bootstrap.fish
Normal file
90
bootstrap.fish
Normal 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
|
|
@ -45,6 +45,11 @@ To get setup:
|
||||||
$ bootstrap.bat (On Windows)
|
$ bootstrap.bat (On Windows)
|
||||||
...
|
...
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
If you use the `Fish shell <https://fishshell.com/>`_ run `source
|
||||||
|
./bootstrap.fish` instead.
|
||||||
|
|
||||||
#. Configure the GN build.
|
#. Configure the GN build.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
|
@ -40,8 +40,13 @@ runs bootstrap.
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
On Windows the scripts used to set up the environment are ``bootstrap.bat``
|
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
|
and ``activate.bat``.
|
||||||
``.sh`` endings unless the distinction is relevant.
|
|
||||||
|
``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``.
|
On POSIX systems, the environment can be deactivated by running ``deactivate``.
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ def _evaluate_env_in_shell(env):
|
||||||
delete=False,
|
delete=False,
|
||||||
mode='w+',
|
mode='w+',
|
||||||
) as temp:
|
) as temp:
|
||||||
env.write(temp)
|
|
||||||
temp_name = temp.name
|
temp_name = temp.name
|
||||||
|
env.write(temp, shell_file=temp_name)
|
||||||
|
|
||||||
# Evaluate env sourcing script and capture output of 'env'.
|
# Evaluate env sourcing script and capture output of 'env'.
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
@ -164,7 +164,7 @@ class EnvironmentTest(unittest.TestCase):
|
||||||
self.env.set(self.var_not_set, '/foo/bar/baz')
|
self.env.set(self.var_not_set, '/foo/bar/baz')
|
||||||
self.env.add_replacement('FOOBAR', '/foo/bar')
|
self.env.add_replacement('FOOBAR', '/foo/bar')
|
||||||
buf = six.StringIO()
|
buf = six.StringIO()
|
||||||
self.env.write(buf)
|
self.env.write(buf, shell_file='test.sh')
|
||||||
assert '/foo/bar' not in buf.getvalue()
|
assert '/foo/bar' not in buf.getvalue()
|
||||||
|
|
||||||
def test_variable_replacement(self):
|
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.set(self.var_not_set, '/foo/bar/baz')
|
||||||
self.env.add_replacement('FOOBAR')
|
self.env.add_replacement('FOOBAR')
|
||||||
buf = six.StringIO()
|
buf = six.StringIO()
|
||||||
self.env.write(buf)
|
self.env.write(buf, shell_file='test.sh')
|
||||||
print(buf.getvalue())
|
print(buf.getvalue())
|
||||||
assert '/foo/bar/baz' not in buf.getvalue()
|
assert '/foo/bar/baz' not in buf.getvalue()
|
||||||
|
|
||||||
|
|
|
@ -200,6 +200,7 @@ class EnvSetup(object):
|
||||||
)
|
)
|
||||||
self._cipd_cache_dir = cipd_cache_dir
|
self._cipd_cache_dir = cipd_cache_dir
|
||||||
self._shell_file = shell_file
|
self._shell_file = shell_file
|
||||||
|
self._env._shell_file = shell_file
|
||||||
self._is_windows = os.name == 'nt'
|
self._is_windows = os.name == 'nt'
|
||||||
self._quiet = quiet
|
self._quiet = quiet
|
||||||
self._install_dir = install_dir
|
self._install_dir = install_dir
|
||||||
|
@ -628,14 +629,14 @@ Then use `set +x` to go back to normal.
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(self._shell_file, 'w') as outs:
|
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(
|
deactivate = os.path.join(
|
||||||
self._install_dir,
|
self._install_dir,
|
||||||
'deactivate{}'.format(os.path.splitext(self._shell_file)[1]),
|
'deactivate{}'.format(os.path.splitext(self._shell_file)[1]),
|
||||||
)
|
)
|
||||||
with open(deactivate, 'w') as outs:
|
with open(deactivate, 'w') as outs:
|
||||||
self._env.write_deactivate(outs)
|
self._env.write_deactivate(outs, shell_file=deactivate)
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
# Skipping sysname and nodename in os.uname(). nodename could change
|
# Skipping sysname and nodename in os.uname(). nodename could change
|
||||||
|
|
|
@ -333,6 +333,7 @@ class Environment(object):
|
||||||
self.replacements = []
|
self.replacements = []
|
||||||
self._join = Join(pathsep)
|
self._join = Join(pathsep)
|
||||||
self._finalized = False
|
self._finalized = False
|
||||||
|
self._shell_file = ''
|
||||||
|
|
||||||
def add_replacement(self, variable, value=None):
|
def add_replacement(self, variable, value=None):
|
||||||
self.replacements.append((variable, value))
|
self.replacements.append((variable, value))
|
||||||
|
@ -440,7 +441,7 @@ class Environment(object):
|
||||||
|
|
||||||
if not self._windows:
|
if not self._windows:
|
||||||
buf = StringIO()
|
buf = StringIO()
|
||||||
self.write_deactivate(buf)
|
self.write_deactivate(buf, shell_file=self._shell_file)
|
||||||
self._actions.append(Function('_pw_deactivate', buf.getvalue()))
|
self._actions.append(Function('_pw_deactivate', buf.getvalue()))
|
||||||
self._blankline()
|
self._blankline()
|
||||||
|
|
||||||
|
@ -457,17 +458,27 @@ class Environment(object):
|
||||||
def json(self, outs):
|
def json(self, outs):
|
||||||
json_visitor.JSONVisitor().serialize(self, outs)
|
json_visitor.JSONVisitor().serialize(self, outs)
|
||||||
|
|
||||||
def write(self, outs):
|
def write(self, outs, shell_file):
|
||||||
if self._windows:
|
if self._windows:
|
||||||
visitor = batch_visitor.BatchVisitor(pathsep=self._pathsep)
|
visitor = batch_visitor.BatchVisitor(pathsep=self._pathsep)
|
||||||
|
else:
|
||||||
|
if shell_file.endswith('.fish'):
|
||||||
|
visitor = shell_visitor.FishShellVisitor()
|
||||||
else:
|
else:
|
||||||
visitor = shell_visitor.ShellVisitor(pathsep=self._pathsep)
|
visitor = shell_visitor.ShellVisitor(pathsep=self._pathsep)
|
||||||
visitor.serialize(self, outs)
|
visitor.serialize(self, outs)
|
||||||
|
|
||||||
def write_deactivate(self, outs):
|
def write_deactivate(self, outs, shell_file):
|
||||||
if self._windows:
|
if self._windows:
|
||||||
return
|
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)
|
visitor.serialize(self, outs)
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
|
@ -54,7 +54,7 @@ class _BaseShellVisitor(object): # pylint: disable=useless-object-inheritance
|
||||||
|
|
||||||
|
|
||||||
class ShellVisitor(_BaseShellVisitor):
|
class ShellVisitor(_BaseShellVisitor):
|
||||||
"""Serializes an Environment into a shell file."""
|
"""Serializes an Environment into a bash-like shell file."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ShellVisitor, self).__init__(*args, **kwargs)
|
super(ShellVisitor, self).__init__(*args, **kwargs)
|
||||||
|
@ -174,7 +174,7 @@ class ShellVisitor(_BaseShellVisitor):
|
||||||
|
|
||||||
|
|
||||||
class DeactivateShellVisitor(_BaseShellVisitor):
|
class DeactivateShellVisitor(_BaseShellVisitor):
|
||||||
"""Removes values from an Environment."""
|
"""Removes values from a bash-like shell environment."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
pathsep = kwargs.pop('pathsep', ':')
|
pathsep = kwargs.pop('pathsep', ':')
|
||||||
|
@ -227,3 +227,132 @@ class DeactivateShellVisitor(_BaseShellVisitor):
|
||||||
|
|
||||||
def visit_function(self, function):
|
def visit_function(self, function):
|
||||||
pass # Not relevant.
|
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
410
pw_env_setup/util.fish
Normal 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
|
|
@ -21,6 +21,8 @@ export PATH
|
||||||
# - bootstrap.sh
|
# - bootstrap.sh
|
||||||
# - pw_cli/color.py
|
# - pw_cli/color.py
|
||||||
# - pw_env_setup/py/pw_env_setup/colors.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.
|
# So please keep them matching then modifying them.
|
||||||
pw_none() {
|
pw_none() {
|
||||||
|
@ -160,6 +162,7 @@ pw_get_env_root() {
|
||||||
# the contortions that would be needed to share this snippet across shell,
|
# the contortions that would be needed to share this snippet across shell,
|
||||||
# batch, and Python. Locations:
|
# batch, and Python. Locations:
|
||||||
#
|
#
|
||||||
|
# - pw_env_setup/util.fish
|
||||||
# - pw_env_setup/util.sh
|
# - pw_env_setup/util.sh
|
||||||
# - pw_cli/branding.py
|
# - pw_cli/branding.py
|
||||||
# - pw_env_setup/py/pw_env_setup/windows_env_start.py
|
# - pw_env_setup/py/pw_env_setup/windows_env_start.py
|
||||||
|
@ -181,9 +184,13 @@ _PW_BANNER_FUNC="_pw_banner"
|
||||||
|
|
||||||
_pw_hello() {
|
_pw_hello() {
|
||||||
_PW_TEXT="$1"
|
_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
|
if [ -n "$PW_BANNER_FUNC" ]; then
|
||||||
_PW_BANNER_FUNC="$PW_BANNER_FUNC"
|
_PW_BANNER_FUNC="$PW_BANNER_FUNC"
|
||||||
fi
|
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
|
if [ -z "$PW_ENVSETUP_QUIET" ] && [ -z "$PW_ENVSETUP_NO_BANNER" ]; then
|
||||||
pw_green "\n WELCOME TO...\n"
|
pw_green "\n WELCOME TO...\n"
|
||||||
"$_PW_BANNER_FUNC"
|
"$_PW_BANNER_FUNC"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user