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

Use a shared, persistent environment for tasks #44152

Closed
akbyrd opened this issue Feb 21, 2018 · 16 comments
Closed

Use a shared, persistent environment for tasks #44152

akbyrd opened this issue Feb 21, 2018 · 16 comments
Assignees
Labels
feature-request Request for new features or functionality *out-of-scope Posted issue is not in scope of VS Code tasks Task system issues
Milestone

Comments

@akbyrd
Copy link
Contributor

akbyrd commented Feb 21, 2018

Issue Type

Feature Request

Description

I'm compiling C++ on Windows using MSVC 2015. Currently, I'm using cmd.exe as my shell and calling a build.bat as my build task. In that batch file I call vcvarsall.bat to initialize the environment. However, that script is slow and accounts for more than half the runtime of my build task.

I'd like to be able to call vcvarsall.bat once and have my build task inherit that environment each time it is run, thereby cutting my compile times in half and getting closer to what I would see with Visual Studio.

I tried setting

"terminal.integrated.shellArgs.windows": ["/K", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat"]

However that exposes multiple problems:

  1. This gets run for each task, defeating the idea from the outset
  2. The spaces aren't properly escaped when passed to the task shell instance and I get the error 'C:\Program' is not recognized as an internal or external command, operable program or batch file.
  3. If I move that to a batch file so there are no spaces in the path then the batch file gets run but the task command is never run and the task hangs and never exits.
  4. Tasks don't inherit the Terminal environment (I'm guessing only the VSCode process environment is inherited)

I believe I could run VSCode from a command environment where vcvarsall had already been run, but that requires a custom shortcut, therefore only working when that shortcut is used and requiring additional setup for every team member.

VS Code Info

VS Code version: Code 1.20.1 (f88bbf9, 2018-02-13T15:34:36.336Z)
OS version: Windows_NT x64 10.0.16299

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

I think there is no good way for VS Code to source this in globally since it would affect other tasks as well which might not want to see the environment setup by vcvarsall. The idea is that VS Code inherits the environment from the shell you start it from.

All I could think of is setting the env inside the task itself using the options property, however this will require duplicating logic from vcvarsall which might be cumbersome as well.

Using /K is basically not what you want since it only executes the passed command and keeps the command prompt running. The actually task is then not executed.

We are aware of the spacing issue with shell args and are working on a solution. But even if this is fixed it will not allow the /K to do what you want.

I am leaning towards closing this issue since I can't see how we would be able to globally source vcvarsall without causing other problems.

@dbaeumer dbaeumer added the info-needed Issue requires more information from poster label Feb 22, 2018
@akbyrd
Copy link
Contributor Author

akbyrd commented Feb 22, 2018

Hmm. Could we have an option on tasks to say 'reuse the same shell for each invocation of this task'?

In the script that my task runs I can simply check the environment and skip vcvarsall if it's already been run. This alleviates the concern about one task seeing the environment meant for another task, while also allowing us to save time on tasks with heavy setup.

Personally, I don't have any issue with all tasks seeing the same environment. I'd much rather have that than nothing and so long as it's an opt-in feature it won't harm the workflow of others.

Alternatively, providing a way to alter the 'global' environment of VS Code after launch would work in my case. If there was a way to get vcvarsall all in the global environment through workspace settings I wouldn't be uncomfortable with using it in a team setting.

I recognize this issue doesn't have a super clear cut solution, but it's a large enough workflow issue that I'd like to push for something. Cutting my compile times in half is huge for productivity, and that's without using any form of incremental building or linking which would only make the vcvarsall pain that much more obvious.

@dbaeumer dbaeumer added feature-request Request for new features or functionality and removed info-needed Issue requires more information from poster labels Feb 23, 2018
@dbaeumer dbaeumer added this to the Backlog milestone Feb 23, 2018
@dbaeumer
Copy link
Member

IMO the best solution to share an environment with VS Code is to start VS Code from a shell that has the environment setup.

I will keep the item open as a feature request.

@llgcode
Copy link

llgcode commented Apr 6, 2018

Hi @dbaeumer ,
like @akbyrd, I also interested to have this feature. From what I understand, a task could just initialize env vars, other task that depends on it can execute in the same shell with environment already configured by the first task. So for example an option "dependsOnShellTask" can be added to task configuration to use same shell/environment another task. So if a shell is already open no need to reexecute the first task.

The other feature request that is slightly different from the above one :
I created an extension that execute process command with specific environment initialized (that takes long time to initialized). It will be convenient if these environment vars could be referenced in tasks.json or prefill by a vscode command.

I've tried to use ${command:commandID} syntax in tasks.json but it doesn't works:
https://code.visualstudio.com/docs/editor/variables-reference#_settings-and-command-variables

@dbaeumer
Copy link
Member

dbaeumer commented Apr 6, 2018

@llgcode as I was trying to explain there is not good way to detect when a shell is idle. So we don't know whether the shell can accept a new command nor do we know when a task is finished which makes it very hard to implement the feature in a reliable way.

@akbyrd
Copy link
Contributor Author

akbyrd commented Apr 6, 2018

On Windows a new shell instance can inherit the current environment. Could this be leveraged to create a 'template shell' that is initialized once then used to spawn new shells? This obviates the need to know when a task shell is idle and able to be reused since we'd still get a fresh shell for each task.

Maybe something along these lines:

  • In my build task I specify a setupTask.
  • A new 'template shell' is created and the setupTask is run inside it.
  • When invoking the build task a new shell is spawned inheriting from the 'template shell'.

In the context of cmd.exe this appears to be a very straightforward pattern (start propagates the environment to the new process by default) and it mostly leverages existing features of VS Code.

@llgcode
Copy link

llgcode commented Apr 9, 2018

Ok Thanks,
and what about launching a new cmd and cloning environment to this new one?

@JimmyDeemo
Copy link

JimmyDeemo commented Sep 6, 2018

IMO the best solution to share an environment with VS Code is to start VS Code from a shell that has the environment setup.

Please can I just confirm; does this work?

e.g. If I run a .bat file that sets up some PATH elements, followed by opening VSCode, and then open the terminal (or run a build task), will that recognise the PATH values I just applied.

One way I tried to get round this was to set my terminal as a custom .bat file that did setup and then launched cmd.

"terminal.integrated.shellArgs.windows": "C:\\path\\to\\my\\shell.bat"

This was fine when opening a terminal, but the arguments for a build task appeared to be swallowed by the .bat file, meaning running the build task was just the same as opening the terminal.

Edit: Yes, this does work. So if you want to achieve this just launch you VSCode via a bat file which sets up you environment.

@S-Koell
Copy link

S-Koell commented Nov 8, 2019

I am also interested in this feature!
We are compiling against a oracle database and it would save a lot of time if it wouldn’t need to connect again on every compile.

@alexr00
Copy link
Member

alexr00 commented Nov 11, 2019

@S-Koell if have complicated build and can write an extension to provide your build task check out https://code.visualstudio.com/api/extension-guides/task-provider#customexecution
It is made for exactly the kind of thing you're asking for.

@markm77
Copy link

markm77 commented Jan 16, 2020

Please note similar request #87889 where I am proposing support for repo (folder) environment variables for use in launch configs, tasks, the integrated terminal and anything else related to that repo/folder ....

@Synxis
Copy link

Synxis commented Feb 9, 2021

Hello,

I also need this feature, as all my build tools (that I cannot change) depend on a long setup with hundreds of environment variables...

I think a nice solution would be to have some kind of subshells (that could be defined in tasks.json) with a name and a setup command (or commands), and then just fill the name of this subshell in CommandOptions::shell instead of putting an executable.

@phaseOne
Copy link
Contributor

Having this feature would enable a use case where I'd like to run shell commands on a remote system as tasks via ssh. It's an embedded system I'm trying to do remote development on that doesn't have the support for vscode's Remote-SSH extension. My goal here is to replicate the experience of using PyCharm's remote interpreter for python.

Example use case task that is currently impossible
{
    "type": "shell",
    "label": "spawn remote debug process",
    "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "dedicated",
        "showReuseMessage": true,
        "clear": false
    },
    "options": {
        "shell": {
            "executable": "ssh",
            "args": [
                "-t",
                "raspberrypi.local",
                "cd ~/app && pipenv shell"
            ]
        }
    },
    "command": "python -m debugpy --listen 0.0.0.0:5678 --wait-for-client server.py",
    "problemMatcher": []
}

@alexr00 alexr00 added the *out-of-scope Posted issue is not in scope of VS Code label Nov 15, 2021
@starball5
Copy link

@llgcode See #168947.

@llgcode
Copy link

llgcode commented Sep 3, 2024

I guess it's too late to vote for this feature now. I don't remember I add a vote on it. I may search issues feature to vote more often .

@llgcode See #168947.

@igiona
Copy link

igiona commented Dec 23, 2024

@llgcode check this out: #36769

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality *out-of-scope Posted issue is not in scope of VS Code tasks Task system issues
Projects
None yet
Development

No branches or pull requests

12 participants