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

variable substitution in tasks.json #43782

Closed
bobbrow opened this issue Feb 15, 2018 · 18 comments
Closed

variable substitution in tasks.json #43782

bobbrow opened this issue Feb 15, 2018 · 18 comments
Assignees
Labels
feature-request Request for new features or functionality tasks Task system issues
Milestone

Comments

@bobbrow
Copy link
Member

bobbrow commented Feb 15, 2018

The C++ extension has some users who would like access to some information that the extension is currently holding private. Based on the tasks documentation the only way I see to export that information in a way that a task could use it is to add a configuration setting to our package.json.

The trouble is that we don't want our users to be able to modify the setting value. Is there a way to make some settings read-only? Or is there perhaps another way that we can expose information for tasks to consume?

@vscodebot vscodebot bot added the tasks Task system issues label Feb 15, 2018
@dbaeumer
Copy link
Member

@bobbrow I am not sure I understand you correctly. The two other ways are reading a setting maintained by VS Code ${config:} or reading an environment variable ${env:}. What would you like to see supported?

@dbaeumer dbaeumer added the info-needed Issue requires more information from poster label Feb 19, 2018
@bobbrow
Copy link
Member Author

bobbrow commented Feb 20, 2018

${env:} could potentially work, but if our extension modifies the environment in its own context, can VSCode's task running service see those changes? I was under the impression that only our extension would be able to see the changes it made to its environment.

${config: } is based on variables the extension defines in package.json, correct? Since the value that we would want to expose only applies at the folder level and it reflects the current state of IntelliSense for that folder, we wouldn't want this to setting to be modifiable by users, and it also doesn't make a lot of sense to have it be available in the global scope. If there is another way to register a config variable such that it is readable by the tasks service, but not writable by anyone but us, that would be the ideal.

Other ideas we're considering:

  • define a "config" setting in package.json, but if the user tries to change it, just overwrite the value (e.g. set it back to what it was before the user changed).
  • export an API that another extension can consume, and that extension can define and manage the "config" setting. This just kicks the can down the road though. I did make the suggestion to one of the customers who asked for this feature that they didn't need to work with tasks at all if they are writing their own extension and they could just work with an exported API. But there have been other asks from our customers who are not writing extensions and still want to work with tasks.

@dbaeumer
Copy link
Member

Alternatively have you considered to provide a task provider that adds a task programmatically to the system instead of having it in the tasks.json. Then you have the full control over how the command is constructed and there is no need to resolve variables on task execution time.

@bobbrow
Copy link
Member Author

bobbrow commented Feb 21, 2018

We don't know what the task will be or how the requested variable would be used, so I don't think that we can "provide" the tasks. If using the TaskProvider stuff, I would need a callback to resolve the variables the user puts in their tasks.

We could then whitelist a variable (e.g. ${cpptools:activeConfig}) that could be resolved by our extension when the task is about to execute. (maybe: make ${cpptools:activeConfig}). The variable is dynamic so we'd need to re-resolve it every time the task is executed.

Based on what I see in #33523, it doesn't appear that the TaskProvider API was designed to do variable substitution. Perhaps maybe I can request that VSCode allow extensions to register VariableResolvers. I think that would address the issue sufficiently. VSCode could use its default resolver for variables, but if it doesn't find a match, then it could query a backup resolver registered by the extension.

@dbaeumer
Copy link
Member

The resolveTask hook is meant for something different. It is basically a performance optimization to not load a task provider if a task is customized in the tasks.json. But we could have another hook that is called on perExecute to resolve variables in the task.

What exactly do you want to achieve. Having a make release and a make debug. Couldn't these be simply two tasks ?

@bobbrow
Copy link
Member Author

bobbrow commented Feb 22, 2018

make was just an example of a possible command. Our customers use a ton of different build tools and custom scripts, so we can't possibly know what tasks they want. They are also free to name ${activeConfig} anything they want. If they define my_build_script.sh ${cpptools:activeAconfig} <arg2> <arg3> in a task somewhere, is there a way for us to know? We don't want to duplicate VSCode's efforts by parsing tasks.json and then providing a copy of those tasks via the TaskResolver.

@dbaeumer
Copy link
Member

@bobbrow can you provide me with a couple of examples. I am still not fully getting how the various configurations should go together. It sounds a little like half of a task should be specified in task land and the other half somewhere else.

@bobbrow
Copy link
Member Author

bobbrow commented Feb 23, 2018

In the cpptools extension, we have a concept of "configurations" which define compiler settings that we use for IntelliSense. A developer can create multiple configs to change how IntelliSense works on a given subset of code in the workspace. The developer might name these configs to align with how their build system works.

For example, CMake's add_executable("foo") might align with cpptools config "foo". Let's say that the developer wants to build "foo" since that's the code they are working on right now. They might have the following build task:

{
	"version": "2.0.0",
	"tasks" : [
		{
			"label": "build",
			"type": "shell",
			"command": "my_build_script.sh",
			"args": ["${cpptools:activeConfig}", "-verbose", ...],
			"isBackground": true
		}
	]
}

Since "foo" is the active config, "foo" should be substituted in for ${cpptools:activeConfig}

They might also have a launch.json following a similar strategy and they want to launch the executable for the code they are currently working on. It would be nice if our extension could register a backup VariableResolver that can handle variables that VSCode is unable to resolve.

@dbaeumer
Copy link
Member

@bobbrow thanks for the example

Instead of having a plugable resolver service I would rather pass the task to the extension again to allow either tweaking some of the properties or to fully control the execution. This at the end opens up more use cases.

@ajssousa
Copy link

ajssousa commented Mar 9, 2018

Hi.

I have the WSL using Ubuntu and want to use gdb installed on WSL through the VSC.
Evertything works fine if i use the full path like in WSL (e.g. /mnt/c/Users/..)

The problem is if i want to use relative paths, the VSC is not converting an passing right to gdb inside WSL.

My setup:

    "name": "gdb using WSL bash",
    "type": "cppdbg",
    "request": "launch",
    "program": "${workspaceFolder}/s3/S3IDMain",
    "args": [""],
    "stopAtEntry": false,
    "cwd": "${workspaceFolder}/s3/",
    "environment": [],
    "externalConsole": true,
    "pipeTransport": {
        "debuggerPath": "/usr/bin/gdb",
        "pipeProgram": "C:\\Windows\\sysnative\\bash.exe",
        "pipeArgs": ["-c"],
        "pipeCwd": ""
    },
    "sourceFileMap": {
        "/mnt/e": "e:\\"
    },
    "setupCommands": [
        {
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
        }
    ]
},

It says Unexpected GDB output from command "-environment-cd"

The ${workspaceFolder} variable is always converting to Win32 type path. This is correct since I'm in Windows.
But it is possible to have a path translation for the ${workspaceFolder} to a Linux or Windows path type, maybe using a "Linux" or "Win32" tags like cpptools extension is using for the include paths in cpp projects?

@bobbrow
Copy link
Member Author

bobbrow commented Mar 9, 2018

If we get this feature, then we could potentially define an extension-specific variable that would do what you are asking. ${cpptools:linuxWorkspaceFolder} or something like that.

@mbodmer
Copy link

mbodmer commented Mar 22, 2018

I have an additional usage example here, something like what is discussed here.

We work under Linux developing the same software for multiple embedded architectures. So we have multiple configuration since there are multiple toolchains. We use multiple CMake configurations and create a build directory for each configuration e.g: ${workspaceFolder}/build/${currentActiveCppConfiguration}. The build command (make, ninja) then has to be issued in this directory and the vscode build task should adjust the path corresponding to the current selected build configuration in vscode.

Something like this:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build_application_all",
            "type": "shell",
            "command": "ninja -C build/${currentActiveCppConfiguration} all && ninja -C build/${currentActiveCppConfiguration} install",
            "isBackground": true,
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

It would really be a big step forward if we could do this. Thanks for working on it

@mbodmer
Copy link

mbodmer commented May 18, 2018

Sorry for asking again. Is there any update on this?

@dbaeumer
Copy link
Member

No work has started on this. How do you pick your active build configuration? May be you could write an extension that shows a picker and stores the active build configuration in a setting which you can then refer to from ${config:....}

@chkp-roic
Copy link

Another example/question,
Our code building process is done via an http server which starts the build process after receiving a project uuid from the build command. Once the server starts the compilation, GCC compatible output can be fetched from it.
Note: only my extension is aware of the project uuid which is different per workspace.
AFAIU I can implement it by

  • programmatically adding a task which will call a script with the correct workspace uuid. Is this possible?
  • Having my extension manage the build process. This seems to be far from supported.

Bottom line, I'm trying to avoid asking the user to add anything to the configuration files and I want to completely manage the build process.

@alexr00
Copy link
Member

alexr00 commented Dec 21, 2018

I think you can get what you want with command variable substitution. Your extension would define a command, then you can execute the command as part of your task as described here: https://code.visualstudio.com/docs/editor/variables-reference#_settings-command-variables-and-input-variables. Please comment here if this doesn't solve your use-case.

@alexr00 alexr00 closed this as completed Dec 21, 2018
@bobbrow
Copy link
Member Author

bobbrow commented Jan 11, 2019

I'm sorry, I don't understand how that can help us. The extension cannot define the command because we don't know what "task" the user wants to execute. Or are you saying that a command can return a string that we can feed into the args? (e.g. ${command:C_Cpp.getActiveConfiguration})

@dbaeumer dbaeumer assigned alexr00 and unassigned dbaeumer Jan 14, 2019
@alexr00
Copy link
Member

alexr00 commented Jan 15, 2019

I may have misunderstood then. I was saying that a command can return a string that you can feed into the args. Does that help?

@vscodebot vscodebot bot locked and limited conversation to collaborators Feb 4, 2019
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

6 participants