Archived
1
0

Add separate function for VS Code arguments (#4599)

The problem before was that the pop() caused the open in existing
instance functionality to break because the arguments no longer
contained the file.

We could simply remove the pop() but since `workspace` and `folder` are
not CLI arguments I think it makes sense to handle them in a separate
function which can be called at the point where they are needed.  This
also lets us de-duplicate some logic since we create these arguments in
two spots and lets us skip this logic when we do not need it.

The pop() is still avoided because manipulating a passed-in object
in-place seems like a risky move.  If we really need to do this we
should copy the positional argument array instead.
This commit is contained in:
Asher
2021-12-10 12:01:35 -06:00
committed by GitHub
parent 3b91cffae5
commit 9e583fa562
5 changed files with 112 additions and 58 deletions

View File

@ -405,7 +405,10 @@ export const parse = (
throw new Error("--cert-key is missing")
}
logger.debug(() => ["parsed command line", field("args", { ...args, password: undefined })])
logger.debug(() => [
`parsed ${opts?.configFile ? "config" : "command line"}`,
field("args", { ...args, password: undefined }),
])
return args
}
@ -430,8 +433,6 @@ export interface DefaultedArgs extends ConfigArgs {
"user-data-dir": string
/* Positional arguments. */
_: []
folder: string
workspace: string
}
/**
@ -539,25 +540,8 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args._ = []
}
let workspace = ""
let folder = ""
if (args._.length) {
const lastEntry = path.resolve(process.cwd(), args._[args._.length - 1])
const entryIsFile = await isFile(lastEntry)
if (entryIsFile && path.extname(lastEntry) === ".code-workspace") {
workspace = lastEntry
args._.pop()
} else if (!entryIsFile) {
folder = lastEntry
args._.pop()
}
}
return {
...args,
workspace,
folder,
usingEnvPassword,
usingEnvHashedPassword,
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
@ -760,3 +744,34 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
return undefined
}
/**
* Convert our arguments to VS Code server arguments.
*/
export const toVsCodeArgs = async (args: DefaultedArgs): Promise<CodeServerLib.ServerParsedArgs> => {
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,
version: !!args.version,
port: args.port?.toString(),
}
}

View File

@ -5,7 +5,7 @@ import path from "path"
import { Disposable } from "../common/emitter"
import { plural } from "../common/util"
import { createApp, ensureAddress } from "./app"
import { AuthType, DefaultedArgs, Feature, UserProvidedArgs } from "./cli"
import { AuthType, DefaultedArgs, Feature, toVsCodeArgs, UserProvidedArgs } from "./cli"
import { coderCloudBind } from "./coder_cloud"
import { commit, version } from "./constants"
import { register } from "./routes"
@ -35,14 +35,7 @@ export const runVsCodeCli = async (args: DefaultedArgs): Promise<void> => {
const spawnCli = await loadAMDModule<CodeServerLib.SpawnCli>("vs/server/remoteExtensionHostAgent", "spawnCli")
try {
await spawnCli({
...args,
/** Type casting. */
"accept-server-license-terms": true,
help: !!args.help,
version: !!args.version,
port: args.port?.toString(),
})
await spawnCli(await toVsCodeArgs(args))
} catch (error: any) {
logger.error("Got error from VS Code", error)
}

View File

@ -3,6 +3,7 @@ import * as express from "express"
import { WebsocketRequest } from "../../../typings/pluginapi"
import { logError } from "../../common/util"
import { isDevMode } from "../constants"
import { toVsCodeArgs } from "../cli"
import { ensureAuthenticated, authenticated, redirect } from "../http"
import { loadAMDModule, readCompilationStats } from "../util"
import { Router as WsRouter } from "../wsRouter"
@ -87,15 +88,7 @@ export class CodeServerRouteWrapper {
)
try {
this._codeServerMain = await createVSServer(null, {
"connection-token": "0000",
"accept-server-license-terms": true,
...args,
/** Type casting. */
help: !!args.help,
version: !!args.version,
port: args.port?.toString(),
})
this._codeServerMain = await createVSServer(null, await toVsCodeArgs(args))
} catch (createServerError) {
logError(logger, "CodeServerRouteWrapper", createServerError)
return next(createServerError)