mirror of
https://github.com/coder/code-server.git
synced 2026-04-13 11:38:50 -05:00
Update VS Code to 1.92.2 (#6941)
* Update VS Code to 1.92.2
* Use server-main.js to load VS Code
It looks like the bootstrap files are now bundled so we can no longer
require them. We could make them included again, but maybe it is better
to go through the main entrypoint anyway because it includes some nls
stuff which is maybe necessary.
This also fixes what looks like a bug where we could create two servers
if two requests came in. I am not sure what the practical consequences
of that would be, but it will no longer do that.
* Drop es2020 patch
Unfortunately, VS Code will not load with this. It seems to be because
`this` is being used in static properties, and it becomes `void 0` for
some reason under the es2020 target. For example:
static PREFIX_BY_CATEGORY = `${this.PREFIX}${this.SCOPE_PREFIX}`;
becomes
AbstractGotoSymbolQuickAccessProvider.PREFIX_BY_CATEGORY = `${(void 0).PREFIX}${(void 0).SCOPE_PREFIX}`;
Which, obviously, will not work.
Older versions of Safari (and maybe other browsers) are likely affected.
* Fix display language
* Update Playwright
I think maybe because of the dropped es2020 patch that Webkit is now
failing because it is too old.
* Do not wait for networkidle in e2e tests
I am not sure what is going on but some tests on Webkit are timing out
and it seems the page is loaded but something is still trying to
download. Not good, but for now try to at least get the tests passing.
This commit is contained in:
@@ -837,11 +837,6 @@ export interface CodeArgs extends UserProvidedCodeArgs {
|
||||
log?: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Types for ../../lib/vscode/src/vs/server/node/server.main.ts:65.
|
||||
*/
|
||||
export type SpawnCodeCli = (args: CodeArgs) => Promise<void>
|
||||
|
||||
/**
|
||||
* Convert our arguments to equivalent VS Code server arguments.
|
||||
* Does not add any extra arguments.
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { field, logger } from "@coder/logger"
|
||||
import http from "http"
|
||||
import * as path from "path"
|
||||
import { Disposable } from "../common/emitter"
|
||||
import { plural } from "../common/util"
|
||||
import { createApp, ensureAddress } from "./app"
|
||||
import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvidedArgs } from "./cli"
|
||||
import { commit, version } from "./constants"
|
||||
import { AuthType, DefaultedArgs, Feature, toCodeArgs, UserProvidedArgs } from "./cli"
|
||||
import { commit, version, vsRootPath } from "./constants"
|
||||
import { register } from "./routes"
|
||||
import { isDirectory, loadAMDModule, open } from "./util"
|
||||
import { VSCodeModule } from "./routes/vscode"
|
||||
import { isDirectory, open } from "./util"
|
||||
|
||||
/**
|
||||
* Return true if the user passed an extension-related VS Code flag.
|
||||
@@ -46,12 +48,10 @@ export interface OpenCommandPipeArgs {
|
||||
*/
|
||||
export const runCodeCli = async (args: DefaultedArgs): Promise<void> => {
|
||||
logger.debug("Running Code CLI")
|
||||
|
||||
// See ../../lib/vscode/src/vs/server/node/server.main.ts:65.
|
||||
const spawnCli = await loadAMDModule<SpawnCodeCli>("vs/server/node/server.main", "spawnCli")
|
||||
|
||||
try {
|
||||
await spawnCli(await toCodeArgs(args))
|
||||
const mod = require(path.join(vsRootPath, "out/server-main")) as VSCodeModule
|
||||
const serverModule = await mod.loadCodeWithNls()
|
||||
await serverModule.spawnCli(await toCodeArgs(args))
|
||||
// Rather than have the caller handle errors and exit, spawnCli will exit
|
||||
// itself. Additionally, it does this on a timeout set to 0. So, try
|
||||
// waiting for VS Code to exit before giving up and doing it ourselves.
|
||||
|
||||
@@ -8,10 +8,10 @@ import * as path from "path"
|
||||
import { WebsocketRequest } from "../../../typings/pluginapi"
|
||||
import { logError } from "../../common/util"
|
||||
import { CodeArgs, toCodeArgs } from "../cli"
|
||||
import { isDevMode } from "../constants"
|
||||
import { isDevMode, vsRootPath } from "../constants"
|
||||
import { authenticated, ensureAuthenticated, ensureOrigin, redirect, replaceTemplates, self } from "../http"
|
||||
import { SocketProxyProvider } from "../socket"
|
||||
import { isFile, loadAMDModule } from "../util"
|
||||
import { isFile } from "../util"
|
||||
import { Router as WsRouter } from "../wsRouter"
|
||||
|
||||
export const router = express.Router()
|
||||
@@ -31,11 +31,46 @@ export interface IVSCodeServerAPI {
|
||||
dispose(): void
|
||||
}
|
||||
|
||||
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
|
||||
export type CreateServer = (address: string | net.AddressInfo | null, args: CodeArgs) => Promise<IVSCodeServerAPI>
|
||||
/**
|
||||
* VS Code's CLI entrypoint (../../../lib/vscode/src/server-main.js).
|
||||
*
|
||||
* Normally VS Code will run `node server-main.js` which starts either the web
|
||||
* server or the CLI (for installing extensions, etc) but we patch it so we can
|
||||
* `require` it and call its functions directly in order to integrate with our
|
||||
* web server.
|
||||
*/
|
||||
export type VSCodeModule = {
|
||||
// See ../../../lib/vscode/src/server-main.js:339.
|
||||
loadCodeWithNls(): {
|
||||
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
|
||||
createServer(address: string | net.AddressInfo | null, args: CodeArgs): Promise<IVSCodeServerAPI>
|
||||
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:65.
|
||||
spawnCli(args: CodeArgs): Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
// The VS Code server is dynamically loaded in when a request is made to this
|
||||
// router by `ensureCodeServerLoaded`.
|
||||
/**
|
||||
* Load then create the VS Code server.
|
||||
*/
|
||||
async function loadVSCode(req: express.Request): Promise<IVSCodeServerAPI> {
|
||||
const mod = require(path.join(vsRootPath, "out/server-main")) as VSCodeModule
|
||||
const serverModule = await mod.loadCodeWithNls()
|
||||
return serverModule.createServer(null, {
|
||||
...(await toCodeArgs(req.args)),
|
||||
"accept-server-license-terms": true,
|
||||
// This seems to be used to make the connection token flags optional (when
|
||||
// set to 1.63) but we have always included them.
|
||||
compatibility: "1.64",
|
||||
"without-connection-token": true,
|
||||
})
|
||||
}
|
||||
|
||||
// To prevent loading the module more than once at a time. We also have the
|
||||
// resolved value so you do not need to `await` everywhere.
|
||||
let vscodeServerPromise: Promise<IVSCodeServerAPI> | undefined
|
||||
|
||||
// The resolved value from the dynamically loaded VS Code server. Do not use
|
||||
// without first calling and awaiting `ensureCodeServerLoaded`.
|
||||
let vscodeServer: IVSCodeServerAPI | undefined
|
||||
|
||||
/**
|
||||
@@ -49,21 +84,21 @@ export const ensureVSCodeLoaded = async (
|
||||
if (vscodeServer) {
|
||||
return next()
|
||||
}
|
||||
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
|
||||
const createVSServer = await loadAMDModule<CreateServer>("vs/server/node/server.main", "createServer")
|
||||
if (!vscodeServerPromise) {
|
||||
vscodeServerPromise = loadVSCode(req)
|
||||
}
|
||||
try {
|
||||
vscodeServer = await createVSServer(null, {
|
||||
...(await toCodeArgs(req.args)),
|
||||
"accept-server-license-terms": true,
|
||||
// This seems to be used to make the connection token flags optional (when
|
||||
// set to 1.63) but we have always included them.
|
||||
compatibility: "1.64",
|
||||
"without-connection-token": true,
|
||||
})
|
||||
vscodeServer = await vscodeServerPromise
|
||||
} catch (error) {
|
||||
vscodeServerPromise = undefined // Unset so we can try again.
|
||||
logError(logger, "CodeServerRouteWrapper", error)
|
||||
if (isDevMode) {
|
||||
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
|
||||
return next(
|
||||
new Error(
|
||||
(error instanceof Error ? error.message : error) +
|
||||
" (Have you applied the patches? If so, VS Code may still be compiling)",
|
||||
),
|
||||
)
|
||||
}
|
||||
return next(error)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import * as path from "path"
|
||||
import safeCompare from "safe-compare"
|
||||
import * as util from "util"
|
||||
import xdgBasedir from "xdg-basedir"
|
||||
import { vsRootPath } from "./constants"
|
||||
|
||||
export interface Paths {
|
||||
data: string
|
||||
@@ -503,31 +502,6 @@ export function isNodeJSErrnoException(error: unknown): error is NodeJS.ErrnoExc
|
||||
// TODO: Replace with proper templating system.
|
||||
export const escapeJSON = (value: cp.Serializable) => JSON.stringify(value).replace(/"/g, """)
|
||||
|
||||
type AMDModule<T> = { [exportName: string]: T }
|
||||
|
||||
/**
|
||||
* Loads AMD module, typically from a compiled VSCode bundle.
|
||||
*
|
||||
* @deprecated This should be gradually phased out as code-server migrates to lib/vscode
|
||||
* @param amdPath Path to module relative to lib/vscode
|
||||
* @param exportName Given name of export in the file
|
||||
*/
|
||||
export const loadAMDModule = async <T>(amdPath: string, exportName: string): Promise<T> => {
|
||||
// Set default remote native node modules path, if unset
|
||||
process.env["VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH"] =
|
||||
process.env["VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH"] || path.join(vsRootPath, "remote", "node_modules")
|
||||
|
||||
require(path.join(vsRootPath, "out/bootstrap-node")).injectNodeModuleLookupPath(
|
||||
process.env["VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH"],
|
||||
)
|
||||
|
||||
const module = await new Promise<AMDModule<T>>((resolve, reject) => {
|
||||
require(path.join(vsRootPath, "out/bootstrap-amd")).load(amdPath, resolve, reject)
|
||||
})
|
||||
|
||||
return module[exportName] as T
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a string on the first equals. The result will always be an array with
|
||||
* two items regardless of how many equals there are. The second item will be
|
||||
|
||||
Reference in New Issue
Block a user