mirror of
https://github.com/coder/code-server.git
synced 2026-07-01 22:52:24 +02:00
There is a new use of parsedArgs so we have to pass that in since we parse on demand instead of globally.
343 lines
16 KiB
Diff
343 lines
16 KiB
Diff
Prepare Code for integration with code-server
|
|
|
|
1. We already have the arguments so allow passing them in. There is also a
|
|
slight change in a few directories to preserve the directory structure we
|
|
have been using and to not override passed-in arguments.
|
|
2. Modify the entry point to allow importing the code, instead of just running
|
|
the server immediately.
|
|
3. Modify the terminal environment to filter out code-server environment variables.
|
|
4. Add the code-server version to the help dialog.
|
|
5. Add ready events for use in an iframe.
|
|
6. Add our icons and remove the existing ones.
|
|
7. Use our own manifest.
|
|
|
|
Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/server/node/server.main.ts
|
|
+++ code-server/lib/vscode/src/vs/server/node/server.main.ts
|
|
@@ -12,7 +12,7 @@ import { createServer as doCreateServer,
|
|
import { parseArgs, ErrorReporter } from '../../platform/environment/node/argv.js';
|
|
import { join, dirname } from '../../base/common/path.js';
|
|
import { performance } from 'perf_hooks';
|
|
-import { serverOptions } from './serverEnvironmentService.js';
|
|
+import { serverOptions, ServerParsedArgs } from './serverEnvironmentService.js';
|
|
import product from '../../platform/product/common/product.js';
|
|
import * as perf from '../../base/common/performance.js';
|
|
|
|
@@ -34,38 +34,47 @@ const errorReporter: ErrorReporter = {
|
|
}
|
|
};
|
|
|
|
-const args = parseArgs(process.argv.slice(2), serverOptions, errorReporter);
|
|
+function parse(): ServerParsedArgs {
|
|
+ return parseArgs(process.argv.slice(2), serverOptions, errorReporter);
|
|
+}
|
|
|
|
-const REMOTE_DATA_FOLDER = args['server-data-dir'] || process.env['VSCODE_AGENT_FOLDER'] || join(os.homedir(), product.serverDataFolderName || '.vscode-remote');
|
|
-const USER_DATA_PATH = join(REMOTE_DATA_FOLDER, 'data');
|
|
-const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User');
|
|
-const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage');
|
|
-const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
|
|
-const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
|
|
-args['user-data-dir'] = USER_DATA_PATH;
|
|
-const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath);
|
|
-const BUILTIN_EXTENSIONS_FOLDER_PATH = join(APP_ROOT, 'extensions');
|
|
-args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
|
|
-args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
|
|
-
|
|
-[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
|
- try {
|
|
- if (!fs.existsSync(f)) {
|
|
- fs.mkdirSync(f, { mode: 0o700, recursive: true });
|
|
- }
|
|
- } catch (err) { console.error(err); }
|
|
-});
|
|
+function createDirs(args: ServerParsedArgs): string {
|
|
+ const REMOTE_DATA_FOLDER = args['server-data-dir'] || args['user-data-dir'] || process.env['VSCODE_AGENT_FOLDER'] || join(os.homedir(), product.serverDataFolderName || '.vscode-remote');
|
|
+ const USER_DATA_PATH = args['user-data-dir'] || join(REMOTE_DATA_FOLDER, 'data');
|
|
+ const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User');
|
|
+ const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage');
|
|
+ const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
|
|
+ const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
|
|
+ args['user-data-dir'] = USER_DATA_PATH;
|
|
+ const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath);
|
|
+ const BUILTIN_EXTENSIONS_FOLDER_PATH = args['builtin-extensions-dir'] || join(APP_ROOT, 'extensions');
|
|
+ args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
|
|
+ args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
|
|
+
|
|
+ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
|
+ try {
|
|
+ if (!fs.existsSync(f)) {
|
|
+ fs.mkdirSync(f, { mode: 0o700, recursive: true });
|
|
+ }
|
|
+ } catch (err) { console.error(err); }
|
|
+ });
|
|
+ return REMOTE_DATA_FOLDER;
|
|
+}
|
|
|
|
/**
|
|
* invoked by server-main.js
|
|
*/
|
|
-export function spawnCli() {
|
|
- runCli(args, REMOTE_DATA_FOLDER, serverOptions);
|
|
+function spawnCli(args = parse()): Promise<void> {
|
|
+ return runCli(args, createDirs(args), serverOptions);
|
|
}
|
|
|
|
/**
|
|
* invoked by server-main.js
|
|
*/
|
|
-export function createServer(address: string | net.AddressInfo | null): Promise<IServerAPI> {
|
|
- return doCreateServer(address, args, REMOTE_DATA_FOLDER);
|
|
+function createServer(address: string | net.AddressInfo | null, args = parse()): Promise<IServerAPI> {
|
|
+ return doCreateServer(address, args, createDirs(args));
|
|
}
|
|
+
|
|
+// The aliases prevent the names getting mangled during minification which would
|
|
+// make it difficult to import.
|
|
+export { spawnCli as spawnCli, createServer as createServer };
|
|
Index: code-server/lib/vscode/src/vs/base/common/processes.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/base/common/processes.ts
|
|
+++ code-server/lib/vscode/src/vs/base/common/processes.ts
|
|
@@ -111,6 +111,8 @@ export function sanitizeProcessEnvironme
|
|
/^VSCODE_(?!(PORTABLE|SHELL_LOGIN|ENV_REPLACE|ENV_APPEND|ENV_PREPEND)).+$/,
|
|
/^SNAP(|_.*)$/,
|
|
/^GDK_PIXBUF_.+$/,
|
|
+ /^CODE_SERVER_.+$/,
|
|
+ /^CS_.+$/,
|
|
];
|
|
const envKeys = Object.keys(env);
|
|
envKeys
|
|
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
|
@@ -0,0 +1,46 @@
|
|
+import { Disposable } from "../../base/common/lifecycle.js";
|
|
+
|
|
+export class CodeServerClient extends Disposable {
|
|
+ constructor (
|
|
+ ) {
|
|
+ super();
|
|
+ }
|
|
+
|
|
+ async startup(): Promise<void> {
|
|
+ // Emit ready events
|
|
+ const event = new CustomEvent('ide-ready');
|
|
+ window.dispatchEvent(event);
|
|
+
|
|
+ if (parent) {
|
|
+ // Tell the parent loading has completed.
|
|
+ parent.postMessage({ event: 'loaded' }, '*');
|
|
+
|
|
+ // Proxy or stop proxing events as requested by the parent.
|
|
+ const listeners = new Map<string, (event: Event) => void>();
|
|
+
|
|
+ window.addEventListener('message', parentEvent => {
|
|
+ const eventName = parentEvent.data.bind || parentEvent.data.unbind;
|
|
+ if (eventName) {
|
|
+ const oldListener = listeners.get(eventName);
|
|
+ if (oldListener) {
|
|
+ document.removeEventListener(eventName, oldListener);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (parentEvent.data.bind && parentEvent.data.prop) {
|
|
+ const listener = (event: Event) => {
|
|
+ parent?.postMessage(
|
|
+ {
|
|
+ event: parentEvent.data.event,
|
|
+ [parentEvent.data.prop]: event[parentEvent.data.prop as keyof Event],
|
|
+ },
|
|
+ window.location.origin,
|
|
+ );
|
|
+ };
|
|
+ listeners.set(parentEvent.data.bind, listener);
|
|
+ document.addEventListener(parentEvent.data.bind, listener);
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+ }
|
|
+}
|
|
Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts
|
|
+++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
|
|
@@ -64,6 +64,7 @@ import { IOpenerService } from '../../pl
|
|
import { mixin, safeStringify } from '../../base/common/objects.js';
|
|
import { IndexedDB } from '../../base/browser/indexedDB.js';
|
|
import { WebFileSystemAccess } from '../../platform/files/browser/webFileSystemAccess.js';
|
|
+import { CodeServerClient } from '../../workbench/browser/client.js';
|
|
import { IProgressService } from '../../platform/progress/common/progress.js';
|
|
import { DelayedLogChannel } from '../services/output/common/delayedLogChannel.js';
|
|
import { dirname, joinPath } from '../../base/common/resources.js';
|
|
@@ -139,6 +140,9 @@ export class BrowserMain extends Disposa
|
|
// Startup
|
|
const instantiationService = workbench.startup();
|
|
|
|
+ const codeServerClient = this._register(instantiationService.createInstance(CodeServerClient));
|
|
+ await codeServerClient.startup();
|
|
+
|
|
// Window
|
|
this._register(instantiationService.createInstance(BrowserWindow));
|
|
|
|
Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
|
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
|
@@ -84,6 +84,8 @@ export interface IAgentSdkProductConfig
|
|
}
|
|
|
|
export interface IProductConfiguration {
|
|
+ readonly codeServerVersion?: string
|
|
+
|
|
readonly version: string;
|
|
readonly date?: string;
|
|
readonly quality?: string;
|
|
Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html
|
|
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html
|
|
@@ -11,7 +11,8 @@
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-title" content="Code">
|
|
- <link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" />
|
|
+ <link rel="apple-touch-icon" sizes="192x192" href="/_static/src/browser/media/pwa-icon-192.png" />
|
|
+ <link rel="apple-touch-icon" sizes="512x512" href="/_static/src/browser/media/pwa-icon-512.png" />
|
|
|
|
<!-- Disable pinch zooming -->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
|
@@ -26,8 +27,9 @@
|
|
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
|
|
|
|
<!-- Workbench Icon/Manifest/CSS -->
|
|
- <link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" />
|
|
- <link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" />
|
|
+ <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" />
|
|
+ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" />
|
|
+ <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
|
|
<style id="vscode-css-modules" type="text/css" media="screen"></style>
|
|
|
|
</head>
|
|
Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.html
|
|
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
|
|
@@ -11,7 +11,8 @@
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-title" content="Code">
|
|
- <link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" />
|
|
+ <link rel="apple-touch-icon" sizes="192x192" href="/_static/src/browser/media/pwa-icon-192.png" />
|
|
+ <link rel="apple-touch-icon" sizes="512x512" href="/_static/src/browser/media/pwa-icon-512.png" />
|
|
|
|
<!-- Disable pinch zooming -->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
|
@@ -23,8 +24,9 @@
|
|
<meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}">
|
|
|
|
<!-- Workbench Icon/Manifest/CSS -->
|
|
- <link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" />
|
|
- <link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" />
|
|
+ <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" />
|
|
+ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" />
|
|
+ <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
|
|
<link rel="stylesheet" href="{{WORKBENCH_WEB_BASE_URL}}/out/vs/code/browser/workbench/workbench.css">
|
|
|
|
</head>
|
|
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
@@ -353,6 +353,7 @@ export class WebClientServer {
|
|
} : undefined;
|
|
|
|
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
|
|
+ codeServerVersion: this._productService.codeServerVersion,
|
|
embedderIdentifier: 'server-distro',
|
|
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
|
|
...this._productService.extensionsGallery,
|
|
Index: code-server/lib/vscode/src/server-main.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/server-main.ts
|
|
+++ code-server/lib/vscode/src/server-main.ts
|
|
@@ -23,6 +23,9 @@ import { IServerAPI } from './vs/server/
|
|
perf.mark('code/server/start');
|
|
(globalThis as { vscodeServerStartTime?: number }).vscodeServerStartTime = performance.now();
|
|
|
|
+// This is not indented to make the diff less noisy. We need to move this out
|
|
+// of the top-level so it will not run immediately and we can control the start.
|
|
+async function start() {
|
|
// Do a quick parse to determine if a server or the cli needs to be started
|
|
const parsedArgs = minimist(process.argv.slice(2), {
|
|
boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'],
|
|
@@ -50,7 +53,7 @@ if (shouldSpawnCli) {
|
|
mod.spawnCli();
|
|
});
|
|
} else {
|
|
- installServerProcessExitDiagnostics();
|
|
+ installServerProcessExitDiagnostics(parsedArgs);
|
|
|
|
let _remoteExtensionHostAgentServer: IServerAPI | null = null;
|
|
let _remoteExtensionHostAgentServerPromise: Promise<IServerAPI> | null = null;
|
|
@@ -153,6 +156,7 @@ if (shouldSpawnCli) {
|
|
}
|
|
});
|
|
}
|
|
+}
|
|
|
|
function sanitizeStringArg(val: unknown): string | undefined {
|
|
if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array
|
|
@@ -173,7 +177,7 @@ function sanitizeStringArg(val: unknown)
|
|
* provided) so they survive process teardown (an async stdio write from an
|
|
* `exit` handler does not).
|
|
*/
|
|
-function installServerProcessExitDiagnostics(): void {
|
|
+function installServerProcessExitDiagnostics(parsedArgs: minimist.ParsedArgs): void {
|
|
if (!process.env['VSCODE_SERVER_EXIT_DIAGNOSTICS']) {
|
|
return;
|
|
}
|
|
@@ -406,3 +410,22 @@ function prompt(question: string): Promi
|
|
});
|
|
});
|
|
}
|
|
+
|
|
+async function loadCodeWithNls() {
|
|
+ const nlsConfiguration = await resolveNLSConfiguration({
|
|
+ userLocale: 'en',
|
|
+ osLocale: 'en',
|
|
+ commit: product.commit,
|
|
+ userDataPath: '',
|
|
+ nlsMetadataPath: import.meta.dirname,
|
|
+ });
|
|
+ return loadCode(nlsConfiguration);
|
|
+}
|
|
+
|
|
+// This alias prevents the name getting mangled during minification which would
|
|
+// make it difficult to import.
|
|
+export { loadCodeWithNls as loadCodeWithNls };
|
|
+
|
|
+if (!process.env.CODE_SERVER_PARENT_PID) {
|
|
+ start();
|
|
+}
|
|
Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
|
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
|
@@ -47,8 +47,11 @@ export function createWorkbenchDialogOpt
|
|
|
|
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
|
|
const detailString = (useAgo: boolean): string => {
|
|
- return localize('aboutDetail',
|
|
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
|
+ return localize('aboutCodeServerDetail',
|
|
+ "code-server: {0}",
|
|
+ productService.codeServerVersion ? `v${productService.codeServerVersion}` : 'Unknown'
|
|
+ ) + '\n' + localize('aboutDetail',
|
|
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
|
productService.version || 'Unknown',
|
|
productService.commit || 'Unknown',
|
|
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',
|