-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Ability to suppress "Finished dev target" and "Running <path>" lines without hiding progress indicators #8743
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
Comments
I am interested in adding this (at least for the I would
|
quiet should mean quiet |
I'm in favor of changing the default output to have a better UX, while still supporting the spammy output with Strawman proposal:
|
To re-phrase my proposal in #8889, the idea I have is that output is split into "sticky" and "non-sticky".
I did say "most status messages", not "all". My ideal "first step" would be for each command to have a "summary" status message that is sticky. Due to how we compose things, this might initially be a "summary per step" ( |
I really wish this were a feature. The best alternative I've been able to come up with so far is this Python script that I got Claude to write today; it's a lot of really unnecessary complexity that I'd really rather avoid putting into my project: import fcntl
import os
import pty
import re
import select
import shutil
import struct
import subprocess
import sys
import termios
def strip_ansi(text):
"""Strip ANSI escape sequences and hyperlinks from text."""
# First remove OSC hyperlinks (everything between \x1b]8;; and \x1b\\)
text = re.sub(r"\x1b]8;;.*?\x1b\\", "", text)
# Then remove other ANSI sequences
return re.sub(r"\x1b\[[^m]*m", "", text)
def is_status_message(line):
"""Check if a line is a status message that should be filtered."""
return (
line.startswith("Finished")
or line.startswith("Running")
or line.startswith("Blocking waiting for file lock")
or not line # empty lines
)
def ensure_release_build(bin):
# Create a pseudo-terminal to preserve color/progress output
master, slave = pty.openpty()
# Get the terminal size
cols, rows = shutil.get_terminal_size()
# Set the PTY window size
# TIOCSWINSZ is terminal window size - see termios(3)
TIOCSWINSZ = getattr(termios, "TIOCSWINSZ", 0x5414)
s = struct.pack("HHHH", rows, cols, 0, 0)
fcntl.ioctl(slave, TIOCSWINSZ, s)
# Run cargo build --release with output going to our pty
process = subprocess.Popen(
["cargo", "build", "--release", "--bin", bin],
stderr=slave,
# Don't pipe stdout - let it go straight to terminal
env={
**os.environ,
"CARGO_TERM_PROGRESS_WHEN": "always", # Always show progress
"CARGO_TERM_COLOR": "always", # Always show colors
"CARGO_TERM_PROGRESS_WIDTH": str(cols), # Set terminal width
"TERM": os.environ.get("TERM", "xterm-256color"), # Ensure TERM is set
},
)
os.close(slave) # Close slave end after process has it
# Buffer for incomplete lines
line_buffer = b""
# Whether we've seen any non-status output
has_real_output = False
while True:
# Wait for data to be available (100ms timeout)
ready, _, _ = select.select([master], [], [], 0.1)
if not ready:
# No data available - check if process is done
if process.poll() is not None:
break
continue
# Read a chunk of data
try:
chunk = os.read(master, 4096)
except OSError:
# PTY was closed
break
if not chunk:
break
# Look for complete lines in the chunk
while b"\n" in chunk:
before, chunk = chunk.split(b"\n", 1)
# Add any previous buffer content to this line
line = line_buffer + before
line_buffer = b""
try:
decoded = line.decode()
except UnicodeDecodeError:
# If we can't decode, just pass it through
sys.stderr.buffer.write(line + b"\n")
sys.stderr.buffer.flush()
continue
# Strip ANSI sequences and clean up the line for checking
clean_line = strip_ansi(decoded).strip().replace("\r", "")
if has_real_output or not is_status_message(clean_line):
has_real_output = True
sys.stderr.buffer.write(line + b"\n")
sys.stderr.buffer.flush()
# Store any remaining partial line
line_buffer = chunk
# If we've seen real output, also pass through any partial content immediately
# This ensures progress indicators show up in real-time
if has_real_output and line_buffer:
sys.stderr.buffer.write(line_buffer)
sys.stderr.buffer.flush()
line_buffer = b""
# Handle any remaining data
if line_buffer and has_real_output:
sys.stderr.buffer.write(line_buffer)
sys.stderr.buffer.flush()
# Clean up the pty
os.close(master)
# Check final status
if process.wait() != 0:
sys.exit(process.returncode)
def cargo_run(bin):
# Ensure the release binary is built
ensure_release_build()
# Run the actual binary directly
binary_path = f"target/release/{bin}"
return subprocess.run([binary_path, *sys.argv[1:]]).returncode |
At least write the wrapper in Rust. This ain't the C/C++ ecosystem. |
To add to my previous comment, this proposal adds a new, specialized knob for users to interact with. Each knob we add comes with a cost: code bloat, compatibility, and documentation bloat (the more that needs to be documented, the harder it is for people to discover any feature, the less value we get out of all features). While my idea does not go to the extreme mentioned here, it goes most of the way and would more widely benefit people. |
@epage it seems like it'd depend on the details of your proposal, but if it doesn't get rid of all build output when there's nothing to build, it doesn't solve my problem. Specifically, let me give a bit of context:
For instance, here's the example from my project's README: ./gradbench run --eval "./gradbench repo eval hello" --tool "./gradbench repo tool pytorch" Here, As I mentioned above, those #!/usr/bin/env bash
cargo run --package=gradbench --profile=release-with-debug -- "$@" The output every time I run the above command would look like this:
The Cargo noise here is even longer than the actual output of my script, which is just unacceptable. Even if all the For a while I was using Anyways, to summarize, if there's a different solution that doesn't add a "specialized knob" then I'm all for it; but without more details, I can't tell whether your proposal would actually help for this issue. |
One of my goals for the reduced output is that there are not status messages for cargo-script (#12207), meaning there is no final status message for that style of invocation. From there, the questions are
|
Sure, I don't really have a preference among the following or other possible solutions, since any one of them would solve my problem, letting me replace my hacky Python script with a simple one- or two-line shell script:
|
Sorry, upon re-reading my last message I realize I was a bit unclear. What I meant to say was: @epage since I don't really care what form this solution takes, but you do, is there anything I can do to help at this point? Specifically, do you prefer one of these possible solutions (or perhaps a sixth option I forgot to list) over the others? If so, then is there a way I can help contribute an implementation? Or if not, is there a way I can help contribute to the discussion to help decide on a choice? |
Cargo script is towards the end and will soon be stabilized. However, the output style for that is a short term hack. I still feel the same that the first thing we should do is re-evaluate our baseline console output (see #8889). That will improve some of the problem and we can then evaluate how far we want to go within that that would cover your use case. If we don't, that gives us a better position for evaluate if and how we should cover your use case because we'd be working from a longer-term baseline rather than "how it works now". For #8889, the two potential starting points are
|
Describe the problem you are trying to solve
I've started using
cargo run --quiet
(aliased tocr
) to avoid thelines that show up on every
cargo run
, since I often work with programs that only emit a few lines of output, and want to keep my scrollback as clean as possible, the lines are pure noise to me.However, this also gets rid of progress indicators for downloads and builds, which make it hard to tell how how long it will be until the program starts, or even if the program has started yet, if
cargo
has things to do before running.Describe the solution you'd like
A flag to just hide the Finished/Running lines that show up.
Alternatively, only show them if cargo is running in
--verbose
or had any actions to perform?Or don't show them if they would have been the only output from cargo, show them otherwise? Not sure of the best method here.
The text was updated successfully, but these errors were encountered: