Skip to content

Commit

Permalink
feat BREAKING: changed wick query from jaq to liquid
Browse files Browse the repository at this point in the history
  • Loading branch information
jsoverson committed Sep 27, 2023
1 parent b3a5281 commit d89a6f4
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 167 deletions.
30 changes: 15 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,27 @@ wick-package = { workspace = true }
wick-logger = { workspace = true }
flow-expression-parser = { workspace = true }
seeded-random = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread"] }
tracing = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
anyhow = { workspace = true }
atty = { workspace = true }
clap = { workspace = true, default-features = true, features = ["derive"] }
dhat = { workspace = true, optional = true }
dialoguer = { workspace = true, features = ["password"] }
human-panic = { workspace = true }
futures = { workspace = true }
thiserror = { workspace = true }
clap = { workspace = true, default-features = true, features = ["derive"] }
nkeys = { workspace = true }
atty = { workspace = true }
jaq-core = { workspace = true, features = ["serde_json"] }
human-panic = { workspace = true }
liquid = { workspace = true }
liquid-json = { workspace = true, features = ["serde"] }
markup-converter = { workspace = true }
nkeys = { workspace = true }
once_cell = { workspace = true }
openssl = { workspace = true, features = ["vendored"], optional = true }
option-utils = { workspace = true }
structured-output = { workspace = true }
regex = { workspace = true }
dhat = { workspace = true, optional = true }
once_cell = { workspace = true }
liquid-json = { workspace = true, features = ["serde"] }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
structured-output = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread"] }
tracing = { workspace = true }

[dev-dependencies]
test_bin = { workspace = true }
Expand Down Expand Up @@ -199,7 +199,7 @@ hyper-reverse-proxy = { version = "0.5", default-features = false }
itertools = { version = "0.11", default-features = false, features = [
"use_std",
] }
jaq-core = { version = "0.10", default-features = false }

json_dotpath = { version = "1.1.0", default-features = false }
lazy_static = { version = "1.4", default-features = false }
liquid = { package = "loose-liquid", version = "0.27", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub(crate) enum CliCommand {
#[clap(subcommand, name = "rpc")]
Rpc(rpc::SubCommands),

/// Command to query JSON, YAML, or TOML file.
/// Command to apply a liquid template to a JSON, YAML, or TOML file.
#[clap(name = "query")]
Query(query::Options),
}
Expand Down
78 changes: 25 additions & 53 deletions src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use std::str::FromStr;

use anyhow::Result;
use clap::Args;
use jaq_core::{parse, Ctx, Definitions, RcIter, Val};
use markup_converter::{Format, Transcoder};
use serde_json::{json, Value};
use serde_json::json;
use structured_output::StructuredOutput;

#[derive(Debug, Clone, Args)]
Expand All @@ -17,17 +16,17 @@ pub(crate) struct Options {
#[clap(short = 'r', long = "raw", action)]
raw_output: bool,

/// Option to print raw output.
/// The markup kind if there is no extension.
#[clap(short = 't', long = "type", action)]
kind: Option<MarkupKind>,

/// Path to JSON, YAML, or TOML file.
#[clap(short = 'f', long = "file", action)]
path: Option<PathBuf>,

/// The query.
/// The template.
#[clap(action)]
query: String,
template: String,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -81,58 +80,31 @@ pub(crate) async fn handle(
}
};
let _enter = span.enter();
let trimmed = opts.template.trim();

let filter = &opts.query;
// If the passed template includes '{{' then we can assume it's a raw template.
let template = if trimmed.contains("{{") {
opts.template
} else {
// The trim_start_matches('.') removes a leading '.' if it exists.
// This allows us to process a jq-style template as well as liquid-style templates.
// Finally, wrap it in double braces to make it a liquid template.
format!("{{{{ {} }}}}", trimmed.trim_start_matches('.'))
};

// parse the filter in the context of the given definitions
let mut errs = Vec::new();
let (filters, errors) = parse::parse(filter, parse::main());
let template = liquid::ParserBuilder::with_stdlib().build()?.parse(&template)?;

if !errors.is_empty() {
for error in errors {
error!("error parsing query: {}", error);
let globals = match input {
serde_json::Value::Object(map) => liquid::model::to_object(&map)?,
_ => {
liquid::object!({
"data": input
})
}
return Err(anyhow!("Errors parsing queries"));
}

let mut lines = Vec::new();
let mut json = Vec::new();

#[allow(clippy::option_if_let_else)]
if let Some(filters) = filters {
// start out only from core filters,
// which do not include filters in the standard library
// such as `map`, `select` etc.
let defs = Definitions::core();

let filters = defs.finish(filters, Vec::new(), &mut errs);
let inputs = RcIter::new(core::iter::empty());

// iterator over the output values
let out = filters.run(Ctx::new([], &inputs), Val::from(input));

for val in out {
match val {
Ok(result) => {
let result: Value = result.into();
if let Value::String(v) = &result {
if opts.raw_output {
lines.push(v.clone());
} else {
lines.push(result.to_string());
}
} else {
lines.push(result.to_string());
}
};

json.push(result);
}
Err(e) => error!("error: {}", e),
};
}
} else {
debug!("no queries successfully parsed");
}
let result = template.render(&globals)?;
let json = json!({"results":result});

Ok(StructuredOutput::new(lines.join("\n"), json!({"results":json})))
Ok(StructuredOutput::new(result, json))
}
27 changes: 5 additions & 22 deletions tests/invoke.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
static DIR: &str = "invoke";
mod utils;

#[rstest::rstest]
#[case("v1-wasmrs.toml")]
#[case("stdin.toml")]
#[case("app.toml")]
fn wick_invoke(#[case] file: &'static str) {
let kind = "unit";
let file = format!("tests/{}/{}/{}", DIR, kind, file);

trycmd::TestCases::new().case(file);
}

// mod integration_test {
// use super::DIR;
// #[rstest::rstest]
// #[case("postgres.toml")]
// fn wick_run(#[case] file: &'static str) {
// let kind = "integration";
// let file = format!("tests/{}/{}/{}", kind, DIR, file);
// trycmd::TestCases::new().case(file);
// }
// }
utils::test_cases!(
unit: ["v1-wasmrs.toml", "stdin.toml", "app.toml"],
integration: []
);
40 changes: 14 additions & 26 deletions tests/new.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
static DIR: &str = "new";
mod utils;

#[rstest::rstest]
#[case("app.toml")]
#[case("app-cli.toml")]
#[case("app-http.toml")]
#[case("app-time.toml")]
#[case("component-composite.toml")]
#[case("component-sql.toml")]
#[case("component-http.toml")]
#[case("component-wasm.toml")]
fn wick_new(#[case] file: &'static str) {
let kind = "unit";
let file = format!("tests/{}/{}/{}", DIR, kind, file);

trycmd::TestCases::new().case(file);
}

// mod integration_test {
// use super::DIR;
// #[rstest::rstest]
// fn wick_run(#[case] file: &'static str) {
// let kind = "integration";
// let file = format!("tests/{}/{}/{}", kind, DIR, file);
// trycmd::TestCases::new().case(file);
// }
// }
utils::test_cases!(
unit: [
"app.toml",
"app-cli.toml",
"app-http.toml",
"app-time.toml",
"component-composite.toml",
"component-sql.toml",
"component-http.toml",
"component-wasm.toml"
],
integration: []
);
8 changes: 8 additions & 0 deletions tests/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mod utils;

utils::test_cases!(
unit: [
"jq-style.toml", "no-curlies.toml", "with-curlies.toml"
],
integration: []
);
6 changes: 6 additions & 0 deletions tests/query/unit/jq-style.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#:schema https://raw.githubusercontent.com/assert-rs/trycmd/main/schema.json
bin.name = "wick"
args = ["query", "-f", "Cargo.toml", " .package.name "]
stdout = """
wick-cli
"""
6 changes: 6 additions & 0 deletions tests/query/unit/no-curlies.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#:schema https://raw.githubusercontent.com/assert-rs/trycmd/main/schema.json
bin.name = "wick"
args = ["query", "-f", "Cargo.toml", " package.name "]
stdout = """
wick-cli
"""
6 changes: 6 additions & 0 deletions tests/query/unit/with-curlies.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#:schema https://raw.githubusercontent.com/assert-rs/trycmd/main/schema.json
bin.name = "wick"
args = ["query", "-f", "Cargo.toml", " {{ package.name }} "]
stdout = """
wick-cli[..]
"""
42 changes: 16 additions & 26 deletions tests/run.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
static DIR: &str = "run";
mod utils;

#[rstest::rstest]
#[case("anonymous-component.toml")]
#[case("imported-component.toml")]
#[case("stdin.toml")]
#[case("file-reader.toml")]
#[case("file-reader-lockdown-fail.toml")]
#[case("file-reader-lockdown-pass.toml")]
#[case("file-reader-lockdown-pass-wildcard-dir.toml")]
#[case("file-reader-lockdown-pass-wildcard-components.toml")]
fn wick_run(#[case] file: &'static str) {
let kind = "unit";
let file = format!("tests/{}/{}/{}", DIR, kind, file);
utils::test_cases!(
unit: [
"anonymous-component.toml",
"imported-component.toml",
"stdin.toml",
"file-reader.toml",
"file-reader-lockdown-fail.toml",
"file-reader-lockdown-pass.toml",
"file-reader-lockdown-pass-wildcard-dir.toml",
"file-reader-lockdown-pass-wildcard-components.toml",

trycmd::TestCases::new().case(file);
}

mod integration_test {
use super::DIR;
#[rstest::rstest]
#[case("postgres.toml")]
fn wick_run(#[case] file: &'static str) {
let kind = "integration";
let file = format!("tests/{}/{}/{}", DIR, kind, file);
trycmd::TestCases::new().case(file);
}
}
],
integration: [
"postgres.toml"
]
);
2 changes: 1 addition & 1 deletion tests/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use utils::*;
use wick_packet::Packet;

#[test_logger::test(tokio::test)]
async fn test_wick_serve() -> utils::TestResult<()> {
async fn test_wick_serve() -> anyhow::Result<()> {
debug!("Starting collection");
let (p_tx, p_handle, port) = start_collection(
"wick",
Expand Down
27 changes: 8 additions & 19 deletions tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
static DIR: &str = "test";
mod utils;

#[rstest::rstest]
#[case("wasm.toml")]
fn wick_run(#[case] file: &'static str) {
let kind = "unit";
let file = format!("tests/{}/{}/{}", DIR, kind, file);

trycmd::TestCases::new().case(file);
}

// mod integration_test {
// use super::DIR;
// #[rstest::rstest]
// fn wick_run(#[case] file: &'static str) {
// let kind = "integration";
// let file = format!("tests/{}/{}/{}", kind, DIR, file);
// trycmd::TestCases::new().case(file);
// }
// }
utils::test_cases!(
unit: [
"wasm.toml"
],
integration: [
]
);
Loading

0 comments on commit d89a6f4

Please sign in to comment.