visual-studio-codepackage-managersvscode-tasks

dependsOn clause conditonal to input variable in Visual Studio Code tasks


I want to define configurable tasks with Visual Studio Code, by defining some input variables.

In my particular case I want one task to depend on the value of the ${input:package_manager} variable with a clause "dependsOn": ["${input:package_manager}"].

However, such setting outputs an error:

Activating task providers all
Couldn't resolve dependent task '${input:package_manager}' in workspace folder 'vscode-remote://

From the documentation it is quite clear that the input variables are not supported in all fields:

Not all values in tasks.json support variable substitution. Specifically, only command, args, and options support variable substitution. Input variables in the inputs section will not be resolved as nesting of input variables is not supported

But what is the alternative to pick up tasks based on user inputs ?

{
    "version": "2.0.0",
    "inputs": [
        {
            "id": "std",
            "description": "std version to be used",
            "type": "pickString",
            "options": ["20","23"],
            "default": "23",
        },
        {
            "id": "build_type",
            "description": "Build type to be used: Debug or Release",
            "type": "pickString",
            "options": ["Debug","Release"],
            "default": "Debug",
        },
        {
            "id": "package_manager",
            "description": "Package Manager",
            "type": "pickString",
            "options": ["vcpkg","conan"],
            "default": "vcpkg",
        },        
    ],
    "tasks": [
        {
            "label": "vcpkg",
            "type": "shell",
            "command": "vcpkg --version",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "hide": true,
        },
        {
            "label": "conan",
            "type": "shell",
            "command": "conan install . -b missing -of build/conan -s compiler=gcc -s compiler.version=14 -s build_type=${input:build_type} -s compiler.cppstd=${input:std}",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "hide": true,
        },
        {
            "label": "Configure CMake",
            "type": "shell",
            "command": "cmake --preset ${input:package_manager} -D CMAKE_BUILD_TYPE=${input:build_type} -DCMAKE_CXX_STANDARD=${input:std}",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "dependsOn": ["${input:package_manager}"],
        },
        {
            "label": "Build Unit Tests",
            "type": "shell",
            "command": "cmake --build --preset ${input:package_manager}-${input:build_type}",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "dependsOn": ["Configure CMake"],
        },
        {
            "label": "Run Unit Tests",
            "type": "shell",
            "command": "cd ${workspaceFolder}/build && ctest -C ${input:build_type} --rerun-failed --output-on-failure",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "problemMatcher": [],
            "dependsOn": ["Build Unit Tests"],
        },
        {
            "label": "Make Docs",
            "type": "shell",
            "command": "cd ${workspaceFolder}/build && make docs ",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "dependsOn": ["Run Unit Tests"],
        },
    ]
}

Solution

  • With the extension I wrote, Command Variable and the command extension.commandvariable.pickStringRemember you can set multiple strings on picking one choice. Use one of these strings as the command of a task.

    {
        "version": "2.0.0",
        "inputs": [
            {
                "id": "std",
                "key": "std",
                "description": "std version to be used",
                "type": "extension.commandvariable.pickStringRemember",
                "options": ["20","23"],
                "default": "23",
            },
            {
                "id": "build_type",
                "key": "build_type",
                "description": "Build type to be used: Debug or Release",
                "type": "extension.commandvariable.pickStringRemember",
                "options": ["Debug","Release"],
                "default": "Debug",
            },
            {
                "id": "pmcommand",
                "description": "Package Manager Command",
                "type": "command",
                "command": "extension.commandvariable.remember",
                "args": { "key": "pmcommand" }
            },
            {
                "id": "rmpackage_manager",
                "description": "Remember Package Manager",
                "type": "command",
                "command": "extension.commandvariable.remember",
                "args": { "key": "package_manager" }
            },
            {
                "id": "rmbuild_type",
                "description": "Remember Build type",
                "type": "command",
                "command": "extension.commandvariable.remember",
                "args": { "key": "build_type" }
            },
            {
                "id": "package_manager",
                "description": "Package Manager",
                "type": "command",
                "command": "extension.commandvariable.pickStringRemember",
                "args": {
                  "key": "package_manager",
                  "options": [
                    ["vcpkg", {
                      "package_manager":"vcpkg",
                      "pmcommand":"vcpkg --version"
                    }],
                    ["conan", {
                      "package_manager":"conan",
                      "pmcommand":"conan install . -b missing -of build/conan -s compiler=gcc -s compiler.version=14 -s build_type=${remember:build_type} -s compiler.cppstd=${remember:std}"
                    }]
                  ],
                  "description": "Pick a Package Manager",
                  "default": "vcpkg"
                }
            },
        ],
        "tasks": [
            {
                "label": "package_manager",
                "type": "shell",
                "command": "${input:pmcommand}",
                "group": "test",
                "presentation": {
                    "reveal": "always",
                    "panel": "shared"
                },
                "hide": true,
            },
            {
                "label": "Configure CMake",
                "type": "shell",
                "command": "cmake --preset ${input:rmpackage_manager} -D CMAKE_BUILD_TYPE=${input:rmbuild_type} -DCMAKE_CXX_STANDARD=${input:std}",
                "group": "test",
                "presentation": {
                    "reveal": "always",
                    "panel": "shared"
                },
                "dependsOn": ["package_manager"],
            },
            {
                "label": "Build Unit Tests",
                "type": "shell",
                "command": "cmake --build --preset ${input:package_manager}-${input:rmbuild_type}",
                "group": "test",
                "presentation": {
                    "reveal": "always",
                    "panel": "shared"
                },
                "dependsOn": ["Configure CMake"],
            },
            {
                "label": "Run Unit Tests",
                "type": "shell",
                "command": "cd ${workspaceFolder}/build && ctest -C ${input:build_type} --rerun-failed --output-on-failure",
                "group": "test",
                "presentation": {
                    "reveal": "always",
                    "panel": "shared"
                },
                "problemMatcher": [],
                "dependsOn": ["Build Unit Tests"],
            },
            {
                "label": "Make Docs",
                "type": "shell",
                "command": "cd ${workspaceFolder}/build && make docs ",
                "group": "test",
                "presentation": {
                    "reveal": "always",
                    "panel": "shared"
                },
                "dependsOn": ["Run Unit Tests"],
            },
        ]
    }
    

    I have not tested it but you can get the idea of how to implement it.

    You might be able to use the Multi Pick option of extension.commandvariable.pickStringRemember and remember multiple strings for certain options and pick a particular one with the __key property.