@@ -19,6 +19,7 @@ pub fn main() -> color_eyre::eyre::Result<()> {
19
19
env_logger:: builder ( ) . format_timestamp ( None ) . init ( ) ;
20
20
color_eyre:: install ( ) ?;
21
21
let mut cli = Cli :: parse ( ) ;
22
+ cli. color . apply ( ) ;
22
23
23
24
if let Err ( error) = cli. command . run ( ) {
24
25
eprintln ! ( "{error}" ) ;
@@ -29,20 +30,21 @@ pub fn main() -> color_eyre::eyre::Result<()> {
29
30
}
30
31
31
32
#[ derive( Parser , Debug , Clone ) ]
33
+ #[ clap( color = concolor_clap:: color_choice( ) ) ]
32
34
struct Cli {
33
35
#[ command( subcommand) ]
34
36
command : Command ,
37
+ #[ command( flatten) ]
38
+ color : concolor_clap:: Color ,
35
39
}
36
40
37
41
#[ derive( Subcommand , Debug , Clone ) ]
38
42
#[ clap( name = env!( "CARGO_PKG_NAME" ) , about, version) ]
39
43
enum Command {
40
44
/// Parse into PL AST
41
45
Parse {
42
- #[ clap( value_parser, default_value = "-" ) ]
43
- input : Input ,
44
- #[ clap( value_parser, default_value = "-" ) ]
45
- output : Output ,
46
+ #[ clap( flatten) ]
47
+ io_args : IoArgs ,
46
48
#[ arg( value_enum, long, default_value = "yaml" ) ]
47
49
format : Format ,
48
50
} ,
@@ -59,16 +61,19 @@ enum Command {
59
61
60
62
/// Parse, resolve & lower into RQ
61
63
Resolve {
62
- #[ clap( value_parser, default_value = "-" ) ]
63
- input : Input ,
64
- #[ clap( value_parser, default_value = "-" ) ]
65
- output : Output ,
64
+ #[ clap( flatten) ]
65
+ io_args : IoArgs ,
66
66
#[ arg( value_enum, long, default_value = "yaml" ) ]
67
67
format : Format ,
68
68
} ,
69
69
70
70
/// Parse, resolve, lower into RQ & compile to SQL
71
- Compile ( IoArgs ) ,
71
+ Compile {
72
+ #[ clap( flatten) ]
73
+ io_args : IoArgs ,
74
+ #[ arg( long, default_value = "true" ) ]
75
+ include_signature_comment : bool ,
76
+ } ,
72
77
73
78
/// Watch a directory and compile .prql files to .sql files
74
79
Watch ( watch:: WatchArgs ) ,
@@ -96,11 +101,10 @@ fn is_stdin(input: &Input) -> bool {
96
101
impl Command {
97
102
/// Entrypoint called by [`main`]
98
103
pub fn run ( & mut self ) -> Result < ( ) > {
99
- if let Command :: Watch ( command) = self {
100
- return watch:: run ( command) ;
101
- } ;
102
-
103
- self . run_io_command ( )
104
+ match self {
105
+ Command :: Watch ( command) => watch:: run ( command) ,
106
+ _ => self . run_io_command ( ) ,
107
+ }
104
108
}
105
109
106
110
fn run_io_command ( & mut self ) -> std:: result:: Result < ( ) , anyhow:: Error > {
@@ -113,7 +117,15 @@ impl Command {
113
117
self . write_output ( & buf) ?;
114
118
}
115
119
Err ( e) => {
116
- print ! ( "{:}" , downcast( e) . composed( & source_id, & source, true ) ) ;
120
+ print ! (
121
+ "{:}" ,
122
+ // TODO: we're repeating this for `Compile`; can we consolidate?
123
+ downcast( e) . composed(
124
+ & source_id,
125
+ & source,
126
+ concolor:: get( concolor:: Stream :: Stdout ) . ansi_color( )
127
+ )
128
+ ) ;
117
129
std:: process:: exit ( 1 )
118
130
}
119
131
}
@@ -167,42 +179,57 @@ impl Command {
167
179
Format :: Yaml => serde_yaml:: to_string ( & ir) ?. into_bytes ( ) ,
168
180
}
169
181
}
170
- // TODO: Allow passing the `Options` to the CLI; map those through.
171
- // We already do this in Watch.
172
- Command :: Compile ( _) => compile ( source, & Options :: default ( ) ) ?. as_bytes ( ) . to_vec ( ) ,
182
+ Command :: Compile {
183
+ include_signature_comment,
184
+ ..
185
+ } => compile (
186
+ source,
187
+ // I'm guessing it's too "clever" to use `Options` directly in
188
+ // the Compile enum variant, and avoid this boilerplate? Would
189
+ // reduce this code somewhat.
190
+ & Options :: default ( )
191
+ . with_color ( concolor:: get ( concolor:: Stream :: Stdout ) . ansi_color ( ) )
192
+ . with_signature_comment ( * include_signature_comment) ,
193
+ ) ?
194
+ . as_bytes ( )
195
+ . to_vec ( ) ,
173
196
Command :: Watch ( _) => unreachable ! ( ) ,
174
197
} )
175
198
}
176
199
177
200
fn read_input ( & mut self ) -> Result < ( String , String ) > {
178
- // TODO: possibly this should be called by the relevant subcommands
179
- // passing in `input`, rather than matching on them and grabbing `input`
180
- // from `self`.
201
+ // Possibly this should be called by the relevant subcommands passing in
202
+ // `input`, rather than matching on them and grabbing `input` from
203
+ // `self`? But possibly if everything moves to `io_args`, then this is
204
+ // quite reasonable?
181
205
use Command :: * ;
182
206
let mut input = match self {
183
- Parse { input, .. } | Resolve { input, .. } => input. clone ( ) ,
184
- Format ( io) | Debug ( io) | Annotate ( io) | Compile ( io) => io. input . clone ( ) ,
207
+ Parse { io_args, .. } | Resolve { io_args, .. } | Compile { io_args, .. } => {
208
+ io_args. input . clone ( )
209
+ }
210
+ Format ( io) | Debug ( io) | Annotate ( io) => io. input . clone ( ) ,
185
211
Watch ( _) => unreachable ! ( ) ,
186
212
} ;
187
213
// Don't wait without a prompt when running `prqlc compile` —
188
214
// it's confusing whether it's waiting for input or not. This
189
215
// offers the prompt.
190
216
if is_stdin ( & input) && atty:: is ( atty:: Stream :: Stdin ) {
191
- println ! ( "Enter PRQL, then ctrl-d:" ) ;
192
- println ! ( ) ;
217
+ println ! ( "Enter PRQL, then ctrl-d:\n " ) ;
193
218
}
194
219
195
220
let mut source = String :: new ( ) ;
196
- ( input) . read_to_string ( & mut source) ?;
221
+ input. read_to_string ( & mut source) ?;
197
222
let source_id = ( input. path ( ) ) . to_str ( ) . unwrap ( ) . to_string ( ) ;
198
223
Ok ( ( source, source_id) )
199
224
}
200
225
201
226
fn write_output ( & mut self , data : & [ u8 ] ) -> std:: io:: Result < ( ) > {
202
227
use Command :: * ;
203
228
let mut output = match self {
204
- Parse { output, .. } | Resolve { output, .. } => output. to_owned ( ) ,
205
- Format ( io) | Debug ( io) | Annotate ( io) | Compile ( io) => io. output . to_owned ( ) ,
229
+ Parse { io_args, .. } | Resolve { io_args, .. } | Compile { io_args, .. } => {
230
+ io_args. output . to_owned ( )
231
+ }
232
+ Format ( io) | Debug ( io) | Annotate ( io) => io. output . to_owned ( ) ,
206
233
Watch ( _) => unreachable ! ( ) ,
207
234
} ;
208
235
output. write_all ( data)
@@ -321,7 +348,13 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
321
348
fn compile ( ) {
322
349
// Check we get an error on a bad input
323
350
let input = "asdf" ;
324
- let result = Command :: execute ( & Command :: Compile ( IoArgs :: default ( ) ) , input) ;
351
+ let result = Command :: execute (
352
+ & Command :: Compile {
353
+ io_args : IoArgs :: default ( ) ,
354
+ include_signature_comment : true ,
355
+ } ,
356
+ input,
357
+ ) ;
325
358
assert_display_snapshot ! ( result. unwrap_err( ) , @r###"
326
359
Error:
327
360
╭─[:1:1]
@@ -337,8 +370,7 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
337
370
fn parse ( ) {
338
371
let output = Command :: execute (
339
372
& Command :: Parse {
340
- input : IoArgs :: default ( ) . input ,
341
- output : IoArgs :: default ( ) . output ,
373
+ io_args : IoArgs :: default ( ) ,
342
374
format : Format :: Yaml ,
343
375
} ,
344
376
"from x | select y" ,
@@ -369,8 +401,7 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
369
401
fn resolve ( ) {
370
402
let output = Command :: execute (
371
403
& Command :: Resolve {
372
- input : IoArgs :: default ( ) . input ,
373
- output : IoArgs :: default ( ) . output ,
404
+ io_args : IoArgs :: default ( ) ,
374
405
format : Format :: Yaml ,
375
406
} ,
376
407
"from x | select y" ,
0 commit comments