From aed598c736858f231911dcb4ff36661e6ae50aa2 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sun, 22 Nov 2020 13:16:54 +1100 Subject: [PATCH] Fixing docs --- .../doc/{Assign Operator.md => Assign.md} | 32 ++--- pkg/yqlib/doc/Boolean Operators.md | 79 +++++++++++- pkg/yqlib/doc/Collect into Array.md | 7 +- pkg/yqlib/doc/Collect into Object.md | 12 +- ...ments Operator.md => Comment Operators.md} | 17 ++- .../doc/{Delete Operator.md => Delete.md} | 9 +- pkg/yqlib/doc/Document Index Operator.md | 8 +- pkg/yqlib/doc/Document Index.md | 54 ++++++++ .../doc/{Equals Operator.md => Equals.md} | 9 +- .../doc/{Explode Operator.md => Explode.md} | 9 +- pkg/yqlib/doc/File Operators.md | 7 +- pkg/yqlib/doc/Mulitply Operator.md | 121 ------------------ .../doc/{Multiply Operator.md => Multiply.md} | 26 ++-- pkg/yqlib/doc/Not Operator.md | 72 ----------- pkg/yqlib/doc/{Path Operator.md => Path.md} | 9 +- ...scent Operator.md => Recursive Descent.md} | 94 +++----------- .../doc/{Select Operator.md => Select.md} | 5 +- pkg/yqlib/doc/{Style Operator.md => Style.md} | 28 ++-- pkg/yqlib/doc/{Tag Operator.md => Tag.md} | 7 +- .../doc/{Traverse Operator.md => Traverse.md} | 51 +++++--- pkg/yqlib/doc/{Union Operator.md => Union.md} | 5 +- .../headers/{Assign Operator.md => Assign.md} | 0 pkg/yqlib/doc/headers/Boolean Operators.md | 2 +- ...ments Operator.md => Comment Operators.md} | 0 .../headers/{Delete Operator.md => Delete.md} | 0 pkg/yqlib/doc/headers/Document Index.md | 1 + .../headers/{Equals Operator.md => Equals.md} | 2 - .../{Explode Operator.md => Explode.md} | 0 pkg/yqlib/doc/headers/File Operators.md | 2 + .../{Multiply Operator.md => Multiply.md} | 9 +- pkg/yqlib/doc/headers/Not Operator.md | 1 - pkg/yqlib/doc/headers/Path Operator.md | 1 - pkg/yqlib/doc/headers/Path.md | 1 + ...scent Operator.md => Recursive Descent.md} | 0 .../headers/{Select Operator.md => Select.md} | 0 .../headers/{Style Operator.md => Style.md} | 0 pkg/yqlib/doc/headers/Tag Operator.md | 1 - pkg/yqlib/doc/headers/Tag.md | 1 + pkg/yqlib/doc/headers/Traverse Operator.md | 1 - pkg/yqlib/doc/headers/Traverse.md | 1 + .../headers/{Union Operator.md => Union.md} | 0 pkg/yqlib/operator_assign_test.go | 16 ++- pkg/yqlib/operator_booleans.go | 17 +++ pkg/yqlib/operator_booleans_test.go | 50 ++++++++ pkg/yqlib/operator_collect_object.go | 6 +- pkg/yqlib/operator_collect_object_test.go | 4 +- pkg/yqlib/operator_comments_test.go | 2 +- pkg/yqlib/operator_delete_test.go | 2 +- ...operator.go => operator_document_index.go} | 0 ...est.go => operator_document_index_test.go} | 2 +- pkg/yqlib/operator_equals_test.go | 2 +- pkg/yqlib/operator_explode_test.go | 2 +- ...rator_multilpy.go => operator_multiply.go} | 0 pkg/yqlib/operator_multiply_test.go | 2 +- pkg/yqlib/operator_not.go | 20 --- pkg/yqlib/operator_not_test.go | 65 ---------- pkg/yqlib/operator_path_test.go | 2 +- pkg/yqlib/operator_recursive_descent_test.go | 34 ++--- pkg/yqlib/operator_select_test.go | 2 +- pkg/yqlib/operator_style_test.go | 16 ++- pkg/yqlib/operator_tag_test.go | 2 +- pkg/yqlib/operator_traverse_path_test.go | 11 +- pkg/yqlib/operator_union_test.go | 2 +- pkg/yqlib/operators_test.go | 14 +- 64 files changed, 414 insertions(+), 543 deletions(-) rename pkg/yqlib/doc/{Assign Operator.md => Assign.md} (84%) rename pkg/yqlib/doc/{Comments Operator.md => Comment Operators.md} (85%) rename pkg/yqlib/doc/{Delete Operator.md => Delete.md} (84%) create mode 100644 pkg/yqlib/doc/Document Index.md rename pkg/yqlib/doc/{Equals Operator.md => Equals.md} (88%) rename pkg/yqlib/doc/{Explode Operator.md => Explode.md} (88%) delete mode 100644 pkg/yqlib/doc/Mulitply Operator.md rename pkg/yqlib/doc/{Multiply Operator.md => Multiply.md} (83%) delete mode 100644 pkg/yqlib/doc/Not Operator.md rename pkg/yqlib/doc/{Path Operator.md => Path.md} (68%) rename pkg/yqlib/doc/{Recursive Descent Operator.md => Recursive Descent.md} (50%) rename pkg/yqlib/doc/{Select Operator.md => Select.md} (83%) rename pkg/yqlib/doc/{Style Operator.md => Style.md} (85%) rename pkg/yqlib/doc/{Tag Operator.md => Tag.md} (77%) rename pkg/yqlib/doc/{Traverse Operator.md => Traverse.md} (82%) rename pkg/yqlib/doc/{Union Operator.md => Union.md} (83%) rename pkg/yqlib/doc/headers/{Assign Operator.md => Assign.md} (100%) rename pkg/yqlib/doc/headers/{Comments Operator.md => Comment Operators.md} (100%) rename pkg/yqlib/doc/headers/{Delete Operator.md => Delete.md} (100%) create mode 100644 pkg/yqlib/doc/headers/Document Index.md rename pkg/yqlib/doc/headers/{Equals Operator.md => Equals.md} (92%) rename pkg/yqlib/doc/headers/{Explode Operator.md => Explode.md} (100%) rename pkg/yqlib/doc/headers/{Multiply Operator.md => Multiply.md} (69%) delete mode 100644 pkg/yqlib/doc/headers/Not Operator.md delete mode 100644 pkg/yqlib/doc/headers/Path Operator.md create mode 100644 pkg/yqlib/doc/headers/Path.md rename pkg/yqlib/doc/headers/{Recursive Descent Operator.md => Recursive Descent.md} (100%) rename pkg/yqlib/doc/headers/{Select Operator.md => Select.md} (100%) rename pkg/yqlib/doc/headers/{Style Operator.md => Style.md} (100%) delete mode 100644 pkg/yqlib/doc/headers/Tag Operator.md create mode 100644 pkg/yqlib/doc/headers/Tag.md delete mode 100644 pkg/yqlib/doc/headers/Traverse Operator.md create mode 100644 pkg/yqlib/doc/headers/Traverse.md rename pkg/yqlib/doc/headers/{Union Operator.md => Union.md} (100%) rename pkg/yqlib/{document_index_operator.go => operator_document_index.go} (100%) rename pkg/yqlib/{document_index_operator_test.go => operator_document_index_test.go} (92%) rename pkg/yqlib/{operator_multilpy.go => operator_multiply.go} (100%) delete mode 100644 pkg/yqlib/operator_not.go delete mode 100644 pkg/yqlib/operator_not_test.go diff --git a/pkg/yqlib/doc/Assign Operator.md b/pkg/yqlib/doc/Assign.md similarity index 84% rename from pkg/yqlib/doc/Assign Operator.md rename to pkg/yqlib/doc/Assign.md index f5b893ba..a783587d 100644 --- a/pkg/yqlib/doc/Assign Operator.md +++ b/pkg/yqlib/doc/Assign.md @@ -5,8 +5,7 @@ Which will assign the LHS node values to the RHS node values. The RHS expression ### relative form: `|=` This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment. -## Examples -### Update node to be the child value +## Update node to be the child value Given a sample.yml file of: ```yaml a: @@ -23,7 +22,7 @@ a: g: foof ``` -### Update node to be the sibling value +## Update node to be the sibling value Given a sample.yml file of: ```yaml a: @@ -40,7 +39,7 @@ a: sibling b: sibling ``` -### Updated multiple paths +## Updated multiple paths Given a sample.yml file of: ```yaml a: fieldA @@ -58,7 +57,7 @@ b: fieldB c: potatoe ``` -### Update string value +## Update string value Given a sample.yml file of: ```yaml a: @@ -74,7 +73,7 @@ a: b: frog ``` -### Update string value via |= +## Update string value via |= Note there is no difference between `=` and `|=` when the RHS is a scalar Given a sample.yml file of: @@ -92,7 +91,7 @@ a: b: frog ``` -### Update selected results +## Update selected results Given a sample.yml file of: ```yaml a: @@ -110,7 +109,7 @@ a: c: cactus ``` -### Update array values +## Update array values Given a sample.yml file of: ```yaml - candy @@ -128,10 +127,10 @@ will output - bogs ``` -### Update empty object +## Update empty object Given a sample.yml file of: ```yaml -'': null +{} ``` then ```bash @@ -139,15 +138,13 @@ yq eval '.a.b |= "bogs"' sample.yml ``` will output ```yaml -'': null -a: - b: bogs +{a: {b: bogs}} ``` -### Update empty object and array +## Update empty object and array Given a sample.yml file of: ```yaml -'': null +{} ``` then ```bash @@ -155,9 +152,6 @@ yq eval '.a.b[0] |= "bogs"' sample.yml ``` will output ```yaml -'': null -a: - b: - - bogs +{a: {b: [bogs]}} ``` diff --git a/pkg/yqlib/doc/Boolean Operators.md b/pkg/yqlib/doc/Boolean Operators.md index 0b8a5e5d..7955937c 100644 --- a/pkg/yqlib/doc/Boolean Operators.md +++ b/pkg/yqlib/doc/Boolean Operators.md @@ -1,6 +1,5 @@ -The `or` and `and` operators take two parameters and return a boolean result. These are most commonly used with the `select` operator to filter particular nodes. -## Examples -### OR example +The `or` and `and` operators take two parameters and return a boolean result. `not` flips a boolean from true to false, or vice versa. These are most commonly used with the `select` operator to filter particular nodes. +## OR example Running ```bash yq eval --null-input 'true or false' @@ -10,7 +9,7 @@ will output true ``` -### AND example +## AND example Running ```bash yq eval --null-input 'true and false' @@ -20,7 +19,7 @@ will output false ``` -### Matching nodes with select, equals and or +## Matching nodes with select, equals and or Given a sample.yml file of: ```yaml - a: bird @@ -42,3 +41,73 @@ will output b: fly ``` +## Not true is false +Running +```bash +yq eval --null-input 'true | not' +``` +will output +```yaml +false +``` + +## Not false is true +Running +```bash +yq eval --null-input 'false | not' +``` +will output +```yaml +true +``` + +## String values considered to be true +Running +```bash +yq eval --null-input '"cat" | not' +``` +will output +```yaml +false +``` + +## Empty string value considered to be true +Running +```bash +yq eval --null-input '"" | not' +``` +will output +```yaml +false +``` + +## Numbers are considered to be true +Running +```bash +yq eval --null-input '1 | not' +``` +will output +```yaml +false +``` + +## Zero is considered to be true +Running +```bash +yq eval --null-input '0 | not' +``` +will output +```yaml +false +``` + +## Null is considered to be false +Running +```bash +yq eval --null-input '~ | not' +``` +will output +```yaml +true +``` + diff --git a/pkg/yqlib/doc/Collect into Array.md b/pkg/yqlib/doc/Collect into Array.md index fa8e25a8..d06927e6 100644 --- a/pkg/yqlib/doc/Collect into Array.md +++ b/pkg/yqlib/doc/Collect into Array.md @@ -3,8 +3,7 @@ This creates an array using the expression between the square brackets. -## Examples -### Collect empty +## Collect empty Running ```bash yq eval --null-input '[]' @@ -13,7 +12,7 @@ will output ```yaml ``` -### Collect single +## Collect single Running ```bash yq eval --null-input '["cat"]' @@ -23,7 +22,7 @@ will output - cat ``` -### Collect many +## Collect many Given a sample.yml file of: ```yaml a: cat diff --git a/pkg/yqlib/doc/Collect into Object.md b/pkg/yqlib/doc/Collect into Object.md index c46f5d79..ded3288d 100644 --- a/pkg/yqlib/doc/Collect into Object.md +++ b/pkg/yqlib/doc/Collect into Object.md @@ -1,15 +1,15 @@ This is used to construct objects (or maps). This can be used against existing yaml, or to create fresh yaml documents. -## Examples -### Collect empty object +## Collect empty object Running ```bash yq eval --null-input '{}' ``` will output ```yaml +{} ``` -### Wrap (prefix) existing object +## Wrap (prefix) existing object Given a sample.yml file of: ```yaml name: Mike @@ -24,7 +24,7 @@ wrap: name: Mike ``` -### Using splat to create multiple objects +## Using splat to create multiple objects Given a sample.yml file of: ```yaml name: Mike @@ -42,7 +42,7 @@ Mike: cat Mike: dog ``` -### Working with multiple documents +## Working with multiple documents Given a sample.yml file of: ```yaml name: Mike @@ -67,7 +67,7 @@ Rosey: monkey Rosey: sheep ``` -### Creating yaml from scratch +## Creating yaml from scratch Running ```bash yq eval --null-input '{"wrap": "frog"}' diff --git a/pkg/yqlib/doc/Comments Operator.md b/pkg/yqlib/doc/Comment Operators.md similarity index 85% rename from pkg/yqlib/doc/Comments Operator.md rename to pkg/yqlib/doc/Comment Operators.md index ab8b8864..d6d133ca 100644 --- a/pkg/yqlib/doc/Comments Operator.md +++ b/pkg/yqlib/doc/Comment Operators.md @@ -1,6 +1,5 @@ Use these comment operators to set or retrieve comments. -## Examples -### Set line comment +## Set line comment Given a sample.yml file of: ```yaml a: cat @@ -14,7 +13,7 @@ will output a: cat # single ``` -### Set head comment +## Set head comment Given a sample.yml file of: ```yaml a: cat @@ -30,7 +29,7 @@ will output a: cat ``` -### Set foot comment, using an expression +## Set foot comment, using an expression Given a sample.yml file of: ```yaml a: cat @@ -46,7 +45,7 @@ a: cat # cat ``` -### Remove comment +## Remove comment Given a sample.yml file of: ```yaml a: cat # comment @@ -62,7 +61,7 @@ a: cat b: dog # leave this ``` -### Remove all comments +## Remove all comments Given a sample.yml file of: ```yaml a: cat # comment @@ -76,7 +75,7 @@ will output a: cat ``` -### Get line comment +## Get line comment Given a sample.yml file of: ```yaml a: cat # meow @@ -90,7 +89,7 @@ will output meow ``` -### Get head comment +## Get head comment Given a sample.yml file of: ```yaml a: cat # meow @@ -104,7 +103,7 @@ will output ``` -### Get foot comment +## Get foot comment Given a sample.yml file of: ```yaml a: cat # meow diff --git a/pkg/yqlib/doc/Delete Operator.md b/pkg/yqlib/doc/Delete.md similarity index 84% rename from pkg/yqlib/doc/Delete Operator.md rename to pkg/yqlib/doc/Delete.md index 8bcf3533..601bf30a 100644 --- a/pkg/yqlib/doc/Delete Operator.md +++ b/pkg/yqlib/doc/Delete.md @@ -1,6 +1,5 @@ Deletes matching entries in maps or arrays. -## Examples -### Delete entry in map +## Delete entry in map Given a sample.yml file of: ```yaml a: cat @@ -15,7 +14,7 @@ will output a: cat ``` -### Delete entry in array +## Delete entry in array Given a sample.yml file of: ```yaml - 1 @@ -32,7 +31,7 @@ will output - 3 ``` -### Delete no matches +## Delete no matches Given a sample.yml file of: ```yaml a: cat @@ -48,7 +47,7 @@ a: cat b: dog ``` -### Delete matching entries +## Delete matching entries Given a sample.yml file of: ```yaml a: cat diff --git a/pkg/yqlib/doc/Document Index Operator.md b/pkg/yqlib/doc/Document Index Operator.md index 5dd62822..30ba1ec6 100644 --- a/pkg/yqlib/doc/Document Index Operator.md +++ b/pkg/yqlib/doc/Document Index Operator.md @@ -1,6 +1,4 @@ - -## Examples -### Retrieve a document index +## Retrieve a document index Given a sample.yml file of: ```yaml a: cat @@ -18,7 +16,7 @@ will output 1 ``` -### Filter by document index +## Filter by document index Given a sample.yml file of: ```yaml a: cat @@ -34,7 +32,7 @@ will output a: frog ``` -### Print Document Index with matches +## Print Document Index with matches Given a sample.yml file of: ```yaml a: cat diff --git a/pkg/yqlib/doc/Document Index.md b/pkg/yqlib/doc/Document Index.md new file mode 100644 index 00000000..948e50e4 --- /dev/null +++ b/pkg/yqlib/doc/Document Index.md @@ -0,0 +1,54 @@ +Use the `documentIndex` operator to select nodes of a particular document. +## Retrieve a document index +Given a sample.yml file of: +```yaml +a: cat +--- +a: frog +``` +then +```bash +yq eval '.a | documentIndex' sample.yml +``` +will output +```yaml +0 +--- +1 +``` + +## Filter by document index +Given a sample.yml file of: +```yaml +a: cat +--- +a: frog +``` +then +```bash +yq eval 'select(. | documentIndex == 1)' sample.yml +``` +will output +```yaml +a: frog +``` + +## Print Document Index with matches +Given a sample.yml file of: +```yaml +a: cat +--- +a: frog +``` +then +```bash +yq eval '.a | ({"match": ., "doc": (. | documentIndex)})' sample.yml +``` +will output +```yaml +match: cat +doc: 0 +match: frog +doc: 1 +``` + diff --git a/pkg/yqlib/doc/Equals Operator.md b/pkg/yqlib/doc/Equals.md similarity index 88% rename from pkg/yqlib/doc/Equals Operator.md rename to pkg/yqlib/doc/Equals.md index 904b0eea..fda10922 100644 --- a/pkg/yqlib/doc/Equals Operator.md +++ b/pkg/yqlib/doc/Equals.md @@ -1,5 +1,3 @@ -## Equals Operator - This is a boolean operator that will return ```true``` if the LHS is equal to the RHS and ``false`` otherwise. ``` @@ -13,8 +11,7 @@ select(.a == .b) ``` -## Examples -### Match string +## Match string Given a sample.yml file of: ```yaml - cat @@ -32,7 +29,7 @@ true false ``` -### Match number +## Match number Given a sample.yml file of: ```yaml - 3 @@ -50,7 +47,7 @@ true false ``` -### Match nulls +## Match nulls Running ```bash yq eval --null-input 'null == ~' diff --git a/pkg/yqlib/doc/Explode Operator.md b/pkg/yqlib/doc/Explode.md similarity index 88% rename from pkg/yqlib/doc/Explode Operator.md rename to pkg/yqlib/doc/Explode.md index 3ca0e208..379d44a0 100644 --- a/pkg/yqlib/doc/Explode Operator.md +++ b/pkg/yqlib/doc/Explode.md @@ -1,6 +1,5 @@ Explodes (or dereferences) aliases and anchors. -## Examples -### Explode alias and anchor +## Explode alias and anchor Given a sample.yml file of: ```yaml f: @@ -18,7 +17,7 @@ f: b: cat ``` -### Explode with no aliases or anchors +## Explode with no aliases or anchors Given a sample.yml file of: ```yaml a: mike @@ -32,7 +31,7 @@ will output a: mike ``` -### Explode with alias keys +## Explode with alias keys Given a sample.yml file of: ```yaml f: @@ -50,7 +49,7 @@ f: cat: b ``` -### Explode with merge anchors +## Explode with merge anchors Given a sample.yml file of: ```yaml foo: &foo diff --git a/pkg/yqlib/doc/File Operators.md b/pkg/yqlib/doc/File Operators.md index a6edf7ba..946dfee9 100644 --- a/pkg/yqlib/doc/File Operators.md +++ b/pkg/yqlib/doc/File Operators.md @@ -1,10 +1,11 @@ File operators are most often used with merge when needing to merge specific files together. Note that when doing this, you will need to use `eval-all` to ensure all yaml documents are loaded into memory before performing the merge (as opposed to `eval` which runs the expression once per document). +## Merging files +Note the use of eval-all to ensure all documents are loaded into memory. ```bash yq eval-all 'select(fileIndex == 0) * select(filename == "file2.yaml")' file1.yaml file2.yaml ``` -## Examples -### Get filename +## Get filename Given a sample.yml file of: ```yaml a: cat @@ -18,7 +19,7 @@ will output sample.yaml ``` -### Get file index +## Get file index Given a sample.yml file of: ```yaml a: cat diff --git a/pkg/yqlib/doc/Mulitply Operator.md b/pkg/yqlib/doc/Mulitply Operator.md deleted file mode 100644 index 24c00aa2..00000000 --- a/pkg/yqlib/doc/Mulitply Operator.md +++ /dev/null @@ -1,121 +0,0 @@ -# Mulitply Operator -## Examples -### Merge objects together -sample.yml: -```yaml -{a: {also: me}, b: {also: {g: wizz}}} -``` -Expression -```bash -yq '. * {"a":.b}' < sample.yml -``` -Result -```yaml -{a: {also: {g: wizz}}, b: {also: {g: wizz}}} -``` -### Merge keeps style of LHS -sample.yml: -```yaml -a: {things: great} -b: - also: "me" - -``` -Expression -```bash -yq '. * {"a":.b}' < sample.yml -``` -Result -```yaml -a: {things: great, also: "me"} -b: - also: "me" -``` -### Merge arrays -sample.yml: -```yaml -{a: [1,2,3], b: [3,4,5]} -``` -Expression -```bash -yq '. * {"a":.b}' < sample.yml -``` -Result -```yaml -{a: [3, 4, 5], b: [3, 4, 5]} -``` -### Merge to prefix an element -sample.yml: -```yaml -{a: cat, b: dog} -``` -Expression -```bash -yq '. * {"a": {"c": .a}}' < sample.yml -``` -Result -```yaml -{a: {c: cat}, b: dog} -``` -### Merge with simple aliases -sample.yml: -```yaml -{a: &cat {c: frog}, b: {f: *cat}, c: {g: thongs}} -``` -Expression -```bash -yq '.c * .b' < sample.yml -``` -Result -```yaml -{g: thongs, f: *cat} -``` -### Merge does not copy anchor names -sample.yml: -```yaml -{a: {c: &cat frog}, b: {f: *cat}, c: {g: thongs}} -``` -Expression -```bash -yq '.c * .a' < sample.yml -``` -Result -```yaml -{g: thongs, c: frog} -``` -### Merge with merge anchors -sample.yml: -```yaml - -foo: &foo - a: foo_a - thing: foo_thing - c: foo_c - -bar: &bar - b: bar_b - thing: bar_thing - c: bar_c - -foobarList: - b: foobarList_b - <<: [*foo,*bar] - c: foobarList_c - -foobar: - c: foobar_c - <<: *foo - thing: foobar_thing - -``` -Expression -```bash -yq '.foobar * .foobarList' < sample.yml -``` -Result -```yaml -c: foobarList_c -<<: [*foo, *bar] -thing: foobar_thing -b: foobarList_b -``` diff --git a/pkg/yqlib/doc/Multiply Operator.md b/pkg/yqlib/doc/Multiply.md similarity index 83% rename from pkg/yqlib/doc/Multiply Operator.md rename to pkg/yqlib/doc/Multiply.md index c82265e6..9f09fea5 100644 --- a/pkg/yqlib/doc/Multiply Operator.md +++ b/pkg/yqlib/doc/Multiply.md @@ -3,8 +3,15 @@ Like the multiple operator in `jq`, depending on the operands, this multiply ope Upcoming versions of `yq` will add support for other types of multiplication (numbers, strings). Note that when merging objects, this operator returns the merged object (not the parent). This will be clearer in the examples below. -## Examples -### Merge objects together, returning merged result only + +## Merging files +Note the use of eval-all to ensure all documents are loaded into memory. + +```bash +yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' file1.yaml file2.yaml +``` + +## Merge objects together, returning merged result only Given a sample.yml file of: ```yaml a: @@ -27,7 +34,7 @@ fieldA: cat fieldB: dog ``` -### Merge objects together, returning parent object +## Merge objects together, returning parent object Given a sample.yml file of: ```yaml a: @@ -55,12 +62,13 @@ b: fieldB: dog ``` -### Merge keeps style of LHS +## Merge keeps style of LHS Given a sample.yml file of: ```yaml a: {things: great} b: also: "me" + ``` then ```bash @@ -73,7 +81,7 @@ b: also: "me" ``` -### Merge arrays +## Merge arrays Given a sample.yml file of: ```yaml a: @@ -101,7 +109,7 @@ b: - 5 ``` -### Merge to prefix an element +## Merge to prefix an element Given a sample.yml file of: ```yaml a: cat @@ -118,7 +126,7 @@ a: b: dog ``` -### Merge with simple aliases +## Merge with simple aliases Given a sample.yml file of: ```yaml a: &cat @@ -138,7 +146,7 @@ g: thongs f: *cat ``` -### Merge does not copy anchor names +## Merge does not copy anchor names Given a sample.yml file of: ```yaml a: @@ -158,7 +166,7 @@ g: thongs c: frog ``` -### Merge with merge anchors +## Merge with merge anchors Given a sample.yml file of: ```yaml foo: &foo diff --git a/pkg/yqlib/doc/Not Operator.md b/pkg/yqlib/doc/Not Operator.md deleted file mode 100644 index 49d4fd54..00000000 --- a/pkg/yqlib/doc/Not Operator.md +++ /dev/null @@ -1,72 +0,0 @@ -This is a boolean operator and will return `true` when given a `false` value (including null), and `false` otherwise. -## Examples -### Not true is false -Running -```bash -yq eval --null-input 'true | not' -``` -will output -```yaml -false -``` - -### Not false is true -Running -```bash -yq eval --null-input 'false | not' -``` -will output -```yaml -true -``` - -### String values considered to be true -Running -```bash -yq eval --null-input '"cat" | not' -``` -will output -```yaml -false -``` - -### Empty string value considered to be true -Running -```bash -yq eval --null-input '"" | not' -``` -will output -```yaml -false -``` - -### Numbers are considered to be true -Running -```bash -yq eval --null-input '1 | not' -``` -will output -```yaml -false -``` - -### Zero is considered to be true -Running -```bash -yq eval --null-input '0 | not' -``` -will output -```yaml -false -``` - -### Null is considered to be false -Running -```bash -yq eval --null-input '~ | not' -``` -will output -```yaml -true -``` - diff --git a/pkg/yqlib/doc/Path Operator.md b/pkg/yqlib/doc/Path.md similarity index 68% rename from pkg/yqlib/doc/Path Operator.md rename to pkg/yqlib/doc/Path.md index 27ec6988..4acacce0 100644 --- a/pkg/yqlib/doc/Path Operator.md +++ b/pkg/yqlib/doc/Path.md @@ -1,6 +1,5 @@ -The path operator can be used to find the traversal paths of matching nodes in an expression. The path is returned as an array, which if traversed in order will lead to the matching node. -## Examples -### Map path +The path operator can be used to get the traversal paths of matching nodes in an expression. The path is returned as an array, which if traversed in order will lead to the matching node. +## Map path Given a sample.yml file of: ```yaml a: @@ -16,7 +15,7 @@ will output - b ``` -### Array path +## Array path Given a sample.yml file of: ```yaml a: @@ -33,7 +32,7 @@ will output - 1 ``` -### Print path and value +## Print path and value Given a sample.yml file of: ```yaml a: diff --git a/pkg/yqlib/doc/Recursive Descent Operator.md b/pkg/yqlib/doc/Recursive Descent.md similarity index 50% rename from pkg/yqlib/doc/Recursive Descent Operator.md rename to pkg/yqlib/doc/Recursive Descent.md index 9eec8436..3a3390e3 100644 --- a/pkg/yqlib/doc/Recursive Descent Operator.md +++ b/pkg/yqlib/doc/Recursive Descent.md @@ -3,69 +3,7 @@ This operator recursively matches all children nodes given of a particular eleme ```bash yq eval '.. style= "flow"' file.yaml ``` -## Examples -### Map -Given a sample.yml file of: -```yaml -a: - b: apple -``` -then -```bash -yq eval '..' sample.yml -``` -will output -```yaml -a: - b: apple -b: apple -apple -``` - -### Array -Given a sample.yml file of: -```yaml -- 1 -- 2 -- 3 -``` -then -```bash -yq eval '..' sample.yml -``` -will output -```yaml -- 1 -- 2 -- 3 -1 -2 -3 -``` - -### Array of maps -Given a sample.yml file of: -```yaml -- a: cat -- 2 -- true -``` -then -```bash -yq eval '..' sample.yml -``` -will output -```yaml -- a: cat -- 2 -- true -a: cat -cat -2 -true -``` - -### Aliases are not traversed +## Aliases are not traversed Given a sample.yml file of: ```yaml a: &cat @@ -74,20 +12,20 @@ b: *cat ``` then ```bash -yq eval '..' sample.yml +yq eval '[..]' sample.yml ``` will output ```yaml -a: &cat +- a: &cat + c: frog + b: *cat +- &cat c: frog -b: *cat -&cat -c: frog -frog -*cat +- frog +- *cat ``` -### Merge docs are not traversed +## Merge docs are not traversed Given a sample.yml file of: ```yaml foo: &foo @@ -111,15 +49,15 @@ foobar: ``` then ```bash -yq eval '.foobar | ..' sample.yml +yq eval '.foobar | [..]' sample.yml ``` will output ```yaml -c: foobar_c -!!merge <<: *foo -thing: foobar_thing -foobar_c -*foo -foobar_thing +- c: foobar_c + !!merge <<: *foo + thing: foobar_thing +- foobar_c +- *foo +- foobar_thing ``` diff --git a/pkg/yqlib/doc/Select Operator.md b/pkg/yqlib/doc/Select.md similarity index 83% rename from pkg/yqlib/doc/Select Operator.md rename to pkg/yqlib/doc/Select.md index 3ddb6cc9..1726853b 100644 --- a/pkg/yqlib/doc/Select Operator.md +++ b/pkg/yqlib/doc/Select.md @@ -1,6 +1,5 @@ Select is used to filter arrays and maps by a boolean expression. -## Examples -### Select elements from array +## Select elements from array Given a sample.yml file of: ```yaml - cat @@ -17,7 +16,7 @@ cat goat ``` -### Select and update matching values in map +## Select and update matching values in map Given a sample.yml file of: ```yaml a: diff --git a/pkg/yqlib/doc/Style Operator.md b/pkg/yqlib/doc/Style.md similarity index 85% rename from pkg/yqlib/doc/Style Operator.md rename to pkg/yqlib/doc/Style.md index 0c78cbe5..d089aa4d 100644 --- a/pkg/yqlib/doc/Style Operator.md +++ b/pkg/yqlib/doc/Style.md @@ -1,6 +1,5 @@ The style operator can be used to get or set the style of nodes (e.g. string style, yaml style) -## Examples -### Set tagged style +## Set tagged style Given a sample.yml file of: ```yaml a: cat @@ -21,7 +20,7 @@ c: !!float 3.2 e: !!bool true ``` -### Set double quote style +## Set double quote style Given a sample.yml file of: ```yaml a: cat @@ -41,7 +40,7 @@ c: "3.2" e: "true" ``` -### Set single quote style +## Set single quote style Given a sample.yml file of: ```yaml a: cat @@ -61,7 +60,7 @@ c: '3.2' e: 'true' ``` -### Set literal quote style +## Set literal quote style Given a sample.yml file of: ```yaml a: cat @@ -85,7 +84,7 @@ e: |- true ``` -### Set folded quote style +## Set folded quote style Given a sample.yml file of: ```yaml a: cat @@ -109,7 +108,7 @@ e: >- true ``` -### Set flow quote style +## Set flow quote style Given a sample.yml file of: ```yaml a: cat @@ -126,7 +125,9 @@ will output {a: cat, b: 5, c: 3.2, e: true} ``` -### Set empty (default) quote style +## Pretty print +Set empty (default) quote style + Given a sample.yml file of: ```yaml a: cat @@ -146,11 +147,10 @@ c: 3.2 e: true ``` -### Read style +## Read style Given a sample.yml file of: ```yaml -a: cat -b: thing +{a: "cat", b: 'thing'} ``` then ```bash @@ -158,8 +158,8 @@ yq eval '.. | style' sample.yml ``` will output ```yaml - - - +flow +double +single ``` diff --git a/pkg/yqlib/doc/Tag Operator.md b/pkg/yqlib/doc/Tag.md similarity index 77% rename from pkg/yqlib/doc/Tag Operator.md rename to pkg/yqlib/doc/Tag.md index 863a2368..519142fd 100644 --- a/pkg/yqlib/doc/Tag Operator.md +++ b/pkg/yqlib/doc/Tag.md @@ -1,6 +1,5 @@ -The tag operator can be used to get or set the tag of ndoes (e.g. `!!str`, `!!int`, `!!bool`). -## Examples -### Get tag +The tag operator can be used to get or set the tag of nodes (e.g. `!!str`, `!!int`, `!!bool`). +## Get tag Given a sample.yml file of: ```yaml a: cat @@ -23,7 +22,7 @@ will output !!seq ``` -### Convert numbers to strings +## Convert numbers to strings Given a sample.yml file of: ```yaml a: cat diff --git a/pkg/yqlib/doc/Traverse Operator.md b/pkg/yqlib/doc/Traverse.md similarity index 82% rename from pkg/yqlib/doc/Traverse Operator.md rename to pkg/yqlib/doc/Traverse.md index dace7ed4..88ccdb10 100644 --- a/pkg/yqlib/doc/Traverse Operator.md +++ b/pkg/yqlib/doc/Traverse.md @@ -1,6 +1,5 @@ -This is the simples (and perhaps most used) operator, it is used to navigate deeply into yaml structurse. -## Examples -### Simple map navigation +This is the simplest (and perhaps most used) operator, it is used to navigate deeply into yaml structurse. +## Simple map navigation Given a sample.yml file of: ```yaml a: @@ -15,7 +14,7 @@ will output b: apple ``` -### Splat +## Splat Often used to pipe children into other operators Given a sample.yml file of: @@ -33,7 +32,23 @@ b: apple c: banana ``` -### Children don't exist +## Special characters +Use quotes around path elements with special characters + +Given a sample.yml file of: +```yaml +"{}": frog +``` +then +```bash +yq eval '."{}"' sample.yml +``` +will output +```yaml +frog +``` + +## Children don't exist Nodes are added dynamically while traversing Given a sample.yml file of: @@ -49,7 +64,7 @@ will output null ``` -### Wildcard matching +## Wildcard matching Given a sample.yml file of: ```yaml a: @@ -66,7 +81,7 @@ apple things ``` -### Aliases +## Aliases Given a sample.yml file of: ```yaml a: &cat @@ -82,7 +97,7 @@ will output *cat ``` -### Traversing aliases with splat +## Traversing aliases with splat Given a sample.yml file of: ```yaml a: &cat @@ -98,7 +113,7 @@ will output frog ``` -### Traversing aliases explicitly +## Traversing aliases explicitly Given a sample.yml file of: ```yaml a: &cat @@ -114,7 +129,7 @@ will output frog ``` -### Traversing arrays by index +## Traversing arrays by index Given a sample.yml file of: ```yaml - 1 @@ -130,7 +145,7 @@ will output 1 ``` -### Maps with numeric keys +## Maps with numeric keys Given a sample.yml file of: ```yaml 2: cat @@ -144,7 +159,7 @@ will output cat ``` -### Maps with non existing numeric keys +## Maps with non existing numeric keys Given a sample.yml file of: ```yaml a: b @@ -158,7 +173,7 @@ will output null ``` -### Traversing merge anchors +## Traversing merge anchors Given a sample.yml file of: ```yaml foo: &foo @@ -189,7 +204,7 @@ will output foo_a ``` -### Traversing merge anchors with override +## Traversing merge anchors with override Given a sample.yml file of: ```yaml foo: &foo @@ -220,7 +235,7 @@ will output foo_c ``` -### Traversing merge anchors with local override +## Traversing merge anchors with local override Given a sample.yml file of: ```yaml foo: &foo @@ -251,7 +266,7 @@ will output foobar_thing ``` -### Splatting merge anchors +## Splatting merge anchors Given a sample.yml file of: ```yaml foo: &foo @@ -284,7 +299,7 @@ foo_a foobar_thing ``` -### Traversing merge anchor lists +## Traversing merge anchor lists Note that the later merge anchors override previous Given a sample.yml file of: @@ -317,7 +332,7 @@ will output bar_thing ``` -### Splatting merge anchor lists +## Splatting merge anchor lists Given a sample.yml file of: ```yaml foo: &foo diff --git a/pkg/yqlib/doc/Union Operator.md b/pkg/yqlib/doc/Union.md similarity index 83% rename from pkg/yqlib/doc/Union Operator.md rename to pkg/yqlib/doc/Union.md index e8975de3..e01782fe 100644 --- a/pkg/yqlib/doc/Union Operator.md +++ b/pkg/yqlib/doc/Union.md @@ -1,6 +1,5 @@ This operator is used to combine different results together. -## Examples -### Combine scalars +## Combine scalars Running ```bash yq eval --null-input '1, true, "cat"' @@ -12,7 +11,7 @@ true cat ``` -### Combine selected paths +## Combine selected paths Given a sample.yml file of: ```yaml a: fieldA diff --git a/pkg/yqlib/doc/headers/Assign Operator.md b/pkg/yqlib/doc/headers/Assign.md similarity index 100% rename from pkg/yqlib/doc/headers/Assign Operator.md rename to pkg/yqlib/doc/headers/Assign.md diff --git a/pkg/yqlib/doc/headers/Boolean Operators.md b/pkg/yqlib/doc/headers/Boolean Operators.md index 15be7b7f..69c46bda 100644 --- a/pkg/yqlib/doc/headers/Boolean Operators.md +++ b/pkg/yqlib/doc/headers/Boolean Operators.md @@ -1 +1 @@ -The `or` and `and` operators take two parameters and return a boolean result. These are most commonly used with the `select` operator to filter particular nodes. \ No newline at end of file +The `or` and `and` operators take two parameters and return a boolean result. `not` flips a boolean from true to false, or vice versa. These are most commonly used with the `select` operator to filter particular nodes. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Comments Operator.md b/pkg/yqlib/doc/headers/Comment Operators.md similarity index 100% rename from pkg/yqlib/doc/headers/Comments Operator.md rename to pkg/yqlib/doc/headers/Comment Operators.md diff --git a/pkg/yqlib/doc/headers/Delete Operator.md b/pkg/yqlib/doc/headers/Delete.md similarity index 100% rename from pkg/yqlib/doc/headers/Delete Operator.md rename to pkg/yqlib/doc/headers/Delete.md diff --git a/pkg/yqlib/doc/headers/Document Index.md b/pkg/yqlib/doc/headers/Document Index.md new file mode 100644 index 00000000..4430ab14 --- /dev/null +++ b/pkg/yqlib/doc/headers/Document Index.md @@ -0,0 +1 @@ +Use the `documentIndex` operator to select nodes of a particular document. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Equals Operator.md b/pkg/yqlib/doc/headers/Equals.md similarity index 92% rename from pkg/yqlib/doc/headers/Equals Operator.md rename to pkg/yqlib/doc/headers/Equals.md index a60d8dfa..5e68bc50 100644 --- a/pkg/yqlib/doc/headers/Equals Operator.md +++ b/pkg/yqlib/doc/headers/Equals.md @@ -1,5 +1,3 @@ -## Equals Operator - This is a boolean operator that will return ```true``` if the LHS is equal to the RHS and ``false`` otherwise. ``` diff --git a/pkg/yqlib/doc/headers/Explode Operator.md b/pkg/yqlib/doc/headers/Explode.md similarity index 100% rename from pkg/yqlib/doc/headers/Explode Operator.md rename to pkg/yqlib/doc/headers/Explode.md diff --git a/pkg/yqlib/doc/headers/File Operators.md b/pkg/yqlib/doc/headers/File Operators.md index 2efc91d8..394a0bc4 100644 --- a/pkg/yqlib/doc/headers/File Operators.md +++ b/pkg/yqlib/doc/headers/File Operators.md @@ -1,5 +1,7 @@ File operators are most often used with merge when needing to merge specific files together. Note that when doing this, you will need to use `eval-all` to ensure all yaml documents are loaded into memory before performing the merge (as opposed to `eval` which runs the expression once per document). +## Merging files +Note the use of eval-all to ensure all documents are loaded into memory. ```bash yq eval-all 'select(fileIndex == 0) * select(filename == "file2.yaml")' file1.yaml file2.yaml ``` \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Multiply Operator.md b/pkg/yqlib/doc/headers/Multiply.md similarity index 69% rename from pkg/yqlib/doc/headers/Multiply Operator.md rename to pkg/yqlib/doc/headers/Multiply.md index 3597af37..62c73302 100644 --- a/pkg/yqlib/doc/headers/Multiply Operator.md +++ b/pkg/yqlib/doc/headers/Multiply.md @@ -2,4 +2,11 @@ Like the multiple operator in `jq`, depending on the operands, this multiply ope Upcoming versions of `yq` will add support for other types of multiplication (numbers, strings). -Note that when merging objects, this operator returns the merged object (not the parent). This will be clearer in the examples below. \ No newline at end of file +Note that when merging objects, this operator returns the merged object (not the parent). This will be clearer in the examples below. + +## Merging files +Note the use of eval-all to ensure all documents are loaded into memory. + +```bash +yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' file1.yaml file2.yaml +``` diff --git a/pkg/yqlib/doc/headers/Not Operator.md b/pkg/yqlib/doc/headers/Not Operator.md deleted file mode 100644 index 87022061..00000000 --- a/pkg/yqlib/doc/headers/Not Operator.md +++ /dev/null @@ -1 +0,0 @@ -This is a boolean operator and will return `true` when given a `false` value (including null), and `false` otherwise. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Path Operator.md b/pkg/yqlib/doc/headers/Path Operator.md deleted file mode 100644 index a731d40e..00000000 --- a/pkg/yqlib/doc/headers/Path Operator.md +++ /dev/null @@ -1 +0,0 @@ -The path operator can be used to find the traversal paths of matching nodes in an expression. The path is returned as an array, which if traversed in order will lead to the matching node. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Path.md b/pkg/yqlib/doc/headers/Path.md new file mode 100644 index 00000000..fdb4ec0b --- /dev/null +++ b/pkg/yqlib/doc/headers/Path.md @@ -0,0 +1 @@ +The path operator can be used to get the traversal paths of matching nodes in an expression. The path is returned as an array, which if traversed in order will lead to the matching node. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Recursive Descent Operator.md b/pkg/yqlib/doc/headers/Recursive Descent.md similarity index 100% rename from pkg/yqlib/doc/headers/Recursive Descent Operator.md rename to pkg/yqlib/doc/headers/Recursive Descent.md diff --git a/pkg/yqlib/doc/headers/Select Operator.md b/pkg/yqlib/doc/headers/Select.md similarity index 100% rename from pkg/yqlib/doc/headers/Select Operator.md rename to pkg/yqlib/doc/headers/Select.md diff --git a/pkg/yqlib/doc/headers/Style Operator.md b/pkg/yqlib/doc/headers/Style.md similarity index 100% rename from pkg/yqlib/doc/headers/Style Operator.md rename to pkg/yqlib/doc/headers/Style.md diff --git a/pkg/yqlib/doc/headers/Tag Operator.md b/pkg/yqlib/doc/headers/Tag Operator.md deleted file mode 100644 index 1243de10..00000000 --- a/pkg/yqlib/doc/headers/Tag Operator.md +++ /dev/null @@ -1 +0,0 @@ -The tag operator can be used to get or set the tag of ndoes (e.g. `!!str`, `!!int`, `!!bool`). \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Tag.md b/pkg/yqlib/doc/headers/Tag.md new file mode 100644 index 00000000..0d329fc1 --- /dev/null +++ b/pkg/yqlib/doc/headers/Tag.md @@ -0,0 +1 @@ +The tag operator can be used to get or set the tag of nodes (e.g. `!!str`, `!!int`, `!!bool`). \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Traverse Operator.md b/pkg/yqlib/doc/headers/Traverse Operator.md deleted file mode 100644 index ff02606c..00000000 --- a/pkg/yqlib/doc/headers/Traverse Operator.md +++ /dev/null @@ -1 +0,0 @@ -This is the simples (and perhaps most used) operator, it is used to navigate deeply into yaml structurse. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Traverse.md b/pkg/yqlib/doc/headers/Traverse.md new file mode 100644 index 00000000..d69c3078 --- /dev/null +++ b/pkg/yqlib/doc/headers/Traverse.md @@ -0,0 +1 @@ +This is the simplest (and perhaps most used) operator, it is used to navigate deeply into yaml structurse. \ No newline at end of file diff --git a/pkg/yqlib/doc/headers/Union Operator.md b/pkg/yqlib/doc/headers/Union.md similarity index 100% rename from pkg/yqlib/doc/headers/Union Operator.md rename to pkg/yqlib/doc/headers/Union.md diff --git a/pkg/yqlib/operator_assign_test.go b/pkg/yqlib/operator_assign_test.go index c3d50bb4..82e928d9 100644 --- a/pkg/yqlib/operator_assign_test.go +++ b/pkg/yqlib/operator_assign_test.go @@ -87,17 +87,19 @@ var assignOperatorScenarios = []expressionScenario{ }, }, { - description: "Update empty object", - document: `{}`, - expression: `.a.b |= "bogs"`, + description: "Update empty object", + dontFormatInputForDoc: true, + document: `{}`, + expression: `.a.b |= "bogs"`, expected: []string{ "D0, P[], (doc)::{a: {b: bogs}}\n", }, }, { - description: "Update empty object and array", - document: `{}`, - expression: `.a.b[0] |= "bogs"`, + description: "Update empty object and array", + dontFormatInputForDoc: true, + document: `{}`, + expression: `.a.b[0] |= "bogs"`, expected: []string{ "D0, P[], (doc)::{a: {b: [bogs]}}\n", }, @@ -116,5 +118,5 @@ func TestAssignOperatorScenarios(t *testing.T) { for _, tt := range assignOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Assign Operator", assignOperatorScenarios) + documentScenarios(t, "Assign", assignOperatorScenarios) } diff --git a/pkg/yqlib/operator_booleans.go b/pkg/yqlib/operator_booleans.go index ee7f6931..74c32cea 100644 --- a/pkg/yqlib/operator_booleans.go +++ b/pkg/yqlib/operator_booleans.go @@ -94,3 +94,20 @@ func AndOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathT return b1 && b2 }) } + +func NotOperator(d *dataTreeNavigator, matchMap *list.List, pathNode *PathTreeNode) (*list.List, error) { + log.Debugf("-- notOperation") + var results = list.New() + + for el := matchMap.Front(); el != nil; el = el.Next() { + candidate := el.Value.(*CandidateNode) + log.Debug("notOperation checking %v", candidate) + truthy, errDecoding := isTruthy(candidate) + if errDecoding != nil { + return nil, errDecoding + } + result := createBooleanCandidate(candidate, !truthy) + results.PushBack(result) + } + return results, nil +} diff --git a/pkg/yqlib/operator_booleans_test.go b/pkg/yqlib/operator_booleans_test.go index b21c4050..ba2b6aa2 100644 --- a/pkg/yqlib/operator_booleans_test.go +++ b/pkg/yqlib/operator_booleans_test.go @@ -45,6 +45,56 @@ var booleanOperatorScenarios = []expressionScenario{ "D0, P[b], (!!bool)::true\n", }, }, + { + description: "Not true is false", + expression: `true | not`, + expected: []string{ + "D0, P[], (!!bool)::false\n", + }, + }, + { + description: "Not false is true", + expression: `false | not`, + expected: []string{ + "D0, P[], (!!bool)::true\n", + }, + }, + { + description: "String values considered to be true", + expression: `"cat" | not`, + expected: []string{ + "D0, P[], (!!bool)::false\n", + }, + }, + { + description: "Empty string value considered to be true", + expression: `"" | not`, + expected: []string{ + "D0, P[], (!!bool)::false\n", + }, + }, + { + description: "Numbers are considered to be true", + expression: `1 | not`, + expected: []string{ + "D0, P[], (!!bool)::false\n", + }, + }, + { + description: "Zero is considered to be true", + expression: `0 | not`, + expected: []string{ + "D0, P[], (!!bool)::false\n", + }, + }, + { + + description: "Null is considered to be false", + expression: `~ | not`, + expected: []string{ + "D0, P[], (!!bool)::true\n", + }, + }, } func TestBooleanOperatorScenarios(t *testing.T) { diff --git a/pkg/yqlib/operator_collect_object.go b/pkg/yqlib/operator_collect_object.go index 54eda111..298880c9 100644 --- a/pkg/yqlib/operator_collect_object.go +++ b/pkg/yqlib/operator_collect_object.go @@ -2,6 +2,8 @@ package yqlib import ( "container/list" + + yaml "gopkg.in/yaml.v3" ) /* @@ -19,7 +21,9 @@ func CollectObjectOperator(d *dataTreeNavigator, matchMap *list.List, pathNode * log.Debugf("-- collectObjectOperation") if matchMap.Len() == 0 { - return list.New(), nil + node := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map", Value: "{}"} + candidate := &CandidateNode{Node: node} + return nodeToMap(candidate), nil } first := matchMap.Front().Value.(*CandidateNode) var rotated []*list.List = make([]*list.List, len(first.Node.Content)) diff --git a/pkg/yqlib/operator_collect_object_test.go b/pkg/yqlib/operator_collect_object_test.go index d03ede2a..4682789f 100644 --- a/pkg/yqlib/operator_collect_object_test.go +++ b/pkg/yqlib/operator_collect_object_test.go @@ -9,7 +9,9 @@ var collectObjectOperatorScenarios = []expressionScenario{ description: `Collect empty object`, document: ``, expression: `{}`, - expected: []string{}, + expected: []string{ + "D0, P[], (!!map)::{}\n", + }, }, { description: `Wrap (prefix) existing object`, diff --git a/pkg/yqlib/operator_comments_test.go b/pkg/yqlib/operator_comments_test.go index 46a16952..7405624f 100644 --- a/pkg/yqlib/operator_comments_test.go +++ b/pkg/yqlib/operator_comments_test.go @@ -75,5 +75,5 @@ func TestCommentOperatorScenarios(t *testing.T) { for _, tt := range commentOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Comments Operator", commentOperatorScenarios) + documentScenarios(t, "Comment Operators", commentOperatorScenarios) } diff --git a/pkg/yqlib/operator_delete_test.go b/pkg/yqlib/operator_delete_test.go index 77e00184..43e02d15 100644 --- a/pkg/yqlib/operator_delete_test.go +++ b/pkg/yqlib/operator_delete_test.go @@ -43,5 +43,5 @@ func TestDeleteOperatorScenarios(t *testing.T) { for _, tt := range deleteOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Delete Operator", deleteOperatorScenarios) + documentScenarios(t, "Delete", deleteOperatorScenarios) } diff --git a/pkg/yqlib/document_index_operator.go b/pkg/yqlib/operator_document_index.go similarity index 100% rename from pkg/yqlib/document_index_operator.go rename to pkg/yqlib/operator_document_index.go diff --git a/pkg/yqlib/document_index_operator_test.go b/pkg/yqlib/operator_document_index_test.go similarity index 92% rename from pkg/yqlib/document_index_operator_test.go rename to pkg/yqlib/operator_document_index_test.go index 9dd61dd2..0f0a3088 100644 --- a/pkg/yqlib/document_index_operator_test.go +++ b/pkg/yqlib/operator_document_index_test.go @@ -37,5 +37,5 @@ func TestDocumentIndexScenarios(t *testing.T) { for _, tt := range documentIndexScenarios { testScenario(t, &tt) } - documentScenarios(t, "Document Index Operator", documentIndexScenarios) + documentScenarios(t, "Document Index", documentIndexScenarios) } diff --git a/pkg/yqlib/operator_equals_test.go b/pkg/yqlib/operator_equals_test.go index a2d0ea15..ce172503 100644 --- a/pkg/yqlib/operator_equals_test.go +++ b/pkg/yqlib/operator_equals_test.go @@ -54,5 +54,5 @@ func TestEqualOperatorScenarios(t *testing.T) { for _, tt := range equalsOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Equals Operator", equalsOperatorScenarios) + documentScenarios(t, "Equals", equalsOperatorScenarios) } diff --git a/pkg/yqlib/operator_explode_test.go b/pkg/yqlib/operator_explode_test.go index 1bd9fe40..5f3aac99 100644 --- a/pkg/yqlib/operator_explode_test.go +++ b/pkg/yqlib/operator_explode_test.go @@ -86,5 +86,5 @@ func TestExplodeOperatorScenarios(t *testing.T) { for _, tt := range explodeTest { testScenario(t, &tt) } - documentScenarios(t, "Explode Operator", explodeTest) + documentScenarios(t, "Explode", explodeTest) } diff --git a/pkg/yqlib/operator_multilpy.go b/pkg/yqlib/operator_multiply.go similarity index 100% rename from pkg/yqlib/operator_multilpy.go rename to pkg/yqlib/operator_multiply.go diff --git a/pkg/yqlib/operator_multiply_test.go b/pkg/yqlib/operator_multiply_test.go index a12a0220..ea29cf47 100644 --- a/pkg/yqlib/operator_multiply_test.go +++ b/pkg/yqlib/operator_multiply_test.go @@ -130,5 +130,5 @@ func TestMultiplyOperatorScenarios(t *testing.T) { for _, tt := range multiplyOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Multiply Operator", multiplyOperatorScenarios) + documentScenarios(t, "Multiply", multiplyOperatorScenarios) } diff --git a/pkg/yqlib/operator_not.go b/pkg/yqlib/operator_not.go deleted file mode 100644 index 3ae7e970..00000000 --- a/pkg/yqlib/operator_not.go +++ /dev/null @@ -1,20 +0,0 @@ -package yqlib - -import "container/list" - -func NotOperator(d *dataTreeNavigator, matchMap *list.List, pathNode *PathTreeNode) (*list.List, error) { - log.Debugf("-- notOperation") - var results = list.New() - - for el := matchMap.Front(); el != nil; el = el.Next() { - candidate := el.Value.(*CandidateNode) - log.Debug("notOperation checking %v", candidate) - truthy, errDecoding := isTruthy(candidate) - if errDecoding != nil { - return nil, errDecoding - } - result := createBooleanCandidate(candidate, !truthy) - results.PushBack(result) - } - return results, nil -} diff --git a/pkg/yqlib/operator_not_test.go b/pkg/yqlib/operator_not_test.go deleted file mode 100644 index 3bac2087..00000000 --- a/pkg/yqlib/operator_not_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package yqlib - -import ( - "testing" -) - -var notOperatorScenarios = []expressionScenario{ - { - description: "Not true is false", - expression: `true | not`, - expected: []string{ - "D0, P[], (!!bool)::false\n", - }, - }, - { - description: "Not false is true", - expression: `false | not`, - expected: []string{ - "D0, P[], (!!bool)::true\n", - }, - }, - { - description: "String values considered to be true", - expression: `"cat" | not`, - expected: []string{ - "D0, P[], (!!bool)::false\n", - }, - }, - { - description: "Empty string value considered to be true", - expression: `"" | not`, - expected: []string{ - "D0, P[], (!!bool)::false\n", - }, - }, - { - description: "Numbers are considered to be true", - expression: `1 | not`, - expected: []string{ - "D0, P[], (!!bool)::false\n", - }, - }, - { - description: "Zero is considered to be true", - expression: `0 | not`, - expected: []string{ - "D0, P[], (!!bool)::false\n", - }, - }, - { - - description: "Null is considered to be false", - expression: `~ | not`, - expected: []string{ - "D0, P[], (!!bool)::true\n", - }, - }, -} - -func TestNotOperatorScenarios(t *testing.T) { - for _, tt := range notOperatorScenarios { - testScenario(t, &tt) - } - documentScenarios(t, "Not Operator", notOperatorScenarios) -} diff --git a/pkg/yqlib/operator_path_test.go b/pkg/yqlib/operator_path_test.go index 5341f7af..8102faf3 100644 --- a/pkg/yqlib/operator_path_test.go +++ b/pkg/yqlib/operator_path_test.go @@ -41,5 +41,5 @@ func TestPathOperatorsScenarios(t *testing.T) { for _, tt := range pathOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Path Operator", pathOperatorScenarios) + documentScenarios(t, "Path", pathOperatorScenarios) } diff --git a/pkg/yqlib/operator_recursive_descent_test.go b/pkg/yqlib/operator_recursive_descent_test.go index 0de62417..e08a98ed 100644 --- a/pkg/yqlib/operator_recursive_descent_test.go +++ b/pkg/yqlib/operator_recursive_descent_test.go @@ -23,9 +23,9 @@ var recursiveDescentOperatorScenarios = []expressionScenario{ }, }, { - description: "Map", - document: `{a: {b: apple}}`, - expression: `..`, + skipDoc: true, + document: `{a: {b: apple}}`, + expression: `..`, expected: []string{ "D0, P[], (!!map)::{a: {b: apple}}\n", "D0, P[a], (!!map)::{b: apple}\n", @@ -33,9 +33,9 @@ var recursiveDescentOperatorScenarios = []expressionScenario{ }, }, { - description: "Array", - document: `[1,2,3]`, - expression: `..`, + skipDoc: true, + document: `[1,2,3]`, + expression: `..`, expected: []string{ "D0, P[], (!!seq)::[1, 2, 3]\n", "D0, P[0], (!!int)::1\n", @@ -44,9 +44,9 @@ var recursiveDescentOperatorScenarios = []expressionScenario{ }, }, { - description: "Array of maps", - document: `[{a: cat},2,true]`, - expression: `..`, + skipDoc: true, + document: `[{a: cat},2,true]`, + expression: `..`, expected: []string{ "D0, P[], (!!seq)::[{a: cat}, 2, true]\n", "D0, P[0], (!!map)::{a: cat}\n", @@ -58,23 +58,17 @@ var recursiveDescentOperatorScenarios = []expressionScenario{ { description: "Aliases are not traversed", document: `{a: &cat {c: frog}, b: *cat}`, - expression: `..`, + expression: `[..]`, expected: []string{ - "D0, P[], (!!map)::{a: &cat {c: frog}, b: *cat}\n", - "D0, P[a], (!!map)::&cat {c: frog}\n", - "D0, P[a c], (!!str)::frog\n", - "D0, P[b], (alias)::*cat\n", + "D0, P[a], (!!seq)::- {a: &cat {c: frog}, b: *cat}\n- &cat {c: frog}\n- frog\n- *cat\n", }, }, { description: "Merge docs are not traversed", document: mergeDocSample, - expression: `.foobar | ..`, + expression: `.foobar | [..]`, expected: []string{ - "D0, P[foobar], (!!map)::c: foobar_c\n!!merge <<: *foo\nthing: foobar_thing\n", - "D0, P[foobar c], (!!str)::foobar_c\n", - "D0, P[foobar <<], (alias)::*foo\n", - "D0, P[foobar thing], (!!str)::foobar_thing\n", + "D0, P[foobar], (!!seq)::- c: foobar_c\n !!merge <<: *foo\n thing: foobar_thing\n- foobar_c\n- *foo\n- foobar_thing\n", }, }, { @@ -96,5 +90,5 @@ func TestRecursiveDescentOperatorScenarios(t *testing.T) { for _, tt := range recursiveDescentOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Recursive Descent Operator", recursiveDescentOperatorScenarios) + documentScenarios(t, "Recursive Descent", recursiveDescentOperatorScenarios) } diff --git a/pkg/yqlib/operator_select_test.go b/pkg/yqlib/operator_select_test.go index 2d3f0966..3b495ee4 100644 --- a/pkg/yqlib/operator_select_test.go +++ b/pkg/yqlib/operator_select_test.go @@ -59,5 +59,5 @@ func TestSelectOperatorScenarios(t *testing.T) { for _, tt := range selectOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Select Operator", selectOperatorScenarios) + documentScenarios(t, "Select", selectOperatorScenarios) } diff --git a/pkg/yqlib/operator_style_test.go b/pkg/yqlib/operator_style_test.go index ff84df12..d98f48a0 100644 --- a/pkg/yqlib/operator_style_test.go +++ b/pkg/yqlib/operator_style_test.go @@ -70,9 +70,10 @@ e: >- }, }, { - description: "Set empty (default) quote style", - document: `{a: cat, b: 5, c: 3.2, e: true}`, - expression: `.. style=""`, + description: "Pretty print", + subdescription: "Set empty (default) quote style", + document: `{a: cat, b: 5, c: 3.2, e: true}`, + expression: `.. style=""`, expected: []string{ "D0, P[], (!!map)::a: cat\nb: 5\nc: 3.2\ne: true\n", }, @@ -86,9 +87,10 @@ e: >- }, }, { - description: "Read style", - document: `{a: "cat", b: 'thing'}`, - expression: `.. | style`, + description: "Read style", + document: `{a: "cat", b: 'thing'}`, + dontFormatInputForDoc: true, + expression: `.. | style`, expected: []string{ "D0, P[], (!!str)::flow\n", "D0, P[a], (!!str)::double\n", @@ -110,5 +112,5 @@ func TestStyleOperatorScenarios(t *testing.T) { for _, tt := range styleOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Style Operator", styleOperatorScenarios) + documentScenarios(t, "Style", styleOperatorScenarios) } diff --git a/pkg/yqlib/operator_tag_test.go b/pkg/yqlib/operator_tag_test.go index 9d4878dc..e918c73f 100644 --- a/pkg/yqlib/operator_tag_test.go +++ b/pkg/yqlib/operator_tag_test.go @@ -32,5 +32,5 @@ func TestTagOperatorScenarios(t *testing.T) { for _, tt := range tagOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Tag Operator", tagOperatorScenarios) + documentScenarios(t, "Tag", tagOperatorScenarios) } diff --git a/pkg/yqlib/operator_traverse_path_test.go b/pkg/yqlib/operator_traverse_path_test.go index 16809ea1..7c98f8aa 100644 --- a/pkg/yqlib/operator_traverse_path_test.go +++ b/pkg/yqlib/operator_traverse_path_test.go @@ -45,6 +45,15 @@ var traversePathOperatorScenarios = []expressionScenario{ "D0, P[1], (!!map)::{c: banana}\n", }, }, + { + description: "Special characters", + subdescription: "Use quotes around path elements with special characters", + document: `{"{}": frog}`, + expression: `."{}"`, + expected: []string{ + "D0, P[{}], (!!str)::frog\n", + }, + }, { description: "Children don't exist", subdescription: "Nodes are added dynamically while traversing", @@ -271,5 +280,5 @@ func TestTraversePathOperatorScenarios(t *testing.T) { for _, tt := range traversePathOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Traverse Operator", traversePathOperatorScenarios) + documentScenarios(t, "Traverse", traversePathOperatorScenarios) } diff --git a/pkg/yqlib/operator_union_test.go b/pkg/yqlib/operator_union_test.go index 578dd12a..41719296 100644 --- a/pkg/yqlib/operator_union_test.go +++ b/pkg/yqlib/operator_union_test.go @@ -29,5 +29,5 @@ func TestUnionOperatorScenarios(t *testing.T) { for _, tt := range unionOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Union Operator", unionOperatorScenarios) + documentScenarios(t, "Union", unionOperatorScenarios) } diff --git a/pkg/yqlib/operators_test.go b/pkg/yqlib/operators_test.go index 6c929f6a..4f38aa91 100644 --- a/pkg/yqlib/operators_test.go +++ b/pkg/yqlib/operators_test.go @@ -114,17 +114,13 @@ func documentScenarios(t *testing.T, title string, scenarios []expressionScenari } w := bufio.NewWriter(f) + writeOrPanic(w, "\n") - writeOrPanic(w, "\n## Examples\n") - - for index, s := range scenarios { + for _, s := range scenarios { if !s.skipDoc { - if s.description != "" { - writeOrPanic(w, fmt.Sprintf("### %v\n", s.description)) - } else { - writeOrPanic(w, fmt.Sprintf("### Example %v\n", index)) - } + writeOrPanic(w, fmt.Sprintf("## %v\n", s.description)) + if s.subdescription != "" { writeOrPanic(w, s.subdescription) writeOrPanic(w, "\n\n") @@ -132,7 +128,7 @@ func documentScenarios(t *testing.T, title string, scenarios []expressionScenari formattedDoc := "" if s.document != "" { if s.dontFormatInputForDoc { - formattedDoc = s.document + formattedDoc = s.document + "\n" } else { formattedDoc = formatYaml(s.document) }