Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions news/4386.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(rules) Fixed stage 1 bootstrap script failing when the executable path,
runfiles root, or `RULES_PYTHON_EXTRACT_ROOT` contains spaces
([#4386](https://github.com/bazel-contrib/rules_python/pull/4386)).
22 changes: 11 additions & 11 deletions python/private/stage1_bootstrap_template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ else
if [[ ! -L "$stub_filename" ]]; then
break
fi
stub_filename=$(readlink $stub_filename)
stub_filename=$(readlink "$stub_filename")
done
echo >&2 "Unable to find runfiles directory for $1"
exit 1
}
RUNFILES_DIR=$(find_runfiles_root $0)
RUNFILES_DIR=$(find_runfiles_root "$0")
fi

if [[ -n "$RULES_PYTHON_TESTING_TELL_RUNFILES_ROOT" ]]; then
Expand All @@ -150,7 +150,7 @@ function find_python_interpreter() {
fi
}

python_exe=$(find_python_interpreter $RUNFILES_DIR $PYTHON_BINARY)
python_exe=$(find_python_interpreter "$RUNFILES_DIR" "$PYTHON_BINARY")

# Zip files have to re-create the venv bin/python3 symlink because they
# don't contain it already.
Expand All @@ -159,7 +159,7 @@ if [[ "$IS_ZIPFILE" == "1" ]]; then
use_exec=1
# It should always be under runfiles, but double check this. We don't
# want to accidentally create symlinks elsewhere.
if [[ "$python_exe" != $RUNFILES_DIR/* ]]; then
if [[ "$python_exe" != "$RUNFILES_DIR"/* ]]; then
echo >&2 "ERROR: Program's venv binary not under runfiles: $python_exe"
exit 1
fi
Expand All @@ -179,15 +179,15 @@ if [[ "$IS_ZIPFILE" == "1" ]]; then
fi
fi
# The bin/ directory may not exist if it is empty.
mkdir -p "$(dirname $python_exe)"
mkdir -p "$(dirname "$python_exe")"
_symlink "$symlink_to" "$python_exe"
elif [[ "$RECREATE_VENV_AT_RUNTIME" == "1" ]]; then
if [[ -n "$RULES_PYTHON_EXTRACT_ROOT" ]]; then
use_exec=1
# Use our runfiles path as a unique, reusable, location for the
# binary-specific venv being created.
venv="$RULES_PYTHON_EXTRACT_ROOT/$(dirname $(dirname $PYTHON_BINARY))"
mkdir -p $RULES_PYTHON_EXTRACT_ROOT
venv="$RULES_PYTHON_EXTRACT_ROOT/$(dirname "$(dirname "$PYTHON_BINARY")")"
mkdir -p "$RULES_PYTHON_EXTRACT_ROOT"
else
# Re-exec'ing can't be used because we have to clean up the temporary
# venv directory that is created.
Expand All @@ -199,7 +199,7 @@ elif [[ "$RECREATE_VENV_AT_RUNTIME" == "1" ]]; then
fi

# Match the basename; some tools, e.g. pyvenv key off the executable name
python_exe="$venv/bin/$(basename $PYTHON_BINARY_ACTUAL)"
python_exe="$venv/bin/$(basename "$PYTHON_BINARY_ACTUAL")"

if [[ ! -e "$python_exe" ]]; then
if [[ "$PYTHON_BINARY_ACTUAL" == /* ]]; then
Expand All @@ -218,7 +218,7 @@ elif [[ "$RECREATE_VENV_AT_RUNTIME" == "1" ]]; then
fi
fi

runfiles_venv="$RUNFILES_DIR/$(dirname $(dirname $PYTHON_BINARY))"
runfiles_venv="$RUNFILES_DIR/$(dirname "$(dirname "$PYTHON_BINARY")")"
# When RESOLVE_PYTHON_BINARY_AT_RUNTIME is true, it means the toolchain
# has thrown two complications at us:
# 1. The build-time assumption of the Python version may not match the
Expand Down Expand Up @@ -256,7 +256,7 @@ EOF
_symlink "$python_exe_actual" "$python_exe"

if [[ ! -e "$venv_site_packages" ]]; then
mkdir -p $(dirname $venv_site_packages)
mkdir -p "$(dirname "$venv_site_packages")"
_symlink "$runfiles_venv_site_packages" "$venv_site_packages"
fi
fi
Expand All @@ -273,7 +273,7 @@ fi
if [[ ! -x "$python_exe" ]]; then
if [[ ! -e "$python_exe" ]]; then
echo >&2 "ERROR: Python interpreter not found: $python_exe"
ls -l $python_exe >&2
ls -l "$python_exe" >&2
exit 1
elif [[ ! -x "$python_exe" ]]; then
echo >&2 "ERROR: Python interpreter not executable: $python_exe"
Expand Down
21 changes: 16 additions & 5 deletions tests/bootstrap_impls/run_binary_find_runfiles_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@ if [[ -z "$bin" ]]; then
exit 1
fi

bin_link_layer_1=$TEST_TMPDIR/link1
bin_link_layer_1="$TEST_TMPDIR/link with spaces 1"
ln -s "$bin" "$bin_link_layer_1"
bin_link_layer_2=$TEST_TMPDIR/link2
bin_link_layer_2="$TEST_TMPDIR/link with spaces 2"
ln -s "$bin_link_layer_1" "$bin_link_layer_2"

result=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' $bin)
result_link_layer_1=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' $bin_link_layer_1)
result_link_layer_2=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' $bin_link_layer_2)
space_dir="$TEST_TMPDIR/dir with spaces"
mkdir -p "$space_dir"
runfiles_with_spaces="$space_dir/test.runfiles"
ln -s "${bin%.runfiles*}.runfiles" "$runfiles_with_spaces"

result=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' "$bin")
result_link_layer_1=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' "$bin_link_layer_1")
result_link_layer_2=$(RUNFILES_DIR='' RUNFILES_MANIFEST_FILE='' "$bin_link_layer_2")
result_space_runfiles=$(RUNFILES_DIR="$runfiles_with_spaces" RUNFILES_MANIFEST_FILE='' "$bin_link_layer_2")

if [[ "$result" != "$result_link_layer_1" ]]; then
echo "Output from test does not match output when invoked via a link;"
Expand All @@ -55,5 +61,10 @@ if [[ "$result" != "$result_link_layer_2" ]]; then
echo "$result_link_layer_2"
exit 1
fi
if ! grep -q "^Hello$" <<<"$result_space_runfiles"; then
echo "Expected output when invoked with RUNFILES_DIR containing spaces, got:"
echo "$result_space_runfiles"
exit 1
fi

exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function expect_match() {
expect_match "sys.executable:.*tmp.*python3" "$actual"

# Now test that using a custom location for the bootstrap files works
venvs_root=$(mktemp -d)
actual=$(RULES_PYTHON_EXTRACT_ROOT=$venvs_root $bin)
venvs_root=$(mktemp -d "$TEST_TMPDIR/venvs root.XXXXXX")
actual=$(RULES_PYTHON_EXTRACT_ROOT="$venvs_root" "$bin")
expect_match "sys.executable:.*$venvs_root" "$actual"

# Exit if any of the expects failed
Expand Down
Loading