metomi / rose

:rose: Rose is a toolkit for writing, editing and running application configurations.
https://metomi.github.io/rose/
GNU General Public License v3.0
55 stars 53 forks source link

Allow setting default values for env variables #2451

Open TomekTrzeciak opened 3 years ago

TomekTrzeciak commented 3 years ago

I would find it quite useful if there was some way to specify default values for environment variables in rose apps, something like:

[env]
MY_VAR ?= default

MY_VAR would be then set to default only if it is not already set in the environment. The only way I can think of to override the env definition currently is to use a command line define rose task-run -D[env]MY_VAR=override, which is far less convenient to use.

oliver-sanders commented 3 years ago

Support for Bash substitutions might be the easiest way to achieve this:

[env]
FOO=${FOO:-default}

Bash vars are already parsed out of the config using some logic in metomi.rose.env.

TomekTrzeciak commented 3 years ago

Support for Bash substitutions might be the easiest way to achieve this:

[env]
FOO=${FOO:-default}

Bash vars are already parsed out of the config using some logic in metomi.rose.env.

That would do the trick, I just don't know how to alter regular expressions in metomi.rose.env in a robust way (default value could in principle contain any characters). OTOH, my suggestion above would be straightforward to implement in env config processor (metomi.rose.config_processors.env).

oliver-sanders commented 3 years ago

I just don't know how to alter regular expressions in metomi.rose.env in a robust way

^
(?P<head>.*?)
(?P<escape>\\*)
(?P<symbol>
\$
(?P<brace_open>\{)?
(?P<name>[A-z_]\w*)
(:-(?P<default>\w*))?
(?(brace_open)\})
)
(?P<tail>.*)
$

# should match
${FOO}
${FOO:-bar}

# shouldn't match
${FOO/a/b}
${FOO:bar}

OTOH, my suggestion above would be straightforward to implement in env config processor (metomi.rose.config_processors.env)

I wouldn't want to go adding a new type of definition because it's not just about supporting that in the config processor but also internally handling a new type of definition and then presenting that throughout the CLI and GUI.

oliver-sanders commented 3 years ago

This allows substitutions so long as they aren't nested.

^
\${
  (?P<key>\w+)
  (
    :-
    (?P<default>
      # don't allow nested substitutions
      (?!\$)
      (
        # allow any chars within single quotes
        (?:'[^']*')?
        # allow any chars within double quotes (except dollar)
        (?:\"[^"\$]*\")?
        # ignore escaped braces
        (?:\\})?
        # match up to the closing brace
        (?:[^}'\"]+)?
      )+
    )
  )?
}
$
# these all match
${FOO}
${FOO:-bar}
${FOO:-}
${FOO:-\}}
${FOO:-''}
${FOO:-'}'}
${FOO:-'}'"}"'"}"'}

# don't allow nested substitutions
${FOO:-${BAR}}

# don't allow nested expressions in double quotes
${FOO:-"${BAR}"}

# don't allow fancy bash syntax
${FOO/a/b}

https://regex101.com/r/OeHImf/3

oliver-sanders commented 2 years ago

Encountered another use case for this.