Skip to content

Commit c6b015e

Browse files
committed
refactor: extract resolveOverride for consistent setting/env path resolution
Add CODER_SSH_LOG_DIR env var fallback for proxy log directory, apply expandPath consistently to both settings and env vars in getBinaryCachePath and getProxyLogPath, and inline the removed getLogPath method.
1 parent 2b058f6 commit c6b015e

4 files changed

Lines changed: 74 additions & 29 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"default": ""
103103
},
104104
"coder.proxyLogDirectory": {
105-
"markdownDescription": "Directory where the Coder CLI outputs SSH connection logs for debugging. When not configured, logs are stored in the extension's global storage directory.",
105+
"markdownDescription": "Directory where the Coder CLI outputs SSH connection logs for debugging. Defaults to the value of `CODER_SSH_LOG_DIR` if not set, otherwise the extension's global storage directory.",
106106
"type": "string",
107107
"default": ""
108108
},

src/core/pathResolver.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,12 @@ export class PathResolver {
3232
* The caller must ensure this directory exists before use.
3333
*/
3434
public getBinaryCachePath(safeHostname: string): string {
35-
const settingPath = vscode.workspace
36-
.getConfiguration()
37-
.get<string>("coder.binaryDestination")
38-
?.trim();
39-
const binaryPath =
40-
settingPath || process.env.CODER_BINARY_DESTINATION?.trim();
41-
return binaryPath
42-
? path.normalize(binaryPath)
43-
: path.join(this.getGlobalConfigDir(safeHostname), "bin");
35+
return (
36+
PathResolver.resolveOverride(
37+
"coder.binaryDestination",
38+
"CODER_BINARY_DESTINATION",
39+
) || path.join(this.getGlobalConfigDir(safeHostname), "bin")
40+
);
4441
}
4542

4643
/**
@@ -53,26 +50,19 @@ export class PathResolver {
5350
}
5451

5552
/**
56-
* Return the default path where log data from the connection is stored.
53+
* Return the proxy log directory from the `coder.proxyLogDirectory` setting
54+
* or the `CODER_SSH_LOG_DIR` environment variable, falling back to the `log`
55+
* subdirectory inside the extension's global storage path.
5756
*
5857
* The CLI will write files here named after the process PID.
5958
*/
60-
public getLogPath(): string {
61-
return path.join(this.basePath, "log");
62-
}
63-
64-
/**
65-
* Return the proxy log directory from user settings, falling back to the
66-
* default log path in extension storage.
67-
*/
6859
public getProxyLogPath(): string {
69-
const configured = expandPath(
70-
String(
71-
vscode.workspace.getConfiguration().get("coder.proxyLogDirectory") ??
72-
"",
73-
).trim(),
60+
return (
61+
PathResolver.resolveOverride(
62+
"coder.proxyLogDirectory",
63+
"CODER_SSH_LOG_DIR",
64+
) || path.join(this.basePath, "log")
7465
);
75-
return configured || this.getLogPath();
7666
}
7767

7868
/**
@@ -131,4 +121,18 @@ export class PathResolver {
131121
public getCodeLogDir(): string {
132122
return this.codeLogPath;
133123
}
124+
125+
/**
126+
* Read a path from a VS Code setting then an environment variable, returning
127+
* the first non-empty value after trimming, tilde/variable expansion, and
128+
* normalization. Returns an empty string when neither source provides a path.
129+
*/
130+
private static resolveOverride(setting: string, envVar: string): string {
131+
const fromSetting = expandPath(
132+
vscode.workspace.getConfiguration().get<string>(setting)?.trim() ?? "",
133+
);
134+
const resolved =
135+
fromSetting || expandPath(process.env[envVar]?.trim() ?? "");
136+
return resolved ? path.normalize(resolved) : "";
137+
}
134138
}

src/remote/remote.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,8 @@ export class Remote {
700700
}
701701

702702
/**
703-
* Return the --log-dir argument value for the ProxyCommand. It may be an
704-
* empty string if the CLI does not support it. Falls back to extension
705-
* storage when the user setting is not configured.
703+
* Return the --log-dir argument value for the ProxyCommand, or an empty
704+
* string when the CLI does not support it.
706705
*
707706
* Value defined in the "coder.sshFlags" setting is not considered.
708707
*/

test/unit/core/pathResolver.test.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,36 @@ describe("PathResolver", () => {
4646
},
4747
);
4848

49-
it("should expand tilde in configured path", () => {
49+
it("should expand tilde and ${userHome} in configured path", () => {
5050
mockConfig.set("coder.proxyLogDirectory", "~/logs");
51+
expect(pathResolver.getProxyLogPath()).not.toContain("~");
52+
53+
mockConfig.set("coder.proxyLogDirectory", "${userHome}/logs");
54+
expect(pathResolver.getProxyLogPath()).not.toContain("${userHome}");
55+
});
56+
57+
it("should normalize configured path", () => {
58+
mockConfig.set("coder.proxyLogDirectory", "/custom/../log/./dir");
59+
expectPathsEqual(pathResolver.getProxyLogPath(), "/log/dir");
60+
});
61+
62+
it("should use CODER_SSH_LOG_DIR environment variable with proper precedence", () => {
63+
// Use the global storage when the environment variable and setting are unset/blank
64+
vi.stubEnv("CODER_SSH_LOG_DIR", "");
65+
mockConfig.set("coder.proxyLogDirectory", "");
66+
expectPathsEqual(pathResolver.getProxyLogPath(), defaultLogPath);
67+
68+
// Test environment variable takes precedence over global storage
69+
vi.stubEnv("CODER_SSH_LOG_DIR", " /env/log/path ");
70+
expectPathsEqual(pathResolver.getProxyLogPath(), "/env/log/path");
71+
72+
// Test setting takes precedence over environment variable
73+
mockConfig.set("coder.proxyLogDirectory", " /setting/log/path ");
74+
expectPathsEqual(pathResolver.getProxyLogPath(), "/setting/log/path");
75+
});
76+
77+
it("should expand tilde in CODER_SSH_LOG_DIR", () => {
78+
vi.stubEnv("CODER_SSH_LOG_DIR", "~/logs");
5179
const result = pathResolver.getProxyLogPath();
5280
expect(result).not.toContain("~");
5381
expect(result).toContain("logs");
@@ -80,6 +108,20 @@ describe("PathResolver", () => {
80108
);
81109
});
82110

111+
it("should expand tilde in configured path", () => {
112+
mockConfig.set("coder.binaryDestination", "~/bin");
113+
const result = pathResolver.getBinaryCachePath("deployment");
114+
expect(result).not.toContain("~");
115+
expect(result).toContain("bin");
116+
});
117+
118+
it("should expand tilde in CODER_BINARY_DESTINATION", () => {
119+
vi.stubEnv("CODER_BINARY_DESTINATION", "~/bin");
120+
const result = pathResolver.getBinaryCachePath("deployment");
121+
expect(result).not.toContain("~");
122+
expect(result).toContain("bin");
123+
});
124+
83125
it("should use CODER_BINARY_DESTINATION environment variable with proper precedence", () => {
84126
// Use the global storage when the environment variable and setting are unset/blank
85127
vi.stubEnv("CODER_BINARY_DESTINATION", "");

0 commit comments

Comments
 (0)