Launch.json: outputfile depending on variable

I use robotcode 2.0.1 and use in vscode in the launch.json the argument

           *"--variable", "ENV:${input:envPick}",*
           *"--variable", "ID:000",*


and

*"inputs": \[
    {
        "id": "envPick",
        "type": "pickString",
        "description": "Welche Umgebung?",
        "options": \["dev", "test", "prod"\],
        "default": "dev"
    }
\]*

and would like to set outputdir dynamically when calling with

output-dir = “c:\temp\logs\${ENV}\${ID}”

so that the logs are then created in e.g. c:\temp\prod\000. Which option can I use to implement this? I have implemented it in the robot.toml with

output-dir = “c:\temp\logs\${ENV}\${ID}”

And I tried it in the launch.json like this:

“–outputdir”, “c:\\temp\\logs}\\${ENV}\\${ID}”,

But the variable ${ENV} and ${ID} are not replaced. How can I implement this? Variables are also required in the workflow itself and I try to define constands only once.

Hello Harold,

you can use dynamic parameters where robot.toml accepts “StringExpression”:

output-dir = { expr = "f'c:\\temp\\logs\\{environ.get('ENV')}\\{environ.get('ID')}'"}

Unfortunately, there is a hickup in generating the documentation. When you type expr in the toml file, you get a tool tip explaining what kind of expressions there are available. That tool tip somehow did not end up in the documentation.

In your specific case, I would only use an expression for ID, not for ENV. ENV is a good candidate for profiles, as in CI/CD environment you would not have VSCode providing you with an input picker.

So in case I understand the case correctly, you could do something like:

[variables]
#in case you need the ID not only in output-path name, but also in tests
execution_id = { expr = "environ.get('ID')" }    

[profiles.dev]
output-dir = { expr = "f'c:\\temp\\logs\\dev\\{environ.get('ID')}'"}

[profiles.dev.variables]
sut_environment = "dev" 

[profiles.test]
output-dir = { expr = "f'c:\\temp\\logs\\test\\{environ.get('ID')}'"}

[profiles.test.variables]
sut_environment = "test" 

[profiles.prod]
output-dir = { expr = "f'c:\\temp\\logs\\prod\\{environ.get('ID')}'"}

[profiles.prod.variables]
sut_environment = "prod" 

Instead of picking the environment from an input field, you would pick it by selecting a profile, which may be convenient, if you have more parameters than the output-dir that are specific to the environment.

Kinds regards,
Markus

1 Like

Hello Markus,

could you please double check the syntax and verify that variables in outputdir are resolved?

I was not able to use the f to replace variables in a string, so I changed to “+” operator to get my result.

For better understanding I use a variable “path” instead of output-dir (same result):

\[Variables\]
path = { expr = “environ.get(‘WV_WORKFLOW_LOGBASE’, ‘’) + ‘\\\\’ + environ.get(‘ENV’, ‘’) + ‘\\\\’ + environ.get(‘WV_WORKFLOW_CONTAINER’, ‘’) +‘\\\\’ + environ.get(‘WV_WORKFLOW_ID’, ‘’) + ‘\_’ + environ.get(‘WV_WORKFLOW_NAME’, ‘’)” }

I tried:

\[profiles.run-from-launch-json\]
output-dir = “${path}”
paths = \[“tasks.robot”\]
args = \[
“–pythonpath”, “.”,
“–report”, “NONE”,
“–logtitle”, “Task log”,
“–loglevel”, “DEBUG”,
“–timestampoutputs”,

\]

The bot has correct value for path. But OUTPUTDIR got the name of the variable instead of the value:

path: c:\\temp\\logs\\dev\\000\\000_Sample_Workflow
OUTPUTDIR: C:\\Projekte\\RPA_Template${path}

And the final output is:

Output:  C:\\Projekte\\RPA_Template${path}\\output-20251103-131814.xml
Log:     C:\\Projekte\\RPA_Template${path}\\log-20251103-131814.html

Hello Harold,

I see. So, the thing is you cannot use robot variables outside of Robot Framework. ${path} is a robot variable. When the output-directory is configured, the variable does not exist, yet.

However, Robotcode maybe could support that funcationality, but I don’t know what implications that would have… Maybe consider opening an enhancement request.

Since robot-variables cannot be used outside Robot Framework, I am afraid, you have to go with some kind of config like the one I posted above, with dedicated profiles per environment.

I would also use f-strings instead of String concatination with +. Writing Python code inside TOML is difficult for the eyes to parse already :wink:

If you don’t want to use dedicated profiles, because the environment share all the same config, you have to use the expression directly in the profile:

[profiles.run-from-launch-json]
output-dir = { expr = "f'{environ.get('WV_WORKFLOW_LOGBASE', '')}\\{environ.get('ENV', '')}\\{environ.get('WV_WORKFLOW_CONTAINER', '')}\\{environ.get('WV_WORKFLOW_ID', '')}_{ environ.get('WV_WORKFLOW_NAME', '')}'" }
paths = [“tasks.robot”]
pythonpath=“.”
report=NONE
logtitle=“Task log”
loglevel=“DEBUG”
timestampoutputs= true

Also be aware, maybe you used the wrong characters in your expression. You need to use quotes and single quotes, but your original expression has these: (‘WV_WORKFLOW_ID’, ‘’) which is not the same as single quotes ('WV_WORKFLOW_ID', '') (hard to catch with the eye, but python does not like it :wink: )

Thank you for your quick reply. The quotes are fine. Apparently, the editor changed the quotation mark when I copied the code into it.

I got the error message

[ ERROR ] Evaluation of ‘output_dir’ failed: EvaluationError: Evaluation of “f’{environ.get(‘WV_WORKFLOW_LOGBASE’, ‘’)}'” failed: SyntaxError: f-string: unmatched ‘(’ (, line 1)

with

[profiles.run-from-launch-json]
output-dir = { expr = “f’{environ.get(‘WV_WORKFLOW_LOGBASE’,  ‘‘)}’” }

and therefore I chose string concatenation with + as a substitute. This ensures that the log files are actually written to the correct location. The only question that remains is why f-strings do not work. I also copied your code but the result is the same. Any idea what I can do better?

Hm… hard to say… From the error message I would assume something is broken with the double- and single-quotes. It reads like the f-string is closed by a single-quote before the closing bracket.

But since the editor is changing the quotation marks somewhow when pasting them here, it is difficult to evaluate. But the error message suggests an issue with the quotation marks, I think.

@hstrohmaier The single quotes you are seeing are modified from the expected ones. Maybe you are using MacOS and have activated the symbols modification.

Here is the correct content to compare with the original:

output-dir = { expr = “f'{environ.get('WV_WORKFLOW_LOGBASE',  '')}'" }

Original:

output-dir = { expr = “f’{environ.get(‘WV_WORKFLOW_LOGBASE’,  ‘‘)}’” }

Maybe you could try a different editor to check the characters.

Thank to both of you. The reason seems to be clear: if I enclose the f-string with double quotation marks (“), there must be no double quotation marks in it. What works:

output-dir = { expr = """
f’{environ.get("WV_WORKFLOW_LOGBASE”, "”)}\{environ.get("ENV”, "”)}\{environ.get("WV_WORKFLOW_CONTAINER”, "”)}\{environ.get("WV_WORKFLOW_ID”, "”)}_{environ.get("WV_WORKFLOW_NAME”, "”)}’
""" }

Still better:

output-dir = { expr = """
str(
Path(environ.get('WV_WORKFLOW_LOGBASE', ''))
/ environ.get('ENV', '')
/ environ.get('WV_WORKFLOW_CONTAINER', '')
/ f"{environ.get('WV_WORKFLOW_ID', '})}_{environ.get('WV_WORKFLOW_NAME', ')}")
""" }
1 Like