Launching Multiple Simultaneous Tasks in VS Code - visual-studio-code

I have a single "project" with 3 separate codebases (loaded into a single workspace), each of which has its own long-running npm start task. I want to run all of these at the same time. This isn't too hard if you just go to Terminal -> Run Task 3 times and launch each individually, but since I do this every day and sometimes multiple times per day, it'd be nice to simplify it into running a single command that launches all 3 at once, preferrably in a split terminal (though not necessary), rather than each having their own tab. Anyone know if this is possible?

What you want to do is make a new separate task and list the 3 tasks you want to run as dependancies. For example, in your tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Task1",
// ...
},
{
"label": "Task2",
// ...
},
{
"label": "Task3",
// ...
},
{
"label": "Run 3 Tasks",
"dependsOn": ["Task1", "Task2", "Task3"]
}
]
}
The default behavior for dependancies will be to run tasks in parellel. This can be changed with the dependsOrder tag.
https://code.visualstudio.com/Docs/editor/tasks

Related

Configuring multiple commands to run in parallel in VS Code tasks (to compile and autoprefix Sass)

I had previously been using Koala to compile my Sass with autoprefixing and minifying (on Windows), but have come to find that Koala is no longer maintained. I'm therefore trying to figure out how people usually compile Sass, autoprefix it, and minify it automatically on save.
I'm not super experienced with command line tools like Gulp but have used NPM enough to get to the point of being able to install Dart Sass, PostCSS, etc., and since I use VS Code, have decided that its internal Tasks feature seems like the easiest way to go.
Currently if I do this in the VS Code terminal:
sass --watch sass:. --style compressed
It works, i.e., it successfully watches for changes in the sass directory and outputs a minified .css file in the parent directory.
If I stop that and do this instead:
postcss style-raw.css --output style.css --use autoprefixer --watch
It also works. I had to rename the original .scss file because apparently postcss doesn't allow --replace and --watch at the same time.
So right now, I have style-raw.scss which compiles to style-raw.css when I run the sass command, and style-raw.css gets autoprefixed and output to style.css when I run the postcss command.
Where I'm stuck is getting both commands to run at the same time via a Task. In my tasks.json file I have:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Sass Compile",
"type": "shell",
"command": "sass --watch sass:. --style compressed | postcss style-raw.css --output style.css --use autoprefixer --watch",
"problemMatcher": [
"$node-sass"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
This is connected to the Build task, which has a keyboard shortcut of ctrl+shift+B, so my ultimate goal thus far has been to be able to just hit ctrl+shift+B to start everything up getting watched and compiled and autoprefixed, etc.
Currently though, only the Sass command runs when I use the keyboard shortcut. I found another post somewhere that said the pipe should work for multiple commands, but it doesn't seem to, or perhaps you can't --watch two things at the same time, I have no idea. I tried an array for command: but that either doesn't work or I didn't have the right format.
Or perhaps there's an entirely different and better way to go about all this, but if anyone can help with using these two commands together, that'd be much appreciated.
UPDATE: SOLUTION --------------------------------------------------------
With the kind help of #soulshined below, I got the multiple commands working (the dependsOn option was the trick), but evidently it won't run two commands with the --watch parameter in the same terminal. For my use case this wouldn't work and I eventually found this extremely helpful article that explains how to run multiple tasks in a split terminal by grouping them.
If anyone else runs across this with the same use case, here is the working tasks.json file:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Compile CSS",
"dependsOn": [
"Sass Compile",
"Prefix Output",
],
"group": {
"kind": "build",
"isDefault": true
},
},
{
"label": "Prefix Output",
"type": "shell",
"command": "postcss style-raw.css --output style.css --use autoprefixer --watch",
"presentation": {
"group": "cssCompile"
}
},
{
"label": "Sass Compile",
"type": "shell",
"command": "sass --watch sass:. --style compressed",
"problemMatcher": [
"$node-sass"
],
"presentation": {
"group": "cssCompile"
}
}
]
}
UPDATE 2: GULP --------------------------------------------------------
Randomly ran across my own post and thought I would add that I now use Gulp. I don't remember why but the VS Code tasks turned into a hassle later on, and Gulp turned out to be not that hard to learn.
Where I'm stuck is getting both commands to run at the same time via a Task
Running concurrently can be tricky to accomplish; consider taking advantage of the dependsOn property. Here is a brief example of running commands tasks consecutively:
"version": "2.0.0",
"tasks": [
{
"label": "Echo All",
"type": "shell",
"command": "echo Done",
"dependsOn": [
"Last"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Last",
"type": "shell",
"command": "echo 'Did it last'",
"dependsOn": "First",
},
{
"label": "First",
"type": "shell",
"command": "echo 'Doing it first'",
}
]
That's a language [shell] agnostic solution. If you would like to run multiple commands you can try adding a semi colon after each statement:
"command": "sass --watch sass:. --style compressed; postcss style-raw.css --output style.css --use autoprefixer --watch"

Where to define a shared problemMatcher to check the terminal?

In vscode I experience sometimes I can click on build errors in the integrated terminal and sometimes it is not possible to do so. This has annoyed me for quite some time because I was not able to find a pattern, until today when I was editing tasks.json.
It looks to be related to defining a problemMatcher in .vscode/tasks.json. Removing the problemMatcher section from the file and build errors in terminal were no longer clickable but putting it back did not re-enable them.
My vscode-project is located in a subfolder of the build tree and its build root for the entire project is two levels up ${workspaceFolder}/../.. which I believe maybe could confuse some build tools.
tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"problemMatcher": {
"fileLocation": "relative",
"severity": "error",
"pattern":{
"regexp": "^system/mytool/(.*):(\\d+):(\\d+):\\s+(warning|error):(.*)$",
"file": 1,
"location": 2,
"column": 3,
"severity": 4,
"message": 5
},
},
"tasks": [
{
"type": "shell",
"label": "android deploy",
"command": "cd ${workspaceFolder}/../..; source build/envsetup.sh ; lunch hikey960-userdebug ; m mytool",
"args": [
],
"options": {
},
"group": "build"
},
]
}
I have seen examples putting "problemMatcher" = "$gcc" inside the task, should I define my problem matcher globally somewhere else and refer to it my name instead?
How to use it to parse the output when I build by typing make-commands in the integrated terminal?
You cannot define problem matchers globally. Instead you have to define them in each task.
This is somewhat ugly because you may have to copy the same problem matcher into a lot of tasks. There is an open issue for this: Global task properties

Running multiple Visual Studio Tasks in Parallel

I'm trying to run a long-lived background task in visual studio (tsc --watch) while also running my app as two separate tasks. So, (app)-[dependsOn]->(tsc --watch). But, it appears that the app task waits for the tsc command to finish before it executes, which is a problem since it runs forever.
I'm simplifying my problem to show the actual issue I'm running into, but should hopefully guide me down the right path.
I have two task in my tasks.json file:
{
"label": "Echo 1",
"command": "echo",
"type": "shell",
"args": [
"echo1"
],
"group": {
"isDefault": true,
"kind": "build"
},
"dependsOrder": "parallel",
"dependsOn": [
"Sleep 5"
]
},
{
"label": "Sleep 5",
"type": "shell",
"command": "sleep",
"isBackground": true,
"args": [
"5"
]
}
Echo 1 -depends on-> Sleep 5
According to visual studio documentation the sleep task should be running in the background allowing the Echo task to do it's thing. But, whenever I execute the Echo 1 task, it waits until Sleep 5 is finished and THEN it actually executes the echo task.
> Executing task: sleep 5 <
Terminal will be reused by tasks, press any key to close it.
> Executing task: echo echo1 <
echo1
Terminal will be reused by tasks, press any key to close it.
I've tried adding the background property detailed in the documentation, but the editor shows a popup with the message Property background is not allowed. whenever I add that field.
Am I missing something else to ensure that the Sleep 5 task doesn't block the Echo 1 task?
I've tried already tried using the presentation with panel: dedicated/new to each task so they don't use the same terminal (not even sure if that's how visual studio executes it's tasks).

Run flutter app on multiple connected devices/emulators simultaneously [duplicate]

This question already has answers here:
Flutter Hot Reload to multiple devices
(6 answers)
Closed 3 years ago.
How can I run my flutter app on multiple devices at the same time without having to go through the sequential procedure of: select a device -> run, select other device -> run, etc.?
Using:
Android Studio 3.2.1
Flutter 1.0.0
Dart 2.1.0
Run command in terminal:
flutter run -d all
or create a script (e.g. runall.sh in root):
#!/usr/bin/env bash
flutter run -d all
and go to "Run" -> "Edit Configurations". Press "+" in upper left corner -> select "Bash". Then set:
Name: runall
Script: [path to runall.sh script]
Interpreter Path: /bin/bash
Select "runall" instead of "main.dart" beside run icon. Performing run (also through shortcut) will now run app on all devices.
Drawback: You'll have to enter "r" followed by Enter in run terminal for hot reload. Icon and shortcut does not work. Hot reload is performed on all devices though.
Just a workaround for now. I'm pretty sure the flutter plugin will cover this soon.
There are many ways to do this as previously answered. If you use VS Code instead of Android Studio as your Flutter IDE, this is how you can use the VSC launch configuration and tasks to run concurrently from a single launch and have hot reload enabled for all devices.
If you have an issue with executing flutter run -d all this is an alternative solution will which let you specify the devices that should run.
Ensure that the devices you specify are available when running flutter devices.
Your current launch.json file may look something like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"type": "dart",
"request": "launch",
"flutterMode": "debug"
}
]
}
Setup
You will need to update this launch.json file and create tasks.json in the same .vscode folder that is in your application's root directory.
Paste only the below code into launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter-All",
"preLaunchTask": "Flutter-Launch-All",
"type": "dart",
},
{
"name": "Flutter-iOS",
"preLaunchTask": "Flutter-Launch-iOS",
"type": "dart",
},
{
"name": "Flutter-Android",
"preLaunchTask": "Flutter-Launch-Android",
"type": "dart",
},
{
"name": "Flutter-Web",
"preLaunchTask": "Flutter-Launch-Web",
"type": "dart",
}
],
}
Paste only the below code into tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Flutter-Launch-All",
"dependsOn": [
"Flutter-Launch-iOS",
"Flutter-Launch-Android",
"Flutter-Launch-Web"
]
},
{
"label": "Flutter-Launch-iOS",
"type": "shell",
"command": "flutter run -d 'iPhone 11' "
},
{
"label": "Flutter-Launch-Android",
"type": "shell",
"command": "flutter run -d 'AOSP on IA Emulator' "
},
{
"label": "Flutter-Launch-Web",
"type": "shell",
"command": "flutter run -d 'Chrome' "
}
]
}
Replace the device names accordingly ('iPhone 11', 'AOSP on IA Emulator', 'Chrome').
Firing up all devices
Press the F5 key.
And you're done.
If the F5 shortcut to Start Debugging does not work for you, navigate to Debug & Run on the side panel and select the Flutter-All Configuration you've just created and then Run.
You will then see the terminal window appear and will able to switch between the individual hot-reload sessions running (as Tasks in their own shell).
Some Background
We use 'Compound Tasks' by way of the dependsOn option on a Task and not 'Compounds' which are for Configurations.
As it is not possible to launch Configurations concurrently, only sequentially, we use tasks which can run concurrently.
Hence, the "Flutter-All" Configuration executes the tasks of the iOS, Android and Web Configurations.
If using Compounds, a Configuration will need to complete before the next runs which is not what we want.
With Tasks we can choose to execute them sequentially however by default they will execute concurrently when using the dependsOn option.
//Do not use this unless you want to use Configurations only by testing them sequentially and not tasks
"compounds": [
{
"name": "Flutter-All",
"configurations": ["Flutter-iOS", "Flutter-Android", "Flutter-Web"],
}
]
If you don't want to use the command line directly each time, you can do the following workaround:
Download bashsupport plugin (link)
Create new configuration of bash, leave the script field empty, and in the interperter options cell insert:flutter run -d all. It should look something like:
If step two didn't work, create a file call something like run_all.sh in your root project. and put the next lines there(assuming that bin/bash is the path to your bash):
#!/bin/bash
flutter run -d all
type in your terminal:chmod 755 run_all.sh.
Specify run_all.sh in your configuration and bin/bash as your interprter path.
Remove flutter run -d all from interperter options.
It should look something like:
You can always have an external tool watch the files for you and trigger a hot reload.
Flutter supports certain signals to trigger a hot reload natively
--pid-file Specify a file to write the process id to. You can send SIGUSR1 to trigger a hot reload and SIGUSR2 to trigger a hot restart.
Here is an fast example:
#!/usr/bin/env bash
set -euo pipefail
# Remove previous pid files
rm -f /tmp/flutter.pid
# Run in a loop a hot reload call in a subshell
(while true
do
# Wait for flutter to start before monitoring pid
while [[ ! -f /tmp/flutter.pid ]]; do sleep 1; done;
# Send hot reload signal when files change
find lib/ -name '*.dart' | entr -n -d -p kill -USR1 $(cat /tmp/flutter.pid)
done) &
# Run all devices under 1 pid
flutter run -d all --pid-file /tmp/flutter.pid
Idea from: https://medium.com/#kikap/how-to-automatically-hot-reload-flutter-when-dart-source-files-change-6e8fdb523004
For more details on entr: http://eradman.com/entrproject/entr.1.html

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"
}
]
}