What are the correct beginsPattern and endsPattern for a background Task in VSCode? - visual-studio-code

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

Related

VScode Code custom task: "terminal process terminated with exit code: 1."

I have configured my first custom task in Visual Studio code as follows to run bun.js (a javascript runtime alternative to Node.js or Deno):
{
"version": "2.0.0",
"tasks": [
{
"label": "my task",
"type": "shell",
"command": "bun",
"args": [
"run",
"dev"
],
"presentation": {
"reveal": "always",
"focus": true,
"panel": "new",
},
}
]
}
When I run the task I get the following error message:
The terminal process "C:\Windows\System32\wsl.exe -e bun run main.ts" terminated with exit code: 1.
I am running Ubuntu Linux on a windows machine and I have verified that the wsl executable is in the above path.
What is causing this process to fail?

Stuck waiting for prelaunch task

I'm trying to run my debug environment as a Poetry session, so I can properly debug encapsulated.
So, my launch.json is straightforward:
{
"name": "Poetry",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5710
},
"preLaunchTask": "poetryDebugSession",
"localRoot": "${workspaceFolder}"
}
and I adapted my tasks.json to try to launch debugpy in Poetry first (this works if I manually run some code in the terminal)
{
"label": "poetryDebugSession",
"type": "shell",
"command": "poetry",
"args": [
"run",
"python",
"-m",
"debugpy",
"--log-to-stderr",
"--wait-for-client",
"--listen",
"5710",
"${relativeFile}",
"&"
],
"presentation": {
"panel": "dedicated",
"clear": true
},
"group": "test",
"isBackground": true,
"runOptions":{
"instanceLimit": 1
},
// This task is run before the launch.json task. Since it needs to run in the
// background and not wait for completion, though, we need to jump through hoops
"problemMatcher": [
{
"owner": "python",
"fileLocation": "absolute",
"pattern": [
{
"regexp": "^\\s+File \"(.*)\", line (\\d+), in (.*)$",
"file": 1,
"line": 2
},
{
"regexp": "^\\s+(.*)$",
"message": 1
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^D[0-9\\.: \\+]+wait_for_client",
"endsPattern": ".*",
}
}
]
}
When I start debugging, the task is properly launched, and debugpy gets all the way to the message I am waiting for that I want the preluanch task to be marked as "ready":
> Executing task: poetry run python -m debugpy --log-to-stderr --wait-for-client --listen 5710 d:\path\to\myfile.py <
# stuff
I+00000.344: pydevd is connected to adapter at 127.0.0.1:61443
D+00000.344: wait_for_client()
I could have sworn I had this working last week but as of 1.58.2 after a restart this morning it doesn't progress past wait_for_client() display, so the debugger never attaches. I'm also a little suspicious that ${relativeFile} includes a full path in my output but that probably doesn't matter.
It should be clear from the code above that I derived my initial implementation from https://stackoverflow.com/a/54017304/1877527 , but still no dice.
The debugpy team helped me find an answer:
https://github.com/microsoft/debugpy/issues/676#issuecomment-886041838
{
"name": "Python: Poetry current file",
"type": "python",
"request": "launch",
"program": "${env:USERPROFILE}/.poetry/bin/poetry",
"python": "<path/to/bare/bones/python>",
"args": ["run", "python", "${file}"],
"console": "integratedTerminal",
}
It worked for me even without the python argument, since my primary dev machine just has one active Python installation.

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 make vscode not wait for finishing a preLaunchTask?

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
....

Running background services in Visual Studio Code

I would like to run a background service like MongoDB from Visual Studio Code. I tried to run it through the task runner like this:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "mongod",
"isShellCommand": false,
"args": ["--dbpath", "data\\db"],
"showOutput": "always"
}
But this will only run it inside VS with no control to stop the server, e.g. by pressing Ctrl+C.
The normal way would be to run a cmd.exe and run the mongod command from there. But I would love to nicely integrate it into VS.
Found a solution to the problem by using one command with subtasks.
This will run "mongod" in a separate cmd.exe shell.
Once started (in this case minimized via /MIN), I can stop the MongoDB by opening the cmd windows and pressing ctrl+C to properly shutdown the database.
It would still be nicer to have the shell running inside vscode, but maybe this will come in an update someday.
{
"version": "0.1.0",
"command": "start",
"isShellCommand": true,
"showOutput": "never",
"args": [
"/MIN"
],
"tasks": [
{
"taskName": "Start MongoDB",
"args": [
"\"MongoDB # localhost:27017\"",
"mongod",
"--dbpath",
"${workspaceRoot}/data/db"
],
"suppressTaskName": true
}
]
}
You can define a watching task like in this webpack example:
{
"version": "0.1.0",
"command": "npm",
"isShellCommand": true,
"echoCommand": false,
"suppressTaskName": true,
"showOutput": "always",
"tasks": [
{
"args": [
"run",
"start",
"--silent"
],
"problemMatcher": [
{
"owner": "custom",
"pattern": [],
"watching": {
"activeOnStart": true,
"beginsPattern": "webpack: bundle is now INVALID",
"endsPattern": "webpack: bundle is now VALID"
}
}
],
"isWatching": true,
"taskName": "development"
}
]
}
The (optional) problem Matcher watching beginsPattern and endsPattern define the console output of the watcher task start and end. The watching task can be terminated via command palette.
https://github.com/Microsoft/vscode/issues/6209#issuecomment-218154235