Skip to content

Commit 11ab645

Browse files
committed
Use new client in commands for the current workspace
These should work now once the clients are pointing to different things.
1 parent c726493 commit 11ab645

File tree

4 files changed

+45
-37
lines changed

4 files changed

+45
-37
lines changed

src/commands.ts

+36-18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ import { Storage } from "./storage"
99
import { OpenableTreeItem } from "./workspacesProvider"
1010

1111
export class Commands {
12+
// These will only be populated when actively connected to a workspace and are
13+
// used in commands. Because commands can be executed by the user, it is not
14+
// possible to pass in arguments, so we have to store the current workspace
15+
// and its client somewhere, separately from the current globally logged-in
16+
// client, since you can connect to workspaces not belonging to whatever you
17+
// are logged into (for convenience; otherwise the recents menu can be a pain
18+
// if you use multiple deployments).
19+
public workspace?: Workspace
20+
public workspaceLogPath?: string
21+
public workspaceRestClient?: Api
22+
1223
public constructor(
1324
private readonly vscodeProposed: typeof vscode,
1425
private readonly restClient: Api,
@@ -162,15 +173,14 @@ export class Commands {
162173
}
163174

164175
/**
165-
* View the logs for the currently logged-in deployment.
176+
* View the logs for the currently connected workspace.
166177
*/
167178
public async viewLogs(): Promise<void> {
168-
// TODO: This will need to be refactored for multi-deployment support.
169-
if (!this.storage.workspaceLogPath) {
170-
vscode.window.showInformationMessage("No logs available.", this.storage.workspaceLogPath || "<unset>")
179+
if (!this.workspaceLogPath) {
180+
vscode.window.showInformationMessage("No logs available.", this.workspaceLogPath || "<unset>")
171181
return
172182
}
173-
const uri = vscode.Uri.file(this.storage.workspaceLogPath)
183+
const uri = vscode.Uri.file(this.workspaceLogPath)
174184
const doc = await vscode.workspace.openTextDocument(uri)
175185
await vscode.window.showTextDocument(doc)
176186
}
@@ -212,14 +222,18 @@ export class Commands {
212222
/**
213223
* Open a link to the workspace in the Coder dashboard.
214224
*
215-
* Must only be called if currently logged in.
225+
* If passing in a workspace, it must belong to the currently logged-in
226+
* deployment.
227+
*
228+
* Otherwise, the currently connected workspace is used (if any).
216229
*/
217230
public async navigateToWorkspace(workspace: OpenableTreeItem) {
218231
if (workspace) {
219232
const uri = this.storage.getUrl() + `/@${workspace.workspaceOwner}/${workspace.workspaceName}`
220233
await vscode.commands.executeCommand("vscode.open", uri)
221-
} else if (this.storage.workspace) {
222-
const uri = this.storage.getUrl() + `/@${this.storage.workspace.owner_name}/${this.storage.workspace.name}`
234+
} else if (this.workspace && this.workspaceRestClient) {
235+
const baseUrl = this.workspaceRestClient.getAxiosInstance().defaults.baseURL
236+
const uri = `${baseUrl}/@${this.workspace.owner_name}/${this.workspace.name}`
223237
await vscode.commands.executeCommand("vscode.open", uri)
224238
} else {
225239
vscode.window.showInformationMessage("No workspace found.")
@@ -229,15 +243,18 @@ export class Commands {
229243
/**
230244
* Open a link to the workspace settings in the Coder dashboard.
231245
*
232-
* Must only be called if currently logged in.
246+
* If passing in a workspace, it must belong to the currently logged-in
247+
* deployment.
248+
*
249+
* Otherwise, the currently connected workspace is used (if any).
233250
*/
234251
public async navigateToWorkspaceSettings(workspace: OpenableTreeItem) {
235252
if (workspace) {
236253
const uri = this.storage.getUrl() + `/@${workspace.workspaceOwner}/${workspace.workspaceName}/settings`
237254
await vscode.commands.executeCommand("vscode.open", uri)
238-
} else if (this.storage.workspace) {
239-
const uri =
240-
this.storage.getUrl() + `/@${this.storage.workspace.owner_name}/${this.storage.workspace.name}/settings`
255+
} else if (this.workspace && this.workspaceRestClient) {
256+
const baseUrl = this.workspaceRestClient.getAxiosInstance().defaults.baseURL
257+
const uri = `${baseUrl}/@${this.workspace.owner_name}/${this.workspace.name}/settings`
241258
await vscode.commands.executeCommand("vscode.open", uri)
242259
} else {
243260
vscode.window.showInformationMessage("No workspace found.")
@@ -248,7 +265,8 @@ export class Commands {
248265
* Open a workspace or agent that is showing in the sidebar.
249266
*
250267
* This essentially just builds the host name and passes it to the VS Code
251-
* Remote SSH extension.
268+
* Remote SSH extension, so it is not necessary to be logged in, although then
269+
* the sidebar would not have any workspaces in it anyway.
252270
*/
253271
public async openFromSidebar(treeItem: OpenableTreeItem) {
254272
if (treeItem) {
@@ -263,9 +281,9 @@ export class Commands {
263281
}
264282

265283
/**
266-
* Open a workspace from the currently logged-in deployment.
284+
* Open a workspace belonging to the currently logged-in deployment.
267285
*
268-
* This must only be called if the REST client is logged in.
286+
* This must only be called if logged into a deployment.
269287
*/
270288
public async open(...args: unknown[]): Promise<void> {
271289
let workspaceOwner: string
@@ -392,20 +410,20 @@ export class Commands {
392410
* this is a no-op.
393411
*/
394412
public async updateWorkspace(): Promise<void> {
395-
if (!this.storage.workspace || !this.storage.restClient) {
413+
if (!this.workspace || !this.workspaceRestClient) {
396414
return
397415
}
398416
const action = await this.vscodeProposed.window.showInformationMessage(
399417
"Update Workspace",
400418
{
401419
useCustom: true,
402420
modal: true,
403-
detail: `${this.storage.workspace.owner_name}/${this.storage.workspace.name} will be updated then this window will reload to watch the build logs and reconnect.`,
421+
detail: `${this.workspace.owner_name}/${this.workspace.name} will be updated then this window will reload to watch the build logs and reconnect.`,
404422
},
405423
"Update",
406424
)
407425
if (action === "Update") {
408-
await this.storage.restClient.updateWorkspaceVersion(this.storage.workspace)
426+
await this.restClient.updateWorkspaceVersion(this.workspace)
409427
}
410428
}
411429
}

src/extension.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
153153
if (!vscodeProposed.env.remoteAuthority) {
154154
return
155155
}
156-
const remote = new Remote(vscodeProposed, storage, ctx.extensionMode)
156+
const remote = new Remote(vscodeProposed, storage, commands, ctx.extensionMode)
157157
try {
158158
await remote.setup(vscodeProposed.env.remoteAuthority)
159159
} catch (ex) {

src/remote.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as semver from "semver"
1212
import * as vscode from "vscode"
1313
import * as ws from "ws"
1414
import { makeCoderSdk } from "./api"
15+
import { Commands } from "./commands"
1516
import { getHeaderCommand } from "./headers"
1617
import { SSHConfig, SSHValues, defaultSSHConfigResponse, mergeSSHConfigValues } from "./sshConfig"
1718
import { computeSSHProperties, sshSupportsSetEnv } from "./sshSupport"
@@ -27,6 +28,7 @@ export class Remote {
2728
public constructor(
2829
private readonly vscodeProposed: typeof vscode,
2930
private readonly storage: Storage,
31+
private readonly commands: Commands,
3032
private readonly mode: vscode.ExtensionMode,
3133
) {}
3234

@@ -84,7 +86,7 @@ export class Remote {
8486
this.storage,
8587
)
8688
// Store for use in commands.
87-
this.storage.restClient = restClient
89+
this.commands.workspaceRestClient = restClient
8890

8991
// First thing is to check the version.
9092
const buildInfo = await restClient.getBuildInfo()
@@ -114,7 +116,7 @@ export class Remote {
114116
let workspace: Workspace
115117
try {
116118
workspace = await restClient.getWorkspaceByOwnerAndName(parts[0], parts[1])
117-
this.storage.workspace = workspace
119+
this.commands.workspace = workspace
118120
} catch (error) {
119121
if (!isAxiosError(error)) {
120122
throw error
@@ -199,7 +201,7 @@ export class Remote {
199201
...workspace,
200202
latest_build: latestBuild,
201203
}
202-
this.storage.workspace = workspace
204+
this.commands.workspace = workspace
203205
}
204206

205207
// If a build is running we should stream the logs to the user so they can
@@ -257,7 +259,7 @@ export class Remote {
257259
})
258260
writeEmitter.fire("Build complete")
259261
workspace = await restClient.getWorkspace(workspace.id)
260-
this.storage.workspace = workspace
262+
this.commands.workspace = workspace
261263
terminal.dispose()
262264

263265
if (buildComplete) {
@@ -425,7 +427,7 @@ export class Remote {
425427
return
426428
}
427429
refreshWorkspaceUpdatedStatus(workspace)
428-
this.storage.workspace = workspace
430+
this.commands.workspace = workspace
429431
workspaceUpdate.fire(workspace)
430432
if (workspace.latest_build.status === "stopping" || workspace.latest_build.status === "stopped") {
431433
const action = this.vscodeProposed.window.showInformationMessage(
@@ -525,7 +527,7 @@ export class Remote {
525527
return
526528
}
527529
disposables.push(this.showNetworkUpdates(pid))
528-
this.storage.workspaceLogPath = path.join(this.storage.getLogPath(), `${pid}.log`)
530+
this.commands.workspaceLogPath = path.join(this.storage.getLogPath(), `${pid}.log`)
529531
})
530532

531533
// Register the label formatter again because SSH overrides it!

src/storage.ts

-12
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,6 @@ import { getHeaderCommand, getHeaders } from "./headers"
1515
const MAX_URLS = 10
1616

1717
export class Storage {
18-
// These will only be populated when actively connected to a workspace and are
19-
// used in commands. Because commands can be executed by the user, it is not
20-
// possible to pass in arguments, so we have to store the current workspace
21-
// and client somewhere, separately from the current login, since you can
22-
// connect to workspaces not belonging to whatever you are logged into (for
23-
// convenience; otherwise the recents menu can be a pain if you use multiple
24-
// deployments).
25-
// TODO: Should maybe store on the Commands class instead.
26-
public workspace?: Workspace
27-
public workspaceLogPath?: string
28-
public restClient?: Api
29-
3018
constructor(
3119
private readonly output: vscode.OutputChannel,
3220
private readonly memento: vscode.Memento,

0 commit comments

Comments
 (0)