@@ -9,9 +9,21 @@ use cap_std::fs::Dir;
9
9
use cap_std_ext:: cap_std;
10
10
use cap_std_ext:: prelude:: CapStdExtCommandExt ;
11
11
12
+ /// How much information we output
13
+ #[ derive( Debug , PartialEq , Eq , Default ) ]
14
+ enum CmdVerbosity {
15
+ /// Nothing is output
16
+ Quiet ,
17
+ /// Only the task description is output
18
+ #[ default]
19
+ Description ,
20
+ /// The task description and the full command line are output
21
+ Verbose ,
22
+ }
23
+
12
24
pub ( crate ) struct Task {
13
25
description : String ,
14
- quiet : bool ,
26
+ verbosity : CmdVerbosity ,
15
27
quiet_output : bool ,
16
28
pub ( crate ) cmd : Command ,
17
29
}
@@ -40,14 +52,21 @@ impl Task {
40
52
cmd. stdin ( Stdio :: null ( ) ) ;
41
53
Self {
42
54
description,
43
- quiet : false ,
55
+ verbosity : Default :: default ( ) ,
44
56
quiet_output : false ,
45
57
cmd,
46
58
}
47
59
}
48
60
61
+ /// Don't output description by default
49
62
pub ( crate ) fn quiet ( mut self ) -> Self {
50
- self . quiet = true ;
63
+ self . verbosity = CmdVerbosity :: Quiet ;
64
+ self
65
+ }
66
+
67
+ /// Output description and cmdline
68
+ pub ( crate ) fn verbose ( mut self ) -> Self {
69
+ self . verbosity = CmdVerbosity :: Verbose ;
51
70
self
52
71
}
53
72
@@ -72,13 +91,38 @@ impl Task {
72
91
self . run_with_stdin_buf ( None )
73
92
}
74
93
94
+ fn pre_run_output ( & self ) {
95
+ match self . verbosity {
96
+ CmdVerbosity :: Quiet => { }
97
+ CmdVerbosity :: Description => {
98
+ println ! ( "{}" , self . description) ;
99
+ }
100
+ CmdVerbosity :: Verbose => {
101
+ // Output the description first
102
+ println ! ( "{}" , self . description) ;
103
+
104
+ // Lock stdout so we buffer
105
+ let mut stdout = std:: io:: stdout ( ) . lock ( ) ;
106
+ let cmd_args = std:: iter:: once ( self . cmd . get_program ( ) )
107
+ . chain ( self . cmd . get_args ( ) )
108
+ . map ( |arg| arg. to_string_lossy ( ) ) ;
109
+ // We unwrap() here to match the default for println!() even though
110
+ // arguably that's wrong
111
+ stdout. write_all ( b">" ) . unwrap ( ) ;
112
+ for s in cmd_args {
113
+ stdout. write_all ( b" " ) . unwrap ( ) ;
114
+ stdout. write_all ( s. as_bytes ( ) ) . unwrap ( ) ;
115
+ }
116
+ stdout. write_all ( b"\n " ) . unwrap ( ) ;
117
+ }
118
+ }
119
+ }
120
+
75
121
/// Run the command with optional stdin buffer, returning an error if the command does not exit successfully.
76
122
pub ( crate ) fn run_with_stdin_buf ( self , stdin : Option < & [ u8 ] > ) -> Result < ( ) > {
123
+ self . pre_run_output ( ) ;
77
124
let description = self . description ;
78
125
let mut cmd = self . cmd ;
79
- if !self . quiet {
80
- println ! ( "{description}" ) ;
81
- }
82
126
let mut output = None ;
83
127
if self . quiet_output {
84
128
let tmpf = tempfile:: tempfile ( ) ?;
@@ -117,11 +161,9 @@ impl Task {
117
161
118
162
/// Like [`run()`], but return stdout.
119
163
pub ( crate ) fn read ( self ) -> Result < String > {
164
+ self . pre_run_output ( ) ;
120
165
let description = self . description ;
121
166
let mut cmd = self . cmd ;
122
- if !self . quiet {
123
- println ! ( "{description}" ) ;
124
- }
125
167
tracing:: debug!( "exec: {cmd:?}" ) ;
126
168
cmd. stdout ( Stdio :: piped ( ) ) ;
127
169
let child = cmd
0 commit comments