Skip to content

Commit 99695ee

Browse files
feat: Improve exec error handling (bazel-contrib#1368)
At times binaries are not in the path. This commit tests that the binary exists before we try to execute the binary. This allows us to provide a more informative error message to the user. Closes: bazel-contrib#662 --------- Co-authored-by: Richard Levasseur <richardlev@gmail.com>
1 parent e549810 commit 99695ee

File tree

5 files changed

+53
-10
lines changed

5 files changed

+53
-10
lines changed

python/pip_install/pip_repository.bzl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED")
2424
load("//python/private:normalize_name.bzl", "normalize_name")
2525
load("//python/private:render_pkg_aliases.bzl", "render_pkg_aliases")
2626
load("//python/private:toolchains_repo.bzl", "get_host_os_arch")
27+
load("//python/private:which.bzl", "which_with_fail")
2728

2829
CPPFLAGS = "CPPFLAGS"
2930

@@ -108,10 +109,7 @@ def _get_xcode_location_cflags(rctx):
108109
if not rctx.os.name.lower().startswith("mac os"):
109110
return []
110111

111-
# Locate xcode-select
112-
xcode_select = rctx.which("xcode-select")
113-
114-
xcode_sdk_location = rctx.execute([xcode_select, "--print-path"])
112+
xcode_sdk_location = rctx.execute([which_with_fail("xcode-select", rctx), "--print-path"])
115113
if xcode_sdk_location.return_code != 0:
116114
return []
117115

python/private/BUILD.bazel

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ bzl_library(
5757
deps = ["@bazel_skylib//lib:types"],
5858
)
5959

60+
bzl_library(
61+
name = "which_bzl",
62+
srcs = ["which.bzl"],
63+
visibility = [
64+
"//docs:__subpackages__",
65+
"//python:__subpackages__",
66+
],
67+
)
68+
6069
bzl_library(
6170
name = "py_cc_toolchain_bzl",
6271
srcs = [

python/private/toolchains_repo.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ load(
3030
"PLATFORMS",
3131
"WINDOWS_NAME",
3232
)
33+
load(":which.bzl", "which_with_fail")
3334

3435
def get_repository_name(repository_workspace):
3536
dummy_label = "//:_"
@@ -325,7 +326,7 @@ def get_host_os_arch(rctx):
325326
os_name = WINDOWS_NAME
326327
else:
327328
# This is not ideal, but bazel doesn't directly expose arch.
328-
arch = rctx.execute(["uname", "-m"]).stdout.strip()
329+
arch = rctx.execute([which_with_fail("uname", rctx), "-m"]).stdout.strip()
329330

330331
# Normalize the os_name.
331332
if "mac" in os_name.lower():

python/private/which.bzl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
"""Wrapper for repository which call"""
16+
17+
_binary_not_found_msg = "Unable to find the binary '{binary_name}'. Please update your PATH to include '{binary_name}'."
18+
19+
def which_with_fail(binary_name, rctx):
20+
"""Tests to see if a binary exists, and otherwise fails with a message.
21+
22+
Args:
23+
binary_name: name of the binary to find.
24+
rctx: repository context.
25+
26+
Returns:
27+
rctx.Path for the binary.
28+
"""
29+
binary = rctx.which(binary_name)
30+
if binary == None:
31+
fail(_binary_not_found_msg.format(binary_name = binary_name))
32+
return binary

python/repositories.bzl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ load(
2727
"toolchain_aliases",
2828
"toolchains_repo",
2929
)
30+
load("//python/private:which.bzl", "which_with_fail")
3031
load(
3132
":versions.bzl",
3233
"DEFAULT_RELEASE_BASE_URL",
@@ -123,8 +124,9 @@ def _python_repository_impl(rctx):
123124
sha256 = rctx.attr.zstd_sha256,
124125
)
125126
working_directory = "zstd-{version}".format(version = rctx.attr.zstd_version)
127+
126128
make_result = rctx.execute(
127-
["make", "--jobs=4"],
129+
[which_with_fail("make", rctx), "--jobs=4"],
128130
timeout = 600,
129131
quiet = True,
130132
working_directory = working_directory,
@@ -140,7 +142,7 @@ def _python_repository_impl(rctx):
140142
rctx.symlink(zstd, unzstd)
141143

142144
exec_result = rctx.execute([
143-
"tar",
145+
which_with_fail("tar", rctx),
144146
"--extract",
145147
"--strip-components=2",
146148
"--use-compress-program={unzstd}".format(unzstd = unzstd),
@@ -179,15 +181,16 @@ def _python_repository_impl(rctx):
179181
if not rctx.attr.ignore_root_user_error:
180182
if "windows" not in rctx.os.name:
181183
lib_dir = "lib" if "windows" not in platform else "Lib"
182-
exec_result = rctx.execute(["chmod", "-R", "ugo-w", lib_dir])
184+
185+
exec_result = rctx.execute([which_with_fail("chmod", rctx), "-R", "ugo-w", lib_dir])
183186
if exec_result.return_code != 0:
184187
fail_msg = "Failed to make interpreter installation read-only. 'chmod' error msg: {}".format(
185188
exec_result.stderr,
186189
)
187190
fail(fail_msg)
188-
exec_result = rctx.execute(["touch", "{}/.test".format(lib_dir)])
191+
exec_result = rctx.execute([which_with_fail("touch", rctx), "{}/.test".format(lib_dir)])
189192
if exec_result.return_code == 0:
190-
exec_result = rctx.execute(["id", "-u"])
193+
exec_result = rctx.execute([which_with_fail("id", rctx), "-u"])
191194
if exec_result.return_code != 0:
192195
fail("Could not determine current user ID. 'id -u' error msg: {}".format(
193196
exec_result.stderr,

0 commit comments

Comments
 (0)