Skip to content

Commit d2c50f1

Browse files
redpanda-fCopilot
andauthored
feat: introduce notty flag for version command (#82)
* feat: introduce --noterminal flag for version command * refactor: replace magic numbers with named constants in `format_relative_time` (#86) * Initial plan * refactor: replace magic numbers with named constants in format_relative_time Co-authored-by: redpanda-f <181817029+redpanda-f@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: redpanda-f <181817029+redpanda-f@users.noreply.github.com> * add: notty --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: redpanda-f <181817029+redpanda-f@users.noreply.github.com>
1 parent b9b958d commit d2c50f1

3 files changed

Lines changed: 67 additions & 35 deletions

File tree

src/cli.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ pub enum Commands {
5959
/// Show status of the foc-devnet system
6060
Status,
6161
/// Show version information
62-
Version,
62+
Version {
63+
/// Force plain output without tracing prefixes, even when stdout is a terminal
64+
#[arg(long)]
65+
notty: bool,
66+
},
6367
}
6468

6569
/// Build subcommands

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
4949
main_app::command_handlers::handle_build(build_command)
5050
}
5151
Commands::Status => main_app::command_handlers::handle_status(),
52-
Commands::Version => main_app::version::handle_version(),
52+
Commands::Version { notty } => main_app::version::handle_version(notty),
5353
};
5454

5555
// Handle the result

src/main_app/version.rs

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,26 @@
44
55
use foc_devnet::config::{Config, Location};
66
use foc_devnet::version_info::VersionInfo;
7+
use std::io::IsTerminal;
78
use tracing::info;
89

9-
/// Execute the version command
10-
pub fn handle_version() -> Result<(), Box<dyn std::error::Error>> {
10+
/// Emit a line either as a tracing INFO event or a plain println.
11+
macro_rules! emit {
12+
($plain:expr, $fmt:literal $(, $arg:expr)*) => {
13+
if $plain {
14+
println!($fmt $(, $arg)*);
15+
} else {
16+
info!($fmt $(, $arg)*);
17+
}
18+
};
19+
}
20+
21+
/// Execute the version command.
22+
///
23+
/// Plain output (no tracing prefixes) is used when stdout is not a terminal,
24+
/// or when `notty` is `true` (explicit override).
25+
pub fn handle_version(notty: bool) -> Result<(), Box<dyn std::error::Error>> {
26+
let plain = notty || !std::io::stdout().is_terminal();
1127
// Version information is read-only, no poison protection needed
1228
let version_info = VersionInfo::from_env();
1329
let dirty_suffix = if version_info.dirty.is_empty() {
@@ -16,59 +32,71 @@ pub fn handle_version() -> Result<(), Box<dyn std::error::Error>> {
1632
"-dirty"
1733
};
1834

19-
info!("foc-devnet {}", version_info.version);
20-
info!("Commit: {}{}", version_info.commit, dirty_suffix);
21-
info!("Branch: {}", version_info.branch);
35+
emit!(plain, "foc-devnet {}", version_info.version);
36+
emit!(plain, "Commit: {}{}", version_info.commit, dirty_suffix);
37+
emit!(plain, "Branch: {}", version_info.branch);
2238

23-
// Calculate relative time
24-
let now = chrono::Utc::now().timestamp();
25-
let diff_seconds = now - version_info.build_timestamp;
26-
27-
let relative_time = if diff_seconds < 60 {
28-
format!("({} seconds ago)", diff_seconds)
29-
} else if diff_seconds < 3600 {
30-
format!("({} minutes ago)", diff_seconds / 60)
31-
} else if diff_seconds < 86400 {
32-
format!("({} hours ago)", diff_seconds / 3600)
33-
} else {
34-
format!("({} days ago)", diff_seconds / 86400)
35-
};
39+
let relative_time =
40+
format_relative_time(chrono::Utc::now().timestamp() - version_info.build_timestamp);
3641

37-
info!(
42+
emit!(
43+
plain,
3844
"Built (UTC): {} {}",
39-
version_info.build_time_utc, relative_time
45+
version_info.build_time_utc,
46+
relative_time
4047
);
41-
info!("Built (Local): {}", version_info.build_time_local);
48+
emit!(plain, "Built (Local): {}", version_info.build_time_local);
4249

43-
// Print default configuration values
4450
let default_config = Config::default();
45-
info!("");
46-
print_location_info("default:code:lotus", &default_config.lotus);
47-
print_location_info("default:code:curio", &default_config.curio);
51+
emit!(plain, "");
52+
print_location_info(plain, "default:code:lotus", &default_config.lotus);
53+
print_location_info(plain, "default:code:curio", &default_config.curio);
4854
print_location_info(
55+
plain,
4956
"default:code:filecoin-services",
5057
&default_config.filecoin_services,
5158
);
52-
print_location_info("default:code:multicall3", &default_config.multicall3);
53-
info!("default:yugabyte: {}", default_config.yugabyte_download_url);
59+
print_location_info(plain, "default:code:multicall3", &default_config.multicall3);
60+
emit!(
61+
plain,
62+
"default:yugabyte: {}",
63+
default_config.yugabyte_download_url
64+
);
5465

5566
Ok(())
5667
}
5768

58-
/// Print location information in a formatted way
59-
fn print_location_info(label: &str, location: &Location) {
69+
const SECS_PER_MIN: i64 = 60;
70+
const SECS_PER_HOUR: i64 = 3_600;
71+
const SECS_PER_DAY: i64 = 86_400;
72+
73+
/// Format a duration in seconds as a human-readable relative time string.
74+
fn format_relative_time(diff_seconds: i64) -> String {
75+
if diff_seconds < SECS_PER_MIN {
76+
format!("({} seconds ago)", diff_seconds)
77+
} else if diff_seconds < SECS_PER_HOUR {
78+
format!("({} minutes ago)", diff_seconds / SECS_PER_MIN)
79+
} else if diff_seconds < SECS_PER_DAY {
80+
format!("({} hours ago)", diff_seconds / SECS_PER_HOUR)
81+
} else {
82+
format!("({} days ago)", diff_seconds / SECS_PER_DAY)
83+
}
84+
}
85+
86+
/// Print location information in a formatted way.
87+
fn print_location_info(plain: bool, label: &str, location: &Location) {
6088
match location {
6189
Location::LocalSource { dir } => {
62-
info!("{}: local source at {}", label, dir);
90+
emit!(plain, "{}: local source at {}", label, dir);
6391
}
6492
Location::GitCommit { url, commit } => {
65-
info!("{}: {}, commit {}", label, url, commit);
93+
emit!(plain, "{}: {}, commit {}", label, url, commit);
6694
}
6795
Location::GitTag { url, tag } => {
68-
info!("{}: {}, tag {}", label, url, tag);
96+
emit!(plain, "{}: {}, tag {}", label, url, tag);
6997
}
7098
Location::GitBranch { url, branch } => {
71-
info!("{}: {}, branch {}", label, url, branch);
99+
emit!(plain, "{}: {}, branch {}", label, url, branch);
72100
}
73101
}
74102
}

0 commit comments

Comments
 (0)