admin管理员组

文章数量:1302999

I've set up a devcontainer in a Visual Studio Code Ruby project, and the launch configurations don't seem to be able to override environment variables from the devcontainer. I set up the devcontainer to launch from Docker Compose, with one environment variable set in the .env file.

EXAMPLE_VALUE=from-env-file

Another environment variable is set in compose.yml.

services:
  active_sinatra:
    restart: unless-stopped
    image: donkirkby/active-sinatra-devcontainer:v0.2.2
    environment:
      - EXAMPLE_VALUE
      - EXAMPLE_VALUE2=from-compose-file
    volumes:
      - .:/opt/active_sinatra

I wrote example_script.rb to display the environment variables, plus a third that isn't set yet.

value = ENV.fetch('EXAMPLE_VALUE', 'not set')
puts "example value is #{value.inspect}."

value2 = ENV.fetch('EXAMPLE_VALUE2', 'not set')
puts "example value 2 is #{value2.inspect}."

value3 = ENV.fetch('EXAMPLE_VALUE3', 'not set')
puts "example value 3 is #{value3.inspect}."

I set up a launch configuration that overrides all three environment variables.

        {
            "type": "ruby_lsp",
            "name": "Debug example",
            "request": "launch",
            "program": "ruby /opt/active_sinatra/example_script.rb",
            "env": {
                "EXAMPLE_VALUE": "1 from launch",
                "EXAMPLE_VALUE2": "2 from launch",
                "EXAMPLE_VALUE3": "3 from launch"
            }
        },

Unfortunately, my Ruby script only sees the third environment variable when I debug it with the launch configuration.

Ruby REPL: You can run any Ruby expression here.
Note that output to the STDOUT/ERR printed on the TERMINAL.
[experimental]
  `,COMMAND` runs `COMMAND` debug command (ex: `,info`).
  `,help` to list all debug commands.
DEBUGGER: Disconnected.
example value is "from-env-file".
example value 2 is "from-compose-file".
example value 3 is "3 from launch".

Is there a way to change one of the existing environment variables using the launch configuration, or do I have to change the Docker Compose configuration, relaunch the container, and then launch my debugger?

If you want to play around with my example code, you can see it on GitHub, then open a codespace on the docker-compose branch.

I've set up a devcontainer in a Visual Studio Code Ruby project, and the launch configurations don't seem to be able to override environment variables from the devcontainer. I set up the devcontainer to launch from Docker Compose, with one environment variable set in the .env file.

EXAMPLE_VALUE=from-env-file

Another environment variable is set in compose.yml.

services:
  active_sinatra:
    restart: unless-stopped
    image: donkirkby/active-sinatra-devcontainer:v0.2.2
    environment:
      - EXAMPLE_VALUE
      - EXAMPLE_VALUE2=from-compose-file
    volumes:
      - .:/opt/active_sinatra

I wrote example_script.rb to display the environment variables, plus a third that isn't set yet.

value = ENV.fetch('EXAMPLE_VALUE', 'not set')
puts "example value is #{value.inspect}."

value2 = ENV.fetch('EXAMPLE_VALUE2', 'not set')
puts "example value 2 is #{value2.inspect}."

value3 = ENV.fetch('EXAMPLE_VALUE3', 'not set')
puts "example value 3 is #{value3.inspect}."

I set up a launch configuration that overrides all three environment variables.

        {
            "type": "ruby_lsp",
            "name": "Debug example",
            "request": "launch",
            "program": "ruby /opt/active_sinatra/example_script.rb",
            "env": {
                "EXAMPLE_VALUE": "1 from launch",
                "EXAMPLE_VALUE2": "2 from launch",
                "EXAMPLE_VALUE3": "3 from launch"
            }
        },

Unfortunately, my Ruby script only sees the third environment variable when I debug it with the launch configuration.

Ruby REPL: You can run any Ruby expression here.
Note that output to the STDOUT/ERR printed on the TERMINAL.
[experimental]
  `,COMMAND` runs `COMMAND` debug command (ex: `,info`).
  `,help` to list all debug commands.
DEBUGGER: Disconnected.
example value is "from-env-file".
example value 2 is "from-compose-file".
example value 3 is "3 from launch".

Is there a way to change one of the existing environment variables using the launch configuration, or do I have to change the Docker Compose configuration, relaunch the container, and then launch my debugger?

If you want to play around with my example code, you can see it on GitHub, then open a codespace on the docker-compose branch.

Share Improve this question edited Mar 3 at 19:02 Don Kirkby asked Feb 6 at 23:21 Don KirkbyDon Kirkby 56.2k27 gold badges219 silver badges302 bronze badges 1
  • It seems to be different stackoverflow/a/70748562/11000412 – Oliver Gaida Commented Feb 27 at 6:21
Add a comment  | 

2 Answers 2

Reset to default 2 +500

I'll wager you can blame the current implementation of Debugger.resolveDebugConfiguration in debugger.ts.

It beings with the doc comment:

Resolve the user's debugger configuration. Here we receive what is configured in launch.json and can modify and insert defaults for the user. The most important thing is making sure the Ruby environment is a part of it so that we launch using the right bundle and Ruby version.

I highly suspect these lines:

    if (debugConfiguration.env) {
      // If the user has their own debug launch configurations, we still need to inject the Ruby environment
      debugConfiguration.env = Object.assign(
        debugConfiguration.env,
        workspace.ruby.env,
      );

Quoting MDN, which is a little more obvious than the ECMAScript spec here,

Properties in the target object are overwritten by properties in the sources if they have the same key. Later sources' properties overwrite earlier ones.

We can see workspace defined as workspace = this.workspaceResolver(folder?.uri);. Debugger#workspaceResolver is initialized in the constructor, and the constructor is called in rubyLsp.ts, passing RubyLsp#workspaceResolver. In any case, Ruby#env wraps _env, which is modified in Ruby#mergeComposedEnvironment and Ruby#runActivation, which gets the new value from a call to VersionManager#activate. There are a lot of version managers, but from sampling them all (Asdf, Mise, Custom , None, Rbenv and Rvm, and Shadowenv), they all seem to include process.env in what they provide as the new value. I'll guess that that's the issue, assuming that the extension host starts with an environment influenced by the environment of your devcontainer.

Documentation of the Ruby LSP activation is here.

There's potential you could work around the issue by using custom activation and setting your stuff in there instead of in your launch config, but that just seems like a gross thing to do. I'd suggest you raise this issue to the maintainers of the extension. The solution might be as simple as changing this:

debugConfiguration.env = Object.assign(
  debugConfiguration.env,
  workspace.ruby.env,
);

to this:

debugConfiguration.env = {
  ...workspace.ruby.env,
  ...debugConfiguration.env,
};

but I can't speak for that because I'm not a maintainer and I don't know the design context, and I don't even do Ruby development or use this extension. I could be totally wrong.

An issue ticket has been raised at Environment variables can't be overridden in debug launch #3265. I wrote a pull request at https://github/Shopify/ruby-lsp/pull/3266.


*Unrelated... why do they assign the result of Object.assign to what they passed as its first argument?

Currently, it is not possible to override the environment variables using the launch configuration. The Ruby LSP extension uses Object.assign to assign the existing environment variables to the environment variables set in the launch configuration. So the environment variables set in the launch.json file will be overwritten by the docker compose configuration.

Checkout of the section of the code in debugger.ts where the environment variables are assigned:

  ...
  if (debugConfiguration.env) {
    // If the user has their own debug launch configurations, we still need to inject the Ruby environment
    debugConfiguration.env = Object.assign(
      debugConfiguration.env,
      workspace.ruby.env,
    );
  }
  ...

So yes, to change the environment variables you need to change the Docker Compose configuration and relaunch/rebuild the container.

本文标签: rubyCan Visual Studio Code override environment variablesStack Overflow