Skip to content

Rename executable #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories = ["command-line-utilities", "parsing"]

[[bin]]
doc = false
name = "yq"
name = "whyq"
path = "yq.rs"

[dependencies]
Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# whyq - low overhead yq implementation
[![CI](https://github.com/clux/yq/actions/workflows/release.yml/badge.svg)](https://github.com/clux/yq/actions/workflows/release.yml)
[![CI](https://github.com/clux/whyq/actions/workflows/release.yml/badge.svg)](https://github.com/clux/whyq/actions/workflows/release.yml)
[![Crates.io](https://img.shields.io/crates/v/whyq.svg)](https://crates.io/crates/whyq)
[![dependency status](https://deps.rs/repo/github/clux/whyq/status.svg)](https://deps.rs/repo/github/clux/whyq)

Expand Down Expand Up @@ -36,7 +36,7 @@ cargo binstall whyq
- reads __multidoc yaml__ input, handles [yaml merge keys](https://yaml.org/type/merge.html) (expanding tags)
- reads from __stdin xor file__ (file if last arg is a file)
- output conversion shortcuts: `-y` (YAML) or `-t` (TOML)
- drop-in replacement to [python-yq](https://kislyuk.github.io/yq/) (`provides: yq`)
- drop-in replacement to [python-yq](https://kislyuk.github.io/yq/) (with `alias yq=whyq`)
- ~[1MB](https://github.com/clux/whyq/releases/latest) in binary size (for small cloud CI images / [binstalled ci actions](https://github.com/cargo-bins/cargo-binstall#faq))

### Limitations
Expand All @@ -48,15 +48,16 @@ cargo binstall whyq
- No XML/CSV support (or other more exotic formats)

## Usage

### YAML Input

Use as [jq](https://jqlang.github.io/jq/tutorial/) either via stdin:

```sh
$ yq '.[3].kind' -r < test/deploy.yaml
$ whyq '.[3].kind' -r < test/deploy.yaml
Service

$ yq -y '.[3].metadata' < test/deploy.yaml
$ whyq -y '.[3].metadata' < test/deploy.yaml
labels:
app: controller
name: controller
Expand All @@ -66,15 +67,17 @@ namespace: default
or from a file arg (at the end):

```sh
$ yq '.[3].kind' -r test/deploy.yaml
$ yq -y '.[3].metadata' test/deploy.yaml
$ whyq '.[3].kind' -r test/deploy.yaml
$ whyq -y '.[3].metadata' test/deploy.yaml
```

The default input format is YAML and is what the binary is named for (and the most common primary usage case).

If you want to use it as the top level `yq` executable you can `alias yq=whyq`. This should be compatible with `python-yq`, but have some differences with the go yq.

### TOML Input

Using say `Cargo.toml` from this repo as input, and aliasing `tq='yq --input=toml'`:
Using say `Cargo.toml` from this repo as input, and aliasing `tq='whyq --input=toml'`:

```sh
$ tq '.package.categories[]' -r < Cargo.toml
Expand All @@ -96,14 +99,14 @@ $ tq '.profile' -c < Cargo.toml
{"release":{"lto":true,"panic":"abort","strip":"symbols"}}
```

Add `alias tq='yq --input=toml'` to your `.bashrc` or `.zshrc` (etc) to make this permanent if you find it useful.
Add `alias tq='whyq --input=toml'` to your `.bashrc` or `.zshrc` (etc) to make this permanent if you find it useful.

### JSON Input

If you need to convert json to another format you pass `--input=json`:

```sh
$ yq --input=json '.ingredients | keys' -y < test/guacamole.json
$ whyq --input=json '.ingredients | keys' -y < test/guacamole.json
- avocado
- coriander
- cumin
Expand All @@ -119,7 +122,7 @@ $ yq --input=json '.ingredients | keys' -y < test/guacamole.json
Select with nested query and raw output:

```sh
$ yq '.spec.template.spec.containers[].image' -r < test/grafana.yaml
$ whyq '.spec.template.spec.containers[].image' -r < test/grafana.yaml
quay.io/kiwigrid/k8s-sidecar:1.24.6
quay.io/kiwigrid/k8s-sidecar:1.24.6
docker.io/grafana/grafana:10.1.0
Expand All @@ -128,20 +131,20 @@ docker.io/grafana/grafana:10.1.0
Select on multidoc:

```sh
$ yq -y '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].ports[0].containerPort' test/deploy.yaml
$ whyq -y '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].ports[0].containerPort' test/deploy.yaml
8000
```

Escaping keys with slashes etc in them:

```sh
yq -y '.updates[] | select(.["package-ecosystem"] == "cargo") | .groups' .github/dependabot.yml
whyq -y '.updates[] | select(.["package-ecosystem"] == "cargo") | .groups' .github/dependabot.yml
```

Using helpers from `jq` [modules](https://jqlang.github.io/jq/manual/#modules) e.g. [k.jq](https://github.com/clux/whyq/blob/main/test/modules/k.jq):

```sh
$ yq 'include "k"; .[] | gvk' -r -L$PWD/test/modules < test/deploy.yaml
$ whyq 'include "k"; .[] | gvk' -r -L$PWD/test/modules < test/deploy.yaml
v1.ServiceAccount
rbac.authorization.k8s.io/v1.ClusterRole
rbac.authorization.k8s.io/v1.ClusterRoleBinding
Expand All @@ -159,7 +162,7 @@ If you pass on `-r`,`-c` or `-c` for raw/compact output, then this will generall
The project respects `RUST_LOG` when set, and sends these diagnostic logs to stderr:

```sh
$ RUST_LOG=debug yq '.version' test/circle.yml
$ RUST_LOG=debug whyq '.version' test/circle.yml
2023-09-18T23:17:04.533055Z DEBUG yq: args: Args { input: Yaml, output: Jq, yaml_output: false, toml_output: false, in_place: false, jq_query: ".version", file: Some("test/circle.yml"), compact_output: false, raw_output: false, join_output: false, modules: None }
2023-09-18T23:17:04.533531Z DEBUG yq: found 1 documents
2023-09-18T23:17:04.533563Z DEBUG yq: input decoded as json: {"definitions":{"filters":{"on_every_commit":{"tags":{"only":"/.*/"}},"on_tag":{"branches":{"ignore":"/.*/"},"tags":{"only":"/v[0-9]+(\\.[0-9]+)*/"}}},"steps":[{"step":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"step":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}}]},"jobs":{"build":{"docker":[{"image":"clux/muslrust:stable"}],"environment":{"IMAGE_NAME":"whyq"},"resource_class":"xlarge","steps":["checkout",{"run":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}},{"run":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"run":"echo versions"}]},"release":{"docker":[{"image":"clux/muslrust:stable"}],"resource_class":"xlarge","steps":["checkout",{"run":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}},{"run":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"upload":{"arch":"x86_64-unknown-linux-musl","binary_name":"${IMAGE_NAME}","source":"target/x86_64-unknown-linux-musl/release/${IMAGE_NAME}","version":"${CIRCLE_TAG}"}}]}},"version":2.1,"workflows":{"my_flow":{"jobs":[{"build":{"filters":{"tags":{"only":"/.*/"}}}},{"release":{"filters":{"branches":{"ignore":"/.*/"},"tags":{"only":"/v[0-9]+(\\.[0-9]+)*/"}}}}]},"version":2}}
Expand Down
54 changes: 27 additions & 27 deletions test/yq.test.bats
Original file line number Diff line number Diff line change
@@ -1,107 +1,107 @@
#!/usr/bin/env bats

@test "stdin" {
run yq -y '.[2].kind' < test/deploy.yaml
run whyq -y '.[2].kind' < test/deploy.yaml
echo "$output" && echo "$output" | grep "ClusterRoleBinding"
}

@test "file" {
if [[ "${CI}" =~ "true" ]]; then
skip # isTerminal seems to do the wrong thing on github actions..
fi
yq -y '.[2].kind' test/deploy.yaml
run yq -y '.[2].kind' test/deploy.yaml
whyq -y '.[2].kind' test/deploy.yaml
run whyq -y '.[2].kind' test/deploy.yaml
echo "$output" && echo "$output" | grep "ClusterRoleBinding"
}

@test "compact_json_output" {
run yq '.[2].metadata' -c < test/deploy.yaml
run whyq '.[2].metadata' -c < test/deploy.yaml
echo "$output" && echo "$output" | grep '{"name":"controller"}'
}

@test "nested_select" {
run yq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].ports[0].containerPort' -r < test/deploy.yaml
run whyq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].ports[0].containerPort' -r < test/deploy.yaml
echo "$output" && echo "$output" | grep "8000"
}

@test "nested_select_json" {
run yq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].readinessProbe' -c < test/deploy.yaml
run whyq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].readinessProbe' -c < test/deploy.yaml
echo "$output" && echo "$output" | grep '{"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":5,"periodSeconds":5}'

run yq '.spec.template.spec.containers[].image' -r < test/grafana.yaml
run whyq '.spec.template.spec.containers[].image' -r < test/grafana.yaml
}

@test "jq_compat" {
cat test/deploy.yaml | yq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].readinessProbe' -c > test/output.json
cat test/deploy.yaml | whyq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].readinessProbe' -c > test/output.json
run jq ".httpGet.path" test/output.json
echo "$output" && echo "$output" | grep '"/health"'
rm test/output.json
}

@test "yq_in_place_edit" {
cat test/secret.yaml | yq -i '.metadata.name="updated-name"' > test/output.yaml
cat test/output.yaml | yq '.metadata.name' | grep 'updated-name'
@test "whyq_in_place_edit" {
cat test/secret.yaml | whyq -i '.metadata.name="updated-name"' > test/output.yaml
cat test/output.yaml | whyq '.metadata.name' | grep 'updated-name'
rm test/output.yaml
}

@test "exit_codes" {
run yq -h
run whyq -h
[ "$status" -eq 0 ]
run yq --help
run whyq --help
[ "$status" -eq 0 ]
if [[ "${CI}" =~ "true" ]]; then
skip # ci is fun
fi
run yq
run whyq
[ "$status" -eq 1 ]
}

@test "toml" {
run yq --input=toml -y '.package.edition' -r < Cargo.toml
run whyq --input=toml -y '.package.edition' -r < Cargo.toml
echo "$output" && echo "$output" | grep '2021'

run yq --input=toml '.dependencies.clap.features' -c < Cargo.toml
run whyq --input=toml '.dependencies.clap.features' -c < Cargo.toml
echo "$output" && echo "$output" | grep '["cargo","derive"]'
}

@test "yaml_merge" {
run yq '.workflows.my_flow.jobs[0].build' -c < test/circle.yml
run whyq '.workflows.my_flow.jobs[0].build' -c < test/circle.yml
echo "$output" && echo "$output" | grep '{"filters":{"tags":{"only":"/.*/"}}}'

run yq '.jobs.build.steps[1].run.name' -r < test/circle.yml
run whyq '.jobs.build.steps[1].run.name' -r < test/circle.yml
echo "$output" && echo "$output" | grep "Version information"
}

@test "inplace" {
run yq -yi '.kind = "Hahah"' test/grafana.yaml
run yq -r .kind test/grafana.yaml
run whyq -yi '.kind = "Hahah"' test/grafana.yaml
run whyq -r .kind test/grafana.yaml
echo "$output" && echo "$output" | grep "Hahah"
yq -yi '.kind = "Deployment"' test/grafana.yaml # undo
whyq -yi '.kind = "Deployment"' test/grafana.yaml # undo
}

@test "join" {
run yq -j '.spec.template.spec.containers[].image' test/grafana.yaml
run whyq -j '.spec.template.spec.containers[].image' test/grafana.yaml
echo "$output" && echo "$output" | grep "quay.io/kiwigrid/k8s-sidecar:1.24.6quay.io/kiwigrid/k8s-sidecar:1.24.6docker.io/grafana/grafana:10.1.0"
}

@test "json_input" {
run yq --input=json ".ingredients | keys" -c < test/guacamole.json
run whyq --input=json ".ingredients | keys" -c < test/guacamole.json
echo "$output" && echo "$output" | grep '["avocado","coriander","cumin","garlic","lime","onions","pepper","salt","tomatoes"]'
}

@test "jq_modules" {
run yq 'include "k"; . | gvk' -r -L$PWD/test/modules < test/grafana.yaml
run whyq 'include "k"; . | gvk' -r -L$PWD/test/modules < test/grafana.yaml
echo "$output" && echo "$output" | grep 'apps/v1.Deployment'
}

@test "paramless" {
run yq -y <<< '["foo"]'
run whyq -y <<< '["foo"]'
echo "$output" && echo "$output" | grep '\- foo'
run yq <<< '"bar"'
run whyq <<< '"bar"'
echo "$output" && echo "$output" | grep '"bar"'
}

@test "multidoc-jq-output-to-yaml" {
run yq '.[].metadata.labels' -y test/deploy.yaml
run whyq '.[].metadata.labels' -y test/deploy.yaml
echo "$output" && echo "$output" | rg -U '\- null\n- null\n- null\n- app: controller\n- app: controller'
}
Loading