Terminate another task from within a postDebugTask - VS Code - visual-studio-code

I have a debug launch configuration (launch.json) like below.
{
"version": "0.2.0",
"configurations": [
{
"name": "Current TS File",
"type": "node",
"request": "launch",
"preLaunchTask": "Pre Debug Task",
"postDebugTask": "Stop Watch Styles",
"args": ["${relativeFile}"],
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
"sourceMaps": true,
"cwd": "${workspaceRoot}",
"protocol": "inspector",
}
]
}
My tasks configuration (tasks.json) is like
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "next:copy",
"label": "Copy Files",
"problemMatcher": []
},
{
"type": "npm",
"script": "styles:tsw",
"label": "Watch Styles",
"problemMatcher": [],
},
{
"label": "Pre Debug Task",
"isBackground": true,
"dependsOn" :[
"Copy Files",
"Watch Styles"
]
},
{
"label": "Stop Watch Styles",
// No sure what should come here
}
]
}
Trying to stop watch process in postDebugTask, is there a way to Terminate Task by providing name (Watch Styles) as parameter in tasks.json. Watch styles is a continuously running process, please suggest if there is any other approach to terminate a task after debugging is complete.

This will terminate all tasks after debug stops
Or in this case, just build_runner watch...
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"preLaunchTask": "flutter: build_runner watch",
"postDebugTask": "Terminate All Tasks"
}
]
}
tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Terminate All Tasks",
"command": "echo ${input:terminate}",
"type": "shell",
"problemMatcher": []
}
],
"inputs": [
{
"id": "terminate",
"type": "command",
"command": "workbench.action.tasks.terminate",
"args": "terminateAll"
}
]
}
More info here: https://code.visualstudio.com/docs/editor/variables-reference#_command-variables

This works for me:
{
"label": "postdebugKill",
"type": "process",
"command":[
"${command:workbench.action.tasks.terminate}",
"${command:workbench.action.acceptSelectedQuickOpenItem}",
],
},
The first "${command:workbench.action.tasks.terminate}" will bring up a panel asking you to select which task to terminate. So if you had multiple running tasks and wanted to choose one you would use this command only.
The second "${command:workbench.action.acceptSelectedQuickOpenItem}" will terminate the selected task in that panel mentioned above. (So you will not even see the terminate panel.) If you have only one running task when you call the postdebugKill task, it will be selected automatically and thus terminated. Otherwise whichever task is listed first will be terminated. Again, if you have more than one other task running and you want to select which to terminate don't include this second command.
I don't know of any way to list, perhaps via an args option a label name for which task to terminate if running. It would be nice to have this functionality.
[postdebugKill name can be whatever you want.]
To call a postdebug task your launch.json config might look like this:
{
"type": "node",
"request": "launch",
"name": "Gulp: serve",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"args": [
"serve"
],
// "preLaunchTask": "someTask",
"postDebugTask": "postdebugKill"
},
Upon stopping that "Gulp: serve" debugging session, the task "postdebugKill" will be triggered. And so if I had used the "preLaunchTask" to start a task or had simply started a task running before launching the "Gulp: serve" debugging session - that preLaunchTask would be terminated.
The ability to run vscode commands in a task was recently added to vscode. Some minimal info here: using a command in a task doc.

[I'll add another answer because the new additional info is extensive.]
It seems there is an issue with running a preLaunchTask and then launching a debugging session. See particularly debugging does not work on first try. It appears to be fixed though in an insiders edition and may be released in early February 2019. terminal not sending onLineData.
In the meantime there is a suggested fix within one of the issues that I have lost the link to and that is a problemMatcher which will signal to the debugger that the dependent tasks have completed.
In my watching task I used this:
"problemMatcher": [
{
"base": "$tsc-watch",
"background": {
"activeOnStart": true,
"beginsPattern": "Using gulpfile ~\\OneDrive\\experimental\\gulpfile.js",
"endsPattern": "Starting 'watch'..."
}
}
],
I chose that because when I manually start the gulp:watch task I get this in the terminal:
[22:27:48] Using gulpfile ~\OneDrive\experimental\gulpfile.js
[22:27:48] Starting 'watch'...
[22:27:48] Starting 'watch'...
So you see the start and end pattern there that I copied (with extra escaping).
I suggest that you separately run your "Pre Debug Task" and copy the start and ending output into your "Pre Debug Task" problemMatcher and see if it now works.
My code in the first answer I believe is correct, I just wasn't using "isBackground" and "dependsOn" as you are. But I have added "isBackground" to mine and the problemMatcher option and it works flawlessly now.
Hopefully, this will be fixed in the next February 2019 release and there will be no need for this workaround.

If on Linux or macOS, a less hacky solution that just works is using pkill. If on Windows, see below.
First run the task and find the full command vscode runs for that task, with $ ps -af
Then use pkill + the full command in a postDebugTask.
I have an entry in tasks.json like this:
{
"label": "stop npm:watch",
"type": "shell",
"command": "pkill -f 'sh -c node ./scripts/watch.js'",
"presentation": {
"reveal": "silent",
"panel": "dedicated",
"close": true,
}
}
'sh -c node ./scripts/watch.js' is how vscode runs my npm:watch task.
The presentation properties prevent this task from taking focus or taking up terminal space after it finishes successfully.
Then you reference that task in a launch.json configuration:
{
...
"preLaunchTask": "npm:watch",
"postDebugTask": "stop npm:watch",
...
}
If the full command contains changing parameters (paths, port numbers, etc.), you can use a part of the command or regex.
e.g.: I could have probably matched with './scripts/watch.js' or 'node.*watch'.
For Windows: you can make this work by substituting pkill for taskkill.
If you want to support both Unix and Windows, you can make a script that does one or the other depending on the underlying OS.

Related

VSCode - How to specify which project to debug - Azure Functions

My question is a noobie question.
I have an azure function app project, along with a test project. Initially, I start with just the function application project and then I just recently re-org the project folders and added the associated test.csproj
The folder structure I have right now looks like this:
Since moving the function app into the "src" folder, when I want to just run locally, I make sure that from my powershell terminal, I do the following:
cd src
func start
And everything works really well. But if I want to step through the code / debug, hitting F5 doesn't work because it doesn't know which project I'm trying to debug.
Can you tell me how I can debug either project from the parent folder that I'm in ?
I've tried to change my launch.json from this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to .NET Functions",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}"
}
]
}
To this:
{
"version": "0.2.0",
"configurations": [
{
"name": "FunctionApp",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}",
"program": "${workspaceFolder}/src/bin/Debug/net6.0/bin/widgets.dll",
"cwd": "${workspaceFolder}/src"
}
]
}
And now I see a Green play button with the name "FunctionApp" in my "Run and Debug" bar across the top, but when I try to run it, I get an error that says:
Executing task: C:\Program Files\dotnet\dotnet.exe clean /property:GenerateFullPaths=true /consoleloggerparameters:NoSummary <
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET Copyright
(C) Microsoft Corporation. All rights reserved.
MSBUILD : error MSB1003: Specify a project or solution file. The
current working directory does not contain a project or solution file.
The terminal process "C:\Program Files\dotnet\dotnet.exe 'clean',
'/property:GenerateFullPaths=true',
'/consoleloggerparameters:NoSummary'" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
EDIT 1
I tried to follow this example:
https://i.stack.imgur.com/a7ZVk.png
I also changed all references in my task.json from "process" to "shell" based on this post: Debugging Azure Function with vscode
So presently, this is what the two files look like:
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to .NET Functions",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}"
}
]
}
tasks.json
Just showing what I understand is the relevant section...
{
"version": "2.0.0",
"tasks": [
{
"label": "host function",
"command": "func host start",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/src"
}
},
But the error I'm getting is this:
Failed to detect running Functions host within "60" seconds. You may
want to adjust the "azureFunctions.pickProcessTimeout" setting.
When I try Run -> Start with debugging, the application starts, and I can trigger my API... but it doesn't stop at any of the breakpoints.
So the complete solution was to
a) Revert my launch.json back to the original version which looks like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to .NET Functions",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}"
}
]
}
b) added new section to my tasks.json:
{
"label": "host function",
"command": "func host start",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/src"
}
},
c) Then I changed ALL references to "process" to "shell" in the tasks.json.
d) Lastly, to fix the error with azureFunctions.pickProcessTimeout, I did the following:
File -> Preferences -> Settings -> search for the specific setting and increased from 60 seconds to 180

Run bash script with VS Code

I want to run bash script when I hit F5 and see the results in the terminal like I can do with python scripts or whatever. I tried to do that with Bash Debug however it automatically goes to the debug mode and stops at the first step even if I do not put breakpoint. This is the launch configuration I use.
{
"type": "bashdb",
"request": "launch",
"name": "Run mysql test",
"cwd": "${workspaceFolder}",
"program": "/srv/gpf/dba/mysqlslap/run.sh",
"args": []
}
I don't know about running bash in a debug mode (doesn't seem like you need those features based on your example) but you can easily get your script to run as a Task or Build option.
Place this at .vscode/tasks.json of your project dir
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Run as Bash Script",
"type": "shell",
"command": "/bin/bash ${file}",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
You can place whatever you want in the "command" parameter.
As you can see, it's of type "kind": "build" so I can hit ctrl+shift+B and this will execute in a terminal.
Note, you can also use the command palette (F1 or ctrl+shift+P) and use Task: Run as Task too.
Source: https://code.visualstudio.com/Docs/editor/tasks

VSCode launch configuration to run python file without debugging

I understand that by creating a launch.json file in VSCode (slightly more cumbersome than pycharm), I can set debug configurations to launch individual python files.
For example:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Poker",
"type": "python",
"request": "launch",
"cwd": "C:/Users/dickr/git/poker",
"program": "C:/Users/dickr/git/Poker/poker/main.py",
"console": "integratedTerminal",
"env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}
},
]
}
That all works great, but how can I run it in normal mode, without a debugger? How can this be defined in the launch configuration so I can select this in the dropdown, and potentially pass arguments with it?
Write a task in a tasks.json file. For documentation on tasks, see https://code.visualstudio.com/docs/editor/tasks#_custom-tasks.
Your might look something like this:
{
"version": "2.0.0",
"tasks": [
{
"label": "run python script",
"type": "process",
"command": "python3 C:/Users/dickr/git/Poker/poker/main.py",
"options": {
"cwd": "C:/Users/dickr/git/poker"
},
"presentation": {
"reveal": "always",
}
}
]
}
though I'd suggest that if possible, you use variable substitution to try to get rid of the absolute paths that won't be the same on other machines (assuming you want to be able to run the task on other machines).
Then run the task. You can even bind the task to keyboard shortcuts. See the documentation for more info: https://code.visualstudio.com/docs/editor/tasks.

Visual Studio Code Task is Prepending the working directory to the command

I'm trying to setup visual studio code for rust to do debugging. In my launch.json file I have
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/target/debug/vscode-rust-debug-example.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"preLaunchTask": "localcargobuildtask"
}
]
}
and in my tasks.json I have
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "localcargobuildtask",
"command": "echo hi",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Where "echo hi" is in my tasks I eventually want to have something like "cargo build" or "cargo test" or whatever. But this is just a starting step.
But when I press F5 the output I get is
> Executing task: C:\programs\VSCodeWorkspaces\RustProjects\vscode-rust-debug-example-debug-config-included\echo hi <
The terminal process terminated with exit code: 2
Terminal will be reused by tasks, press any key to close it.
Rather than running "echo" from where ever the terminal finds it (working directory first, then check global path variable like you would expect) it is actually looking for a program named "echo" in my root folder of the workspace.
How do I tell visual studio code "No I don't want you to run workspace/echo, I want you to run echo in workspace" ? Or is there another more direct way to tell visual studio code "compile this before you debug it" ?
The answer to this question How to debug Rust unit tests on Windows?
suggests that changing
"command": "cargo build",
into
"command": "cargo",
"args": [
"build"
],
in the tasks.json file works and somehow it does. Maybe the editor is configured to search the %path% for single word commands, or maybe some plugin I installed overwrote the "cargo" command. Maybe the reason echo wasn't found is because it is a terminal command, not a program. Maybe the error message was a lie and it was only reporting that it couldn't find workspacefolder\command despite checking %path%? Or maybe none of that. I have no idea. It is some pretty idiosyncratic behavior.

How to run several tasks in VSCode

I am trying to migrate to VSCode and having a problem with setting-up tasks. It is easy to define tasks in tasks.json but I would like to run several tasks simultaneously (which I can't).
Here is my use-case: I have two watchers in my project (one for gulp and another one for webpack). Plus I want to be able to run webpack task separately. When I run one of the watchers I cannot run anything else - VSCode requires me to terminate the running task at first.
In Visual Studio I used Task Runner where several tasks were running simultaneously. Is it possible to achieve the same in VSCode?
Using compound tasks, you can specify dependsOn and dependsOrder on a separate task, and run them in parallel like this:
{
"label": "start-tasks",
"dependsOrder": "parallel",
"dependsOn": [
"taskOne",
"taskTwo"
]
}
The problem is that "Run Test Task" and "Run Build Task" do not execute all tasks in that specific group. Usually you get a drop down selection so you can choose which task to execute. Since you have specified one of the tasks as default, the selection will be skipped and instead the default task is executed.
You can work around that by adding dependencies. Take the following example:
{
"version": "2.0.0",
"tasks": [
{
"label": "Echo 1",
"command": "echo",
"type": "shell",
"args": [ "echo1" ],
"group": {
"kind": "build",
"isDefault": true
},
"dependsOn":["Echo 2"]
},
{
"label": "Echo 2",
"type": "shell",
"command": "echo",
"args": [ "echo2" ],
"group": "build"
}
]
}