Skip to content

Conversation

@CommanderStorm
Copy link
Member

@CommanderStorm CommanderStorm commented Jan 10, 2026

This PR migrates us from our own progress bar to indicativ.

Needs tracing done first

This produces the following output:

00:00:02 -> eta: 10w [░                                        0%] 611973/1,466,015,503,701 (249,001.8169/s) | ✓ 5 □ 509994 

and when done

0:00:01 -> eta: 0s [████████████████████████████████████████ 100%] 5/5 (137.9386/s) | ✓ 5 □ 0

I was resonably uncreative with the template, might be a better option, not sure -> https://docs.rs/indicatif/latest/indicatif/#templates

Also note that this is not the be-all/end-all of solutions, this for example has the following problems:
It does not use all of indicatif/indicatif-tracins' functionality -> for example we could use a trace or a multiprocess-style, ...
=> iterative development

@CommanderStorm CommanderStorm changed the title feat: indicativ based progress bar feat(martin-cp): indicativ based progress bar Jan 14, 2026
@CommanderStorm CommanderStorm marked this pull request as ready for review January 14, 2026 07:05
Copilot AI review requested due to automatic review settings January 14, 2026 07:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the martin-cp tool from a custom progress bar implementation to the indicatif library. The changes integrate tracing-indicatif for progress bar support while maintaining tracing compatibility.

Changes:

  • Adds indicatif and tracing-indicatif dependencies to enable standardized progress bar functionality
  • Introduces init_with_progress method in logging.rs to initialize tracing with indicatif integration
  • Refactors the Progress struct in martin-cp.rs to use indicatif's ProgressBar instead of custom Display implementation
  • Extracts log bridge initialization into a separate init_log_bridge function

Reviewed changes

Copilot reviewed 3 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Cargo.toml Adds workspace dependencies for indicatif 0.18.3 and tracing-indicatif 0.3
Cargo.lock Updates dependency lock with new indicatif-related packages and transitive dependencies
martin/Cargo.toml References the new workspace dependencies for the martin crate
martin/src/logging.rs Adds init_with_progress method and refactors init_tracing to support optional progress bar; extracts log bridge initialization
martin/src/bin/martin-cp.rs Refactors Progress struct to use indicatif ProgressBar; removes custom duration formatting and Display implementation

Comment on lines 200 to 201
// (e.g., by test harness or other initialization code)
let _ = log_builder.init();
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactored init_log_bridge function extracts the log bridge initialization logic, which is good for code organization. However, the comment on line 199-200 mentions avoiding panicking if the logger is already initialized, but the original code used .expect() which would panic. The new behavior silently ignores all errors including real initialization failures. Consider adding a debug log when initialization is skipped or fails for troubleshooting purposes.

Suggested change
// (e.g., by test harness or other initialization code)
let _ = log_builder.init();
// (e.g., by test harness or other initialization code), but log failures
if let Err(err) = log_builder.init() {
// This is usually benign (logger already initialized), but log for diagnostics.
tracing::debug!("Skipping log bridge initialization: {err}");
}

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +150
pub fn init_with_progress(self, env_filter: EnvFilter) {
use tracing_subscriber::fmt::layer as fmt_layer;

let registry = tracing_subscriber::registry().with(env_filter.clone());

// code below looks duplicated, but it has to be this way due to how types currently work.
// maybe there is a better way that I can not see
match self {
LogFormat::Full => {
let indicatif_layer = tracing_indicatif::IndicatifLayer::new();
registry
.with(
fmt_layer()
.with_span_events(FmtSpan::NONE)
.with_writer(indicatif_layer.get_stderr_writer()),
)
.with(indicatif_layer)
.init();
}
LogFormat::Compact => {
let indicatif_layer = tracing_indicatif::IndicatifLayer::new();
registry
.with(
fmt_layer()
.compact()
.with_span_events(FmtSpan::NONE)
.with_writer(indicatif_layer.get_stderr_writer()),
)
.with(indicatif_layer)
.init();
}
LogFormat::Pretty => {
let indicatif_layer = tracing_indicatif::IndicatifLayer::new();
registry
.with(
fmt_layer()
.pretty()
.with_writer(indicatif_layer.get_stderr_writer()),
)
.with(indicatif_layer)
.init();
}
LogFormat::Bare => {
let indicatif_layer = tracing_indicatif::IndicatifLayer::new();
registry
.with(
fmt_layer()
.compact()
.with_span_events(FmtSpan::NONE)
.without_time()
.with_target(false)
.with_ansi(false)
.with_writer(indicatif_layer.get_stderr_writer()),
)
.with(indicatif_layer)
.init();
}
LogFormat::Json => {
let indicatif_layer = tracing_indicatif::IndicatifLayer::new();
registry
.with(
fmt_layer()
.json()
.with_span_events(FmtSpan::NONE)
.with_writer(indicatif_layer.get_stderr_writer()),
)
.with(indicatif_layer)
.init();
}
}
}
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The init_with_progress method contains significant code duplication with the original init method. The only differences are the creation of indicatif_layer and using get_stderr_writer(). Consider refactoring to reduce duplication, for example by extracting a helper method that builds the format layer with a writer parameter, or by having init delegate to init_with_progress with a conditional indicatif layer.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I knew how..

Comment on lines 199 to 201
// Use try_init to avoid panicking if logger is already initialized
// (e.g., by test harness or other initialization code)
let _ = log_builder.init();
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling for the log bridge initialization has been changed from .expect("Failed to initialize log -> tracing bridge") to let _ = log_builder.init() which silently ignores errors. While the comment explains this is intentional to avoid panicking if already initialized, this could hide other initialization errors. Consider logging a debug message when initialization fails, or at least documenting in the function docstring that duplicate initialization attempts are silently ignored.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants