Can ${input:fileContent} be used with configurations.connect.host in a launch.json configuration?
I'm trying to build a launch configuration that will,
- submit a python script to be ran on a server farm,
- wait for an indication that the script has started a debugpy server, and is listening for connections,
- ascertain the machine that is now listening for a debug client connection, and
- proceed to connect the debugger client to the remote server.
I have coded this solution as follows:
launch.jsonruns apreLaunchTaskcalledlaunchTest, that uses a shell script to,- submit the job to run on the farm.
- waits for a file to exist that contains what machine the job is running on, and also indicates the debug server is now listening.
launch.jsonalso defines the host to connect to as${input:debugpyLauncHost}input:debugpyLauncHostusesextension.commandvariable.file.contentto get the value from the file.
It appears that the launch configuration evaluates the value of ${input:debugpyLauncHost}, before running the preLaunchTask. Because, while launchTest starts the server and the file is created with the machine name, ${input:debugpyLauncHost} returns nothing, and the host connection fails.
I experimented with added delays after the file exists, but regardless of the length it doesn't matter. If on the other hand, I pre-populate the file before running the launch configuration ( and forcing the job to run on that specific machine ), ${input:debugpyLauncHost} successfully returns the machine name from the file and the client connects to the server.
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Py Debugger",
"type": "debugpy",
"preLaunchTask": "launchTest",
"request": "attach",
"connect": {
"host": "${input:debugpyLaunchHost}",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "${workspaceFolder}"
}
],
"postDebugTask": "delete DebugpyLaunchHost.tmp"
}
],
"inputs": [
{
"id": "debugpyLaunchHost",
"type": "command",
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/.vscode/debugpyLaunchHost.tmp"
}
}
]
}
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "launchTest",
"type": "shell",
"command": "proj_env",
"args": [
"${workspaceFolder}/trunk/script/launch_test.sh"
],
"problemMatcher": []
},
{
"label": "delete DebugpyLaunchHost.tmp",
"type": "shell",
"command": "rm",
"args": [
"${workspaceFolder}/.vscode/debugpyLaunchHost.tmp"
],
"problemMatcher": []
}
]
}
The details of launch_test.sh aren't important, but it's working as expected.
Is there another way to leverage this extension to accomplish my goal?
@LoggerMN Other users have also found this problem with launch configs.
I have mentioned this in issue microsoft/vscode#215905 at the vscode repo in comment
I have found a workaround by using a couple of extensions:
You can define a key binding that will run the preLaunchTask and then launch a named launch config.
VSC has the command runCommands but it does not wait till the task is finished and you can't add a delay between commands. The extension multi-command is an alternative with delay option.
I have chosen to define shift+F5 to start this sequence:
keybindings.json
{
"key": "shift+f5",
"command": "extension.multiCommand.execute",
"args": {
"interval": 6000,
"sequence": [
{
"command": "workbench.action.tasks.runTask",
"args": "getServer"
},
"launches.PythonCurrentArgs"
]
},
"when": "editorTextFocus"
}
The preLaunchTask is called getServer:
.vscode/tasks.json
{
"label": "getServer",
"type": "shell",
"command": "c:\\Python312\\python.exe ${workspaceFolder}/getServer.py ${workspaceFolder}/.vscode/debugServer.tmp",
"problemMatcher": []
}
getServer.py
import sys
import time
time.sleep(2) # sim some wait time
with open(sys.argv[1], "w") as file:
file.write('apricot')
Define the launch config to use:
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File with Arguments",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"args": "${input:getServername}"
}
],
"inputs": [
{
"id": "getServername",
"type": "command",
"command": "extension.commandvariable.file.content",
"args": { "fileName": "${workspaceFolder}/.vscode/debugServer.tmp" }
}
]
}
In .vscode/settings.json define a name to launch a config with a command.
.vscode/settings.json
"launches": {
"PythonCurrentArgs": "Python Debugger: Current File with Arguments (Workspacename)"
}
You make the file you want to debug current and press shift+F5.
You need to adjust:
- the
intervalin the keybinding - the name of the workspace in the
.vscode/settings.json:(Workspacename)
You can use intellisence and get suggestions to fill the string.
The file I used for testing is:
test-launch.py
import sys
print('Use server:', sys.argv[1])
print()
Maybe we can add a feature request to add a conditional wait till a file is found/modified to multi-command. But the last update was 2 years ago.