Vscode: Cannot define multiple commands in tasks.json

Created on 3 Dec 2015  ·  99Comments  ·  Source: microsoft/vscode

Hi,

I cannot find a way to define multiple tasks which executes different commands in the .vscode/tasks.json file of my project directory.

From what I understood, I can only declare a single TaskConfiguration within this file. Am I wrong?

To make my problem more understandable, let's say I would like to define 3 tasks with their own set of arguments:

  • foo: foo --arg
  • bar1: bar --arg 1
  • bar2: bar --arg 2

How can I make tasks.json reflect this need?

feature-request tasks

Most helpful comment

Hi, I need the feature too :+1: But, priority is low. Because, we can multiple command with the trick: http://qiita.com/usagi/items/5a0f4edc99420173abb3 ( Sorry, its wrote in Japanese. )

The abstract of the trick are:

  • Use the top-level command to sh or cmd.exe or powershell.exe or any other common shell program.
  • Set the top-level args to -c ( with sh) or /c ( with cmd.exe ) or -Command ( with powershell.exe ).
  • Set sub-level args to any your command with \" quoted. ( eg. : "args" : "\"your-command arg1 arg2 arg3\"" )

Example tasks.json:

{ "version": "0.1.0"
, "command": "sh"
, "isShellCommand": true
, "showOutput": "always"
, "args": [ "-c" ]
, "tasks":
  [ { "taskName": "la"
    , "suppressTaskName": true
    , "args": [ "\"ls -la\"" ]
    }
  , { "taskName": "hoge"
    , "suppressTaskName": true
    , "args": [ "\"echo hoge\"" ]
    }
  , { "taskName": "build"
    , "suppressTaskName": true
    , "args": [ "\"mkdir -k build; cd build; cmake ..; make\"" ]
    }
  , { "taskName": "debug"
    , "suppressTaskName": true
    , "args": [ "\"cd build; gdb bin/my-executable\"" ]
    }
  ]
}

Its can run in the current release version ( 0.10.3 ). :rabbit:

All 99 comments

Let me suggest a simple example to implementation (tasks.json) ....

{
        // ROOT WITHOUT COMMAND
    "version": "0.1.0",
    "isShellCommand": true,
    "showOutput": "silent",
    "args": [],

    "tasks": [
        {
             //CHILDREN WITH COMMAND ;)
            "taskName": "Build Type Script",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "command": "tsc",
            "args": ["tsc -p ."]
        },
        {
            "taskName": "Open Browser",
            "suppressTaskName": true,
            "command": "live-server",
            "args": ["--open public_html"]
        }
    ]
}

AND CTRL+SHIFT+B:

{ "key": "ctrl+shift+b",          "command": "workbench.action.tasks.runTask" }

Hi, I need the feature too :+1: But, priority is low. Because, we can multiple command with the trick: http://qiita.com/usagi/items/5a0f4edc99420173abb3 ( Sorry, its wrote in Japanese. )

The abstract of the trick are:

  • Use the top-level command to sh or cmd.exe or powershell.exe or any other common shell program.
  • Set the top-level args to -c ( with sh) or /c ( with cmd.exe ) or -Command ( with powershell.exe ).
  • Set sub-level args to any your command with \" quoted. ( eg. : "args" : "\"your-command arg1 arg2 arg3\"" )

Example tasks.json:

{ "version": "0.1.0"
, "command": "sh"
, "isShellCommand": true
, "showOutput": "always"
, "args": [ "-c" ]
, "tasks":
  [ { "taskName": "la"
    , "suppressTaskName": true
    , "args": [ "\"ls -la\"" ]
    }
  , { "taskName": "hoge"
    , "suppressTaskName": true
    , "args": [ "\"echo hoge\"" ]
    }
  , { "taskName": "build"
    , "suppressTaskName": true
    , "args": [ "\"mkdir -k build; cd build; cmake ..; make\"" ]
    }
  , { "taskName": "debug"
    , "suppressTaskName": true
    , "args": [ "\"cd build; gdb bin/my-executable\"" ]
    }
  ]
}

Its can run in the current release version ( 0.10.3 ). :rabbit:

Nice @usagi , this is my solution:

{
    "version": "0.1.0",
    "command": "cmd", 
    "isShellCommand": true,
    "showOutput": "silent",
    "args": ["/C"],

    "tasks": [
        {
        "taskName": "Build Type Script",
        "suppressTaskName": true,
        "isBuildCommand": true,
        "args": ["tsc -p ."]
        },
        {
        "taskName": "Open Browser",
        "suppressTaskName": true,
        "isBuildCommand": true,
        "args": ["live-server --open=public_html"]
        }
    ]
}

tip: cmd for windows, sh for linux

shortcut: (override default build command)

{ "key": "ctrl+shift+b",          "command": "workbench.action.tasks.runTask" } 

when i hit ctrl+shift+b, subtasks show up:

05

Bonus:

you can define your own shortcut:

{ "key": "ctrl+shift+alt+o",          "command": "workbench.action.tasks.runTask/taskName" } 

This is very important. Say I want a test command and a build command. The test command needs to run mocha and the build command babel or tsc for example. "command" should be allowed for individual tasks in the tasks array.

The workaround is nice, but it is not cross-platform and quotes have to be escaped.
For cross-platform you would have to define

{
  "linux": {
    "command": "sh",
    "args": ["-c"]
  },
  "osx": {
    "command": "sh",
    "args": ["-c"]
  },
  "windows": {
    "command": "powershell",
    "args": ["-Command"]
  }
}

and then duplicate the tasks property for every single OS :/

@felixfbecker It's nice follow-up :+1: We can use "windows", "linux", and "osx" for cross-platform portability.

Another plus one - and in my case, I can't use the workaround since I need a per OS switch and I can't rely on sh or cmd.

@cfjedimaster Why can't you use the workaround exactly?

Because my top level command would be start on Windows and open on OSX. So I can't use _just_ cmd or _just_ start and pass different args.

@cfjedimaster You mean like this?

{
  "version": "0.1.0",
  "isShellCommand": true,
  "osx": {
    "command": "sh",
    "args": ["-c"],
    "tasks": [
      {"name": "run", "args": ["open mysuperawesomefile.txt"]}
    ]
  },
  "windows": {
    "command": "cmd",
    "args": ["/C"],
    "tasks": [
      {"name": "run", "args": ["start mysuperawesomefile.txt"]}
    ]
  }
}

Yes. But to be clear, I wouldn't want to replicate all the tasks for both. Basically, I want to be able to do N tasks per file as the original requestor suggested. For me, 9 of the 10 tasks I want can all be in one definition. _One_ of them is different though and needs to do X for Windows and Y for OSX.

Yeah I know it _is_ a lot of code duplication, which is why they should really implement this feature. But for the time being, it's what works.

@danielschmitz From your example, only the first taskName runs when I press Ctrl+Shift+B. I don't get presented with a list as in your screenshot.

task does however present me with that list and both my options runs.

{
    "version": "0.1.0",
    "command": "cmd", 
    "isShellCommand": true,
    "showOutput": "silent",
    "args": ["/C"],

    "tasks": [
        {
        "taskName": "Build CustApp",
        "suppressTaskName": true,
        "isBuildCommand": true,
        "args": ["${cwd}/Sw/A_XMC/make_all.bat"]
        },
        {
        "taskName": "GTAGS",
        "suppressTaskName": true,
        "isBuildCommand": true,
        "args": ["gtags"]
        }
    ]
}

Sorry @danielschmitz I misread your comment on adding workbench.action.tasks.runTask. Though I created a ticket for the same popup behavior with workbench.action.tasks.build.

https://github.com/Microsoft/vscode/issues/2840

@bbenoist I set up my VS Code tasks to use my Gruntfile.js tasks.

I simply hit F1 and enter task test and it runs my tests. I can do this for any task I have configured.

{
    "version": "0.1.0",
    "command": "grunt",
    "isShellCommand": true,
    "args": [
        "--no-color"
    ],
    "tasks": [
        {
            "taskName": "clean",
            "args": [],
            "isBuildCommand": false,
            "problemMatcher": "$msCompile"
        },
        {
            "taskName": "build",
            "args": [],
            "isBuildCommand": true,
            "problemMatcher": "$tsc"
        },
        {
            "taskName": "tslint",
            "args": [],
            "isBuildCommand": false,
            "problemMatcher": "$msCompile"
        }
    ]
}

@brennanMKE Thanks for the info but I needed to call different executables for different tasks. See @danielschmitz's example implementation for a practical example. https://github.com/Microsoft/vscode/issues/981#issuecomment-162330360

@danielschmitz @usagi @felixfbecker @cfjedimaster @csholmq Thanks everyone for the feedback and suggestions!

FYI, I ended up using Jake to define all my tasks and pushed my concept up to calling a vscode-configure task which makes the Jakefile regenerate its tasks and the appropriate .vscode configuration from the content of the JSON file.

First here is a bit of context about the app I wanted to configure VS Code for:

  • Native development: C++ and Fortran
  • Build is CMake-based.
  • Daily usage of remote clusters and Vagrant boxes to build and debug.
  • Cross platform code on both Windows and Linux.

My custom Jakefile allowed me to add the following capabilities to VS Code:

  • Multiple target configuration management. You can create variants of any property.
  • Execute task locally, via SSH or via Vagrant SSH and WinRM commands.
  • Support remote debugging by generating appropriate configuration for webfreaks.debug.
  • Support Error and Warning locations by generating the appropriate problem matchers. It even works when building via SSH.
  • Allow configuration inheritance to prevent configuration duplication.
  • Declare virtual configurations whose purpose is only to be inherited.
  • Any task can make a reference to a single custom problem matcher.

Unfortunately, I cannot share my work for now because I need a special agreement for this. However, I can show you an example of a JSON configuration which would be compatible with the system I described:

{
  "defaultConfig": "ubuntu-debug",
  "problemMatchers": {
    "gcc": {
      "owner": "gcc",
      "fileLocation": [ "relative", "${workspaceRoot}" ],
      "pattern": {
        "regexp": "^(${sourceDir}\\/)?(.*):(\\d+):\\d+:\\s+(warning|error):\\s+(.*)$",
        "file": 2, "line": 3, "severity": 4, "message": 5
      }
    },
    "gfortran": {
      "owner": "gfortran",
      "fileLocation": [ "relative", "${workspaceRoot}" ],
      "pattern": [
        {
          "regexp": "^(${sourceDir}\\/)?(.*):(\\d+)\\.\\d+:\\s*$",
          "file": 2, "line": 3
        },
        {
          "regexp": "^\\s*(.*)$",
          "code": 1
        },
        { "regexp": "^.*$" },
        {
          "regexp": "(Error|Warning):\\s*(.*)$",
          "severity": 1, "message": 2, "loop": true
        }
      ]
    }
  },
  "configs": {
    "local": {
      "enabled": false,
      "sourceDir": "${workspaceRoot}",
      "cpus": 8,
      "problemMatchers": [ "$msCompile" ]
    },
    "vagrant": {
      "enabled": false,
      "useVagrant": true,
      "sourceDir": "/src",
      "cpus": 1,
      "problemMatchers": [ "gcc", "gfortran" ]
    },
    "debug": {
      "enabled": false,
      "cmake": { "buildType": "Debug" }
    },
    "release": {
      "enabled": false,
      "cmake": { "buildType": "Release" }
    },
    "ubuntu-debug": {
      "enabled": true,
      "buildDir": "/home/vagrant/build-debug",
      "parents": [ "vagrant", "debug" ]
    },
    "ubuntu-release": {
      "enabled": true,
      "buildDir": "/home/vagrant/build-release",
      "parents": [ "vagrant", "release" ]
    },
    "local-debug": {
      "enabled": true,
      "build-dir": "${workspaceRoot}/build-debug",
      "parents": [ "local", "debug" ]
    },
    "local-release": {
      "enabled": true,
      "build-dir": "${workspaceRoot}/build-release",
      "parents": [ "local", "release" ]
    }
  }
}

Alternatives which would provide all the capabilities listed below in a simpler configuration file are welcome :smiley:

Not 100% related but interested people can take a look at the new Shell extension I made. It's able to run shell commands directly from the editor :rocket:

I think the schema in this request could solve the problem: https://github.com/Microsoft/vscode/issues/4475

It allows to define multiple commands and it is very easy to transform to the current tasks.json schema.

@danielschmitz Hmm, the pop up seems to work, but that "runTask/" doesn't seem to work. It says "No handler found" when I invoke the keybinding. I'd like to keybind 2 different task_names. Can't seem to find any documentation on that "/"....

I'm getting questions on this issue for my Status Bar Tasks extension. My extension simply passes whatever is in the arguments directly to Node's child_process module for execution. To make VS Code happy, I have a shell command in the top-level command (aka the @usagi method).

It looks like this slipped for the April iteration. Can we expect this to be fixed in May?

@DanB91 this code is a suggestion.

It would be also nice to be just able to use the "play" button to start a task instead of navigating trough a menu. Maybe an option for each task , serial , parallel ...

@danielschmitz the suggestion code, with the command property within the tasks themselves, says "Propery 'command' not allowed'. Plus,without a command property at the top outside of tasks, ctrl+shift+b says there's no tasks found.

I actually used gulp to solve this issue, since while this is a vs code limitation, it also is a single-threaded limitation (cannot have two file-watchers for example). Instead, gulp is file-watching, I simply run the task from vs code so I can see the output and control the task life cycle. Note that I do not filewatch from the task.json and it happens inside the gulp file. Also the gulp file uses the tsconfig for properties, so tsc is configured in the usual manner.

gulpfile.js
var gulp = require('gulp');
var markdown = require('gulp-markdown');
var ts = require('gulp-typescript');

gulp.task('markdown', function() {
    return gulp.src('**/*.md')
        .pipe(markdown())
        .pipe(gulp.dest("build/"));
});

var tsProject = ts.createProject('tsconfig.json');
gulp.task('typescript', function() {
    var tsResult = tsProject.src()
        .pipe(ts(tsProject));

    return tsResult.js.pipe(gulp.dest('build'));
});

gulp.task('default', function() {
    gulp.watch('**/*.md', ['markdown']);
    gulp.watch('**/*.ts', ['typescript']);
});

tasks.json
{
    "version": "0.1.0",
    "command": "gulp",
    "showOutput": "always",
    "isShellCommand": true,
    "tasks": [
        {
            "taskName": "default",
            "isBuildCommand": true,
            "showOutput": "always"
        }
    ]
}

@viperscape This has little to do with being single-threaded, Gulp is just as single-threaded as VS Code itself, and tasks are always run in a seperate process.

@felixfbecker the gulp task is watching _two_ file types simultaneously:

gulp.task('default', function() {
    gulp.watch('**/*.md', ['markdown']);
    gulp.watch('**/*.ts', ['typescript']);
});

Using this example: I'm not sure how you could simulate this using vscode tasks because filewatching is a blocking procedure.

@viperscape this is issue is not about running two tasks in parallel, but defining different commands for different tasks

@felixfbecker I understand, just pointing out that the current work around posted above does not ideally work for blocking commands, thus the gulp solution. I'm eager to do this all within vs code tasks, instead of gulp-- when full support is added. While it's being developed, I thought it was important to point this out, as I assume people might want to run a file watcher on multiple types of files to run separate commands on them; like compiling markdown and typescript. Additionally, if anyone is interested, there is gulp-run which might also fill any gaps in the mean time.

@viperscape Even if VS Code supports multiple commands you will still not be able to run them in parallel...

@danielschmitz I've configured tasks in a similar way to you. However after I run the live-server task, any subsequent task I run results in the VSCode error "There is an active running task right now. Terminate it first before executing another task". Obviously live-server continues to run to serve the page.

VSCode appears to only support one running task at a time. I wonder; are you experiencing the same behaviour? Have some other configuration you haven't listed in this issue log that lets the magic happen?

@ZodmanPerth

got this error too.... :(

image

my personal soluction now is open a console/terminal and run a npm task...

@danielschmitz I sort of do something similar with my Status Bar Tasks extension. Since it runs tasks using Node's child_process module, I believe it can run simultaneous tasks.

Here is my sample to run Python3.1 and Python3.5

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "cmd",
    "isShellCommand": true,
    "args": ["/C"],
    "showOutput": "always",
    "tasks": [
        {
            "taskName": "Python3.1",
            "suppressTaskName": true,
            "isBuildCommand": true,
             "args": ["D:\\Program Files (x86)\\python3.1\\python.exe", "-u", "${file}" 
            ]
        },
        {
            "taskName": "Python3.5",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "args": ["D:\\Program Files (x86)\\python3.5\\python.exe", "-u",  "${file}" 
            ]
        }
    ]
}

Hope this out soon with proper UI with concurrent tasks, visible tasks names, runtime state.

I also belive running tasks with state could be shown on bottom status bar and clickable to open/hide output.

This is the solution for cmake . and make

{
    "version": "0.1.0",
    "command": "sh",
    "args": ["-c", "cmake . && make"],
    "isShellCommand": true,
    "showOutput": "always"
}

@dbaeumer On the backlog for an awfully long time (and related issue: https://github.com/Microsoft/vscode/issues/6496). Is this just not going to happen in the foreseeable future?

I'm getting a little bit of negative feedback (https://github.com/GuardRex/vscode-status-bar-tasks/issues/8) regarding my extension over this problem persisting. My extension is opinionated on this point, where I have it only using what the dev puts into the task arguments as the full command to run for Node's child_process module.

Two devs now have asked me about not doing it that way and figuring out some option that will allow the top-level command to be prefixed to the arguments the way VSC normally runs tasks from the Command Palette.

However, I agree with this issue and those 24 other :+1:'s up there .... we really need a way to tell it to either add the command or don't (e.g., https://github.com/Microsoft/vscode/issues/6496).

@GuardRex I see your frustration around this (and from the others). Believe me.

Since we are a small team of developers, there is only so many feature requests and issues we can work on for one milestone. Every month we pick items from the backlog to plan for the current iteration. Please see https://github.com/Microsoft/vscode/wiki/Issue-Tracking#planning for more information. Nevertheless we always welcome pull requests and are happy to accept them if they meet our quality standards.

@dbaeumer wanted to say thank you to all you guys, despite all current limitations and issues VSCode became my editor of choice, you are doing really great job.

The problem with "use sh as the task runner" is that that won't work for Windows developers.
Or, alternatively, "use cmd as the task runner" won't work with Mac / Linux developers.
Starting out in VSCode, I _immediately_ run into this problem, because I want to build typescript and sass files into my runnable project, and there's no simple way to specify "do A and B when building."
So, I have to install and learn one of the zillions of build tools available in node (like gulp) just to get my very first page off the ground.
This is an extremely poor new-user experience, and for teams of more than one developer, forcing everybody to use the same OS is of course a non-starter.
Therefore, I submit that this should actually be a higher priority problem to fix!

@jwatte You can already specify different commands for different platforms, as mentioned above in this thread and explained at http://code.visualstudio.com/docs/editor/tasks. To just run a typescript and a sass command what you want would look something like this:

{
    "version": "0.1.0",
    "windows": {
        "command": "cmd",
        "args": ["/C", "typescript command && sass command"]
    },
    "linux": {
        "command": "sh",
        "args": ["-c", "typescript command && sass command"]
    },
    "osx": {
        "command": "sh",
        "args": ["-c", "typescript command && sass command"]
    },
    "isShellCommand": true,
    "showOutput": "always"
}

Also as noted above, it's a fair bit of repetition, but it works. An alternative method, to avoid the repetition, would be to use npm's own script-running capabilities. There's no need to go so far as to use gulp or grunt here.

This feature will be nice because if you had a dotnet project and a typescript project at the same root directory, you have to choose between one or another to build.

I would like to be able to build a whole project, in one build command and create 4 files in this example:

  • Sass core -> master.css
  • Sass theme1 -> mytheme1.css
  • Sass theme2 -> mytheme2.css
  • TypeScript -> master.js

Sneaky trick, settting space as command works on Windows:

{
    "version": "0.1.0",
    "command": " ",
    "isShellCommand": true,
    "args": [],
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "build",
            "args": ["dotnet", "build", "src/Api/"],
            "isBuildCommand": false,
            "isWatching": false,
            "problemMatcher": "$msCompile"
        }
    ]
}

Another thing you can do is put it in a sh file to make it easy:

{
    "version": "0.1.0",
    "linux": {
        "command": "sh",
        "args": ["${workspaceRoot}/.vscode/build.sh" ]
    },
    "osx": {
        "command": "sh",
        "args": ["${workspaceRoot}/.vscode/build.sh"]
    },
    "windows": {
        "command": "sh",
        "args": ["'${workspaceRoot}\\.vscode\\build.sh'"]
    }
}

Note: I am not sure if the windows sh works because I have WSL installed or because I installed git with linux commands, or if it just works in windows.

Then in the sh file You could have something like this:

# Build the TypeScript
tsc

# Build the core css
node-sass src/sass/main.scss dist/css/main.css

# Build the theme
node-sass src/sass/themes/material/main.scss dist/css/themes/material.css

@Ciantic Not sure if I'm missing the point here. But why the space? This works for me:

{
    "command": "${workspaceRoot}/Sw/A_XMC/make.bat",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "1. Build",
            "args": ["all"],
            "isBuildCommand": true
        },
        {
            "taskName": "2. Rebuild",
            "args": ["rebuild"]
        },
        {
            "taskName": "3. Clean",
            "args": ["clean"]
        }
    ]
}

@csholmq This issue is about defining different commands per task. You are defining make.bat for all tasks.

@felixfbecker Ah, so simple. That's what I missed :)

On Linux, I suggest using env -- foo -arg blah instead of bash -c "foo -arg blah" to get rid of those inconvenient quotes.

I think that the spirit of VSCode tasks is: forget bash scripts, just define here what you want to do (build resources, compile, deploy etc.). It's impossible to achieve this using a common command for everything (unless you use the cmd or sh tricks).

I think that the most flexible solution would be to allow BaseTaskConfiguration inside the TaskDescription.

E.g.

{
    "version": "0.1.0",
    "command": "my_default_command",
    "args": ["--default", "--args"],
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "run",
            "args": ["main.py"],
            "windows": {
                "command": "python.exe"
            },
            "linux": {
                "command": "python"
            }
        }
    ]
}

Is it possible defining different commands by different file extensions?

[
    {
        "extension" : ".ts",
        "version": "0.1.0",
        "command": "tsc",
        "isShellCommand": true,
        "args": ["./${file}"],
        "showOutput": "silent",
        "problemMatcher": "$tsc"
    },
    {
        "extension" : ".scsc",
        "version": "0.1.0",
        "command": "node-sass",
        "isShellCommand": true,
        "args": ["./${file}"],
    }
]

In fact i need to build the current opened file and i don't want to use gulp and other tools
Thanks

I added support to be able to have different command per tasks. It looks like this:

{
    "version": "0.1.0",
    "tasks": [
        {
            "taskName": "grunt",
            "command": "grunt",
            "args": [
                "compile"
            ]
        },
        {
            "taskName": "gulp",
            "command": "gulp",
            "args": [
                "deploy"
            ]
        }
    ]
}

This thread is very long and quite some comments deal with workarounds to overcome the one command limitation. The new solution will also support OS specific command redefinition per task.

Is there anything that is not covered by this expect the request to have a command per file extension?

@dbaeumer With this new feature, is the top-level command that we current have going away? ... or does it work such that if it sees the command on the task that it ignores the top-level command?

What happens if you have this ...

{
    "version": "0.1.0",
    "command": "gulp",
    "isShellCommand": true,
    "showOutput": "silent",
    "args": [],
    "tasks": [
        {
            "taskName": "grunt",
            "command": "grunt",
            "args" : [ "compile" ]
        }
    ]
}

This is perfect for the use cases I've seen in our projects.

On Fri, Jan 20, 2017, 15:35 Luke Latham notifications@github.com wrote:

@dbaeumer https://github.com/dbaeumer With this new feature, is the
top-level command that we current have going away? ... or does it work such
that if it sees the command on the task that it ignores the top-level
command?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/981#issuecomment-274185963,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAiaa89zOHNfrGqTpCE4TFWdLt6JEkUzks5rUSiegaJpZM4GuOMJ
.

@GuardRex you can still define a top-level command that tasks inherit. If they define their own it overrides the top level.

@dbaeumer Is it possible to trigger one command based on the files that have changed when in watch mode? Here is an example of what I mean:

{
    "version": "0.1.0",
    "tasks": [
        {
            "taskName": "typescript",
            "command": "tsc",
            "watchMode": true,
            "watchFiles": [
                "**/*.ts",
                "tsconfig.json"
            ]
        },
        {
            "taskName": "sass",
            "command": "node-sass",
            "watchMode": true,
            "args": [
                "src/scss/master.scss"
            ],
            "watchFiles": [
                "**/*.scss"
            ]
        }
    ]
}

@TheColorRed no this is not planned. For typescript this is better achieved using the tsc -w option. For compilers that don't support this I would recommend using an external task system that supports this (e.g. gulp watch). If we do this in VSCode we would start a node-sass process everytime a *.scss file changes. Not very efficient and it will drain the battery on laptop :-)

@dbaeumer Will there be command to see all currently running tasks and to kill individual and/or all of them.

There is also a watch CLI on npm, this is totally possible with the current system.

@dbaeumer That is too bad, I was hoping that a gulp watch like system could be added to this... Many of my gulp files are redundant, so to me it would be more convenient to have it in the json file :-)

@edvinv we rely on the terminal support here. If you start a task in the terminal you will see something like this:
capture

So there is currently no plan to built an extra UI for this.

@TheColorRed IMO such a support should then go into the corresponding language server. I know that for TS we have plans to support compileOnSave and full project compile. Something comparable could be built for saas as well.

@dbaeumer Just tried it in 1.9 and it's working nicely, although I did notice one thing, a "isShellCommand": true at the top level isn't inherited by tasks under it if they have their own command. Adding isShellCommand:true to each task (where required) fixes it.

Not sure if this is intentional; I can see the logic either way though I would have expected it to be inherited.

@stkb actually this is intended. The idea is that as soon as you specify a command on a task level it will not inherit from a global command. I thought that will be easier to explain especially when merging would merge args and options.

@dbaeumer not sure if no one thought about this or if the idea was omitted on purpose, but in the launch.json file there is an option for preLaunchTask. However there isn't a way to run multiple launch tasks that I can see.

@TheColorRed do you mean more than one task on prelaunch? The idea here is that you can have compound tasks in the tasks.json so that the debugger can still refer to one pre launch task.

@dbaeumer what I have in mind is having 2+ pre launch tasks, so for example take this configuration:

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "preLaunchTask": [
                "Build Server",
                "Build Client"
            ]
        }
    ]
}

This would then build the server and once that is done build the client.

Another thought (maybe a better approach)

Allow for a task to have something like an onComplete (or onFinish like gulp/node use) event which could trigger another task. So, for example using the above you could do something like this:

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "preLaunchTask": "Build Server"
        }
    ]
}

This would then trigger the task below as it does now, but then that task has an onComplete which would then trigger the other task. This would helpful in chaining tasks together.

tasks.json

{
    "version": "0.1.0",
    "tasks": [
        {
            "taskName": "Build Server",
            "onComplete": "Build Client"
            // Other settings here
        },
        {
            "taskName": "Build Client"
            // Other settings here
        }
    ]
}

@TheColorRed ok. We have something like this on the plan however the syntax will be different. It will go more like

{
    "tasks": [
        {
            "taskName": "Build Server",
            // More properties
        },
        {
            "taskName": "Build Client",
            // More properties
        },
        {
             "taskName": "Build",
             "dependsOn: ["Build Server", Build Client"]
        }
    ]
}

We are still discussion how to best express sequencing and parallel execution here.

I apologize if I have missed the solution to my question already. This seems like the best place to drop my question, because it does surround this issue. Is there a way, (or will there be a way) to configure tasks.json to run all tasks defined with a single, top level task name? Ideally, I would like to be able to run the default
ctrl+shft+B
and have it kick off _all_ tasks defined.

E.g:
I have all my scripts defined in my package.json to so they're available across all IDEs/editors.

  "scripts": {
    "typescript": "tsc -w",
    "gulp": "gulp",
    "test": "./node_modules/karma/bin/karma start",
    "build": "webpack --config build/webpack.build.config.js",
    "start": "webpack-dev-server --config build/webpack.dev.config.js"
  },

For vs code though, I would like to be able to bundle all them up in the tasks.json. Then pop the default build command have it kick off all these tasks:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "args": [
        "run"
    ],
    "showOutput": "always",
    "runAll": true // <= DOES SOMETHING LIKE THIS EXIST????
    "tasks": [
        {
            "taskName": "typescript",
            "isBuildCommand": true
        },
        {
            "taskName": "test",
            "isBuildCommand": true
        },
        {
            "taskName": "start",
            "isBuildCommand": true
        },
        {
            "taskName": "gulp",
            "isBuildCommand": true
        }
    ]
}

Yes it is planed, but the syntax will be slightly different. More along something like this:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "args": [
        "run"
    ],
    "showOutput": "always",
    "tasks": [
        {
            "taskName": "typescript",
        },
        {
            "taskName": "test",
        },
        {
            "taskName": "start",
        },
        {
            "taskName": "gulp",
        },
        {
             "taskName": "build",
             "dependsOn" : ["gulp", ....],
             "isBuildCommand": true
        }
    ]
}

Major reason being is that I actually want to deprecated isBuildCommand in favour of assigning key bindings to task so that people can use more than one keyboard short cut

Fantastic! Will each of those subtasks be assigned their own dedicated terminal session, or all stdout & stderr redirected to the output?

The plan is to give them all there own terminal.

From the comments above, I am not sure what works and what does not.

This is my tasks.json which consists of 2 tasks to compile client side code and express server code. If I run tsc with the separate tsconfigs on the command line, it works fine. In VSCODE it appears that only the first task is run. Is there something missing or is it not possible to do this in VSCODE?

{
"version": "0.1.0",
"tasks": [
{
"taskName": "tsc",
"command": "tsc",
"args": ["-w","--listEmittedFiles","-p","tsconfig-client.json"],
"isBuildCommand": true,
"isShellCommand": true,
"isBackground": true,
"suppressTaskName": true,
"problemMatcher": "$tsc-watch"
},
{
"taskName": "tsc",
"command": "tsc",
"args": ["-w","--listEmittedFiles","-p","tsconfig-server.json"],
"isBuildCommand": true,
"isShellCommand": true,
"isBackground": true,
"suppressTaskName": true,
"problemMatcher": "$tsc-watch"
}
]
}

Release notes (v.1.10.0) just came out for this. The example format is ...

{
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "Client Build",
            "command": "gulp",
            "args": ["build"],
            "isShellCommand": true,
            "options": {
                "cwd": "${workspaceRoot}/client"
            }
        },
        {
            "taskName": "Server Build",
            "command": "gulp",
            "args": ["build"],
            "isShellCommand": true,
            "options": {
                "cwd": "${workspaceRoot}/server"
            }
        },
        {
            "taskName": "Build",
            "dependsOn": ["Client Build", "Server Build"]
        }
    ]
}

@GuardRex just tried it with latest 1.10.1 build, but got error:

Error: the task 'START' doesn't define a command. The task will be ignored. Its definition is:
{
    "taskName": "START",
    "dependsOn": [
        "webpack-dev-watch",
        "npm-start"
    ]
}

Problem solved, my tasks.json file has "version": "0.1.0", when i changed version to 2.0.0 it starts working!

@psulek Great catch! I'm glad you let me know ... I have an extension that doesn't support this now, but my users might be demanding that I do support it later.

is there a way to make the tasks running one after the other?
{ "taskName": "Build", "dependsOn": ["Client Build", "Server Build"] }

this will build the client and server build in parallel and the last build will hide the first build result ("press a key to continue").

I created a meta task for test that call all the test tasks on the dotnet projects I need. But the first runs are hidden by the last one until you press enter.

@Jonathan34 I'm sorry. That's not supported by the extension. That's a new feature for VSC, and I haven't had a chance to look at it.

@Jonathan34 yes there is: The dependsOn works like dependent task in any other task runner (for example like gulp). If you want to depend the client build on the server build do:

{
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "Client Build",
            "command": "gulp",
            "dependsOn": "Server Build",
            "args": ["build"],
            "isShellCommand": true,
            "options": {
                "cwd": "${workspaceRoot}/client"
            }
        },
        {
            "taskName": "Server Build",
            "command": "gulp",
            "args": ["build"],
            "isShellCommand": true,
            "options": {
                "cwd": "${workspaceRoot}/server"
            }
        }
    ]
}

This will execute them in sequence.

@dbaeumer As this is true you cant use it like this:
taskA -> depends on [taskB, taskC] - where taskB and taskC is executed in synchronous way because now they are executed in parallel.

You need to do it this way (in current implementation):
taskC -> depends on taskB
taskB -> depends on taskA

And you need to run taskC, which is not equal to run taskA which has deps on [taskB, taskC].

@psulek agree in our scenario.

But the client server build example had an artificial Build task which didn't run a command. Therefore I removed it and made client build depend on server build.

So if you want to run two tasks in parallel you need a artificial task (without a command) to describe this. If you want to run two task in sequence you don't need and artificial task.

@dbaeumer @psulek that should work i will try! thanks

I have another problem with this:
in launch.json (v 0.2.0) i have added some debugging entries with a preLaunchTask.
when i now debug, i get: There is a task {0} running. Can not run pre launch task build.
if i empty the content of the preLaunchTask, it works but the code is not built before.

Could it be that upgrading the tasks,json to v2.0.0 while having a launch,json at version 0.2.0 creates some incompatibilities?

launch.json

"version": "0.2.0",
    "configurations": [{
     {
            "name": ".NET Core Launch (myapp)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceRoot}/Services/myapp/src/bin/Debug/netcoreapp1.1/myapp.dll",
            "args": [],
            "cwd": "${workspaceRoot}/Services/myapp/src/bin/Debug/netcoreapp1.1/",
            "stopAtEntry": false,
            "externalConsole": false,
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Local",
                "ASPNETCORE_URLS": "http://*:5000"
            }
     }]

tasks.json

"version": "2.0.0",
    "command": "",
    "isShellCommand": true,
    "args": [],
    "tasks": [{
            "taskName": "build",
            "command": "dotnet",
            "args": [
                "build"
            ],
            "options": {
                "cwd": "${workspaceRoot}"
            },
            "isBuildCommand": true,
            "showOutput": "always",
            "problemMatcher": "$msCompile"
        },
        //... some other tasks here not related to build and a dependency between those.
]}

This is definitely a bug with task version 2.0.0. See https://github.com/Microsoft/vscode/issues/22250

Workaround is to empty the preLaunchTask value to "" and build manually before running the tests.

Team,

Just started using vscode and couldn't make multiple commands work, for e.g below I am trying to run a static html file in chrome and trying to transpile my Sass file:

{
    "version": "0.1.0",
    "isShellCommand": true,
    "showOutput": "silent",
    "args": [],
    "tasks": [
        {
            "taskName": "Run",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "command": "Chrome",
            "osx": {
                "command": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
            },
            "args": [
                "${file}"
            ]
        },
        {
            "taskName": "NodeTranspile",
            "command": "node-sass",
            "suppressTaskName": true,
            "args": [
                "myLoc.scss",
                "myLoc.css"
            ]
        }
    ]
}

OUTPUT:
Error: no valid command name provided.

Am I doing something wrong ?

{Both tasks works fine if ran individually.}

Thanks much in advance for your time.

@foo-baar Do you have to change "version": "0.1.0", to "version": "2.0.0",? ... I thought someone said that has to be done (for new features anyway).

@GuardRex
screen shot 2017-03-10 at 12 54 47 pm

@GuardRex Code Version: 1.8.1 (1.8.1)

@foo-baar Old version of VSC? What's it say for the version under Help > About? Current version should be 1.10.2.

Commands per task work even in the old runner, but require 1.9

@dbaeumer Your response raised good point to my suspicion: why my vscode was not auto updated or shown me a latest version is available ? Shall it be raised as a separate bug ? (case it's not known issue)

(BTW: Updating to latest version fixed the task.json issue, thanks on that).

@foo-baar yes, please open a separate issue for that. VS Code should inform you about updates.

Done @dbaeumer, Danke

Having different commands for different tasks is available since 1.9. I am closing the issue. If anyone sees problems with the support available since 1.9 please open a separate issue.

@dbaeumer Hi! Since you closed this ticket (and also closed #7863 as a duplicate of this one), does that mean that vscode now supports concurrent execution of commands?

It does with the new terminal runner you need to opt in using "version": "2.0.0"

@dbaeumer Hey, this is great. Can you advertize this to the world! See my Stack Overflow question:
https://stackoverflow.com/questions/43809502/getting-babel-to-watch-two-folders

@DrYSG we will. We are currently working on making the terminal runner the default and writing corresponding documentation.

@dbaeumer here is a idea (suggestion?) If I have 4 background tasks running, I don't really want to keep swapping the display for each task. I would like to be able to merge a few terminal outputs, and have a header (TASK 1: -> output string , etc. ) so that I can follow a few tasks at at a time and see what they are doing.

@DrYSG you may want to check out my https://github.com/vilic/biu. (Sadly not well-documented)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

villiv picture villiv  ·  3Comments

v-pavanp picture v-pavanp  ·  3Comments

mrkiley picture mrkiley  ·  3Comments

biij5698 picture biij5698  ·  3Comments

shanalikhan picture shanalikhan  ·  3Comments