devcontainers / features

A collection of Dev Container Features managed by Dev Container spec maintainers. See https://github.com/devcontainers/feature-starter to publish your own
https://containers.dev/features
MIT License
916 stars 368 forks source link

Add option to opt out of extensions #386

Closed ghost closed 8 months ago

ghost commented 1 year ago

Some features install extensions along with themselves and I'm not always interested in them. For example, the golang.Go extension that is installed in the Go feature or the dbaeumer.vscode-eslint extension that is installed in the Node feature are not extensions that I use.

To prevent bloat it would be very nice if extensions could be opted out of in feature options.

Here is an example of how I think this could work:

"features": {
  "ghcr.io/devcontainers/features/node:1": {
     "extensions": {
        "dbaeumer.vscode-eslint": false
     }
  }
}
samruddhikhandale commented 1 year ago

Hi @andreilg 👋

https://github.com/devcontainers/cli/pull/262 introduced an experimental --skip-persisting-customizations-from-features flag for the devcontainer build command. It omits all the Feature specified customizations ie. if your devcontainer.json referred to a set of Features, then their corresponding customizations (which includes extensions) will not be applied to your dev container.

Wondering if that could be sufficient for your scenario? I could help make this flag more formalized.

Let me know if your scenario requires more control/options to pick & choose the customizations/extensions, then we could chat further.

ghost commented 1 year ago

Thank you for your response.

The way I'm currently using devcontainers is through a devcontainer.json file with features running in GitHub Codespaces.

That cli flag seems helpful but I don't necessarily want to turn off all customizations or even all extensions but rather pick and choose within the devcontainer.json feature what customizations to include.

My suggested example above is how I envision this could work since it allows for granular control of customizations.

samruddhikhandale commented 1 year ago

Thanks for the clarification.

Here is an example of how I think this could work:

"features": {
    "ghcr.io/devcontainers/features/node:1":
        "extensions": [
            "dbaeumer.vscode-eslint": false
        ]
}

Shouldn't extensions be wrapped in an object? 👇

"features": {
    "ghcr.io/devcontainers/features/node:1": {
          "extensions": [
              "dbaeumer.vscode-eslint": false
          ]
     }
}

Currently, every key-value inside this object is expected to be a Feature option. Doing something like this needs a spec change & would need to reserve 'extensions' keyword for this specific purpose. This could potentially be a breaking change for authors who have been using extensions as a Feature option in their devcontainer-feature.json.

Instead, I am thinking of a similar but a little tweaked approach to your suggestion.

"features": {
    "ghcr.io/devcontainers/features/node:1": {
        "_DISABLE_VSCODE_EXTENSIONS": [
            "dbaeumer.vscode-eslint" // or use "*" to disable all extensions
        ]
    }
},

The Features' option expects camel case, hence, shouldn't break any existing dev configs. We could make a spec change to support this.

@Chuxel / @bamurtaugh Would appreciate your thoughts on this one 👀

bamurtaugh commented 1 year ago

Thanks for the tag, @samruddhikhandale! And thanks for opening, @andreilg - this is an interesting scenario.

@samruddhikhandale I like your idea above that avoids potentially breaking users. I'd be interested to see if other folks mention this as a helpful or important addition for them. I'm going to pop this issue in our dev container community Slack channel to get some more 👀

ghost commented 1 year ago

Shouldn't extensions be wrapped in an object? 👇

Yes, my mistake. The array should also be an object I believe. I have updated my original post.

This could potentially be a breaking change for users who have been using extensions as a Feature option in their devcontainer-feature.json.

I see what you mean since the azure-cli feature has an extensions feature option already.

Instead, I am thinking of a similar but a little tweaked approach to your suggestion.

That looks like a good way of going about it.

Edit: @bamurtaugh Thank you. To give a little more context for why I personally want this:

With the nature of codespaces, I feel like any possibility to reduce bloat will always be desirable and I imagine a lot of people are in a similar situation and just find the lack of control over customization to be a minor annoyance that can add up over time.

chrmarti commented 1 year ago

In the devcontainer.json we use "customizations" to add extensions, that would also be a good place to remove them, e.g.:

    "customizations": {
        "vscode": {
            "extensions": {
                "dbaeumer.vscode-eslint": false,
                "ms-python.python": true
            }
        }
    },

(The current "extensions" property uses an array to add extensions.)

samruddhikhandale commented 1 year ago

A similar request was reported in https://github.com/devcontainers/action/issues/139.

Chuxel commented 1 year ago

If we limit this to just extensions, the proposal in https://github.com/microsoft/vscode-remote-release/issues/415 isn't a bad one. Just prefix the name with a "-" to omit.

    "customizations": {
        "vscode": {
            "extensions": {
                "-dbaeumer.vscode-eslint",
                "ms-python.python"
            }
        }
    }
kompasbank-lasse commented 1 year ago

any progess on this issue ?

Nefcanto commented 1 year ago

The problem we face is that we do not use devcontainers.json at all, yet it automatically installs extensions for us. We simply attach to a running container, and we manually do everything from there as devcontainers.json is extremely buggy and lacks many useful things like offline installation of VS Code Server from a media.

However, right now, as we attach to a running container, it seems that VS Code (or Dev Containers) automatically infers some stuff and automatically decides what to install. It installs ES Lint automatically for us, which we don't use. And it installs C# extension for us which we use, but we want to use a special version of it that we manually install.

I wonder who has come up with this decision to force installing extensions upon teams. I would immediately fire him. This decision is one of the worst decisions a team can make on a global scale.

My suggestion is that you don't infer anything at all. In other words, DO NOT assume anything for us, please. Let us decide what is best for us. Do not force extensions upon us if we have not opted-in

Also as I specified in the other issue, this inference is a poor decision because:

igormcoelho commented 1 year ago

+1 for this... I'm struggling a lot with this limitation. My C++ devcontainer depends on clangd extension "llvm-vs-code-extensions.vscode-clangd" that conflicts with Microsoft C/C++ extension that most people have "ms-vscode.cpptools-extension-pack". So, I need to disable this extension, otherwise container breaks. I tried several alternatives, and none worked. First, I wrongly tried to use "postCreateCommand": "code --uninstall-extension ms-vscode.cpptools" to uninstall extension as soon as container is loader, but it seems that "postCreateCommand" is not running before installation, but after (it complains that no vscode exists at that point). Then, I tried to use "customizations:vscode:settings": { "C_Cpp.intelliSenseEngine": "disabled" } to disable the extension if it exists, but it does not seem to override user settings.json typically "C_Cpp.intelliSenseEngine": "default" My only alternative now is to commit the .vscode/settings.json with "C_Cpp.intelliSenseEngine": "disabled", but it will break project for anyone trying to use Microsoft C/C++ extension outside the devcontainer. So, it will be very welcome to have a way to disable an extension (BTW, I like the proposed "minus" notation).

Suniron commented 1 year ago

In my case, I'm using Vue3 in my project but since we want the take-over mode of Volar, we want to disable the built-in ts-server.

See https://vuejs.org/guide/typescript/overview.html#volar-takeover-mode

alessandro-newzoo commented 1 year ago

@Chuxel @samruddhikhandale @bamurtaugh hi, we need an answer here please.

It's beyond ridiculous that your company somehow decided to silently shove loads of extensions down everyone's throat, some of which are even freemium and spam you with requests to sign up for a premium plan.

I got these by just adding PHP to my features:

xdebug.php-debug
bmewburn.vscode-intelephense-client
xdebug.php-pack
devsense.phptools-vscode

That's FOUR extensions I don't want, for just one package.

Why would anyone think this was a good idea, and most importantly why has nothing been done in almost a year after this issue has been opened?

garrettw commented 1 year ago

Most if not all of those are very standard extensions for a PHP dev to use in VS Code.

solid-pixel commented 1 year ago

Most if not all of those are very standard extensions for a PHP dev to use in VS Code.

What do you know about other people's standards?? It seems pretty obvious that it is not the case for everyone, otherwise this issue would not exist.

There are multiple extensions one can choose from, and they have every right to do so. I for one use Trunk to handle all of my formatting needs for different languages. I also don't use xdebug.

Or one might simply not need any at all, as sometimes you only need PHP to run some services that rely on it.

garrettw commented 1 year ago

@solid-pixel You're not wrong. I know not everyone uses the same PHP extensions. I just said they're common.

What do you know about other people's standards??

I've talked to plenty of PHP devs that use these extensions, so I know they're common. But I never claimed everyone uses them.

h7x4 commented 1 year ago

This is getting off topic. It's clear from the previous comments that overriding the extension list of a devcontainer feature is something that would be desirable. Let's keep the comments constructive and discuss how this should work, what the API should look like, usecases, etc. rather than pointing fingers, discussing the popularity/standardization of PHP extensions and requesting urgency among maintainers.

Nefcanto commented 1 year ago

@h7x4 The decision is very very clear. Microsoft MUST NOT assume default extensions for any team. Instead of opt-out it should be opt-in.

Any team that wants any extensions should specify them with their IDs. That's it.

And if teams want to create conventions across multiple projects (cross-project), then the devcontainer.json should have the inheritance/merging capability to read from a base file.

But if they don't make that decision (which is extremely annoying and arrogant if they don't), then at least they should create this contract in devcontainer.json:

  1. If a list of extensions is specified, this means that this list should override the defaults
  2. An empty list still means overriding the defaults, without installing new extensions. It simply means no extensions please.
  3. If no extension is specified and not even an empty list, the defaults can be installed automatically.
igormcoelho commented 12 months ago

If someone finds a way to, at least, execute a command after all extensions are loaded, then each user could at least remove unnecessary extensions like this: "postCreateCommand": "code --uninstall-extension ms-vscode.cpptools" ... but we need some postPostPostPostCreateCommand, something that really runs last in execution... do any of you think this is possible?

aetos382 commented 11 months ago

I think the idea of using - to disable individual extensions is not good. If the feature author adds a new (we don't want) extension, we have to disable it each time.

I would like to be able to disable all extensions at once as described in this comment ( I want to do it via devcontainer.json). Then we can enable the extensions we need individually.

hoang-himself commented 11 months ago

@aetos382 you just described https://github.com/devcontainers/features/issues/386#issuecomment-1788398534

chrmarti commented 11 months ago

Note that the - syntax is available in Dev Containers 0.323.0-pre-release. (https://github.com/microsoft/vscode-remote-release/issues/9177)

BAAZKonqi commented 11 months ago

The commit you mentioned seems only to edit the specifications of the devcontainer.json file. Is the actual functionality also included? If so, how can I already use this? I tried Dev Containers 0.325.0-pre-release with the latest VSCode Insiders, but it does not work for me.

I used the following syntax to exclude intellicode from C# Dev Kit:

"customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit@1.0.14",
        "-ms-dotnettools.vscodeintellicode-csharp"
      ]
    }
  },
chrmarti commented 11 months ago

ms-dotnettools.csdevkit comes with ms-dotnettools.vscodeintellicode-csharp as part of an extension pack. The Dev Containers extension currently just omits extensions from the list of extensions it asks to be installed, but can't tell VS Code to specifically skip certain extensions. /fyi @sandy081

alexandreczg commented 8 months ago

Any update on this? I don't want the suggested extensions by any given feature. I rather mine.

samruddhikhandale commented 8 months ago

https://github.com/devcontainers/features/issues/386#issuecomment-1827597782

I believe this ^ should be available in VS Code stable as well.

@chrmarti should we close this issue out?

chrmarti commented 8 months ago

Yes, this is available with the --prefix syntax. Closing, thanks.

alexandreczg commented 8 months ago

@chrmarti Is there any documentation of this usage you can point me to? Much appreciated.

chrmarti commented 5 months ago

@alexandreczg Can't find it right now, I'll see where in the docs we can add it. There was a release note: https://github.com/microsoft/vscode-docs/blob/main/remote-release-notes/v1_85.md#opt-out-of-extensions