bazelbuild / bazelbuild/bazel

Support `console` actions that can print directly to the terminal to provide human-friendly status updates.

Open
#28,435 3 comments 1 reaction 0 assignees View on GitHub
P4 team-CLI type: feature request
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 20h
Merged PRs (30d)
72

Description

### Description of the feature request:

This is a quality-of-life feature request that applies to Bazel actions that run for a very long time, and whose command are capable of printing human-friendly status updates (e.g. using ANSI VT code sequences) when their stdout is a tty.

The Fuchsia-specific issue tracking this is https://fxbug.dev/468378699

This feature is already implemented by Ninja, and is *very* useful for the Fuchsia build because when a NInja action invokes Bazel, the following happens:

- Ninja clears its interactive progress output (e.g. table of pending commands).
- Ninja hands over the terminal to Bazel, which can print its own interactive and colored progress output.
- When Bazel completes, Ninja regains the terminal, prints the output of any other parallel console that completed before Bazel, then restores its own interactive progress output.

Here is an animated image that shows how that works in practice (Bazel is invoked at the end of the loop):

Image

This issue is asking for a similar feature in Bazel, because the Fuchsia build also has Bazel actions invoking Ninja in sub-build directories, and so far the user experience is poor:

- Ninja runs for several minutes, but nothing gets printed except a single line Bazel status update for the invoking action.

- When the action completes, the whole buffered Ninja output is printed in one go, typically several hundreds or thousands of lines (one per built artifact) because Ninja detected it was _not_ running in a tty.

Function requirements could look like:

- A new `execution-requirements` tag such as `console`, which would also imply `local` automatically. Custom Bazel rules could create actions with this to specify they run in this mode. No need for non-local support.

- The Bazel local scheduler would ensure that no more than one console action can run at a time. There is only one terminal, and it cannot be shared without chaos.

- Before starting the console command, Bazel would clear its interactive progress output (e.g. lines describing running actions).

- Bazel would not write anything to the terminal until the console command completes (or in case of user interruption, see below).

- When the console command completes, Bazel would first print the buffered output of any other command that did complete before the command one (possibly with the usual build info associated with them), then would take control of the terminal again / restore its own progress output.

- The tty can be passed either directly (through file description / handle inheritance) when spawing the console command, or a pty could be allocated on Posix systems, which would allow buffering the output of the console command. Ninja chose the first option, which means that console command outputs are not buffered by Bazel.

- User interruption must be supported correctly, i.e .if Ctrl-C is pressed, the SIGINT signal should be sent once to the console command.

This is a subtle implementation detail in Ninja, because it decided to run console commands in the same Posix session as the Ninja process itself. Meaning that pressing Ctrl-C will send a SIGINT signal to both the Ninja process and the console action.

Ninja normally handles the SIGINT signal by passing it to all command sub-processes (each one running in its own session), but it needs to avoid doing that for the console one, otherwise the latter would receive SIGINT twice, which can cause unexpected issues.

On Windows, things are simpler, as the Ctrl-C is passed to all subprocesses, independent of their nature.

### Which category does this issue belong to?

_No response_

### What underlying problem are you trying to solve with this feature?

_No response_

### Which operating system are you running Bazel on?

_No response_

### What is the output of `bazel info release`?

_No response_

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.

_No response_

### What's the output of `git remote get-url origin; git rev-parse HEAD` ?

```text

```

### Have you found anything relevant by searching the web?

_No response_

### Any other information, logs, or outputs that you want to share?

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by locating Bazel’s local scheduler and execution-requirements handling, then compare the console-action behavior described here with Ninja’s implementation. Done means a documented design and implementation covering console-action serialization, terminal ownership and progress restoration, output handling, and correct interruption behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.