Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot define multiple commands in tasks.json #981

Closed
bbenoist opened this issue Dec 3, 2015 · 99 comments
Closed

Cannot define multiple commands in tasks.json #981

bbenoist opened this issue Dec 3, 2015 · 99 comments
Labels
feature-request Request for new features or functionality tasks Task system issues

Comments

@bbenoist
Copy link

bbenoist commented Dec 3, 2015

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?

@dbaeumer dbaeumer added the feature-request Request for new features or functionality label Dec 4, 2015
@danielschmitz
Copy link

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
Copy link

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
Copy link

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 Task system issues label Dec 7, 2015
@felixfbecker
Copy link
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
Copy link

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
Copy link

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
Copy link
Contributor

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

@cfjedimaster
Copy link

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
Copy link
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
Copy link

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
Copy link
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 mentioned this issue Feb 2, 2016
97 tasks
@egamma egamma changed the title Cannot define multiple commands in tasks.js Cannot define multiple commands in tasks.json Feb 4, 2016
@csholmq
Copy link

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
Copy link

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
Copy link

@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
Copy link
Author

@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
Copy link
Author

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
Copy link

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.

@psulek
Copy link

psulek commented Mar 2, 2017

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

@guardrex
Copy link

guardrex commented Mar 2, 2017

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

@Jonathan34
Copy link

Jonathan34 commented Mar 7, 2017

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.

@guardrex
Copy link

guardrex commented Mar 7, 2017

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

@dbaeumer
Copy link
Member

dbaeumer commented Mar 8, 2017

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

@psulek
Copy link

psulek commented Mar 8, 2017

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

@dbaeumer
Copy link
Member

dbaeumer commented Mar 8, 2017

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

@Jonathan34
Copy link

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

@dbaeumer
Copy link
Member

dbaeumer commented Mar 8, 2017

This is definitely a bug with task version 2.0.0. See #22250

@Jonathan34
Copy link

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

@foo-baar
Copy link

foo-baar commented Mar 10, 2017

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.

@guardrex
Copy link

guardrex commented Mar 10, 2017

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

@foo-baar
Copy link

foo-baar commented Mar 10, 2017

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

@guardrex Code Version: 1.8.1 (1.8.1)

@guardrex
Copy link

guardrex commented Mar 10, 2017

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

@dbaeumer
Copy link
Member

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

@foo-baar
Copy link

foo-baar commented Mar 10, 2017

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

@dbaeumer
Copy link
Member

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

@foo-baar
Copy link

Done @dbaeumer, Danke

@dbaeumer
Copy link
Member

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.

@radix
Copy link

radix commented May 5, 2017

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

@dbaeumer
Copy link
Member

dbaeumer commented May 8, 2017

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

@DrYSG
Copy link

DrYSG commented May 8, 2017

@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

@dbaeumer
Copy link
Member

dbaeumer commented May 9, 2017

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

@DrYSG
Copy link

DrYSG commented May 9, 2017

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

@vilicvane
Copy link

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

@dbaeumer dbaeumer removed this from the Backlog milestone Nov 10, 2017
@vscodebot vscodebot bot locked and limited conversation to collaborators Nov 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality tasks Task system issues
Projects
None yet
Development

No branches or pull requests