Skip to content

Commit 2df57b0

Browse files
Copilotgarrytrinder
andcommitted
feat: support passing environment variables when starting Dev Proxy
Co-authored-by: garrytrinder <11563347+garrytrinder@users.noreply.github.com>
1 parent 98c5f6c commit 2df57b0

6 files changed

Lines changed: 110 additions & 3 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ Shows Dev Proxy status at a glance:
211211
| `dev-proxy-toolkit.closeTerminal` | `boolean` | `true` | Close terminal when stopping |
212212
| `dev-proxy-toolkit.apiPort` | `number` | `8897` | Port for Dev Proxy API communication |
213213
| `dev-proxy-toolkit.devProxyPath` | `string` | `""` | Custom path to Dev Proxy executable (uses auto-detection if empty) |
214+
| `dev-proxy-toolkit.env` | `object` | `{}` | Environment variables to set when starting Dev Proxy |
214215

215216
## Tasks
216217

@@ -239,6 +240,22 @@ Run Dev Proxy as a VS Code task for integration with build workflows.
239240
}
240241
```
241242

243+
You can pass environment variables to Dev Proxy using the `env` property:
244+
245+
```json
246+
{
247+
"label": "Start Dev Proxy",
248+
"type": "devproxy",
249+
"command": "start",
250+
"env": {
251+
"NODE_ENV": "development",
252+
"DEBUG": "true"
253+
},
254+
"isBackground": true,
255+
"problemMatcher": "$devproxy-watch"
256+
}
257+
```
258+
242259
## MCP Server
243260

244261
This extension includes an MCP server for AI-assisted development. See [Dev Proxy MCP Server](https://github.com/dev-proxy-tools/mcp) for available tools.

package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@
156156
"type": "string"
157157
},
158158
"description": "Additional command-line arguments"
159+
},
160+
"env": {
161+
"type": "object",
162+
"additionalProperties": {
163+
"type": "string"
164+
},
165+
"description": "Environment variables to set when starting Dev Proxy"
159166
}
160167
}
161168
}
@@ -213,6 +220,14 @@
213220
"type": "string",
214221
"default": "",
215222
"description": "Custom path to the Dev Proxy executable. If empty, auto-detection is used."
223+
},
224+
"dev-proxy-toolkit.env": {
225+
"type": "object",
226+
"additionalProperties": {
227+
"type": "string"
228+
},
229+
"default": {},
230+
"description": "Environment variables to set when starting Dev Proxy."
216231
}
217232
}
218233
},

src/services/terminal.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,26 @@ export class TerminalService {
1010
private readonly createNewTerminal: boolean;
1111
private readonly showTerminal: boolean;
1212
private readonly closeTerminalOnStop: boolean;
13+
private readonly env: { [key: string]: string } | undefined;
1314

1415
constructor(config?: TerminalServiceConfig) {
1516
this.createNewTerminal = config?.createNewTerminal ?? true;
1617
this.showTerminal = config?.showTerminal ?? true;
1718
this.closeTerminalOnStop = config?.closeTerminalOnStop ?? true;
19+
this.env = config?.env;
1820
}
1921

2022
/**
2123
* Create a TerminalService using VS Code configuration.
2224
*/
2325
static fromConfiguration(): TerminalService {
2426
const config = vscode.workspace.getConfiguration('dev-proxy-toolkit');
27+
const env = config.get<{ [key: string]: string }>('env');
2528
return new TerminalService({
2629
createNewTerminal: config.get<boolean>('newTerminal', true),
2730
showTerminal: config.get<boolean>('showTerminal', true),
2831
closeTerminalOnStop: config.get<boolean>('closeTerminal', true),
32+
env: env && Object.keys(env).length > 0 ? env : undefined,
2933
});
3034
}
3135

@@ -41,7 +45,15 @@ export class TerminalService {
4145
return vscode.window.activeTerminal;
4246
}
4347

44-
const terminal = vscode.window.createTerminal('Dev Proxy');
48+
const terminalOptions: vscode.TerminalOptions = {
49+
name: 'Dev Proxy',
50+
};
51+
52+
if (this.env) {
53+
terminalOptions.env = this.env;
54+
}
55+
56+
const terminal = vscode.window.createTerminal(terminalOptions);
4557

4658
if (this.showTerminal) {
4759
terminal.show();
@@ -79,4 +91,5 @@ export interface TerminalServiceConfig {
7991
createNewTerminal?: boolean;
8092
showTerminal?: boolean;
8193
closeTerminalOnStop?: boolean;
94+
env?: { [key: string]: string };
8295
}

src/task-provider.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface DevProxyTaskDefinition extends vscode.TaskDefinition {
77
command: 'start' | 'stop';
88
configFile?: string;
99
args?: string[];
10+
env?: { [key: string]: string };
1011
label?: string;
1112
}
1213

@@ -68,9 +69,13 @@ export class DevProxyTaskProvider implements vscode.TaskProvider {
6869

6970
if (definition.command === 'start') {
7071
const args = this.buildArgumentsFromDefinition(definition);
71-
execution = new vscode.ShellExecution(this.devProxyExe, args, {
72+
const shellOptions: vscode.ShellExecutionOptions = {
7273
cwd: '${workspaceFolder}'
73-
});
74+
};
75+
if (definition.env && Object.keys(definition.env).length > 0) {
76+
shellOptions.env = definition.env;
77+
}
78+
execution = new vscode.ShellExecution(this.devProxyExe, args, shellOptions);
7479
} else if (definition.command === 'stop') {
7580
// Use curl to stop Dev Proxy via API
7681
const configuration = vscode.workspace.getConfiguration('dev-proxy-toolkit');

src/test/task-provider.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,28 @@ suite('DevProxyTaskProvider', () => {
161161

162162
assert.ok(resolved, 'Should resolve task with args');
163163
});
164+
165+
test('should handle env in definition', () => {
166+
const provider = new DevProxyTaskProvider(mockContext);
167+
168+
const taskDefinition = {
169+
type: 'devproxy',
170+
command: 'start' as const,
171+
env: { 'NODE_ENV': 'test', 'DEBUG': 'true' },
172+
label: 'Start with Env',
173+
};
174+
175+
const mockTask = new vscode.Task(
176+
taskDefinition,
177+
vscode.TaskScope.Workspace,
178+
'Start with Env',
179+
'devproxy'
180+
);
181+
182+
const resolved = provider.resolveTask(mockTask);
183+
184+
assert.ok(resolved, 'Should resolve task with env');
185+
});
164186
});
165187

166188
suite('task properties', () => {

src/test/terminal.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,41 @@ suite('TerminalService', () => {
111111
assert.ok((mockTerminal.hide as sinon.SinonStub).calledOnce);
112112
assert.ok((mockTerminal.show as sinon.SinonStub).notCalled);
113113
});
114+
115+
test('should pass env to terminal when env is provided', () => {
116+
const mockTerminal = {
117+
show: sandbox.stub(),
118+
hide: sandbox.stub(),
119+
name: 'Dev Proxy',
120+
} as unknown as vscode.Terminal;
121+
122+
const createStub = sandbox.stub(vscode.window, 'createTerminal').returns(mockTerminal);
123+
124+
const env = { 'NODE_ENV': 'test', 'DEBUG': 'true' };
125+
const service = new TerminalService({ createNewTerminal: true, showTerminal: true, env });
126+
service.getOrCreateTerminal();
127+
128+
assert.ok(createStub.calledOnce);
129+
const options = createStub.firstCall.args[0] as vscode.TerminalOptions;
130+
assert.deepStrictEqual(options.env, env, 'Should pass env to terminal options');
131+
});
132+
133+
test('should not include env in terminal options when env is undefined', () => {
134+
const mockTerminal = {
135+
show: sandbox.stub(),
136+
hide: sandbox.stub(),
137+
name: 'Dev Proxy',
138+
} as unknown as vscode.Terminal;
139+
140+
const createStub = sandbox.stub(vscode.window, 'createTerminal').returns(mockTerminal);
141+
142+
const service = new TerminalService({ createNewTerminal: true, showTerminal: true });
143+
service.getOrCreateTerminal();
144+
145+
assert.ok(createStub.calledOnce);
146+
const options = createStub.firstCall.args[0] as vscode.TerminalOptions;
147+
assert.strictEqual(options.env, undefined, 'Should not include env in terminal options');
148+
});
114149
});
115150

116151
suite('disposeDevProxyTerminals', () => {

0 commit comments

Comments
 (0)