From 086ec55b06d403e3414ea08c14288d2516ab0225 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Tue, 1 Jul 2025 19:14:31 +0300 Subject: [PATCH 1/2] fix: improve /openDevContainer support with local workspace folder This change allows `localWorkspaceFolder` and `localConfigFile` to be provided which allows us to use `dev-container` rather than `attached-container` to enter enabling all dev container features like file change detection and rebuilding. --- CHANGELOG.md | 3 +++ src/commands.ts | 27 +++++++++++++++++++++++++-- src/extension.ts | 10 ++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3af0db4..f07f13fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Update `/openDevContainer` to support all dev container features when hostPath + and configFile are provided. + ## [v1.9.2](https://github.com/coder/vscode-coder/releases/tag/v1.9.2) 2025-06-25 ### Fixed diff --git a/src/commands.ts b/src/commands.ts index c1d49f91..43e77944 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -631,6 +631,8 @@ export class Commands { const workspaceAgent = args[2] as string; const devContainerName = args[3] as string; const devContainerFolder = args[4] as string; + const localWorkspaceFolder = args[5] as string | undefined; + const localConfigFile = args[6] as string | undefined; await openDevContainer( baseUrl, @@ -639,6 +641,8 @@ export class Commands { workspaceAgent, devContainerName, devContainerFolder, + localWorkspaceFolder, + localConfigFile, ); } @@ -751,6 +755,8 @@ async function openDevContainer( workspaceAgent: string, devContainerName: string, devContainerFolder: string, + localWorkspaceFolder: string | undefined, + localConfigFile: string | undefined, ) { const remoteAuthority = toRemoteAuthority( baseUrl, @@ -759,11 +765,28 @@ async function openDevContainer( workspaceAgent, ); + if (!localWorkspaceFolder) { + localConfigFile = undefined; + } + let configFile; + if (localConfigFile) { + configFile = { + path: localConfigFile, + scheme: "vscode-fileHost", + }; + } const devContainer = Buffer.from( - JSON.stringify({ containerName: devContainerName }), + JSON.stringify({ + containerName: devContainerName, + hostPath: localWorkspaceFolder, + configFile, + localDocker: false, + }), "utf-8", ).toString("hex"); - const devContainerAuthority = `attached-container+${devContainer}@${remoteAuthority}`; + + const type = localWorkspaceFolder ? "dev-container" : "attached-container"; + const devContainerAuthority = `${type}+${devContainer}@${remoteAuthority}`; let newWindow = true; if (!vscode.workspace.workspaceFolders?.length) { diff --git a/src/extension.ts b/src/extension.ts index 10fd7783..05eb7319 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -165,6 +165,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { const workspaceAgent = params.get("agent"); const devContainerName = params.get("devContainerName"); const devContainerFolder = params.get("devContainerFolder"); + const localWorkspaceFolder = params.get("localWorkspaceFolder"); + const localConfigFile = params.get("localConfigFile"); if (!workspaceOwner) { throw new Error( @@ -190,6 +192,12 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { ); } + if (localConfigFile && !localWorkspaceFolder) { + throw new Error( + "local workspace folder must be specified as a query parameter if local config file is provided", + ); + } + // We are not guaranteed that the URL we currently have is for the URL // this workspace belongs to, or that we even have a URL at all (the // queries will default to localhost) so ask for it if missing. @@ -228,6 +236,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { workspaceAgent, devContainerName, devContainerFolder, + localWorkspaceFolder, + localConfigFile, ); } else { throw new Error(`Unknown path ${uri.path}`); From 52a37a955566129a4292ad0621dd9b2e3388faf9 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Wed, 2 Jul 2025 11:53:10 +0300 Subject: [PATCH 2/2] refactor args --- src/commands.ts | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 43e77944..d6734376 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -620,20 +620,20 @@ export class Commands { * * Throw if not logged into a deployment. */ - public async openDevContainer(...args: string[]): Promise { + public async openDevContainer( + workspaceOwner: string, + workspaceName: string, + workspaceAgent: string, + devContainerName: string, + devContainerFolder: string, + localWorkspaceFolder: string = "", + localConfigFile: string = "", + ): Promise { const baseUrl = this.restClient.getAxiosInstance().defaults.baseURL; if (!baseUrl) { throw new Error("You are not logged in"); } - const workspaceOwner = args[0] as string; - const workspaceName = args[1] as string; - const workspaceAgent = args[2] as string; - const devContainerName = args[3] as string; - const devContainerFolder = args[4] as string; - const localWorkspaceFolder = args[5] as string | undefined; - const localConfigFile = args[6] as string | undefined; - await openDevContainer( baseUrl, workspaceOwner, @@ -755,8 +755,8 @@ async function openDevContainer( workspaceAgent: string, devContainerName: string, devContainerFolder: string, - localWorkspaceFolder: string | undefined, - localConfigFile: string | undefined, + localWorkspaceFolder: string = "", + localConfigFile: string = "", ) { const remoteAuthority = toRemoteAuthority( baseUrl, @@ -765,20 +765,18 @@ async function openDevContainer( workspaceAgent, ); - if (!localWorkspaceFolder) { - localConfigFile = undefined; - } - let configFile; - if (localConfigFile) { - configFile = { - path: localConfigFile, - scheme: "vscode-fileHost", - }; - } + const hostPath = localWorkspaceFolder ? localWorkspaceFolder : undefined; + const configFile = + hostPath && localConfigFile + ? { + path: localConfigFile, + scheme: "vscode-fileHost", + } + : undefined; const devContainer = Buffer.from( JSON.stringify({ containerName: devContainerName, - hostPath: localWorkspaceFolder, + hostPath, configFile, localDocker: false, }), pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy