-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a way to redirect stdout/stderr into a file #5511
Comments
Assigning to @dslomov for triage. |
/sub I wish this feature existed. It's important for bazelbuild/bazel-skylib#149 |
I agree this would be useful. The current workaround is to use the shell. This is unfortunate because we need two implementations (bash / windows). So, something similar to https://github.com/bazelbuild/bazel-skylib/blob/master/rules/private/copy_file_private.bzl You also need to be careful about quoting. We have https://github.com/bazelbuild/bazel-skylib/blob/master/lib/shell.bzl for the Linux shell, but nothing for cmd yet. |
Quoting arguments is difficult with cmd. I typically put paths into envvars instead. |
Has any progress been made on this? Or, can anyone share a general wrapper that could be used to achieve the same goal? |
I agree that extending ctx.run to allow redirecting the standard output to a file is a reasonable feature. I don't think it's necessary for stderr because its contents are unstructured, and by redirecting it, build failure messages would become hidden. |
Redirecting stderr is useful in the case where you are building tests for error messages. For example
|
If you're creating a genrule, you're using a shell, so redirection is trivial. |
I'm jumping the gun a bit. What I would like to see out of genrule is the capability to raw run a command without having bash. Something more like an execv. |
I agree, we should remove all dependencies on Bash from the core, which would mean replacing all uses of genrule with either: |
It appears the output of bazel commands is already output to a file, no? In See: https://stackoverflow.com/questions/46529412/save-terminal-bazel-build-output/46530169#46530169 This file is also accessible via something like this, assuming you're in your git repo's root dir: But yes, I agree, an easy way to output this file where we want it on a given run would be very much desired. |
Alternative approaches:
|
This will make it easier to use a toolchain configuration for CUE in the future. The `dump` CUE command had to be replaced with a `dumpFile` one due to bazelbuild/bazel#5511. Bug: 168620448 Bug: 171800001 Change-Id: I54dffdc414ba86592fe088570723e9bb3d455960
This will make it easier to use a toolchain configuration for CUE in the future. The `dump` CUE command had to be replaced with a `dumpFile` one due to bazelbuild/bazel#5511. Bug: 168620448 Bug: 171800001 Change-Id: I54dffdc414ba86592fe088570723e9bb3d455960
This removes the python dependency in favor of a heavier reliance the shell. While not ideal right now, a resolution of bazelbuild/bazel#5511 would allow us to do the file grepping in starlark We could use entirely native rules this way, only calling out to the `jar` binary directly, which should be included with any jdk, and therefore result in a rule that is much leaner on dependencies while also more portable. Note: This hasn't been tested yet. I've thought a few times I did using the JS example, but each time it has turned out bazel ended up using different rules. This is a start, and an approach, but not a ready patch. This also still crucially lacks an implementation for .js.map files, which is technically trivial, but I'd like to ideally do it without invoking more shells.
This removes the python dependency in favor of a heavier reliance the shell. While not ideal right now, a resolution of bazelbuild/bazel#5511 would allow us to do the file grepping in starlark We could use entirely native rules this way, only calling out to the `jar` binary directly, which should be included with any jdk, and therefore result in a rule that is much leaner on dependencies while also more portable. Note: This hasn't been tested yet. I've thought a few times I did using the JS example, but each time it has turned out bazel ended up using different rules. This is a start, and an approach, but not a ready patch. This also still crucially lacks an implementation for .js.map files, which is technically trivial, but I'd like to ideally do it without invoking more shells.
This removes the python dependency in favor of a heavier reliance the shell. While not ideal right now, a resolution of bazelbuild/bazel#5511 would allow us to do the file grepping in starlark We could use entirely native rules this way, only calling out to the `jar` binary directly, which should be included with any jdk, and therefore result in a rule that is much leaner on dependencies while also more portable. Note: This hasn't been tested yet. I've thought a few times I did using the JS example, but each time it has turned out bazel ended up using different rules. This is a start, and an approach, but not a ready patch. This also still crucially lacks an implementation for .js.map files, which is technically trivial, but I'd like to ideally do it without invoking more shells.
This will make it easier to use a toolchain configuration for CUE in the future. The `dump` CUE command had to be replaced with a `dumpFile` one due to bazelbuild/bazel#5511. Bug: 168620448 Bug: 171800001 Change-Id: I54dffdc414ba86592fe088570723e9bb3d455960
I am curious why a simple non-breaking, improve everyone's life feature, can be that hard to get addressed in every project. The ctx.actions side deside not to support stdout/err redirection. The bazel command insists on capture all action stdout and garbage fill users terminal with If this feature is not implemented, once rules move to starlark, I'd like too see users terminal is always garbage filled, with |
Stumbled over the same issue. As alternative to (nonportable) shell code and (big & hairy) C++ compilers, there's also Python: from optparse import OptionParser
import os
import sys
import subprocess
if __name__ == '__main__':
parser = OptionParser()
parser.add_option('--output',
dest = 'output',
help = 'filename where to redirect stdout')
parser.add_option('--verbose',
action = 'store_true',
default = False,
dest = 'verbose',
help = 'provide diagnostic output')
(options, args) = parser.parse_args()
# run actual program
if options.verbose:
print(f'Running binary (argv={repr(args)}).')
process = subprocess.run(args,
capture_output = True,
universal_newlines = True)
if options.verbose:
print('Stdout:')
print(''.join(' ' + l for l in process.stdout.splitlines(keepends = True)))
print('Stderr:')
print(''.join(' ' + l for l in process.stderr.splitlines(keepends = True)))
print(f'Process finished with exit code {process.returncode}.')
# write results to the output file
with open(options.output, 'w') as f:
f.write(process.stdout)
sys.exit(process.returncode) Put this wrapper into a |
@UlrichEckhardt that is fine and effective Python, but I think in this case Python has a number of issues:
All this means that on short-running actions, your wrapper becomes the major cost. If one must use a wrapper, keeping it very fast to startup, with few runfiles, is key. A small shell script or preferably a statically linked native binary would be my choice. However, all this is moot. The point of this issue is that it would be trivial for Bazel add input and output redirection to/from |
The additional external dependency is a deal breaker, because it hurts availability. The effectiveness, however, only affect the experience. The build system is actually quite complex nowadays, a wrapper just adds some accidental complexity. |
Another advantage of the integral redirect would be that a build action that fails could then automatically dump the redirected log to the console, similar to the behavior of --test_output=errors. This can all be accomplished by wrapper scripts, but getting it right efficiently and consistently should make this a first-class bazel feature. |
Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 1+ years. It will be closed in the next 90 days unless any other activity occurs. If you think this issue is still relevant and should stay open, please post any comment here and the issue will no longer be marked as stale. |
I think this is still a desired functionality. |
I second the motion. Just because the request is so fully described there's nothing more to say and the team hasn't gotten around to implementing it in 6 years doesn't make it stale. |
Description of the problem / feature request:
It is common for programs in unix world to output the result of an invocation to stdout. The current way to capture that output is to either use
ctx.actions.run_shell()
or a wrapping shell script to redirect it to a file. This requires spawning an extra process and hence adds some overhead. Perhaps it makes sense to provide a way forctx.actions.run()
to redirect stdout and/or stderr into a file.Feature requests: what underlying problem are you trying to solve with this feature?
I have a tool that does what I described above - writes the result of its invocation to stdout. I need to capture that output and put it into a file - it is the output of the rule. Currently I have to wrap it in a shell script and I thought it might be good to suggest this feature. Thanks.
The text was updated successfully, but these errors were encountered: