Skip to content

Commit 9916c81

Browse files
committed
Refactor: Replace _execute_error() with _execute_or_fail().
This refactor has two simple goals: * Simplify control flow: callers no longer need to `if-then-else` themselves, which becomes cumbersome when you have a sequence of calls to `repository_ctx.execute()`. * Improve the output on failure (by listing the failing command).
1 parent 3b9e6d9 commit 9916c81

File tree

1 file changed

+35
-31
lines changed

1 file changed

+35
-31
lines changed

nixpkgs/nixpkgs.bzl

+35-31
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,17 @@ def _nixpkgs_package_impl(repository_ctx):
9797
# as we can do.
9898
timeout = 1073741824
9999

100-
res = repository_ctx.execute(nix_build, quiet = False, timeout = timeout,
101-
environment=dict(NIX_PATH=nix_path))
102-
if res.return_code == 0:
103-
output_path = res.stdout.splitlines()[-1]
104-
else:
105-
_execute_error(res, "Cannot build Nix attribute `{}`"
106-
.format(repository_ctx.attr.attribute_path))
107-
100+
exec_result = _execute_or_fail(
101+
repository_ctx,
102+
nix_build,
103+
failure_message = "Cannot build Nix attribute '{}'.".format(
104+
repository_ctx.attr.attribute_path
105+
),
106+
quiet = False,
107+
timeout = timeout,
108+
environment=dict(NIX_PATH=nix_path),
109+
)
110+
output_path = exec_result.stdout.splitlines()[-1]
108111
# Build a forest of symlinks (like new_local_package() does) to the
109112
# Nix store.
110113
_symlink_children(repository_ctx, output_path)
@@ -142,6 +145,26 @@ def nixpkgs_package(*args, **kwargs):
142145
else:
143146
_nixpkgs_package(*args, **kwargs)
144147

148+
def _execute_or_fail(repository_ctx, arguments, failure_message = "", *args, **kwargs):
149+
"""Call repository_ctx.execute() and fail if non-zero return code."""
150+
result = repository_ctx.execute(arguments, *args, **kwargs)
151+
if result.return_code:
152+
outputs = dict(
153+
failure_message = failure_message,
154+
arguments = arguments,
155+
return_code = result.return_code,
156+
stderr = result.stderr,
157+
)
158+
fail("""
159+
{failure_message}
160+
Command: {arguments}
161+
Return code: {return_code}
162+
Error output:
163+
{stderr}
164+
""").format(**outputs)
165+
return result
166+
167+
145168
def _symlink_children(repository_ctx, target_dir):
146169
"""Create a symlink to all children of `target_dir` in the current
147170
build directory."""
@@ -154,13 +177,10 @@ def _symlink_children(repository_ctx, target_dir):
154177
# filenames can contain \n
155178
"-print0",
156179
]
157-
find_res = repository_ctx.execute(find_args)
158-
if find_res.return_code == 0:
159-
for target in find_res.stdout.rstrip("\0").split("\0"):
160-
basename = target.rpartition("/")[-1]
161-
repository_ctx.symlink(target, basename)
162-
else:
163-
_execute_error(find_res)
180+
exec_result = _execute_or_fail(repository_ctx, find_args)
181+
for target in exec_result.stdout.rstrip("\0").split("\0"):
182+
basename = target.rpartition("/")[-1]
183+
repository_ctx.symlink(target, basename)
164184

165185

166186
def _executable_path(repository_ctx, exe_name, extra_msg=""):
@@ -170,19 +190,3 @@ def _executable_path(repository_ctx, exe_name, extra_msg=""):
170190
fail("Could not find the `{}` executable in PATH.{}\n"
171191
.format(exe_name, " " + extra_msg if extra_msg else ""))
172192
return path
173-
174-
175-
def _execute_error(exec_result, msg):
176-
"""Print a nice error message for a failed `execute`."""
177-
fail("""
178-
execute() error: {msg}
179-
status code: {code}
180-
stdout:
181-
{stdout}
182-
stderr:
183-
{stderr}
184-
""".format(
185-
msg=msg,
186-
code=exec_result.return_code,
187-
stdout=exec_result.stdout,
188-
stderr=exec_result.stderr))

0 commit comments

Comments
 (0)