How to make vscode not wait for finishing a preLaunchTask? - visual-studio-code

I have a debug setup in Visual Studio code where I run an external binary which can execute my JS files (using duktape). The debug adapter currently only supports attach requests (not launch) so I have to run the binary before I can debug the JS scripts.
In order to avoid having to start the application manually I created a task for it and set that in my launch.json file:
{
"version": "0.2.0",
"configurations": [{
"name": "Attach MGA",
"type": "duk",
"preLaunchTask": "debug mga",
"request": "attach",
"address": "localhost",
"port": 9091,
"localRoot": "${workspaceRoot}",
"stopOnEntry": false,
"debugLog": true
}]
}
The task is defined so:
{
"version": "0.1.0",
"command": "<absolute path to>/mga",
"isShellCommand": false,
"showOutput": "always",
"suppressTaskName": true,
"tasks": [{
"taskName": "debug mga",
"args": ["--debugger", "main.json"]
}]
}
The problem is now that vscode waits for the pre launch task to finish, while the application waits for a debugger to attach. Catch 22.
How can I avoid that vscode waits for the pre launch task to finish?
Update:
Meanwhile I have read up on the vscode task page and came up with this task configuration. Still, it doesn't work for me
{
"version": "2.0.0",
"tasks": [
{
"label": "launch-mga",
"type": "shell",
"command": "<absolute path to>/mga",
"args": [
"config/main.json",
"--debugger"
],
"isBackground": true,
"problemMatcher": {
"owner": "custom",
"pattern": {
"regexp": "_____"
},
"background": {
"activeOnStart": true,
"beginsPattern": "^.*Waiting for debug connection.*$",
"endsPattern": "^.*blah.*$"
},
},
}
]
}
The launched application prints the wait message and then waits endlessly for a debug connection. Maybe the problem has to do with the application (which is kinda Node.js like terminal app), written in C++?

This worked for me.
Note all these are required, even though none are important:
problemMatcher.pattern.regexp
problemMatcher.pattern.file
problemMatcher.pattern.location
problemMatcher.pattern.message
problemMatcher.background.activeOnStart
problemMatcher.background.beginsPattern
problemMatcher.background.endsPattern
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build-extras",
"type": "shell",
"isBackground": true,
"command": "./script/build-extras",
// This task is run before some debug tasks.
// Problem is, it's a watch script, and since it never exits, VSCode
// complains. All this is needed so VSCode just lets it run.
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": ".",
}
}
]
}
]
}

Background / watching tasks
Some tools support running in the background while watching the file system for changes and then triggering an action when a file changes on disk. With Gulp such functionality is provided through the npm module gulp-watch. The TypeScript compiler tsc has built in support for this via the --watch command line option.
To provide feedback that a background task is active in VS Code and producing problem results, a problem matcher has to use additional information to detect these state changes in the output. Let's take the tsc compiler as an example. When the compiler is started in watch mode, it prints the following additional information to the console:
> tsc --watch
12:30:36 PM - Compilation complete. Watching for file changes.
When a file changes on disk which contains a problem, the following output appears:
12:32:35 PM - File change detected. Starting incremental compilation...
src/messages.ts(276,9): error TS2304: Cannot find name 'candidate'.
12:32:35 PM - Compilation complete. Watching for file changes.
Looking at the output shows the following pattern:
The compiler runs when File change detected. Starting incremental compilation... is printed to the console.
The compiler stops when Compilation complete. Watching for file changes. is printed to the console.
Between those two strings problems are reported.
The compiler also runs once the initial start (without printing File change detected. Starting incremental compilation... to the console).
To capture this information, a problem matcher can provide a background property.
For the tsc compiler, an appropriate background property looks like this:
"background": {
"activeOnStart": true,
"beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
"endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}
In addition to the background property on the problem matcher, the task itself has to be marked as isBackground so that the task keeps running in the background.
A full handcrafted tasks.json for a tsc task running in watch mode looks like this:
{
"version": "2.0.0",
"tasks": [
{
"label": "watch",
"command": "tsc",
"args": ["--watch"],
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"fileLocation": "relative",
"pattern": {
"regexp": "^([^\\s].*)\\((\\d+|\\,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
"file": 1,
"location": 2,
"severity": 3,
"code": 4,
"message": 5
},
"background": {
"activeOnStart": true,
"beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
"endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}
}
}
]
}
PS: Content taken from https://code.visualstudio.com/docs/editor/tasks
Edit-1
The task needs to be launched as a daemon then only isBackground is going to help. So you will have something like
"isShellCommand": true,
"command": "<absolute path to>/mga --config xyz abc &",

As of Nov 2022, the accepted and upvoted solutions to this question did not work.
I essentially needed a way to run Jacoco report after Junit tests finished running inside vscode java test runner. I managed to hack a way using bash and nohup, it may not be the solution for everybody but it works in my case.
tasks.json:
"tasks": [
{
"label": "runJacocoReport",
"type": "shell",
"command": "./delayTheReport.sh"
}
]
delayTheReport.sh
echo "Starting"
coproc nohup ./report.sh > nohupout.txt
sleep 1
echo "Report started in background"
report.sh
echo "Sleeping"
# This is magic number, you can replace it with a loop that checks for a certain file to exist or similar
sleep 15
echo "Starting"
# Do the thing you need to do
....

Related

Configuring a customized build task in vs code for c++

I had a custom build system in sublime for C++ which takes input from one file and redirects the output to another.
My sublime build system is as follows :
{
"cmd": ["g++.exe","-std=c++14", "${file}", "-o", "${file_base_name}.exe", "&&" , "${file_base_name}.exe<inputf.in>outputf.in"],
"selector":"source.cpp",
"shell":true,
"working_dir":"$file_path"
}
this helped in taking input from "inputf.in" file and print the output in "outputf.in" whenever i ran my program.
I want similar functionality in vs code but dont know how to configure build-task.
Here is a build task for a Node addon, you have to put it in .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "npx node-pre-gyp build -j max",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceFolder}/build"
]
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
You can press Ctrl-Shift-P to bring the command palette and select configure build task.
The problem matcher allows VSCode to highlight the compiler errors in your editor.
The default build task is the one you launch with a hotkey.

How can I start debugging R or Python code using the same key in Visual Studio Code?

Trying to avoid the XY problem, my problem at the very high level: I work in a VS Code workspace with R and Python code files, and I often need to debug one or the other. Currently I have different debug launch configurations saved, and I need to switch between them manually - that is a pain. I would like to use F5 to
launch the Python debugger when the editor is active in a .py file
launch the R debugger when the editor is active in a .R file
I see many technical ways of doing that, but all have their roadblocks (some of which may just poor documentation):
Create my own extension with a dynamic debug configuration that determines the type of the active editor and starts the correct debug configuration. (A lot of effort required.)
Use a "compound" launch configuration, starting both R and Python launch configurations, and stopping all but one. This can be done using a "prelaunchTask" for each, but non-zero return codes create error message that I don't like.
Use editor-dependent key mappings ("when": "editorLangId == 'python'"), but which command for debugging to start and how to pass the launch configuration? There is vscode.startDebug which takes arguments (https://github.com/microsoft/vscode/issues/4615), but I cannot keybind to that. And then there is workbench.action.debug.start which seems to ignore arguments. And then there is vscode.commands.executeCommand to which I cannot keybind, either.
Use a multi-command extension to bind a key to something like "set debug configuration, then press F5". But how to do that?
Etc. etc.
After much fiddling, here is one solution following idea 2:
settings.json (launch configs could be put into launch.json):
{
"debug.onTaskErrors": "abort",
"launch": {
"compounds": [
{
"name": "Python/R: Current File",
"configurations": [
"Python: Current File",
"R: Current File",
],
},
],
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"preLaunchTask": "check_ext py",
"request": "launch",
// ...
},
{
"name": "R: Current File",
"type": "R-Debugger",
"preLaunchTask": "check_ext R",
"request": "launch",
// ...
}
],
},
}
tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "check_ext py",
"type": "shell",
"command": "echo ${fileExtname} | grep -i ^.py$",
},
{
"label": "check_ext R",
"type": "shell",
"command": "echo ${fileExtname} | grep -i '^.R$'",
},
],
}

VSCode: Open new terminal as part of task?

Visual Studio Code was just updated to allow running a task and having them open in a split terminal. This is great, however I'm looking for one more thing to make this perfect.
I would like to be able to open a total of 3 terminals via a task. One for my NPM build, one for my backend MAVEN build, and a third that is just a blank new terminal I can use for git commands when needed.
I can't seem to find a way to tell VSC to run a task that just opens a new terminal ready to use without providing it a command. I would even settle with giving it a simple command like "node -v" just to start it out, as long as that panel is still usable after. Right now it wants to close it after it has ran.
Here is my task setup: I have one task setup as the build task that depends on two others. I envision adding a third one to that which would just open the new terminal:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Maven and NPM",
"dependsOn": [ "maven", "npm" ],
"group": {
"kind": "build",
"isDefault": true,
},
},
{
"label": "maven",
"command": "...",
"type": "shell",
"presentation": {
"reveal": "always",
"group": "build"
},
"options": {
"cwd": "${workspaceRoot}/server"
}
},
{
"label": "npm",
"type": "shell",
"command": "ng serve --port 4203 --proxy-config proxy.conf.json",
"presentation": {
"reveal": "always",
"group": "build"
},
"options": {
"cwd": "${workspaceRoot}/client-APS"
}
}
]
}
The following should work:
{
"type": "process",
"label": "terminal",
"command": "/bin/bash", // <-- your shell here
"args": [
"-l" // login shell for bash
],
"problemMatcher": [],
"presentation": {
"echo": false, // silence "Executing task ..."
"focus": true,
"group": "build", // some arbitrary name for the group
"panel": "dedicated"
},
"runOptions": {
"runOn": "folderOpen"
}
}
I was trying to achieve something very similar when I stumbled my way into this solution: Here, I'm auto-launching (and setting the focus on) the terminal when the folder is opened in vscode -- and further tasks that share the same presentation.group gets placed in split terminals when they're run (with new vs. reused splits depending on their presentation.panel)
(The runOptions bit is superfluous for your case, but I'm keeping it in case it is helpful for someone)
Note: For this example, you may or may not need the -l option depending on your settings for terminal.integrated.shell*, terminal.integrated.automationShell* and terminal.integrated.inheritEnv -- this issue has some discussion on what is involved in setting up the shell environment.

How to use cpx when debugging in VS Code?

I want to use cpx as a background task for one of my debugging configurations inside Visual Studio Code. However it has no output and causes this error:
Since cpx does it's job in less then a second I don't need it to be tracked. Is there a way to tell VS Code just to run the task and not track it?
Here's my tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"script": "cpx",
"type": "npm",
"isBackground": true
}
]
}
If you want to execute the task only once, just set isBackground: false.
Otherwise, before Visual Studio Code launches debugger, it needs to know when background task has completed its initial job. It happens by watching task output with problem matcher but, as you have pointed out, cpx by default does not output anything. Here's my suggestion:
Pass --verbose flag to cpx which gives us some output ending with Be watching...
Use following problem matcher with your task:
{
"version": "2.0.0",
"tasks": [
{
"script": "cpx",
"type": "npm",
"isBackground": true,
"problemMatcher": {
"background": {
"activeOnStart": true, // monitoring should happen immediately after start
"beginsPattern": "^whatever", // irrelevant
"endsPattern": "^Be watching.*" // pattern indicating that task is done
},
// we don't need pattern section but it's required by the schema.
"pattern": [
{
"regexp": "^whatever",
"file": 1,
"location": 2,
"message": 3
}
]
}
}
]
}

What are the correct beginsPattern and endsPattern for a background Task in VSCode?

I have a static website (i.e. just html and client side JavaScript) that I serve with python while debugging locally. I have a VSCode task that will start python correctly and am trying to set that task as the preLaunchTask on a Debugger for Chrome launch task. The desired behavior is that whenever I start debugging the serve task below ensures the site is being served.
If I understand background tasks correctly one can set a beginsPattern and endsPattern to signal state changes.
I am expecting that when python echos
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
to stdout that the problemMatcher below would signal to the launch task that it had started. Instead, the launch task waits forever, and doesn't proceed until the task's shell command is terminated.
Can tasks be configured to achieve this sort of behavior?
Launch Configuration
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8000",
"webRoot": "${workspaceFolder}/webroot",
"preLaunchTask": "serve"
}
]
}
Serve Task
{
"version": "2.0.0",
"tasks": [
{
"label": "serve",
"type": "shell",
"command": "python3 -m http.server",
"windows": {
"command": "py -m http.server"
},
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/webroot"
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "dedicated"
},
"problemMatcher": {
"owner": "custom",
"pattern":[
{
"regexp": "^([^\\s].*)$",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern":"^Serving HTTP (.*)$",
"endsPattern":"^Keyboard interrupt received, exiting(.*)$"
}
}
}
]
}
So we also had a similar problem: wanted to set up a Debugger on a Django app running inside Docker. On my setup, the debugger launched a preLaunchTask which starts the remote interpreter debugger, among other things (like installing ptvsd.
Original Steps:
preLaunchTask calls a script (./run-debug.sh).
This script calls remote debugger with this command:
docker container exec -it my_app python debug.py runserver --noreload --nothreading 0.0.0.0:8000
On the debug.py file, there's a print statement to know that the debugger started.
That didn't work, apparently, VSCode doesn't catch the output of the debugger. Instead, on the run-debug.sh file I added an echo statement: Starting debugger session: which VSCode caught ^_^. That fixed the issue for me.
tasks.json, relevant problem matcher:
"problemMatcher": {
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"beginsPattern": "^Starting debugger session:",
"endsPattern": ".",
}
}
run-debug.sh script, relevant part:
# Start remote process
echo 'Starting debugger session:' #VSCode beginsPattern will catch this!
docker container exec -it my_app python debug.py runserver --noreload --nothreading 0.0.0.0:8000