feat(settings): add settings.env field for environment variable configuration

Add support for defining environment variables in settings.json files.
These variables are loaded with the lowest priority:
1. System/process environment variables (highest)
2. .env files
3. settings.env (lowest/fallback)

This allows users to configure default environment variables in their
user or workspace settings without conflicting with existing env vars
or .env file values.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
tanzhenxin 2026-02-08 09:33:31 +08:00
parent 36931e1eab
commit 5f8884b60c
3 changed files with 224 additions and 4 deletions

View file

@ -848,7 +848,16 @@ export function setUpCloudShellEnvironment(envFilePath: string | null): void {
process.env['GOOGLE_CLOUD_PROJECT'] = 'cloudshell-gca';
}
}
/**
* Loads environment variables from .env files and settings.env.
*
* Priority order (highest to lowest):
* 1. CLI flags
* 2. process.env (system/export/inline environment variables)
* 3. .env files (no-override mode)
* 4. settings.env (no-override mode)
* 5. defaults
*/
export function loadEnvironment(settings: Settings): void {
const envFilePath = findEnvFile(process.cwd());
@ -861,9 +870,9 @@ export function loadEnvironment(settings: Settings): void {
setUpCloudShellEnvironment(envFilePath);
}
// Step 1: Load from .env files (higher priority than settings.env)
// Only set if not already present in process.env (no-override mode)
if (envFilePath) {
// Manually parse and load environment variables to handle exclusions correctly.
// This avoids modifying environment variables that were already set from the shell.
try {
const envFileContent = fs.readFileSync(envFilePath, 'utf-8');
const parsedEnv = dotenv.parse(envFileContent);
@ -879,7 +888,7 @@ export function loadEnvironment(settings: Settings): void {
continue;
}
// Load variable only if it's not already set in the environment.
// Only set if not already present in process.env (no-override)
if (!Object.hasOwn(process.env, key)) {
process.env[key] = parsedEnv[key];
}
@ -889,6 +898,16 @@ export function loadEnvironment(settings: Settings): void {
// Errors are ignored to match the behavior of `dotenv.config({ quiet: true })`.
}
}
// Step 2: Load environment variables from settings.env as fallback (lowest priority)
// Only set if not already present (no-override, after .env is loaded)
if (settings.env) {
for (const [key, value] of Object.entries(settings.env)) {
if (!Object.hasOwn(process.env, key) && typeof value === 'string') {
process.env[key] = value;
}
}
}
}
/**