44
55use foc_devnet:: config:: { Config , Location } ;
66use foc_devnet:: version_info:: VersionInfo ;
7+ use std:: io:: IsTerminal ;
78use 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