feat: oxidize open_stream
Metadata
Current evaluation
Merged oxidized open_stream implementation. Refactored Printer into a global static variable and moved logging into it, requiring explicit initialization via Emitter.init_logger(). Depends on PR 411. Merged despite some failing CI tests.
Suggested action: —
No scores available.
Issue body
- [x] Have you followed the guidelines for contributing?
- [x] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)?
- [x] Have you successfully run `make lint && make test`?
---
This is based on (and thus requires) #411. The diff will be pretty noisy until it is merged.
I recommend not reviewing the code directly until I've had an opportunity to clean up the commit history once #411 lands, but this can be tested using the scripts below in the meantime.
This PR adds the `open_stream` method back to the emitter. This required refactoring the `Printer` class to not solely exist as a field on an `Emitter` instance, as the stream handler object needed access too. Now, the `Printer` is a global, static variable that gets initialized upon the first print. For similar reasons, the logging mechanism has been moved into the printer and must be explicitly initialized via the new `Emitter.init_logger()`.
Here is some example code to test the changes:
```py
# testing.py
import subprocess
from craft_cli import EmitterMode
from craft_cli._rs.emitter import Emitter
e = Emitter("blah.log", EmitterMode.TRACE, "example.com", "hello from rust!")
e.init_logger()
with e.open_stream() as stream:
subprocess.run(["bash", "testing.sh"], stdout=stream, stderr=stream)
```
```bash
# testing.sh
for i in {1..6}; do
echo $i
sleep 1
done
```
Known bugs: It seems that trace-level events (and perhaps others?) duplicate the timestamp in logs (tracked in CRAFT 4999). Also, the `text` parameter for `open_stream` is missing until CRAFT 4968 is complete, as otherwise the two tasks would duplicate work to add prefix behaviors.
CRAFT-4964.
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| qwen/qwen3.6-35b-a3b | — | — | Merged oxidized open_stream implementation. Refactored Printer into a global static variable and moved logging into it, requiring explicit initialization via Emitter.init_logger(). Depends on PR 411. Merged despite some failing CI tests. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Merged. Restored the open_stream method to the emitter by refactoring Printer into a global static variable and embedding logging, requiring explicit init_logger initialization. Depends on PR 411. Addresses CRAFT-4964. |
Update history
No update history recorded yet.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #411 feat: oxidize the emitter | craft-cli | merged | Merged. The emitter class was oxidized to Rust using PyO3 and Maturin, removing the global emit function. The PR updated the build backend, required Rust 1.80+, and was merged after addressing CI failures and review feedback. | |
| #419 feat: oxidize streaming_brief feature | craft-cli | merged | Merged after maintainer approval. The change re-adds the streaming_brief feature for niche logging scenarios and restores message prefixing for Emitter.open_stream. Commits were force-pushed to clean history before merging. |