-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
TaskProvider: resolveTask() never gets called #33523
Comments
@LaurentTreguier the API is currently in for a feature we would like to provide in the future. The idea is not that an extension can provide an incomplete task and that the task can be resolved later. Could you provide an example where that would be valueable. The idea of the feature is to resolve tasks configuration defined in tasks.json without calling provideTasks first. |
So the feature is simply not yet implemented ? The fact that I can't get it to work makes more sense now 😅... |
Yes, that is the idea. The reason being is that fetching all tasks takes a while and if a task is customized in the tasks.json we could resolve it without fetching all tasks. |
I spent quite some time of making task multi folder aware. I will postpone that one for September. |
@dbaeumer have you had time to return to this issue? It seems that this API will be VSCode's mechanism to enable users to provide customizations for detected tasks. I'm working on enabling the taskProvider API in the C# extension and it is important for us to enable user-driven customization [e.g. selecting a build configuration like debug|release]. It would be great to know when this is coming so we can better plan our next steps! |
@TheRealPiotrP having Can you explain in an example what currently isn't working for me better understand what is missing for the C# team. |
@dbaeumer thanks! I think I may have jumped to a solution instead of focusing on the problem I'm trying to solve, so let's do a slight reboot. In the 0.1.0 tasks.json format, .NET tasks looked like this:
This is largely boilerplate, so I'm glad we're able to reduce it with the Tasks API. However, a nice feature of this format was that we could guide users to selectively modify the
My expectation with task customization is that I should be able to expose a custom property on my task e.g. Configuration and allow the user to modify that property. However, I don't see the data flow by which this customization would make it back to our extension and allow us to augment the generated command. The only wire-up point that I've identified for Tasks is How should I be accessing info coming from tasks.json? |
The flow would be like this:
{
"type": "dotnet",
"....": "...."
} The user can then edit that stub and add a command When executed the command property will overwrite the one provided by the task provider. All properties can be customized that way. Alternatively you can even contribute a Release and a Debug task so that the user sees both in the dropdown list. Since the Task list is now MRU having more tasks in there is not really hurting. |
@dbaeumer what is the purpose of the additional properties we can expose in the task definition? Can I not read these back inside of our extension? |
@TheRealPiotrP actually I don't understand your question. May be you can give me an example. Contributing tasks need a definition the package.json of how the format of the TaskDefinition looks like. There is an example here showing how that works: https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample and the definition in the package.json is here: https://github.com/Microsoft/vscode-extension-samples/blob/master/task-provider-sample/package.json#L18 Do you have already code that contributes a dotnet task. If yes I will have a look to see what might be the problem. |
@dbaeumer sure. Consider the example you linked:
This defines a task with two custom properties:
And, upon running
So now I have this task configuration in In other words, what happens if I modify the task in my tasks.json to be:
My expectation as a user is that the task will now act upon the new file path. However, as an extension author I don't see how I will find out that the user changed the value of the Given that you have gone to some length to enable these custom properties, I'm sure that they are valuable tools... I'm just don't know how to make use of them. When I looked at the sample, I assumed the intent was similar to this:
and that
Now I could instruct the user to replace Debug with Release and my task would somehow get access to the configuration change. Based on this conversation I think my understanding is simply wrong... so I'd like to understand the real intent for these additional task properties. |
@TheRealPiotrP The current model is a merge model base on the tasks provided by the task provider. So in the rake example the task engine would search for a task provided by the rake extension that has the properties {
"type": "Rake",
"task": "doSomething",
"file": "my/rake.file"
} and take it as a base for the task to be executed. Any properties specified in the tasks.json for that file {
"type": "Rake",
"task": "doSomething",
"file": "my/rake.file"
"presentation": {
"reveal": "never"
}
} It will overwrite the So in you case the dotnet task provider needs to provide all customizable tasks. The resolve hook is more an optimization that a task provider doesn't need to provide all tasks on request if a task configured in the tasks.json is executed. But if a user starts blank (which is the default) it is more convenient for the user if the task provider provides all possible tasks. Otherwise he would need to know how to start with a stub in the tasks.json file. |
@dbaeumer but where is there any possibility of actually using the overridden task ? There is only one place in the code where a |
The task engine does this. Tasks provided by a task provider are internally translated into the same object format structure the task from a tasks.json file are transformed to and then merged. So you can only override properties. If you for example want to provide a new command the user needs to provide the full command in the tasks.json file. Usually users only want to override presentation properties or attach problem matchers. So this is an easy way to do so without letting the user type the task in the tasks.json file in the first place. I agree that for more advanced cases a resolve is desirable with is why we added it (but to calling it yet) |
@dbaeumer thanks for the detailed explanation of where we are today! It sounds like an API for enabling user-extension communication via Tasks.json is not immediately on the roadmap. However, according to the documentation it looks like I may be able to interrogate tasks.json a bit more directly. Unless you feel this is contrary to where VS Code is headed, I'm going to experiment with something like this:
Why go to such trouble? We have a coupling between our launch configurations and our task definitions. Our prebuild task in launch.json will trigger a build, but that build's output varies depending on the aforementioned configuration properties. Today users are forced to modify the By moving our configuration into well-known fields we can take a step towards simplifying the problem, both for ourselves and for our users. One additional task ahead of me is the rationalization of data stored in launch.json vs. tasks.json. I've not had much time to invest in launch.json, but it appears that the new configuration API is a map function that converts objects from the extension into a launch.json. This suggests the launch.json is intended to be a persistent artifact. Tasks.json, on the other hand, seems to be becoming more virtualized: users can still generate the file for customization, but will be able to happily run tasks without it. This suggests that I should actually be inspecting the launch.json file for configuration, and that I should perhaps even create a special I'm sharing a bunch of context here because I've had a hard time finding other folks' opinions on how best to use the new APIs and I hope this input may be useful both to the VS Code team and to other extension contributors! |
@TheRealPiotrP having these additional fields in tasks.json makes perfect sense and we do the same for the TypeScript tasks. The TaskDefinitions have an option property to determine whether the build is a normal build or a watch build. {
"type": "typescript",
"tsconfig": "tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
]
} If you encounter problems with that approach please let me know. |
Is this already implemented? Thanks! |
No work has started here yet. |
Interested in this feature too. |
I spent a day trying to make sense of this API until I found this issue. Leaving aside hacks, I don't see how custom task properties are useful without A somewhat related issue I encountered is that a provided task is not shown in "Run Task..." if its scope is set. I have no idea why. More extensive documentation for the task API in general and I wonder if integrations of external cli tools that don't require parsing a build script are better implemented as commands? Couldn't find any information on this either. |
@fcurts agree with the documentation. I created microsoft/vscode-docs#1624 this week :-) and we do maintain an example here: https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample Regarding resolveTask: the idea here is that we can resolve a task added to the tasks.json without call the task provider before hand. The idea is not to call the method before a task is executed. We have a different issue for this.
Can you provide more details for this. |
Probably this: #40515 |
Yes, except that I see the same behavior (task not shown) for I'd be grateful if somebody could explain how to choose between implement sth. like "run javadoc tool" as task vs. command and what the purpose of task parameters is given that they can't be accessed during task execution (or perhaps I just need to avoid shell execution?). |
@fcurts yes, you are affected by #40515. Tools in 99% shouldn't run in the global especially if they rely on files in the workspace. Reason is multi root workspaces. If you have a workspace with two root folders a task like A global task would for example be So you should actually use this constructor: https://github.com/Microsoft/vscode/blob/master/src/vs/vscode.d.ts#L4751 and pass the workspace folder the task should run on. You might want to look here for an example on how to do that: https://github.com/Microsoft/vscode/blob/master/extensions/gulp/src/main.ts#L143 |
@dbaeumer Would you take a PR for this? I believe this is the behavior. Let me know if I'm wrong. In cases where
What should happen if |
@joelday yes, that is the expected behavior. If |
FYI for anyone looking at this issue: |
Thank you @joelday for implementing If anyone is interested, there are other built-in extensions that should properly implement Finally, we should create a setting to only use tasks.json for performance: #76522 |
Steps to Reproduce:
taskProvider
that provides incomplete tasks inprovideTasks()
and completes them inresolveTask
Here is a minimal example:
Reproduces without extensions: Yes
As I understand,
resolveTask()
should be called to complete incomplete tasks just like with code lenses:provideCodeLenses()
can return incomplete code lenses that will be later completed upon callingresolveCodeLens()
.However,
resolveTask()
never seems to be called at any point, and ifprovideTasks()
returns incomplete tasks, these tasks will simply not get listed when trying to list all available tasks.Am I missing something on how
resolveTask()
is supposed to work, or is there a bug here ? I've tried looking at other task providers, but every single one of them only useprovideTasks()
.The text was updated successfully, but these errors were encountered: