Skip to content

Commit ab59868

Browse files
committed
wip: checking ci with bootstrap=script by default
1 parent 04f5798 commit ab59868

File tree

8 files changed

+286
-4
lines changed

8 files changed

+286
-4
lines changed

.bazelci/presubmit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ buildifier:
2626
.reusable_config: &reusable_config
2727
build_targets:
2828
- "--"
29-
- "..."
29+
- "//tests/base_rules:all"
3030
# As a regression test for #225, check that wheel targets still build when
3131
# their package path is qualified with the repo name.
3232
- "@rules_python//examples/wheel/..."
@@ -35,7 +35,7 @@ buildifier:
3535
- "--build_tag_filters=-integration-test"
3636
test_targets:
3737
- "--"
38-
- "..."
38+
- "//tests/base_rules:all"
3939
test_flags:
4040
- "--test_tag_filters=-integration-test"
4141
.common_workspace_flags: &common_workspace_flags

python/private/stage1_bootstrap_template.sh

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ PYTHON_BINARY='%python_binary%'
1616
IS_ZIPFILE="%is_zipfile%"
1717

1818
if [[ "$IS_ZIPFILE" == "1" ]]; then
19-
zip_dir=$(mktemp -d --suffix Bazel.runfiles_)
19+
# NOTE: Macs have an old version of mktemp, so we must use only the
20+
# minimal functionality of it.
21+
zip_dir=$(mktemp -d)
2022

2123
if [[ -n "$zip_dir" && -z "${RULES_PYTHON_BOOTSTRAP_VERBOSE:-}" ]]; then
2224
trap 'rm -fr "$zip_dir"' EXIT
@@ -27,7 +29,7 @@ if [[ "$IS_ZIPFILE" == "1" ]]; then
2729
# The alternative requires having to copy ourselves elsewhere with the prelude
2830
# stripped (because zip can't extract from a stream). We avoid that because
2931
# it's wasteful.
30-
( unzip -q -d "$zip_dir" "$0" 2>/dev/null || /bin/true )
32+
( unzip -q -d "$zip_dir" "$0" 2>/dev/null || true )
3133

3234
RUNFILES_DIR="$zip_dir/runfiles"
3335
if [[ ! -d "$RUNFILES_DIR" ]]; then
@@ -105,6 +107,11 @@ declare -a interpreter_args
105107
# NOTE: Only works for 3.11+
106108
interpreter_env+=("PYTHONSAFEPATH=1")
107109

110+
if [[ "$IS_ZIPFILE" == "1" ]]; then
111+
interpreter_args+=("-XRULES_PYTHON_ZIP_DIR=$zip_dir")
112+
fi
113+
114+
108115
export RUNFILES_DIR
109116

110117
command=(

tests/base_rules/BUILD.bazel

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,19 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
load("//tests/support:sh_py_run_test.bzl", "sh_py_run_test")
16+
17+
sh_py_run_test(
18+
name = "run_binary_zip_off_test",
19+
build_python_zip = "no",
20+
py_src = "bin.py",
21+
sh_src = "run_binary_zip_off_test.sh",
22+
)
23+
24+
sh_py_run_test(
25+
name = "run_binary_zip_on_test",
26+
build_python_zip = "yes",
27+
py_src = "bin.py",
28+
sh_src = "run_binary_zip_on_test.sh",
29+
)

tests/base_rules/bin.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2024 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://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,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
import sys
16+
17+
print("Hello")
18+
print(
19+
"RULES_PYTHON_ZIP_DIR:{}".format(sys._xoptions.get("RULES_PYTHON_ZIP_DIR", "UNSET"))
20+
)
21+
print("file:", __file__)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2024 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://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,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# --- begin runfiles.bash initialization v3 ---
16+
# Copy-pasted from the Bazel Bash runfiles library v3.
17+
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
18+
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
19+
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
20+
source "$0.runfiles/$f" 2>/dev/null || \
21+
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
22+
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
23+
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
24+
# --- end runfiles.bash initialization v3 ---
25+
set +e
26+
27+
bin=$(rlocation $BIN_RLOCATION)
28+
if [[ -z "$bin" ]]; then
29+
echo "Unable to locate test binary: $BIN_RLOCATION"
30+
exit 1
31+
fi
32+
actual=$($bin 2>&1)
33+
34+
# How we detect if a zip file was executed from depends on which bootstrap
35+
# is used.
36+
# bootstrap_impl=script outputs RULES_PYTHON_ZIP_DIR=<somepath>
37+
# bootstrap_impl=system_python outputs file:.*Bazel.runfiles
38+
expected_pattern="Hello"
39+
if ! (echo "$actual" | grep "$expected_pattern" ) >/dev/null; then
40+
echo "expected output to match: $expected_pattern"
41+
echo "but got:\n$actual"
42+
exit 1
43+
fi
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2024 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://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,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# --- begin runfiles.bash initialization v3 ---
16+
# Copy-pasted from the Bazel Bash runfiles library v3.
17+
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
18+
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
19+
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
20+
source "$0.runfiles/$f" 2>/dev/null || \
21+
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
22+
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
23+
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
24+
# --- end runfiles.bash initialization v3 ---
25+
set +e
26+
27+
bin=$(rlocation $BIN_RLOCATION)
28+
if [[ -z "$bin" ]]; then
29+
echo "Unable to locate test binary: $BIN_RLOCATION"
30+
exit 1
31+
fi
32+
actual=$($bin)
33+
34+
# How we detect if a zip file was executed from depends on which bootstrap
35+
# is used.
36+
# bootstrap_impl=script outputs RULES_PYTHON_ZIP_DIR:<somepath>
37+
# bootstrap_impl=system_python outputs file:.*Bazel.runfiles
38+
expected_pattern="RULES_PYTHON_ZIP_DIR:/\|file:.*Bazel.runfiles"
39+
if ! (echo "$actual" | grep "$expected_pattern" ) >/dev/null; then
40+
echo "expected output to match: $expected_pattern"
41+
echo "but got: $actual"
42+
exit 1
43+
fi
44+

tests/base_rules/run_zip_test.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright 2023 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://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,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# --- begin runfiles.bash initialization v3 ---
16+
# Copy-pasted from the Bazel Bash runfiles library v3.
17+
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
18+
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
19+
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
20+
source "$0.runfiles/$f" 2>/dev/null || \
21+
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
22+
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
23+
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
24+
# --- end runfiles.bash initialization v3 ---
25+
set +e
26+
27+
bin=$(rlocation _main/tests/base_rules/_run_zip_test_bin)
28+
if [[ -z "$bin" ]]; then
29+
echo "Unable to locate test binary"
30+
exit 1
31+
fi
32+
actual=$($bin)
33+
34+
if [[ ! "$actual" == RULES_PYTHON_ZIP_DIR=/* ]]; then
35+
echo "expected output: RULES_PYTHON_ZIP_DIR=<some path>"
36+
echo "but got: $actual"
37+
exit 1
38+
fi

tests/support/sh_py_run_test.bzl

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2024 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://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,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Run a py_binary with altered config settings in an sh_test.
15+
16+
This facilitates verify running binaries with different configuration settings
17+
without the overhead of a bazel-in-bazel integration test.
18+
"""
19+
20+
load("//python:py_binary.bzl", "py_binary")
21+
22+
def _perform_transition_impl(_input_settings, attr):
23+
settings = {
24+
"//command_line_option:build_python_zip": attr.build_python_zip,
25+
}
26+
return settings
27+
28+
_perform_transition = transition(
29+
implementation = _perform_transition_impl,
30+
inputs = [],
31+
outputs = [
32+
"//command_line_option:build_python_zip",
33+
],
34+
)
35+
36+
def _transition_impl(ctx):
37+
default_info = ctx.attr.target[DefaultInfo]
38+
exe_ext = default_info.files_to_run.executable.extension
39+
if exe_ext:
40+
exe_ext = "." + exe_ext
41+
exe_name = ctx.label.name + exe_ext
42+
43+
executable = ctx.actions.declare_file(exe_name)
44+
ctx.actions.symlink(output = executable, target_file = default_info.files_to_run.executable)
45+
46+
default_outputs = [executable]
47+
48+
# todo: could probably check target.owner vs src.owner to check if it should
49+
# be symlinked or included as-is
50+
# For simplicity of implementation, we're assuming the target being run is
51+
# py_binary-like. In order for Windows to work, we need to make sure the
52+
# file that the .exe launcher runs (the .zip or underlying non-exe
53+
# executable) is a sibling of the .exe file with the same base name.
54+
for src in default_info.files.to_list():
55+
if src.extension in ("", "zip"):
56+
ext = ("." if src.extension else "") + src.extension
57+
output = ctx.actions.declare_file(ctx.label.name + ext)
58+
ctx.actions.symlink(output = output, target_file = src)
59+
default_outputs.append(output)
60+
61+
return [
62+
DefaultInfo(
63+
executable = executable,
64+
files = depset(default_outputs),
65+
runfiles = default_info.default_runfiles,
66+
),
67+
testing.TestEnvironment(
68+
environment = ctx.attr.env,
69+
),
70+
]
71+
72+
transition_binary = rule(
73+
implementation = _transition_impl,
74+
attrs = {
75+
"bootstrap_impl": attr.string(),
76+
"build_python_zip": attr.string(default = "auto"),
77+
"env": attr.string_dict(),
78+
"target": attr.label(executable = True, cfg = "target"),
79+
"_allowlist_function_transition": attr.label(
80+
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
81+
),
82+
},
83+
cfg = _perform_transition,
84+
executable = True,
85+
)
86+
87+
def sh_py_run_test(*, name, sh_src, py_src, **kwargs):
88+
bin_name = "_{}_bin".format(name)
89+
native.sh_test(
90+
name = name,
91+
srcs = [sh_src],
92+
data = [bin_name],
93+
deps = [
94+
"@bazel_tools//tools/bash/runfiles",
95+
],
96+
env = {
97+
"BIN_RLOCATION": "$(rlocationpath {})".format(bin_name),
98+
},
99+
)
100+
101+
transition_binary(
102+
name = bin_name,
103+
tags = ["manual"],
104+
target = "_{}_plain_bin".format(name),
105+
**kwargs
106+
)
107+
108+
py_binary(
109+
name = "_{}_plain_bin".format(name),
110+
srcs = [py_src],
111+
main = py_src,
112+
tags = ["manual"],
113+
)

0 commit comments

Comments
 (0)