From 29ca7625f94d7ea2ebb9234f045c3bd12815fe79 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 1 Mar 2022 14:14:14 -0700 Subject: [PATCH 01/14] refactor: remove folder/workspace from vsCodeCliArgs Since we handle this in the vscode.ts route, we no longer need to pass it to VS Code as a CLI arg since it's deprecated on that side. --- src/node/cli.ts | 16 ---------------- test/unit/node/cli.test.ts | 25 ------------------------- 2 files changed, 41 deletions(-) diff --git a/src/node/cli.ts b/src/node/cli.ts index e996f34125b6..ac0d97a0de57 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -770,25 +770,9 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom * Convert our arguments to VS Code server arguments. */ export const toVsCodeArgs = async (args: DefaultedArgs): Promise => { - let workspace = "" - let folder = "" - if (args._.length) { - const lastEntry = path.resolve(args._[args._.length - 1]) - const entryIsFile = await isFile(lastEntry) - if (entryIsFile && path.extname(lastEntry) === ".code-workspace") { - workspace = lastEntry - } else if (!entryIsFile) { - folder = lastEntry - } - // Otherwise it is a regular file. Spawning VS Code with a file is not yet - // supported but it can be done separately after code-server spawns. - } - return { "connection-token": "0000", ...args, - workspace, - folder, "accept-server-license-terms": true, /** Type casting. */ help: !!args.help, diff --git a/test/unit/node/cli.test.ts b/test/unit/node/cli.test.ts index 327219ea4be3..108f2e841bef 100644 --- a/test/unit/node/cli.test.ts +++ b/test/unit/node/cli.test.ts @@ -726,29 +726,6 @@ describe("toVsCodeArgs", () => { it("should convert empty args", async () => { expect(await toVsCodeArgs(await setDefaults(parse([])))).toStrictEqual({ ...vscodeDefaults, - folder: "", - workspace: "", - }) - }) - - it("should convert with workspace", async () => { - const workspace = path.join(await tmpdir(testName), "test.code-workspace") - await fs.writeFile(workspace, "foobar") - expect(await toVsCodeArgs(await setDefaults(parse([workspace])))).toStrictEqual({ - ...vscodeDefaults, - workspace, - folder: "", - _: [workspace], - }) - }) - - it("should convert with folder", async () => { - const folder = await tmpdir(testName) - expect(await toVsCodeArgs(await setDefaults(parse([folder])))).toStrictEqual({ - ...vscodeDefaults, - folder, - workspace: "", - _: [folder], }) }) @@ -757,8 +734,6 @@ describe("toVsCodeArgs", () => { await fs.writeFile(file, "foobar") expect(await toVsCodeArgs(await setDefaults(parse([file])))).toStrictEqual({ ...vscodeDefaults, - folder: "", - workspace: "", _: [file], }) }) From 69498e93fdafca0eec96fc56fed6a08e99711c5a Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 1 Mar 2022 15:13:34 -0700 Subject: [PATCH 02/14] feat(vscode): redirect to folder from cli --- src/node/cli.ts | 12 +--- src/node/routes/vscode.ts | 45 ++++++++---- test/unit/node/routes/vscode.test.ts | 103 +++++++++++++-------------- 3 files changed, 84 insertions(+), 76 deletions(-) diff --git a/src/node/cli.ts b/src/node/cli.ts index ac0d97a0de57..a38b2db1c891 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -3,15 +3,7 @@ import { promises as fs } from "fs" import yaml from "js-yaml" import * as os from "os" import * as path from "path" -import { - canConnect, - generateCertificate, - generatePassword, - humanPath, - paths, - isNodeJSErrnoException, - isFile, -} from "./util" +import { canConnect, generateCertificate, generatePassword, humanPath, paths, isNodeJSErrnoException } from "./util" const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "vscode-ipc") @@ -448,7 +440,7 @@ export interface DefaultedArgs extends ConfigArgs { "extensions-dir": string "user-data-dir": string /* Positional arguments. */ - _: [] + _: string[] | [] } /** diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index fe9c441813b9..c6eb59b3bc9f 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -1,12 +1,13 @@ import { logger } from "@coder/logger" import * as express from "express" +import * as path from "path" import { WebsocketRequest } from "../../../typings/pluginapi" import { logError } from "../../common/util" import { toVsCodeArgs } from "../cli" import { isDevMode } from "../constants" import { authenticated, ensureAuthenticated, redirect, self } from "../http" import { SocketProxyProvider } from "../socket" -import { loadAMDModule } from "../util" +import { isFile, loadAMDModule } from "../util" import { Router as WsRouter } from "../wsRouter" import { errorHandler } from "./errors" @@ -33,27 +34,43 @@ export class CodeServerRouteWrapper { }) } - const { query } = await req.settings.read() - if (query) { - // Ew means the workspace was closed so clear the last folder/workspace. - if (req.query.ew) { - delete query.folder - delete query.workspace - } + let folder = undefined + let workspace = undefined + const to = self(req) + const settings = await req.settings.read() + const lastOpened = settings.query || {} + + // Ew means the workspace was closed so clear the last folder/workspace. + if (req.query.ew) { + delete lastOpened.folder + delete lastOpened.workspace + } + if (!req.query.folder && !req.query.workspace) { // Redirect to the last folder/workspace if nothing else is opened. if ( - !req.query.folder && - !req.query.workspace && - (query.folder || query.workspace) && + (lastOpened.folder || lastOpened.workspace) && !req.args["ignore-last-opened"] // This flag disables this behavior. ) { - const to = self(req) return redirect(req, res, to, { - folder: query.folder, - workspace: query.workspace, + folder: lastOpened.folder, + workspace: lastOpened.workspace, }) + } else if (req.args._.length > 0) { + if (req.args._.length) { + const lastEntry = path.resolve(req.args._[req.args._.length - 1]) + const entryIsFile = await isFile(lastEntry) + if (entryIsFile && path.extname(lastEntry) === ".code-workspace") { + workspace = lastEntry + } else if (!entryIsFile) { + folder = lastEntry + } + } } + return redirect(req, res, to, { + folder, + workspace, + }) } // Store the query parameters so we can use them on the next load. This diff --git a/test/unit/node/routes/vscode.test.ts b/test/unit/node/routes/vscode.test.ts index d896f846762c..7dd58ff74b44 100644 --- a/test/unit/node/routes/vscode.test.ts +++ b/test/unit/node/routes/vscode.test.ts @@ -1,19 +1,9 @@ import { promises as fs } from "fs" -import { Response } from "node-fetch" import * as path from "path" import { clean, tmpdir } from "../../../utils/helpers" import * as httpserver from "../../../utils/httpserver" import * as integration from "../../../utils/integration" -interface WorkbenchConfig { - folderUri?: { - path: string - } - workspaceUri?: { - path: string - } -} - describe("vscode", () => { let codeServer: httpserver.HttpServer | undefined @@ -52,52 +42,25 @@ describe("vscode", () => { } }) - /** - * Get the workbench config from the provided response. - */ - const getConfig = async (resp: Response): Promise => { - expect(resp.status).toBe(200) - const html = await resp.text() - const match = html.match(//) - if (!match || !match[1]) { - throw new Error("Unable to find workbench configuration") - } - const config = match[1].replace(/"/g, '"') - try { - return JSON.parse(config) - } catch (error) { - console.error("Failed to parse workbench configuration", config) - throw error - } - } - - it("should have no default folder or workspace", async () => { - codeServer = await integration.setup(["--auth=none"], "") - - const config = await getConfig(await codeServer.fetch("/")) - expect(config.folderUri).toBeUndefined() - expect(config.workspaceUri).toBeUndefined() - }) - - it("should have a default folder", async () => { - const defaultDir = await tmpdir(testName) - codeServer = await integration.setup(["--auth=none", defaultDir], "") + it("should redirect to the passed in workspace", async () => { + const workspace = path.join(await tmpdir(testName), "test.code-workspace") + await fs.writeFile(workspace, "") + codeServer = await integration.setup(["--auth=none", workspace], "") - // At first it will load the directory provided on the command line. - const config = await getConfig(await codeServer.fetch("/")) - expect(config.folderUri?.path).toBe(defaultDir) - expect(config.workspaceUri).toBeUndefined() + const resp = await codeServer.fetch("/") + const url = new URL(resp.url) + expect(url.pathname).toBe("/") + expect(url.search).toBe(`?workspace=${workspace}`) }) - it("should have a default workspace", async () => { - const defaultWorkspace = path.join(await tmpdir(testName), "test.code-workspace") - await fs.writeFile(defaultWorkspace, "") - codeServer = await integration.setup(["--auth=none", defaultWorkspace], "") + it("should redirect to the passed in directory", async () => { + const folder = await tmpdir(testName) + codeServer = await integration.setup(["--auth=none", folder], "") - // At first it will load the workspace provided on the command line. - const config = await getConfig(await codeServer.fetch("/")) - expect(config.folderUri).toBeUndefined() - expect(config.workspaceUri?.path).toBe(defaultWorkspace) + const resp = await codeServer.fetch("/") + const url = new URL(resp.url) + expect(url.pathname).toBe("/") + expect(url.search).toBe(`?folder=${folder}`) }) it("should redirect to last query folder/workspace", async () => { @@ -136,6 +99,42 @@ describe("vscode", () => { await resp.text() }) + it("should add the workspace as a query param maintaining the slashes", async () => { + const workspace = path.join(await tmpdir(testName), "test.code-workspace") + await fs.writeFile(workspace, "") + codeServer = await integration.setup(["--auth=none", workspace], "") + + let resp = await codeServer.fetch("/", undefined) + + expect(resp.status).toBe(200) + const url = new URL(resp.url) + expect(url.search).toBe(`?workspace=${workspace}`) + await resp.text() + }) + + it("should do nothing when nothing is passed in", async () => { + codeServer = await integration.setup(["--auth=none"], "") + + let resp = await codeServer.fetch("/", undefined) + + expect(resp.status).toBe(200) + const url = new URL(resp.url) + expect(url.search).toBe("") + await resp.text() + }) + + it("should add the folder as a query param maintaining the slashes", async () => { + const folder = await tmpdir(testName) + codeServer = await integration.setup(["--auth=none", folder], "") + + let resp = await codeServer.fetch("/", undefined) + + expect(resp.status).toBe(200) + const url = new URL(resp.url) + expect(url.search).toBe(`?folder=${folder}`) + await resp.text() + }) + it("should not redirect when last opened is ignored", async () => { codeServer = await integration.setup(["--auth=none", "--ignore-last-opened"], "") From 9da026464cfe8216470d8428a1e0e09ddea3087b Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:20:01 -0700 Subject: [PATCH 03/14] Update src/node/routes/vscode.ts Co-authored-by: Asher --- src/node/routes/vscode.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index c6eb59b3bc9f..4e684666350d 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -57,14 +57,12 @@ export class CodeServerRouteWrapper { workspace: lastOpened.workspace, }) } else if (req.args._.length > 0) { - if (req.args._.length) { - const lastEntry = path.resolve(req.args._[req.args._.length - 1]) - const entryIsFile = await isFile(lastEntry) - if (entryIsFile && path.extname(lastEntry) === ".code-workspace") { - workspace = lastEntry - } else if (!entryIsFile) { - folder = lastEntry - } + const lastEntry = path.resolve(req.args._[req.args._.length - 1]) + const entryIsFile = await isFile(lastEntry) + if (entryIsFile && path.extname(lastEntry) === ".code-workspace") { + workspace = lastEntry + } else if (!entryIsFile) { + folder = lastEntry } } return redirect(req, res, to, { From 27840094fa8f75b645706572509429dcade1b810 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:16:57 -0700 Subject: [PATCH 04/14] fixup!: update _: type --- src/node/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/cli.ts b/src/node/cli.ts index a38b2db1c891..9928db1c68d6 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -440,7 +440,7 @@ export interface DefaultedArgs extends ConfigArgs { "extensions-dir": string "user-data-dir": string /* Positional arguments. */ - _: string[] | [] + _: string[] } /** From 4e2cf5442f1f09399d4dbc985308ff68c3b92619 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:21:02 -0700 Subject: [PATCH 05/14] fixup!: move vars to lower if block --- src/node/routes/vscode.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 4e684666350d..a137b89b9766 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -34,9 +34,6 @@ export class CodeServerRouteWrapper { }) } - let folder = undefined - let workspace = undefined - const to = self(req) const settings = await req.settings.read() const lastOpened = settings.query || {} @@ -47,6 +44,9 @@ export class CodeServerRouteWrapper { } if (!req.query.folder && !req.query.workspace) { + let folder = undefined + let workspace = undefined + const to = self(req) // Redirect to the last folder/workspace if nothing else is opened. if ( (lastOpened.folder || lastOpened.workspace) && From 1856c6c4815b8069685cbc5bbd389cae55711731 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:26:18 -0700 Subject: [PATCH 06/14] fixup!: share redirect block --- src/node/routes/vscode.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index a137b89b9766..62918aef7120 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -52,10 +52,8 @@ export class CodeServerRouteWrapper { (lastOpened.folder || lastOpened.workspace) && !req.args["ignore-last-opened"] // This flag disables this behavior. ) { - return redirect(req, res, to, { - folder: lastOpened.folder, - workspace: lastOpened.workspace, - }) + folder = lastOpened.folder + workspace = lastOpened.workspace } else if (req.args._.length > 0) { const lastEntry = path.resolve(req.args._[req.args._.length - 1]) const entryIsFile = await isFile(lastEntry) From 7a6731ea42abb0d5eb749b026e35bd1da19c74a5 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:34:09 -0700 Subject: [PATCH 07/14] fixup!: mmove req.query.ew block into if --- src/node/routes/vscode.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 62918aef7120..71a874496867 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -34,19 +34,19 @@ export class CodeServerRouteWrapper { }) } - const settings = await req.settings.read() - const lastOpened = settings.query || {} - - // Ew means the workspace was closed so clear the last folder/workspace. - if (req.query.ew) { - delete lastOpened.folder - delete lastOpened.workspace - } - if (!req.query.folder && !req.query.workspace) { + const settings = await req.settings.read() + const lastOpened = settings.query || {} let folder = undefined let workspace = undefined const to = self(req) + + // Ew means the workspace was closed so clear the last folder/workspace. + if (req.query.ew) { + delete lastOpened.folder + delete lastOpened.workspace + } + // Redirect to the last folder/workspace if nothing else is opened. if ( (lastOpened.folder || lastOpened.workspace) && From d906da991758c116fdf3421666688fe758d88616 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:34:27 -0700 Subject: [PATCH 08/14] fixup!: refactor vscode tests --- test/unit/node/routes/vscode.test.ts | 39 +++++----------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/test/unit/node/routes/vscode.test.ts b/test/unit/node/routes/vscode.test.ts index 7dd58ff74b44..a5246b65b55e 100644 --- a/test/unit/node/routes/vscode.test.ts +++ b/test/unit/node/routes/vscode.test.ts @@ -29,7 +29,7 @@ describe("vscode", () => { expect(resp.status).toBe(200) const html = await resp.text() const url = new URL(resp.url) // Check there were no redirections. - expect(url.pathname + decodeURIComponent(url.search)).toBe(route) + expect(url.pathname + url.search).toBe(route) switch (route) { case "/": case "/vscode/": @@ -42,7 +42,7 @@ describe("vscode", () => { } }) - it("should redirect to the passed in workspace", async () => { + it("should redirect to the passed in workspace using human-readable query", async () => { const workspace = path.join(await tmpdir(testName), "test.code-workspace") await fs.writeFile(workspace, "") codeServer = await integration.setup(["--auth=none", workspace], "") @@ -53,7 +53,7 @@ describe("vscode", () => { expect(url.search).toBe(`?workspace=${workspace}`) }) - it("should redirect to the passed in directory", async () => { + it("should redirect to the passed in folder using human-readable query", async () => { const folder = await tmpdir(testName) codeServer = await integration.setup(["--auth=none", folder], "") @@ -81,7 +81,7 @@ describe("vscode", () => { resp = await codeServer.fetch(route) const url = new URL(resp.url) expect(url.pathname).toBe(route) - expect(decodeURIComponent(url.search)).toBe(`?folder=${folder}&workspace=${workspace}`) + expect(url.search).toBe(`?folder=${folder}&workspace=${workspace}`) await resp.text() } @@ -89,26 +89,13 @@ describe("vscode", () => { resp = await codeServer.fetch("/", undefined, { ew: "true" }) let url = new URL(resp.url) expect(url.pathname).toBe("/") - expect(decodeURIComponent(url.search)).toBe("?ew=true") + expect(url.search).toBe("?ew=true") await resp.text() resp = await codeServer.fetch("/") url = new URL(resp.url) expect(url.pathname).toBe("/") - expect(decodeURIComponent(url.search)).toBe("") - await resp.text() - }) - - it("should add the workspace as a query param maintaining the slashes", async () => { - const workspace = path.join(await tmpdir(testName), "test.code-workspace") - await fs.writeFile(workspace, "") - codeServer = await integration.setup(["--auth=none", workspace], "") - - let resp = await codeServer.fetch("/", undefined) - - expect(resp.status).toBe(200) - const url = new URL(resp.url) - expect(url.search).toBe(`?workspace=${workspace}`) + expect(url.search).toBe("") await resp.text() }) @@ -123,18 +110,6 @@ describe("vscode", () => { await resp.text() }) - it("should add the folder as a query param maintaining the slashes", async () => { - const folder = await tmpdir(testName) - codeServer = await integration.setup(["--auth=none", folder], "") - - let resp = await codeServer.fetch("/", undefined) - - expect(resp.status).toBe(200) - const url = new URL(resp.url) - expect(url.search).toBe(`?folder=${folder}`) - await resp.text() - }) - it("should not redirect when last opened is ignored", async () => { codeServer = await integration.setup(["--auth=none", "--ignore-last-opened"], "") @@ -151,7 +126,7 @@ describe("vscode", () => { resp = await codeServer.fetch("/") const url = new URL(resp.url) expect(url.pathname).toBe("/") - expect(decodeURIComponent(url.search)).toBe("") + expect(url.search).toBe("") await resp.text() }) }) From 36183d97d057b38957684250c7830eb83bfc6fa7 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 13:45:01 -0700 Subject: [PATCH 09/14] refactor: make vscode.ts logic easier to read --- src/node/routes/vscode.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 71a874496867..58f55921e86f 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -26,6 +26,7 @@ export class CodeServerRouteWrapper { private $root: express.Handler = async (req, res, next) => { const isAuthenticated = await authenticated(req) + const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace if (!isAuthenticated) { const to = self(req) @@ -34,30 +35,35 @@ export class CodeServerRouteWrapper { }) } - if (!req.query.folder && !req.query.workspace) { + if (NO_FOLDER_OR_WORKSPACE_QUERY) { const settings = await req.settings.read() const lastOpened = settings.query || {} + // Ew means the workspace was closed so clear the last folder/workspace. + const HAS_EW_QUERY = req.query.ew + // This flag disables the last opened behavior + const IGNORE_LAST_OPENED = req.args["ignore-last-opened"] + const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace + const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0 + const to = self(req) + let folder = undefined let workspace = undefined - const to = self(req) - // Ew means the workspace was closed so clear the last folder/workspace. - if (req.query.ew) { + if (HAS_EW_QUERY) { delete lastOpened.folder delete lastOpened.workspace } // Redirect to the last folder/workspace if nothing else is opened. - if ( - (lastOpened.folder || lastOpened.workspace) && - !req.args["ignore-last-opened"] // This flag disables this behavior. - ) { + if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) { folder = lastOpened.folder workspace = lastOpened.workspace - } else if (req.args._.length > 0) { + } else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) { const lastEntry = path.resolve(req.args._[req.args._.length - 1]) const entryIsFile = await isFile(lastEntry) - if (entryIsFile && path.extname(lastEntry) === ".code-workspace") { + const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace" + + if (IS_WORKSPACE_FILE) { workspace = lastEntry } else if (!entryIsFile) { folder = lastEntry From 02ed52cda3bdf55687c237599b70dfb6018fef37 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 14:19:15 -0700 Subject: [PATCH 10/14] fixup!: fix broken tests and clean up logic --- src/node/routes/vscode.ts | 21 ++++++++++++--------- test/unit/node/routes/vscode.test.ts | 3 +++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 58f55921e86f..364c813c8ad3 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -27,6 +27,8 @@ export class CodeServerRouteWrapper { private $root: express.Handler = async (req, res, next) => { const isAuthenticated = await authenticated(req) const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace + // Ew means the workspace was closed so clear the last folder/workspace. + const WORKSPACE_WAS_CLOSED = req.query.ew if (!isAuthenticated) { const to = self(req) @@ -35,21 +37,19 @@ export class CodeServerRouteWrapper { }) } - if (NO_FOLDER_OR_WORKSPACE_QUERY) { + if (NO_FOLDER_OR_WORKSPACE_QUERY && !WORKSPACE_WAS_CLOSED) { const settings = await req.settings.read() const lastOpened = settings.query || {} - // Ew means the workspace was closed so clear the last folder/workspace. - const HAS_EW_QUERY = req.query.ew // This flag disables the last opened behavior const IGNORE_LAST_OPENED = req.args["ignore-last-opened"] - const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace + const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = (!WORKSPACE_WAS_CLOSED && lastOpened.folder) || lastOpened.workspace const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0 const to = self(req) let folder = undefined let workspace = undefined - if (HAS_EW_QUERY) { + if (WORKSPACE_WAS_CLOSED) { delete lastOpened.folder delete lastOpened.workspace } @@ -69,10 +69,13 @@ export class CodeServerRouteWrapper { folder = lastEntry } } - return redirect(req, res, to, { - folder, - workspace, - }) + + if (folder || workspace) { + return redirect(req, res, to, { + folder, + workspace, + }) + } } // Store the query parameters so we can use them on the next load. This diff --git a/test/unit/node/routes/vscode.test.ts b/test/unit/node/routes/vscode.test.ts index a5246b65b55e..a4c0ba13abca 100644 --- a/test/unit/node/routes/vscode.test.ts +++ b/test/unit/node/routes/vscode.test.ts @@ -68,6 +68,7 @@ describe("vscode", () => { const folder = await tmpdir(testName) const workspace = path.join(await tmpdir(testName), "test.code-workspace") + await fs.writeFile(workspace, "") let resp = await codeServer.fetch("/", undefined, { folder, workspace, @@ -115,6 +116,8 @@ describe("vscode", () => { const folder = await tmpdir(testName) const workspace = path.join(await tmpdir(testName), "test.code-workspace") + await fs.writeFile(workspace, "") + let resp = await codeServer.fetch("/", undefined, { folder, workspace, From c6f5adecc19d31a6aec969a8582d2f3cbcb0795f Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 14:47:48 -0700 Subject: [PATCH 11/14] chore: upgrade vscode version --- vendor/package.json | 2 +- vendor/yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/package.json b/vendor/package.json index 82feee23eb18..9d00927be932 100644 --- a/vendor/package.json +++ b/vendor/package.json @@ -7,6 +7,6 @@ "postinstall": "./postinstall.sh" }, "devDependencies": { - "code-oss-dev": "coder/vscode#0fd21e4078ac1dddb26be024f5d4224a4b86da93" + "code-oss-dev": "coder/vscode#bd734e3d9f21b1bce4dabab2514177e90c090ee6" } } diff --git a/vendor/yarn.lock b/vendor/yarn.lock index abfb361b769c..9a5eff2e1988 100644 --- a/vendor/yarn.lock +++ b/vendor/yarn.lock @@ -274,9 +274,9 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -code-oss-dev@coder/vscode#0fd21e4078ac1dddb26be024f5d4224a4b86da93: +code-oss-dev@coder/vscode#bd734e3d9f21b1bce4dabab2514177e90c090ee6: version "1.63.0" - resolved "https://codeload.github.com/coder/vscode/tar.gz/0fd21e4078ac1dddb26be024f5d4224a4b86da93" + resolved "https://codeload.github.com/coder/vscode/tar.gz/bd734e3d9f21b1bce4dabab2514177e90c090ee6" dependencies: "@microsoft/applicationinsights-web" "^2.6.4" "@parcel/watcher" "2.0.3" From 4ffd9234c799f08f3862a3d2b46fde639526dd5b Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 14:48:32 -0700 Subject: [PATCH 12/14] fixup!: delete unnecessary if closed block --- src/node/routes/vscode.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 364c813c8ad3..c149bdf562e7 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -49,11 +49,6 @@ export class CodeServerRouteWrapper { let folder = undefined let workspace = undefined - if (WORKSPACE_WAS_CLOSED) { - delete lastOpened.folder - delete lastOpened.workspace - } - // Redirect to the last folder/workspace if nothing else is opened. if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) { folder = lastOpened.folder From 477b731433d34ff2f9e7633cb44d16a5201fc060 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 14:58:12 -0700 Subject: [PATCH 13/14] Update src/node/routes/vscode.ts Co-authored-by: Asher --- src/node/routes/vscode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index c149bdf562e7..213dd071f5b5 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -42,7 +42,7 @@ export class CodeServerRouteWrapper { const lastOpened = settings.query || {} // This flag disables the last opened behavior const IGNORE_LAST_OPENED = req.args["ignore-last-opened"] - const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = (!WORKSPACE_WAS_CLOSED && lastOpened.folder) || lastOpened.workspace + const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0 const to = self(req) From 8162fba8525c41c866537d8e849d5ce707ea37e8 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 2 Mar 2022 14:58:54 -0700 Subject: [PATCH 14/14] fixup!: rename to FOLDER_OR_WORKSPACE_WAS_CLOSED --- src/node/routes/vscode.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 213dd071f5b5..b137bfcd5373 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -28,7 +28,7 @@ export class CodeServerRouteWrapper { const isAuthenticated = await authenticated(req) const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace // Ew means the workspace was closed so clear the last folder/workspace. - const WORKSPACE_WAS_CLOSED = req.query.ew + const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew if (!isAuthenticated) { const to = self(req) @@ -37,7 +37,7 @@ export class CodeServerRouteWrapper { }) } - if (NO_FOLDER_OR_WORKSPACE_QUERY && !WORKSPACE_WAS_CLOSED) { + if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) { const settings = await req.settings.read() const lastOpened = settings.query || {} // This flag disables the last opened behavior