Cannot define multiple commands in tasks.json #981

Open
bbenoist opened this Issue Dec 3, 2015 · 71 comments

Projects

None yet
@bbenoist
bbenoist commented Dec 3, 2015 edited

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?

@danielschmitz

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" }
@usagi
usagi commented Dec 6, 2015

Hi, I need the feature too ๐Ÿ‘ 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 ). ๐Ÿฐ

@danielschmitz

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" } 
@egamma egamma added the tasks label Dec 7, 2015
@felixfbecker
Contributor

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 :/

@usagi
usagi commented Dec 8, 2015

@felixfbecker It's nice follow-up ๐Ÿ‘ We can use "windows", "linux", and "osx" for cross-platform portability.

@egamma egamma modified the milestone: Backlog Dec 10, 2015
@cfjedimaster

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.

@felixfbecker
Contributor

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

@cfjedimaster

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.

@felixfbecker
Contributor

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

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.

@felixfbecker
Contributor

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.

@egamma egamma referenced this issue Feb 2, 2016
Closed

February Iteration Plan #2616

92 of 97 tasks complete
@egamma egamma changed the title from Cannot define multiple commands in tasks.js to Cannot define multiple commands in tasks.json Feb 4, 2016
@csholmq
csholmq commented Feb 9, 2016

@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"]
        }
    ]
}
@csholmq
csholmq commented Feb 9, 2016

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.

#2840

@brennanMKE

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

@brennanMKE Thanks for the info but I needed to call different executables for different tasks. See @danielschmitz's example implementation for a practical example. #981 (comment)

@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 ๐Ÿ˜ƒ

@bbenoist

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 ๐Ÿš€

@Alphapage

I think the schema in this request could solve the problem: #4475

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

@DanB91
DanB91 commented Apr 23, 2016 edited

@danielschmitz Hmm, the pop up seems to work, but that "runTask/<task_name>" 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 "/<task_name>"....

@GuardRex

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?

@danielschmitz

@DanB91 this code is a suggestion.

@daslicht
daslicht commented Apr 28, 2016 edited

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

@chrismathewson

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

@viperscape

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"
        }
    ]
}
@felixfbecker
Contributor

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

@viperscape

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

@felixfbecker
Contributor

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

@viperscape

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

@felixfbecker
Contributor

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

@ZodmanPerth

@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?

@danielschmitz

@ZodmanPerth

got this error too.... :(

image

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

@GuardRex

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

@hanbaobao2005
hanbaobao2005 commented Aug 17, 2016 edited

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

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

@whitecolor

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

@TommyEsteban

This is the solution for cmake . and make

{
    "version": "0.1.0",
    "command": "sh",
    "args": ["-c", "cmake . && make"],
    "isShellCommand": true,
    "showOutput": "always"
}
@GuardRex GuardRex referenced this issue in GuardRex/vscode-status-bar-tasks Aug 25, 2016
Closed

Task's parent elements aren't considered #8

@GuardRex

@dbaeumer On the backlog for an awfully long time (and related issue: #6496). Is this just not going to happen in the foreseeable future?

I'm getting a little bit of negative feedback (GuardRex/vscode-status-bar-tasks#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 ๐Ÿ‘'s up there .... we really need a way to tell it to either add the command or don't (e.g., #6496).

@dbaeumer
Member

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

@whitecolor

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

@jwatte
jwatte commented Oct 1, 2016

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!

@stkb
Contributor
stkb commented Oct 1, 2016

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

@dbaeumer dbaeumer was unassigned by egamma Oct 10, 2016
@danfma
danfma commented Oct 11, 2016

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.

@TheColorRed
TheColorRed commented Oct 19, 2016 edited

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
@Ciantic
Ciantic commented Oct 20, 2016

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"
        }
    ]
}
@TheColorRed
TheColorRed commented Oct 27, 2016 edited

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
@csholmq
csholmq commented Nov 1, 2016

@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"]
        }
    ]
}
@felixfbecker
Contributor

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

@csholmq
csholmq commented Nov 1, 2016

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

@ydawei
ydawei commented Nov 8, 2016

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

@Oni
Oni commented Nov 12, 2016

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"
            }
        }
    ]
}
@jeffsim jeffsim pushed a commit to jeffsim/typescriptGulpSample that referenced this issue Dec 11, 2016
Jeff Simon Disabled incremental build since it isn't working
// Incremental builds through changedInPlace are not working like I had
naively hoped they would.  I believe now
// that what I need is a (1) background task running which watches for
file updates and updates a dirtyCache with
// them, and (2) in transpilation tasks check the stream's set of files
against that cache and only pass them
// through if they are in there (and then remove them from the cache
once done).  HOWEVER, VS Code doesn't currently
// support that; Microsoft/vscode#981.  So:
leaving in place in case I'm just missing
// something obvious, but disabling since it isn't working.
6a7c9f3
@ghominejad

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

@dbaeumer
Member

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?

@GuardRex
GuardRex commented Jan 20, 2017 edited

@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" ]
        }
    ]
}
@kamranayub
@dbaeumer
Member

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

@TheColorRed
TheColorRed commented Jan 21, 2017 edited

@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"
            ]
        }
    ]
}
@dbaeumer
Member

@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 :-)

@edvinv
edvinv commented Jan 21, 2017 edited

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

@felixfbecker
Contributor

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

@TheColorRed

@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 :-)

@dbaeumer dbaeumer referenced this issue Jan 23, 2017
Closed

Test: multiple commands in tasks.json #19044

2 of 2 tasks complete
@dbaeumer
Member

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

@dbaeumer
Member

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

@stkb
Contributor
stkb commented Feb 2, 2017

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

@dbaeumer
Member
dbaeumer commented Feb 2, 2017

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

@TheColorRed

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

@dbaeumer
Member
dbaeumer commented Feb 7, 2017

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

@TheColorRed
TheColorRed commented Feb 7, 2017 edited

@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
        }
    ]
}
@dbaeumer
Member
dbaeumer commented Feb 8, 2017

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

@jonfasking
jonfasking commented Feb 8, 2017 edited

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
        }
    ]
}
@dbaeumer
Member
dbaeumer commented Feb 9, 2017 edited

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

@jonfasking

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

@dbaeumer
Member

The plan is to give them all there own terminal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment