Skip to content

Commit

Permalink
feat(prqlc): Add color & signature_comment options
Browse files Browse the repository at this point in the history
This adds `--color` & `--include-signature-comment` options to the `prqlc compile` command.

Closes PRQL#1355. I think we did a not-great job at defining the minimum requirements there, to the extent that this is a simpler construction that leans more heavily on external libraries -- and is both simpler and has better functionality as a result. Even without the external libraries, I think we could have suggested a flatter structure to the `Options' struct.

(Or maybe we'll decide this construction is too simple / leans too much on external libraries).
  • Loading branch information
max-sixty committed Mar 21, 2023
1 parent 5b60e60 commit 4849040
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 34 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion prql-compiler/prqlc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ atty = "0.2.14"
clap = {version = "4.1.1", features = ["derive"]}
clio = {version = "0.2.4", features = ['clap-parse']}
color-eyre = "0.6.1"
concolor = "0.1.0"
concolor-clap = {version = "0.1.0", features = ["api"]}
env_logger = {version = "0.10.0", features = ["color"]}
itertools = "0.10.3"
minijinja = {version = "0.30.4", features = ["unstable_machinery"]}
notify = "^5.1.0"
prql-compiler = {path = '..', version = "0.6.1" }
prql-compiler = {path = '..', version = "0.6.1"}
regex = {version = "1.7.1", features = ["std", "unicode"]}
serde = "^1"
serde_json = "1.0.81"
Expand Down
97 changes: 64 additions & 33 deletions prql-compiler/prqlc/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub fn main() -> color_eyre::eyre::Result<()> {
env_logger::builder().format_timestamp(None).init();
color_eyre::install()?;
let mut cli = Cli::parse();
cli.color.apply();

if let Err(error) = cli.command.run() {
eprintln!("{error}");
Expand All @@ -29,20 +30,21 @@ pub fn main() -> color_eyre::eyre::Result<()> {
}

#[derive(Parser, Debug, Clone)]
#[clap(color = concolor_clap::color_choice())]
struct Cli {
#[command(subcommand)]
command: Command,
#[command(flatten)]
color: concolor_clap::Color,
}

#[derive(Subcommand, Debug, Clone)]
#[clap(name = env!("CARGO_PKG_NAME"), about, version)]
enum Command {
/// Parse into PL AST
Parse {
#[clap(value_parser, default_value = "-")]
input: Input,
#[clap(value_parser, default_value = "-")]
output: Output,
#[clap(flatten)]
io_args: IoArgs,
#[arg(value_enum, long, default_value = "yaml")]
format: Format,
},
Expand All @@ -59,16 +61,19 @@ enum Command {

/// Parse, resolve & lower into RQ
Resolve {
#[clap(value_parser, default_value = "-")]
input: Input,
#[clap(value_parser, default_value = "-")]
output: Output,
#[clap(flatten)]
io_args: IoArgs,
#[arg(value_enum, long, default_value = "yaml")]
format: Format,
},

/// Parse, resolve, lower into RQ & compile to SQL
Compile(IoArgs),
Compile {
#[clap(flatten)]
io_args: IoArgs,
#[arg(long, default_value = "true")]
include_signature_comment: bool,
},

/// Watch a directory and compile .prql files to .sql files
Watch(watch::WatchArgs),
Expand Down Expand Up @@ -96,11 +101,10 @@ fn is_stdin(input: &Input) -> bool {
impl Command {
/// Entrypoint called by [`main`]
pub fn run(&mut self) -> Result<()> {
if let Command::Watch(command) = self {
return watch::run(command);
};

self.run_io_command()
match self {
Command::Watch(command) => watch::run(command),
_ => self.run_io_command(),
}
}

fn run_io_command(&mut self) -> std::result::Result<(), anyhow::Error> {
Expand All @@ -113,7 +117,15 @@ impl Command {
self.write_output(&buf)?;
}
Err(e) => {
print!("{:}", downcast(e).composed(&source_id, &source, true));
print!(
"{:}",
// TODO: we're repeating this for `Compile`; can we consolidate?
downcast(e).composed(
&source_id,
&source,
concolor::get(concolor::Stream::Stdout).ansi_color()
)
);
std::process::exit(1)
}
}
Expand Down Expand Up @@ -167,42 +179,57 @@ impl Command {
Format::Yaml => serde_yaml::to_string(&ir)?.into_bytes(),
}
}
// TODO: Allow passing the `Options` to the CLI; map those through.
// We already do this in Watch.
Command::Compile(_) => compile(source, &Options::default())?.as_bytes().to_vec(),
Command::Compile {
include_signature_comment,
..
} => compile(
source,
// I'm guessing it's too "clever" to use `Options` directly in
// the Compile enum variant, and avoid this boilerplate? Would
// reduce this code somewhat.
&Options::default()
.with_color(concolor::get(concolor::Stream::Stdout).ansi_color())
.with_signature_comment(*include_signature_comment),
)?
.as_bytes()
.to_vec(),
Command::Watch(_) => unreachable!(),
})
}

fn read_input(&mut self) -> Result<(String, String)> {
// TODO: possibly this should be called by the relevant subcommands
// passing in `input`, rather than matching on them and grabbing `input`
// from `self`.
// Possibly this should be called by the relevant subcommands passing in
// `input`, rather than matching on them and grabbing `input` from
// `self`? But possibly if everything moves to `io_args`, then this is
// quite reasonable?
use Command::*;
let mut input = match self {
Parse { input, .. } | Resolve { input, .. } => input.clone(),
Format(io) | Debug(io) | Annotate(io) | Compile(io) => io.input.clone(),
Parse { io_args, .. } | Resolve { io_args, .. } | Compile { io_args, .. } => {
io_args.input.clone()
}
Format(io) | Debug(io) | Annotate(io) => io.input.clone(),
Watch(_) => unreachable!(),
};
// Don't wait without a prompt when running `prqlc compile` —
// it's confusing whether it's waiting for input or not. This
// offers the prompt.
if is_stdin(&input) && atty::is(atty::Stream::Stdin) {
println!("Enter PRQL, then ctrl-d:");
println!();
println!("Enter PRQL, then ctrl-d:\n");
}

let mut source = String::new();
(input).read_to_string(&mut source)?;
input.read_to_string(&mut source)?;
let source_id = (input.path()).to_str().unwrap().to_string();
Ok((source, source_id))
}

fn write_output(&mut self, data: &[u8]) -> std::io::Result<()> {
use Command::*;
let mut output = match self {
Parse { output, .. } | Resolve { output, .. } => output.to_owned(),
Format(io) | Debug(io) | Annotate(io) | Compile(io) => io.output.to_owned(),
Parse { io_args, .. } | Resolve { io_args, .. } | Compile { io_args, .. } => {
io_args.output.to_owned()
}
Format(io) | Debug(io) | Annotate(io) => io.output.to_owned(),
Watch(_) => unreachable!(),
};
output.write_all(data)
Expand Down Expand Up @@ -321,7 +348,13 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
fn compile() {
// Check we get an error on a bad input
let input = "asdf";
let result = Command::execute(&Command::Compile(IoArgs::default()), input);
let result = Command::execute(
&Command::Compile {
io_args: IoArgs::default(),
include_signature_comment: true,
},
input,
);
assert_display_snapshot!(result.unwrap_err(), @r###"
Error:
╭─[:1:1]
Expand All @@ -337,8 +370,7 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
fn parse() {
let output = Command::execute(
&Command::Parse {
input: IoArgs::default().input,
output: IoArgs::default().output,
io_args: IoArgs::default(),
format: Format::Yaml,
},
"from x | select y",
Expand Down Expand Up @@ -369,8 +401,7 @@ group a_column (take 10 | sort b_column | derive [the_number = rank, last = lag
fn resolve() {
let output = Command::execute(
&Command::Resolve {
input: IoArgs::default().input,
output: IoArgs::default().output,
io_args: IoArgs::default(),
format: Format::Yaml,
},
"from x | select y",
Expand Down
5 changes: 5 additions & 0 deletions prql-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ impl Options {
self
}

pub fn with_signature_comment(mut self, signature_comment: bool) -> Self {
self.signature_comment = signature_comment;
self
}

pub fn no_signature(mut self) -> Self {
self.signature_comment = false;
self
Expand Down

0 comments on commit 4849040

Please sign in to comment.