vscode 在启动调试会话之前动态配置环境变量的一种方法

siotufzp  于 4个月前  发布在  Vscode
关注(0)|答案(7)|浏览(76)

我想能够定义一个模板化的启动配置,能够根据类似任务输入的内容动态设置环境变量。例如:

"launch": {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Web (client)",
                "type": "debugpy",
                "request": "launch",
                "program": "manage.py",
                "args": [
                    "runserver",
                    "8001",
                ],
                "django": true,
                "justMyCode": false,
                "env": {
                    "DJANGO_SETTINGS_MODULE": "${input:client}.settings",
                    "DATABASE_NAME": "${input:client}-database",
                },
            },
 "tasks": {
        "version": "2.0.0",
        "inputs": [
            {
                "id": "client",
                "type": "pickString",
                "description": "Which Client?",
                "options": ["ClientA", "ClientB", "ClientC"]
            },

        ],

实际上,我大约有20个不同的"客户端"和更多的环境变量,并且希望避免定义20个不同的启动配置。
这里的建议是一个可能的实现方法。另一个可能的实现方法是在启动调试器之前运行脚本。例如:

"configurations": [
          { ...
               "preLaunchScript": "setup.sh ${input:client}"
          }
     ]

这将把环境变量导入运行调试器的会话中。

7cwmlq89

7cwmlq891#

@jarshwah 你在任务中没有定义 input,这个词在启动配置中使用。你可以使用我编写的扩展 Command Variable 来重用选定的选项,并同时定义其他变量。使用 extension.commandvariable.pickStringRemember 并查看:An example task that stores multiple values:。示例使用了任务,但它对启动配置也同样适用。

a2mppw5e

a2mppw5e2#

如果你只是想选择一个字符串,你也可以在launch.json中使用输入来完成这个操作,对吗?我想pickStringRemember就是这样做的,但它记住了选择的内容?

2o7dmzc5

2o7dmzc53#

@roblourens 看着他想要使用的例子,他想多次使用相同的选择字符串,使用 pickStringRemember 和命令 extension.commandvariable.remember ,他只需要选择一次并多次重复使用选择的字符串。你可以在启动配置中选择,并在关联任务中使用相同的字符串。

inkz8wg9

inkz8wg94#

如果这是问题所在,看起来我们已经在启动配置中处理了这个问题,只解决一次输入。

mutmk8jj

mutmk8jj5#

@roblourens 再次阅读他的问题,他可能想要运行一个定义环境变量的shell脚本,并在启动配置中使用它们。他的示例并没有完全反映出他想要实现的功能。

关于在shell脚本中设置的环境变量永远不会传递到启动配置的环境变量中。

他可以将所需的信息存储在一个文件中,并使用extension.commandvariable.file.content来读取所有特定的字段(键值对、JSON、YAML),并在启动配置中定义环境变量。

问题在于,启动配置在调用preLaunchTask之前解析了所有的变量。更好的做法是有一个preLaunchTask:

  1. 解析preLaunchTask属性字符串中的变量;
  2. 执行结果字符串中指定的任务;
  3. 解析启动配置属性字符串中提到的其他变量;
  4. 现在启动配置已经没有变量,可以执行了。
9rnv2umw

9rnv2umw6#

让我分享一个部分脱敏的我的启动配置,这样更具体:

{
    "name": "Web (Tenant 1)",
    "type": "debugpy",
    "request": "launch",
    "cwd": "${workspaceFolder}/src",
    "program": "manage.py",

    "args": [
        "runserver",
        "8001",
        "--skip-checks"
    ],
    "django": true,
    "justMyCode": false,
    "env": {
        "DJANGO_SETTINGS_MODULE": "localdev.settings",
        "DJANGO_CONFIGURATION": "Tenant1Web",
        "DJANGO_WATCHMAN_TIMEOUT": "10",
        "DATABASE_NAME": "tenant1-writer",
        "DATABASE_READER_NAME": "tenant1-reader",
        "ELASTICSEARCH_ENABLED": "1"
    },
},
{
    "name": "API (Tenant 1)",
    "type": "debugpy",
    "request": "launch",
    "cwd": "${workspaceFolder}/src",
    "program": "manage.py",
    "args": [
        "runserver",
        "8002",
        "--skip-checks"
    ],
    "django": true,
    "justMyCode": false,
    "env": {
        "DJANGO_SETTINGS_MODULE": "localdev.settings",
        "DJANGO_CONFIGURATION": "Tenant1API",
        "DJANGO_WATCHMAN_TIMEOUT": "10",
        "DATABASE_NAME": "tenant1-writer",
        "DATABASE_READER_NAME": "tenant1-reader",
        "ELASTICSEARCH_ENABLED": "0"
    },
},
{
    "name": "Web (Tenant 2)",
    "type": "debugpy",
    "request": "launch",
    "cwd": "${workspaceFolder}/src",
    "program": "manage.py",
    "args": [
        "runserver",
        "8001",
        "--skip-checks"
    ],
    "django": true,
    "justMyCode": false,
    "env": {
        "DJANGO_SETTINGS_MODULE": "localdev.settings",
        "DJANGO_CONFIGURATION": "Tenant2Web",
        "DJANGO_WATCHMAN_TIMEOUT": "10",
        "DATABASE_NAME": "tenant2-writer",
        "DATABASE_READER_NAME": "tenant2-reader",
        "ELASTICSEARCH_ENABLED": "0"
    },
},
{
    "name": "API (Tenant 2)",
    "type": "debugpy",
    "request": "launch",
    "cwd": "${workspaceFolder}/src",
    "program": "manage.py",
    "args": [
        "runserver",
        "8002",
        "--skip-checks"
    ],
    "django": true,
    "justMyCode": false,
    "env": {
        "DJANGO_SETTINGS_MODULE": "localdev.settings",
        "DJANGO_CONFIGURATION": "Tenan2API",
        "DJANGO_WATCHMAN_TIMEOUT": "10",
        "DATABASE_NAME": "tenant2-writer",
        "DATABASE_READER_NAME": "tenant2-reader",
        "ELASTICSEARCH_ENABLED": "0"
    },
},

不同的租户有不同的环境变量值。理想情况下,我希望能够“模板化”环境变量。我们在vscode之外运行程序时,有shell脚本将环境变量导出到环境中 - 想想 use-tenant web 1
我希望能够做的是:“启动网页” -> “选择租户1” -> 它使用该租户所需的环境运行。
感谢@rioj7尽管缺乏示例,但仍然解释了我的意思,你是正确的。我希望能够做到以下两点:

  1. 解析(pickString?)可以插值到环境部分的环境变量;或者
  2. 解析传递给某个脚本的变量,该脚本可以导出可供启动的程序使用的环境变量
whlutmcx

whlutmcx7#

@jarshwah 我有一个可行的概念验证。
由于现在的启动配置是如何工作的,你需要将变量内容的设置和实际的启动/调试分开。
一个启动配置的 env 部分可以包含 ${input} 变量。
变量内容的设置是通过一个任务完成的:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Choose Django Environment",
      "type": "shell",
      "command": "echo",
      "args": [
        "Django Environment: ${input:chooseDjangoEnv}"
      ],
      "problemMatcher": []
    }
  ],
  "inputs": [
    {
      "id": "chooseDjangoEnv",
      "type": "command",
      "command": "extension.commandvariable.pickStringRemember",
      "args": {
        "key": "choice",
        "options": [
          {"label": "Web (Tenant 1)", "value": {"choice":"Web (Tenant 1)", "djangoConfig":"Tenant1Web", "databaseName":"tenant1-writer"}},
          {"label": "Web (Tenant 2)", "value": {"choice":"Web (Tenant 2)", "djangoConfig":"Tenant2Web", "databaseName":"tenant2-writer"}}
         ],
        "description": "Pick a configuration"
      }
    }
  ]
}

你可以将一个键绑定到执行任务:

{
    "key": "ctrl+alt+f5",
    "command": "workbench.action.tasks.runTask",
    "args": "Choose Django Environment"
    "when": "editorTextFocus"
  }

定义以下启动配置:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File with Django environment",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal",
      "env": {
        "DJANGO_CONFIGURATION": "${input:djangoConfig}",
        "DATABASE_NAME": "${input:databaseName}",
      }
    }
  ],
  "inputs": [
    {
      "id": "djangoConfig",
      "type": "command",
      "command": "extension.commandvariable.remember",
      "args": { "key": "djangoConfig" }
    },
    {
      "id": "databaseName",
      "type": "command",
      "command": "extension.commandvariable.remember",
      "args": { "key": "databaseName" }
    }
  ]
}

我已经用以下 Python 文件测试过它:

import os

print('DJANGO_CONFIGURATION:', os.environ['DJANGO_CONFIGURATION'])
print('DATABASE_NAME:', os.environ['DATABASE_NAME'])

为了适应你特定的变量和启动配置,需要修改这个概念。

相关问题