Skip to content
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

[FEATURE]: elseif branches in templating. #5738

Open
salotz opened this issue Feb 16, 2024 · 3 comments
Open

[FEATURE]: elseif branches in templating. #5738

salotz opened this issue Feb 16, 2024 · 3 comments
Labels
devex Developer experience and ease of use. discussion feat/templating Templating in variables and configs feature request

Comments

@salotz
Copy link

salotz commented Feb 16, 2024

Feature Request

Background / Motivation

Currently you are limited to in all of the branching templating to only two branches.
I.e. ternary operator and if-else.

For instance if I have the following:

group:
  $if: ${environment.name == 'local'}
  $then:
    - thinga
    - thingb
  $else:
    - thing c

And I want to now have two different branches in addition to the one for 'local' there isn't really a way to do that.

So I end up needing to do things like templating the item names e.g.:

group:
  $if: ${environment.name == 'local'}
  $then:
    - thinga
    - thingb
  $else:
    - thing${environment.name == 'staging' ? 'c' : 'd'}

Which you can see is just a band aid.

Whats worse is that I can't even use multiple if-else inside the same map/list due to how it expands those. E.g.

group:
  $if: ${environment.name == 'local'}
  $then:
    - thinga
    - thingb

  $if: ${environment.name == 'staging'}
  $then:
    - thingc
  $if: ${environment.name == 'prod'}
  $then:
    - thingd

Gives an error like:

Could not parse garden.yaml in directory file/path/garden.yaml as valid YAML: YAMLException: duplicated mapping key (219:15)

What should the user be able to do?

group:
  $if: ${environment.name == 'local'}
  $then:
    - thinga
    - thingb
  $elseif: ${environment.name == 'staging'}
  $then:
    - thingc
  $elseif: ${environment.name == 'prod'}
  $then:
    - thingd

If environment.name doesn't match this would be a templating error. If there is the trailing else it would be fine.

Why do they want to do this? What problem does it solve?

See above.

Suggested Implementation(s)

The obvious near term fix is to just add support for the elseif part.

In general I think that support for a pre-existing and powerful templating engine (like jsonnet) would be a more holistic approach to addressing non-essential garden functionality like this.

How important is this feature for you/your team?

Its not critical now, but as our stacks grow they increasingly grow ugly hacks and workarounds to this issue.

🌵 Not having this feature makes using Garden painful

@10ko 10ko added the feat/templating Templating in variables and configs label Feb 27, 2024
@salotz
Copy link
Author

salotz commented May 31, 2024

Updated to include another attempt at a workaround that failed.

@stefreak
Copy link
Member

stefreak commented Jun 4, 2024

@salotz absolutely, this is indeed an annoying problem. Thank you for the report!

At the moment we are parsing the document as YAML first, and then apply structural (like $if) and template strings (like ${environment.name}. This means that a syntax that requires duplicate $elseif conditions in the same object would mean implementing our own YAML parser and it would also mean that documents need to be parsed as ordered dictionaries, as the order of the statements matters.

We do have long-term plans internally how we can address this issue to make the configuration more expressive.

In the mean time, I have two other workarounds for you:

  1. Use environment-specific variables (See also https://docs.garden.io/reference/project-config#environments-.variables)
environments:
  - name: local
     variables:
       group:
         - thinga
         - thingb

  - name: staging
     variables:
       group:
         - thingc

  - name: prod
     variables:
       group:
         - thingd
  1. Use object lookup syntax instead of if/else statements
kind: Run
type: exec
name: cleanup
spec:
  command: ${var.commands_by_platform[local.platform]}
variables:
  commands_by_platform:
    windows: [".\cleanup_windows.bat"]
    linux: [".\cleanup_linux.sh"]
    macos: [".\cleanup_macos.sh"]

These workarounds are in no way optimal or equivalent to elseif branching, but due to the technical limitations of the current template system it's hard to address this problem. There might be lower hanging fruits to improving the situation, and we are definitely open for suggestions.

@stefreak stefreak added discussion devex Developer experience and ease of use. 0.14 labels Jun 4, 2024
@stefreak
Copy link
Member

stefreak commented Jun 4, 2024

Here is a proposal of an alternative syntax that is easier to implement with the current limitations of the YAML template system:

groups:
  $match: ${environment.name}
  $exact: # We could implement multiple matchers, e.g. exact, regex, etc
    prod:
      - thingd
    staging:
      - thingc
  $default: # Match could fail if you do not specify default and nothing matches
      - thinga
      - thingb

@stefreak stefreak removed the 0.14 label Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
devex Developer experience and ease of use. discussion feat/templating Templating in variables and configs feature request
Projects
None yet
Development

No branches or pull requests

3 participants