0

I'm using a VSCode multi-root workspace. I want to define some tasks in myprojects.code-workspace using a variable for the root directory.

In a regular .vscode/tasks.json I could use ${workspaceFolder}.

However when I create this simple task in .project.code-workspace:

{
  "label":   "foo",
  "type":    "shell",
  "command": "echo ${workspaceFolder}"
}

...it prints the first workspace path:

/home/username/myprojects/project1

instead of:

/home/username/myprojects

So the ${workspaceFolder} variable is obviously unsuitable.

Is there a variable that refers to the multiroot workspace's root?


UPDATE

To address the "why do you want that" query. It's a very common developer setup: similar to a monorepo as all projects are open simultaneously (for convenience), but not really a monorepo:

myprojects/           # multi-root workspace's root
  .code-workspace     # has tasks which target all projects (so needs multiroot's root directory)
  project1/
    .git/
    src/
  project2/
    .git/
    src/
  project3/
    .git/
    src/
lonix
  • 14,255
  • 23
  • 85
  • 176
  • why do you need the location of the `.code-workspace` file in a task, the task is meant to operate on files in a workspace. the `.code-workspace` file can be any ware located on the disk not even near the workspaces mentioned. – rioV8 Aug 20 '23 at 04:22
  • @rioV8 That's one way to do it. But it's also a common practice to have a `myprojects/` folder with `.code-workspace`, and `project1/`, `project2/`, etc. And I'd like to run tasks on various projects, and for that I need the multiroot's root. – lonix Aug 20 '23 at 04:26
  • you can use the named workspace variable [`${workspaceFolder:NAME}`](https://code.visualstudio.com/docs/editor/variables-reference#_variables-scoped-per-workspace-folder) – rioV8 Aug 20 '23 at 04:47
  • @rioV8 Yes that's a nice option, and use it to target individual projects. But I can't use it to target the root itself. Some tasks have scripts which start at the root and operate on all projects. – lonix Aug 20 '23 at 04:49
  • I believe this is a dup of https://stackoverflow.com/q/76213455/11107541. Please take a look and upvote if anything there helps you. – starball Aug 20 '23 at 05:14
  • @starball I don't think it's a duplicate. The underlying problem is the same, but the use cases differ. He wants to use the variable in `.vscode/settings.json` whereas I want to use it in `multiroot/.code-workspace` for tasks. And for my use case, there is a workaround in a solution below, as well as a plugin in another solution below. – lonix Aug 20 '23 at 08:31
  • he use-case doesn't make something not a duplicate if the core question is the same. If it's not a duplicate, then why did you change the link in your answer from your feature-request issue ticket to the issue ticket linked in the answer that I said this is a duplicate of? – starball Aug 20 '23 at 08:35
  • To avoid disagreements with busybodies like you. And, the context on github differs to that here - that one is about adding the feature, whereas here it's about specific problems. – lonix Aug 20 '23 at 08:48

2 Answers2

0

I don't think this is currently possible - variables defined here lack a suitable option.

If you need this functionality, please upvote this issue on the repo, and add your use case!

In the meantime, one could use a workaround:

{
  "label":   "foo",
  "type":    "shell",
  "command": "echo $(dirname ${workspaceFolder})"
}
lonix
  • 14,255
  • 23
  • 85
  • 176
0

If the location of the .code-workspace file is always 1 up of the workspaces it refers to you can use an extension I wrote: Command Variable

{
  "version": "2.0.0",
  "tasks": [
    {
      "label":   "foo",
      "type":    "shell",
      "command": "echo ${input:codeWorkspaceDir}"
    }
  ],
  "inputs": [
    {
      "id": "codeWorkspaceDir",
      "type": "command",
      "command": "extension.commandvariable.workspace.folder1Up"
    }
  ]
}

This works if the current open file is in one of the workspaces.


If you have a task that should also work when you have no files open you can use

{
  "version": "2.0.0",
  "tasks": [
    {
      "label":   "foo",
      "type":    "shell",
      "command": "echo ${input:codeWorkspaceDir}"
    }
  ],
  "inputs": [
    {
      "id": "codeWorkspaceDir",
      "type": "command",
      "command": "extension.commandvariable.transform",
      "args": {
        "text": "${workspaceFolder:NAME}",
        "find": "\\${pathSeparator}\\w+$",
        "replace": ""
      }
    }
  ]
}

You have to fill in a NAME of one of the workspaces.

What it does is remove the last part of the directory of the text for ${workspaceFolder:NAME}. Depending on the kind of workspace names you have to modify the regular expression or you can hard code the folder name.

If you only work on Windows you could use ;-) :

"find": "\\\\\\w+$"

rioV8
  • 24,506
  • 3
  • 32
  • 49
  • Thanks rio! These are nice options and I'm going through them right to see if they work in my environment... – lonix Aug 20 '23 at 04:56
  • @lonix I made a small adjustment to the second option, the path separator could be a backslash that needs to be escaped, an escaped slash should not be a problem – rioV8 Aug 20 '23 at 06:17