I'm trying to do some pipeline work that injects certain values in a yaml document (an mkdocs config) if they are not currently present. But the problem is that the current values can be either items in a list or objects in a list:
This is valid:
plugins:
- search
but also this is valid:
plugins:
- search:
lang: en
foo: bar
What I want to do is simply take a config, see if it already has a search plugin section or not, and if it doesn't append the config part in the 2nd one. But just checking if search is present is not possible with one function, so I'm looking for ideas how to be able to handle this properly:
$ yq 'contains({"plugins": ["search"]})' test.yaml
true
$ yq 'contains({"plugins": ["search"]})' test2.yaml
false
On a different note: I also tried creating a template.yaml, where yq would merge the template.yaml on top of the current yaml config, so values in the template would always be present, but that proved to be an even bigger challenge than this one.
You didn't specify which of the two implementations of yq you are using (see the Tag Info to yq).
With kislyuk/yq, you could use
anyto test for both cases: any item either itself being the search term, or having a field with the search term as its name usinghas(bind the term to a variable (or pass it as external argument using--arg) if you want to have it in one place only):With mikefarah/yq, to provide a condition, you would use
any_cinstead (passing in external values would be done via environment variables):As for your "different note", you'd need to be more specific by including some samples, etc., and ideally in a separate question. But my initial guess is that you want something along the lines of
.plugins |= (select(any(…) | not) += ["search"])with kislyuk/yq, and equivalently.plugins |= (select(any_c(…) | not) += "search")with mikefarah/yq.