Search code examples
yamljqyq

Conditional statement in yq parser for updating script


I m trying to replace a string value in a yaml file and I m not able to get the if working.

YAML file

apiVersion: kots.io/v1beta1
kind: Config
metadata:
  name: enterprise
spec:
  groups:
    - name: api_authorization
      title: API Authorization
      items:
        - name: api_key
          title: API Key
          type: password
          required: true
        - name: workspace_id
          title: Workspace ID
          type: text
          required: true
    - name: deep_learning
      title: Deep Learning
      description: Deep Learning Service Options
      items:
        - name: triton_release_options
          title: Release Options
          type: heading
        - name: triton_release_version
          title: Triton Release Version
          type: text
          default: "release-v308" ## Shoudl be updated when the triton release is true
          required: true
        - name: tracker_release_version
          title: Tracker Version
          type: text
          default: "release-v308" ## Shoudl be updated when the tracker is being build as part of the component
          required: true

I have tried the following with no luck

yq e '
   .spec.groups[] |=
      if .name == "deep_learning" then
         .items[] |
         select( .name == "triton_release_version" ) |
         .default = "new_release_version"
      else
         .
      end
' config.yaml
yq e '
   .spec.groups[] |
   select(.name == "deep_learning") |
   .items[] |
   select( .name == "triton_release_version" ) |
   .default = "new_release_version"
' config.yaml

I am able to update, but then i m losing the whole yaml file content if i m not using the if condition. With the if I get a syntax error.


Solution

  • Operator precedence is important. You can force order of evaluation by parenthesizing:

    yq e '(
      .spec.groups[]
      | select(.name == "deep_learning")
      | .items[]
      | select(.name == "triton_release_version")
      | .default
    ) = "new_release_version"' config.yaml
    

    First select the items you want to update (…[] | select(…) | …), then update them (… = "new_release_version").

    An alternative way of writing the program is:

    yq e '(
      .spec.groups[]
      | select(.name == "deep_learning").items[]
      | select(.name == "triton_release_version")
    ).default = "new_release_version"' config.yaml
    

    With mikefarah's yq, you get:

    apiVersion: kots.io/v1beta1
    kind: Config
    metadata:
      name: enterprise
    spec:
      groups:
        - name: api_authorization
          title: API Authorization
          items:
            - name: api_key
              title: API Key
              type: password
              required: true
            - name: workspace_id
              title: Workspace ID
              type: text
              required: true
        - name: deep_learning
          title: Deep Learning
          description: Deep Learning Service Options
          items:
            - name: triton_release_options
              title: Release Options
              type: heading
            - name: triton_release_version
              title: Triton Release Version
              type: text
              default: "new_release_version" ## Shoudl be updated when the triton release is true
              required: true
            - name: tracker_release_version
              title: Tracker Version
              type: text
              default: "release-v308" ## Shoudl be updated when the tracker is being build as part of the component
              required: true