From b38cfa473e4f8f37b6e1a348401899d2ea7946cc Mon Sep 17 00:00:00 2001 From: Sandro Date: Thu, 6 Feb 2020 23:05:40 +0100 Subject: [PATCH 1/4] Dockerfile: Combine two runs --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 03026566..2215d190 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,8 +42,8 @@ RUN adduser --gecos '' --disabled-password coder && \ USER coder # Create first so these directories will be owned by coder instead of root # (workdir and mounting appear to both default to root). -RUN mkdir -p /home/coder/project -RUN mkdir -p /home/coder/.local/share/code-server +RUN mkdir -p /home/coder/project \ + && mkdir -p /home/coder/.local/share/code-server WORKDIR /home/coder/project From 250a54220c5a2ad9849fa13d50ab76a83896d4c0 Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 12 Feb 2020 14:09:52 -0600 Subject: [PATCH 2/4] Update VS Code to 1.42.0 --- scripts/vscode.patch | 216 ++++++++++++------------ src/browser/api.ts | 369 ----------------------------------------- src/browser/client.ts | 7 - src/node/connection.ts | 6 +- src/node/server.ts | 20 ++- 5 files changed, 120 insertions(+), 498 deletions(-) delete mode 100644 src/browser/api.ts diff --git a/scripts/vscode.patch b/scripts/vscode.patch index cafd87c9..f301d4a7 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -1,8 +1,8 @@ diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts -index 231180d513..5b98e191c1 100644 +index a68e020f9f..b4ee8a5886 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts -@@ -88,16 +88,17 @@ class RemoteAuthoritiesImpl { +@@ -88,7 +88,7 @@ class RemoteAuthoritiesImpl { if (host && host.indexOf(':') !== -1) { host = `[${host}]`; } @@ -11,9 +11,8 @@ index 231180d513..5b98e191c1 100644 const connectionToken = this._connectionTokens[authority]; let query = `path=${encodeURIComponent(uri.path)}`; if (typeof connectionToken === 'string') { - query += `&tkn=${encodeURIComponent(connectionToken)}`; +@@ -96,8 +96,8 @@ class RemoteAuthoritiesImpl { } -+ // NOTE@coder: Changed this to work against the current path. return URI.from({ scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, - authority: `${host}:${port}`, @@ -78,7 +77,7 @@ index 2c64061da7..c0ef8faedd 100644 // Do nothing. If we can't read the file we have no // language pack config. diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts -index 033cdc575f..23f775f27d 100644 +index abd1e33b18..bf75952ce1 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -37,6 +37,8 @@ export interface ParsedArgs { @@ -90,7 +89,7 @@ index 033cdc575f..23f775f27d 100644 extensionDevelopmentPath?: string[]; // // undefined or array of 1 or more local paths or URIs extensionTestsPath?: string; // either a local path or a URI 'extension-development-confirm-save'?: boolean; -@@ -144,6 +146,8 @@ export interface IEnvironmentService extends IUserHomeProvider { +@@ -147,6 +149,8 @@ export interface IEnvironmentService extends IUserHomeProvider { disableExtensions: boolean | string[]; builtinExtensionsPath: string; extensionsPath?: string; @@ -100,7 +99,7 @@ index 033cdc575f..23f775f27d 100644 extensionTestsLocationURI?: URI; logExtensionHostCommunication?: boolean; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts -index 6832b93c5c..1e451584eb 100644 +index e68e0647c3..49a5aae2fa 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -55,6 +55,8 @@ export const OPTIONS: OptionDescriptions> = { @@ -112,33 +111,34 @@ index 6832b93c5c..1e451584eb 100644 'list-extensions': { type: 'boolean', cat: 'e', description: localize('listExtensions', "List the installed extensions.") }, 'show-versions': { type: 'boolean', cat: 'e', description: localize('showVersions', "Show versions of installed extensions, when using --list-extension.") }, 'category': { type: 'string', cat: 'e', description: localize('category', "Filters installed extensions by provided category, when using --list-extension.") }, -@@ -308,4 +310,3 @@ export function buildHelpMessage(productName: string, executableName: string, ve +@@ -310,4 +312,3 @@ export function buildHelpMessage(productName: string, executableName: string, ve export function buildVersionMessage(version: string | undefined, commit: string | undefined): string { return `${version || localize('unknownVersion', "Unknown version")}\n${commit || localize('unknownCommit', "Unknown commit")}\n${process.arch}`; } - diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts -index 99cab4bba2..531b1d7177 100644 +index 0428e1e888..9b3cddcb3a 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts -@@ -266,6 +266,12 @@ export class EnvironmentService implements IEnvironmentService { +@@ -197,6 +197,13 @@ export class EnvironmentService implements IEnvironmentService { + return path.join(this.userHome, product.dataFolderName, 'extensions'); + } - get driverHandle(): string | undefined { return this._args['driver']; } - get driverVerbose(): boolean { return !!this._args['driver-verbose']; } + @memoize get extraExtensionPaths(): string[] { + return (this._args['extra-extensions-dir'] || []).map((p) => parsePathArg(p, process)); + } + @memoize get extraBuiltinExtensionPaths(): string[] { + return (this._args['extra-builtin-extensions-dir'] || []).map((p) => parsePathArg(p, process)); + } - - constructor(private _args: ParsedArgs, private _execPath: string) { - if (!process.env['VSCODE_LOGS']) { ++ + @memoize + get extensionDevelopmentLocationURI(): URI[] | undefined { + const s = this._args.extensionDevelopmentPath; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts -index 5bfc2bb66c..49a6ce8540 100644 +index 5b05650591..dc5140410e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts -@@ -741,11 +741,15 @@ export class ExtensionManagementService extends Disposable implements IExtension +@@ -743,11 +743,15 @@ export class ExtensionManagementService extends Disposable implements IExtension private scanSystemExtensions(): Promise { this.logService.trace('Started scanning system extensions'); @@ -159,7 +159,7 @@ index 5bfc2bb66c..49a6ce8540 100644 if (this.environmentService.isBuilt) { return systemExtensionsPromise; } -@@ -767,9 +771,16 @@ export class ExtensionManagementService extends Disposable implements IExtension +@@ -769,9 +773,17 @@ export class ExtensionManagementService extends Disposable implements IExtension .then(([systemExtensions, devSystemExtensions]) => [...systemExtensions, ...devSystemExtensions]); } @@ -169,6 +169,7 @@ index 5bfc2bb66c..49a6ce8540 100644 + ...this.environmentService.extraExtensionPaths.map((p) => this.scanExtensions(p, ExtensionType.User)) + ]).then((results) => results.reduce((flat, current) => flat.concat(current), [])); + } ++ + private scanUserExtensions(excludeOutdated: boolean): Promise { this.logService.trace('Started scanning user extensions'); @@ -177,7 +178,7 @@ index 5bfc2bb66c..49a6ce8540 100644 .then(([uninstalled, extensions]) => { extensions = extensions.filter(e => !uninstalled[new ExtensionIdentifierWithVersion(e.identifier, e.manifest.version).key()]); if (excludeOutdated) { -@@ -784,6 +795,12 @@ export class ExtensionManagementService extends Disposable implements IExtension +@@ -786,6 +798,12 @@ export class ExtensionManagementService extends Disposable implements IExtension private scanExtensions(root: string, type: ExtensionType): Promise { const limiter = new Limiter(10); return pfs.readdir(root) @@ -185,12 +186,12 @@ index 5bfc2bb66c..49a6ce8540 100644 + if (error.code !== 'ENOENT') { + throw error; + } -+ return []; ++ return []; + }) .then(extensionsFolders => Promise.all(extensionsFolders.map(extensionFolder => limiter.queue(() => this.scanExtension(extensionFolder, root, type))))) .then(extensions => extensions.filter(e => e && e.identifier)); } -@@ -822,7 +839,7 @@ export class ExtensionManagementService extends Disposable implements IExtension +@@ -824,7 +842,7 @@ export class ExtensionManagementService extends Disposable implements IExtension private async removeUninstalledExtensions(): Promise { const uninstalled = await this.getUninstalledExtensions(); @@ -199,7 +200,7 @@ index 5bfc2bb66c..49a6ce8540 100644 const installed: Set = new Set(); for (const e of extensions) { if (!uninstalled[new ExtensionIdentifierWithVersion(e.identifier, e.manifest.version).key()]) { -@@ -841,7 +858,7 @@ export class ExtensionManagementService extends Disposable implements IExtension +@@ -843,7 +861,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } private removeOutdatedExtensions(): Promise { @@ -252,7 +253,7 @@ index 804d113856..4b651e5c77 100644 } diff --git a/src/vs/platform/product/common/productService.ts b/src/vs/platform/product/common/productService.ts -index 6db9725704..779b3cbdea 100644 +index 120fd66644..52547bdb0e 100644 --- a/src/vs/platform/product/common/productService.ts +++ b/src/vs/platform/product/common/productService.ts @@ -16,6 +16,7 @@ export interface IProductService extends Readonly { @@ -338,7 +339,7 @@ index ad44dcbc33..7a7b5261ff 100644 } diff --git a/src/vs/platform/update/electron-main/abstractUpdateService.ts b/src/vs/platform/update/electron-main/abstractUpdateService.ts -index 8a1c95d37b..8225a85d47 100644 +index d8bf464fed..748715da3b 100644 --- a/src/vs/platform/update/electron-main/abstractUpdateService.ts +++ b/src/vs/platform/update/electron-main/abstractUpdateService.ts @@ -6,7 +6,6 @@ @@ -358,7 +359,7 @@ index 8a1c95d37b..8225a85d47 100644 @IConfigurationService protected configurationService: IConfigurationService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IRequestService protected requestService: IRequestService, -@@ -152,15 +151,8 @@ export abstract class AbstractUpdateService implements IUpdateService { +@@ -156,15 +155,8 @@ export abstract class AbstractUpdateService implements IUpdateService { this.logService.trace('update#quitAndInstall(): before lifecycle quit()'); @@ -375,64 +376,56 @@ index 8a1c95d37b..8225a85d47 100644 return Promise.resolve(undefined); } diff --git a/src/vs/workbench/api/browser/extensionHost.contribution.ts b/src/vs/workbench/api/browser/extensionHost.contribution.ts -index 2905c52411..303ddf211f 100644 +index e69aa80159..2960d00456 100644 --- a/src/vs/workbench/api/browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/browser/extensionHost.contribution.ts -@@ -57,6 +57,7 @@ import './mainThreadComments'; - import './mainThreadTask'; - import './mainThreadLabelService'; +@@ -62,6 +62,7 @@ import './mainThreadTunnelService'; + import './mainThreadAuthentication'; + import './mainThreadTimeline'; import 'vs/workbench/api/common/apiCommands'; +import 'vs/server/src/browser/mainThreadNodeProxy'; export class ExtensionPoints implements IWorkbenchContribution { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts -index ea5ad7991f..8d8e99339e 100644 +index 91045fcda6..d93d3286d8 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts -@@ -67,6 +67,7 @@ import { ILogService } from 'vs/platform/log/common/log'; - import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; - import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; - import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +@@ -72,6 +72,7 @@ import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelServ + import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService'; + import { ExtHostAuthentication } from 'vs/workbench/api/common/extHostAuthentication'; + import { ExtHostTimeline } from 'vs/workbench/api/common/extHostTimeline'; +import { IExtHostNodeProxy } from 'vs/server/src/browser/extHostNodeProxy'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; -@@ -86,6 +87,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I - const rpcProtocol = accessor.get(IExtHostRpcService); - const extHostStorage = accessor.get(IExtHostStorage); +@@ -93,6 +94,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostLogService = accessor.get(ILogService); + const extHostTunnelService = accessor.get(IExtHostTunnelService); + const extHostApiDeprecation = accessor.get(IExtHostApiDeprecationService); + const extHostNodeProxy = accessor.get(IExtHostNodeProxy); // register addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); -@@ -93,6 +95,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I - rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); +@@ -101,6 +103,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); + rpcProtocol.set(ExtHostContext.ExtHostTunnelService, extHostTunnelService); + rpcProtocol.set(ExtHostContext.ExtHostNodeProxy, extHostNodeProxy); // automatically create and register addressable instances const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations)); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts -index 3dab81c9c5..73fc57118a 100644 +index 55130ff918..032534b23e 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts -@@ -655,6 +655,10 @@ export interface MainThreadLabelServiceShape extends IDisposable { +@@ -667,6 +667,16 @@ export interface MainThreadLabelServiceShape extends IDisposable { $unregisterResourceLabelFormatter(handle: number): void; } +export interface MainThreadNodeProxyShape extends IDisposable { + $send(message: string): void; +} -+ - export interface MainThreadSearchShape extends IDisposable { - $registerFileSearchProvider(handle: number, scheme: string): void; - $registerTextSearchProvider(handle: number, scheme: string): void; -@@ -888,6 +892,13 @@ export interface ExtHostLabelServiceShape { - $registerResourceLabelFormatter(formatter: ResourceLabelFormatter): IDisposable; - } - +export interface ExtHostNodeProxyShape { + $onMessage(message: string): void; + $onClose(): void; @@ -440,29 +433,29 @@ index 3dab81c9c5..73fc57118a 100644 + $onUp(): void; +} + - export interface ExtHostSearchShape { - $provideFileSearchResults(handle: number, session: number, query: search.IRawQuery, token: CancellationToken): Promise; - $provideTextSearchResults(handle: number, session: number, query: search.IRawTextQuery, token: CancellationToken): Promise; -@@ -1431,7 +1442,8 @@ export const MainContext = { - MainThreadSearch: createMainId('MainThreadSearch'), - MainThreadTask: createMainId('MainThreadTask'), - MainThreadWindow: createMainId('MainThreadWindow'), -- MainThreadLabelService: createMainId('MainThreadLabelService') -+ MainThreadLabelService: createMainId('MainThreadLabelService'), -+ MainThreadNodeProxy: createMainId('MainThreadNodeProxy') + export interface MainThreadSearchShape extends IDisposable { + $registerFileSearchProvider(handle: number, scheme: string): void; + $registerTextSearchProvider(handle: number, scheme: string): void; +@@ -1498,7 +1508,8 @@ export const MainContext = { + MainThreadLabelService: createMainId('MainThreadLabelService'), + MainThreadTheming: createMainId('MainThreadTheming'), + MainThreadTunnelService: createMainId('MainThreadTunnelService'), +- MainThreadTimeline: createMainId('MainThreadTimeline') ++ MainThreadTimeline: createMainId('MainThreadTimeline'), ++ MainThreadNodeProxy: createMainId('MainThreadNodeProxy'), }; export const ExtHostContext = { -@@ -1465,5 +1477,6 @@ export const ExtHostContext = { - ExtHostStorage: createMainId('ExtHostStorage'), - ExtHostUrls: createExtId('ExtHostUrls'), - ExtHostOutputService: createMainId('ExtHostOutputService'), -- ExtHosLabelService: createMainId('ExtHostLabelService') -+ ExtHosLabelService: createMainId('ExtHostLabelService'), +@@ -1536,5 +1547,6 @@ export const ExtHostContext = { + ExtHostTheming: createMainId('ExtHostTheming'), + ExtHostTunnelService: createMainId('ExtHostTunnelService'), + ExtHostAuthentication: createMainId('ExtHostAuthentication'), +- ExtHostTimeline: createMainId('ExtHostTimeline') ++ ExtHostTimeline: createMainId('ExtHostTimeline'), + ExtHostNodeProxy: createMainId('ExtHostNodeProxy') }; diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts -index a3b5ed0057..f47a97336d 100644 +index 978bf32fcd..a63954cce0 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -5,7 +5,7 @@ @@ -474,41 +467,41 @@ index a3b5ed0057..f47a97336d 100644 import { Barrier } from 'vs/base/common/async'; import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TernarySearchTree } from 'vs/base/common/map'; -@@ -32,6 +32,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData - import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +@@ -33,6 +33,7 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; + import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService'; +import { IExtHostNodeProxy } from 'vs/server/src/browser/extHostNodeProxy'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ -@@ -76,6 +77,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio - protected readonly _extHostWorkspace: ExtHostWorkspace; +@@ -78,6 +79,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio protected readonly _extHostConfiguration: ExtHostConfiguration; protected readonly _logService: ILogService; + protected readonly _extHostTunnelService: IExtHostTunnelService; + protected readonly _nodeProxy: IExtHostNodeProxy; protected readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; protected readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; -@@ -104,7 +106,8 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio - @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, +@@ -107,7 +109,8 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio @ILogService logService: ILogService, @IExtHostInitDataService initData: IExtHostInitDataService, -- @IExtensionStoragePaths storagePath: IExtensionStoragePaths -+ @IExtensionStoragePaths storagePath: IExtensionStoragePaths, + @IExtensionStoragePaths storagePath: IExtensionStoragePaths, +- @IExtHostTunnelService extHostTunnelService: IExtHostTunnelService ++ @IExtHostTunnelService extHostTunnelService: IExtHostTunnelService, + @IExtHostNodeProxy nodeProxy: IExtHostNodeProxy, ) { this._hostUtils = hostUtils; this._extHostContext = extHostContext; -@@ -113,6 +116,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio +@@ -116,6 +119,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; this._logService = logService; + this._nodeProxy = nodeProxy; + this._extHostTunnelService = extHostTunnelService; this._disposables = new DisposableStore(); - this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); -@@ -337,14 +341,14 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio +@@ -341,14 +345,14 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); return Promise.all([ @@ -526,22 +519,22 @@ index a3b5ed0057..f47a97336d 100644 private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts -index 9ae085f536..4e3ccca3d3 100644 +index 72ad75d63e..8c4edee5e3 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts -@@ -26,6 +26,8 @@ import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionS - import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; - import { ILogService } from 'vs/platform/log/common/log'; - import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; +@@ -29,6 +29,8 @@ import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; + import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService'; + import { ExtHostTunnelService } from 'vs/workbench/api/node/extHostTunnelService'; + import { IExtHostApiDeprecationService, ExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostNodeProxy } from 'vs/server/src/browser/extHostNodeProxy'; // register singleton services registerSingleton(ILogService, ExtHostLogService); -@@ -42,3 +44,19 @@ registerSingleton(IExtHostSearch, NativeExtHostSearch); - registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); +@@ -47,3 +49,19 @@ registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); registerSingleton(IExtHostStorage, ExtHostStorage); + registerSingleton(IExtHostTunnelService, ExtHostTunnelService); + +function NotImplementedProxy(name: ServiceIdentifier): { new(): T } { + return class { @@ -687,10 +680,10 @@ index 4781f22676..25143a97c0 100644 throw new Error(`Cannot load module '${request}'`); } diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts -index 807ac56d8f..a22bd92a82 100644 +index 94e7052574..4219adda2c 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts -@@ -50,6 +50,7 @@ import { IndexedDBLogProvider } from 'vs/workbench/services/log/browser/indexedD +@@ -49,6 +49,7 @@ import { IndexedDBLogProvider } from 'vs/workbench/services/log/browser/indexedD import { InMemoryLogProvider } from 'vs/workbench/services/log/common/inMemoryLogProvider'; import { isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows'; import { getWorkspaceIdentifier } from 'vs/workbench/services/workspaces/browser/workspaces'; @@ -698,7 +691,7 @@ index 807ac56d8f..a22bd92a82 100644 class BrowserMain extends Disposable { -@@ -86,6 +87,7 @@ class BrowserMain extends Disposable { +@@ -85,6 +86,7 @@ class BrowserMain extends Disposable { // Startup workbench.startup(); @@ -706,9 +699,9 @@ index 807ac56d8f..a22bd92a82 100644 } private registerListeners(workbench: Workbench, storageService: BrowserStorageService): void { -@@ -247,6 +249,7 @@ class BrowserMain extends Disposable { - const channel = connection.getChannel(REMOTE_FILE_SYSTEM_CHANNEL_NAME); - const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(channel, remoteAgentService.getEnvironment())); +@@ -245,6 +247,7 @@ class BrowserMain extends Disposable { + // Remote file system + const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(remoteAgentService)); fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); + fileService.registerProvider(Schemas.file, remoteFileSystemProvider); @@ -737,7 +730,7 @@ index c509716fc4..e416413084 100644 this._langIdKey.set(value ? this._modeService.getModeIdByFilepathOrFirstLine(value) : null); this._extensionKey.set(value ? extname(value) : null); diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js -index 138707c9a9..9134d5f503 100644 +index 63c9af47e2..021358fef9 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -329,7 +329,8 @@ @@ -770,10 +763,10 @@ index f67f9aa064..add754cd5a 100644 const { choice } = await this.show(Severity.Info, this.productService.nameLong, [nls.localize('copy', "Copy"), nls.localize('ok', "OK")], { detail, cancelId: 1 }); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts -index d54e68fa70..b2c4ea5f6a 100644 +index 1bf4cfad2a..924a2fcd87 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -189,8 +189,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment +@@ -195,8 +195,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment @memoize get webviewExternalEndpoint(): string { @@ -784,17 +777,17 @@ index d54e68fa70..b2c4ea5f6a 100644 } @memoize -@@ -267,6 +267,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment - //#region TODO ENABLE IN WEB +@@ -249,6 +249,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment + installSourcePath!: string; - galleryMachineIdResource?: URI; + builtinExtensionsPath!: string; + extraExtensionPaths!: string[]; + extraBuiltinExtensionPaths!: string[]; - //#endregion - + globalStorageHome!: string; + workspaceStorageHome!: string; diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts -index d164f2c127..5a08106f04 100644 +index fe891a042e..21d0d4bf61 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -119,6 +119,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @@ -806,7 +799,7 @@ index d164f2c127..5a08106f04 100644 this._checkEnableProposedApi(remoteEnv.extensions); diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts -index 75f715cc51..1d6299309d 100644 +index 9e8352ac88..2d1cb0a107 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -32,7 +32,8 @@ export function canExecuteOnWorkspace(manifest: IExtensionManifest, productServi @@ -854,25 +847,27 @@ index 0f35c54431..32fff09b18 100644 } } diff --git a/src/vs/workbench/services/extensions/worker/extHost.services.ts b/src/vs/workbench/services/extensions/worker/extHost.services.ts -index 8a65101aa4..e9c66b3b20 100644 +index bbb72e9511..63f1f6ff46 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.services.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.services.ts -@@ -18,9 +18,10 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa +@@ -18,11 +18,12 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostExtensionService } from 'vs/workbench/api/worker/extHostExtensionService'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { ExtHostLogService } from 'vs/workbench/api/worker/extHostLogService'; + import { IExtHostTunnelService, ExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService'; + import { IExtHostApiDeprecationService, ExtHostApiDeprecationService, } from 'vs/workbench/api/common/extHostApiDeprecationService'; +import { ExtHostNodeProxy, IExtHostNodeProxy } from 'vs/server/src/browser/extHostNodeProxy'; +import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; // register singleton services registerSingleton(ILogService, ExtHostLogService); -@@ -33,25 +34,9 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); - registerSingleton(IExtHostStorage, ExtHostStorage); +@@ -37,23 +38,9 @@ registerSingleton(IExtHostStorage, ExtHostStorage); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); registerSingleton(IExtHostSearch, ExtHostSearch); + registerSingleton(IExtHostTunnelService, ExtHostTunnelService); +registerSingleton(IExtHostNodeProxy, ExtHostNodeProxy); -// register services that only throw errors @@ -893,9 +888,7 @@ index 8a65101aa4..e9c66b3b20 100644 registerSingleton(IExtHostTerminalService, WorkerExtHostTerminalService); registerSingleton(IExtHostTask, WorkerExtHostTask); registerSingleton(IExtHostDebugService, WorkerExtHostDebugService); --registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) { -- whenReady = Promise.resolve(); --}); +-registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) { whenReady = Promise.resolve(); }); +registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); diff --git a/src/vs/workbench/services/localizations/electron-browser/localizationsService.ts b/src/vs/workbench/services/localizations/electron-browser/localizationsService.ts index 99394090da..4891e0fece 100644 @@ -923,18 +916,19 @@ index 99394090da..4891e0fece 100644 } diff --git a/src/vs/workbench/services/update/electron-browser/updateService.ts b/src/vs/workbench/services/update/electron-browser/updateService.ts -index b8f6558b2c..b1fe6b14fd 100644 +index b8f6558b2c..7aeafe6e0e 100644 --- a/src/vs/workbench/services/update/electron-browser/updateService.ts +++ b/src/vs/workbench/services/update/electron-browser/updateService.ts -@@ -6,7 +6,7 @@ +@@ -6,8 +6,8 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event, Emitter } from 'vs/base/common/event'; import { IUpdateService, State } from 'vs/platform/update/common/update'; -import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; -+import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; ++import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export class NativeUpdateService implements IUpdateService { + @@ -21,8 +21,9 @@ export class NativeUpdateService implements IUpdateService { private channel: IChannel; @@ -948,7 +942,7 @@ index b8f6558b2c..b1fe6b14fd 100644 // always set this._state as the state changes this.onStateChange(state => this._state = state); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts -index f424c87d92..af681c3c12 100644 +index 0719b361e0..3a4c5cefe8 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -34,11 +34,14 @@ import 'vs/workbench/services/textfile/browser/browserTextFileService'; diff --git a/src/browser/api.ts b/src/browser/api.ts deleted file mode 100644 index cbc077ce..00000000 --- a/src/browser/api.ts +++ /dev/null @@ -1,369 +0,0 @@ -import * as vscode from "vscode"; -import { CoderApi, VSCodeApi } from "../../typings/api"; -import { createCSSRule } from "vs/base/browser/dom"; -import { Emitter, Event } from "vs/base/common/event"; -import { IDisposable } from "vs/base/common/lifecycle"; -import { URI } from "vs/base/common/uri"; -import { generateUuid } from "vs/base/common/uuid"; -import { localize } from "vs/nls"; -import { SyncActionDescriptor } from "vs/platform/actions/common/actions"; -import { CommandsRegistry, ICommandService } from "vs/platform/commands/common/commands"; -import { IConfigurationService } from "vs/platform/configuration/common/configuration"; -import { IContextMenuService } from "vs/platform/contextview/browser/contextView"; -import { FileDeleteOptions, FileOpenOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, FileWriteOptions, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions } from "vs/platform/files/common/files"; -import { IInstantiationService, ServiceIdentifier } from "vs/platform/instantiation/common/instantiation"; -import { ServiceCollection } from "vs/platform/instantiation/common/serviceCollection"; -import { INotificationService } from "vs/platform/notification/common/notification"; -import { Registry } from "vs/platform/registry/common/platform"; -import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from "vs/workbench/services/statusbar/common/statusbar"; -import { IStorageService } from "vs/platform/storage/common/storage"; -import { ITelemetryService } from "vs/platform/telemetry/common/telemetry"; -import { IThemeService } from "vs/platform/theme/common/themeService"; -import { IWorkspaceContextService } from "vs/platform/workspace/common/workspace"; -import * as extHostTypes from "vs/workbench/api/common/extHostTypes"; -import { CustomTreeView, CustomTreeViewPane } from "vs/workbench/browser/parts/views/customView"; -import { ViewContainerViewlet } from "vs/workbench/browser/parts/views/viewsViewlet"; -import { Extensions as ViewletExtensions, ShowViewletAction, ViewletDescriptor, ViewletRegistry } from "vs/workbench/browser/viewlet"; -import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from "vs/workbench/common/actions"; -import { Extensions as ViewsExtensions, ITreeItem, ITreeViewDataProvider, ITreeViewDescriptor, IViewContainersRegistry, IViewsRegistry, TreeItemCollapsibleState } from "vs/workbench/common/views"; -import { IEditorGroupsService } from "vs/workbench/services/editor/common/editorGroupsService"; -import { IEditorService } from "vs/workbench/services/editor/common/editorService"; -import { IExtensionService } from "vs/workbench/services/extensions/common/extensions"; -import { IWorkbenchLayoutService } from "vs/workbench/services/layout/browser/layoutService"; -import { IViewletService } from "vs/workbench/services/viewlet/browser/viewlet"; - -/** - * Client-side implementation of VS Code's API. - * TODO: Views aren't quite working. - * TODO: Implement menu items for views (for item actions). - * TODO: File system provider doesn't work. - */ -export const vscodeApi = (serviceCollection: ServiceCollection): VSCodeApi => { - const getService = (id: ServiceIdentifier): T => serviceCollection.get(id) as T; - const commandService = getService(ICommandService); - const notificationService = getService(INotificationService); - const fileService = getService(IFileService); - const viewsRegistry = Registry.as(ViewsExtensions.ViewsRegistry); - const statusbarService = getService(IStatusbarService); - - // It would be nice to just export what VS Code creates but it looks to me - // that it assumes it's running in the extension host and wouldn't work here. - // It is probably possible to create an extension host that runs in the - // browser's main thread, but I'm not sure how much jank that would require. - // We could have a web worker host but we want DOM access. - return { - EventEmitter: Emitter, // It can take T so T | undefined should work. - FileSystemError: extHostTypes.FileSystemError, - FileType, - StatusBarAlignment: extHostTypes.StatusBarAlignment, - ThemeColor: extHostTypes.ThemeColor, - TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState, - Uri: URI, - commands: { - executeCommand: (commandId: string, ...args: any[]): Promise => { - return commandService.executeCommand(commandId, ...args); - }, - registerCommand: (id: string, command: (...args: any[]) => any): IDisposable => { - return CommandsRegistry.registerCommand(id, command); - }, - }, - window: { - createStatusBarItem(alignmentOrOptions?: extHostTypes.StatusBarAlignment | vscode.window.StatusBarItemOptions, priority?: number): StatusBarEntry { - return new StatusBarEntry(statusbarService, alignmentOrOptions, priority); - }, - registerTreeDataProvider: (id: string, dataProvider: vscode.TreeDataProvider): IDisposable => { - const tree = new TreeViewDataProvider(dataProvider); - const view = viewsRegistry.getView(id); - (view as ITreeViewDescriptor).treeView.dataProvider = tree; - return { - dispose: () => tree.dispose(), - }; - }, - showErrorMessage: async (message: string): Promise => { - notificationService.error(message); - return undefined; - }, - }, - workspace: { - registerFileSystemProvider: (scheme: string, provider: vscode.FileSystemProvider): IDisposable => { - return fileService.registerProvider(scheme, new FileSystemProvider(provider)); - }, - }, - }; -}; - -/** - * Coder API. This should only provide functionality that can't be made - * available through the VS Code API. - */ -export const coderApi = (serviceCollection: ServiceCollection): CoderApi => { - const getService = (id: ServiceIdentifier): T => serviceCollection.get(id) as T; - return { - registerView: (viewId, viewName, containerId, containerName, icon): void => { - const cssClass = `extensionViewlet-${containerId}`; - const id = `workbench.view.extension.${containerId}`; - class CustomViewlet extends ViewContainerViewlet { - public constructor( - @IConfigurationService configurationService: IConfigurationService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IStorageService storageService: IStorageService, - @IEditorService _editorService: IEditorService, - @IInstantiationService instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService, - ) { - super(id, `${id}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); - } - } - - Registry.as(ViewletExtensions.Viewlets).registerViewlet( - ViewletDescriptor.create(CustomViewlet as any, id, containerName, cssClass, undefined, URI.parse(icon)), - ); - - Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( - SyncActionDescriptor.create(OpenCustomViewletAction as any, id, localize("showViewlet", "Show {0}", containerName)), - "View: Show {0}", - localize("view", "View"), - ); - - // Generate CSS to show the icon in the activity bar. - const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`; - createCSSRule(iconClass, `-webkit-mask: url('${icon}') no-repeat 50% 50%`); - - const container = Registry.as(ViewsExtensions.ViewContainersRegistry).registerViewContainer(containerId); - Registry.as(ViewsExtensions.ViewsRegistry).registerViews([{ - id: viewId, - name: viewName, - ctorDescriptor: { ctor: CustomTreeViewPane }, - treeView: getService(IInstantiationService).createInstance(CustomTreeView as any, viewId, container), - }] as ITreeViewDescriptor[], container); - }, - }; -}; - -class OpenCustomViewletAction extends ShowViewletAction { - public constructor( - id: string, label: string, - @IViewletService viewletService: IViewletService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - ) { - super(id, label, id, viewletService, editorGroupService, layoutService); - } -} - -class FileSystemProvider implements IFileSystemProvider { - private readonly _onDidChange = new Emitter(); - - public readonly onDidChangeFile: Event = this._onDidChange.event; - - public readonly capabilities: FileSystemProviderCapabilities; - public readonly onDidChangeCapabilities: Event = Event.None; - - public constructor(private readonly provider: vscode.FileSystemProvider) { - this.capabilities = FileSystemProviderCapabilities.Readonly; - } - - public watch(resource: URI, opts: IWatchOptions): IDisposable { - return this.provider.watch(resource, opts); - } - - public async stat(resource: URI): Promise { - return this.provider.stat(resource); - } - - public async readFile(resource: URI): Promise { - return this.provider.readFile(resource); - } - - public async writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise { - return this.provider.writeFile(resource, content, opts); - } - - public async delete(resource: URI, opts: FileDeleteOptions): Promise { - return this.provider.delete(resource, opts); - } - - public mkdir(_resource: URI): Promise { - throw new Error("not implemented"); - } - - public async readdir(resource: URI): Promise<[string, FileType][]> { - return this.provider.readDirectory(resource); - } - - public async rename(resource: URI, target: URI, opts: FileOverwriteOptions): Promise { - return this.provider.rename(resource, target, opts); - } - - public async copy(resource: URI, target: URI, opts: FileOverwriteOptions): Promise { - return this.provider.copy!(resource, target, opts); - } - - public open(_resource: URI, _opts: FileOpenOptions): Promise { - throw new Error("not implemented"); - } - - public close(_fd: number): Promise { - throw new Error("not implemented"); - } - - public read(_fd: number, _pos: number, _data: Uint8Array, _offset: number, _length: number): Promise { - throw new Error("not implemented"); - } - - public write(_fd: number, _pos: number, _data: Uint8Array, _offset: number, _length: number): Promise { - throw new Error("not implemented"); - } -} - -class TreeViewDataProvider implements ITreeViewDataProvider { - private readonly root = Symbol("root"); - private readonly values = new Map(); - private readonly children = new Map(); - - public constructor(private readonly provider: vscode.TreeDataProvider) {} - - public async getChildren(item?: ITreeItem): Promise { - const value = item && this.itemToValue(item); - const children = await Promise.all( - (await this.provider.getChildren(value) || []) - .map(async (childValue) => { - const treeItem = await this.provider.getTreeItem(childValue); - const handle = this.createHandle(treeItem); - this.values.set(handle, childValue); - return { - handle, - collapsibleState: TreeItemCollapsibleState.Collapsed, - }; - }) - ); - - this.clear(value || this.root, item); - this.children.set(value || this.root, children); - - return children; - } - - public dispose(): void { - throw new Error("not implemented"); - } - - private itemToValue(item: ITreeItem): T { - if (!this.values.has(item.handle)) { - throw new Error(`No element found with handle ${item.handle}`); - } - return this.values.get(item.handle)!; - } - - private clear(value: T | Symbol, item?: ITreeItem): void { - if (this.children.has(value)) { - this.children.get(value)!.map((c) => this.clear(this.itemToValue(c), c)); - this.children.delete(value); - } - if (item) { - this.values.delete(item.handle); - } - } - - private createHandle(item: vscode.TreeItem): string { - return item.id - ? `coder-tree-item-id/${item.id}` - : `coder-tree-item-uuid/${generateUuid()}`; - } -} - -interface IStatusBarEntry extends IStatusbarEntry { - alignment: StatusbarAlignment; - priority?: number; -} - -class StatusBarEntry implements vscode.StatusBarItem { - private static ID = 0; - - private _id: number; - private entry: IStatusBarEntry; - private visible?: boolean; - private disposed?: boolean; - private statusId: string; - private statusName: string; - private accessor?: IStatusbarEntryAccessor; - private timeout: any; - - constructor(private readonly statusbarService: IStatusbarService, alignmentOrOptions?: extHostTypes.StatusBarAlignment | vscode.window.StatusBarItemOptions, priority?: number) { - this._id = StatusBarEntry.ID--; - if (alignmentOrOptions && typeof alignmentOrOptions !== "number") { - this.statusId = alignmentOrOptions.id; - this.statusName = alignmentOrOptions.name; - this.entry = { - alignment: alignmentOrOptions.alignment === extHostTypes.StatusBarAlignment.Right - ? StatusbarAlignment.RIGHT : StatusbarAlignment.LEFT, - priority, - text: "", - }; - } else { - this.statusId = "web-api"; - this.statusName = "Web API"; - this.entry = { - alignment: alignmentOrOptions === extHostTypes.StatusBarAlignment.Right - ? StatusbarAlignment.RIGHT : StatusbarAlignment.LEFT, - priority, - text: "", - }; - } - } - - public get alignment(): extHostTypes.StatusBarAlignment { - return this.entry.alignment === StatusbarAlignment.RIGHT - ? extHostTypes.StatusBarAlignment.Right : extHostTypes.StatusBarAlignment.Left; - } - - public get id(): number { return this._id; } - public get priority(): number | undefined { return this.entry.priority; } - public get text(): string { return this.entry.text; } - public get tooltip(): string | undefined { return this.entry.tooltip; } - public get color(): string | extHostTypes.ThemeColor | undefined { return this.entry.color; } - public get command(): string | undefined { return this.entry.command; } - - public set text(text: string) { this.update({ text }); } - public set tooltip(tooltip: string | undefined) { this.update({ tooltip }); } - public set color(color: string | extHostTypes.ThemeColor | undefined) { this.update({ color }); } - public set command(command: string | undefined) { this.update({ command }); } - - public show(): void { - this.visible = true; - this.update(); - } - - public hide(): void { - clearTimeout(this.timeout); - this.visible = false; - if (this.accessor) { - this.accessor.dispose(); - this.accessor = undefined; - } - } - - private update(values?: Partial): void { - this.entry = { ...this.entry, ...values }; - if (this.disposed || !this.visible) { - return; - } - clearTimeout(this.timeout); - this.timeout = setTimeout(() => { - if (!this.accessor) { - this.accessor = this.statusbarService.addEntry(this.entry, this.statusId, this.statusName, this.entry.alignment, this.priority); - } else { - this.accessor.update(this.entry); - } - }, 0); - } - - public dispose(): void { - this.hide(); - this.disposed = true; - } -} diff --git a/src/browser/client.ts b/src/browser/client.ts index 80765466..544bd6f7 100644 --- a/src/browser/client.ts +++ b/src/browser/client.ts @@ -9,7 +9,6 @@ import { INotificationService, Severity } from "vs/platform/notification/common/ import { Registry } from "vs/platform/registry/common/platform"; import { PersistentConnectionEventType } from "vs/platform/remote/common/remoteAgentConnection"; import { ITelemetryService } from "vs/platform/telemetry/common/telemetry"; -import { coderApi, vscodeApi } from "vs/server/src/browser/api"; import { INodeProxyService, NodeProxyChannelClient } from "vs/server/src/common/nodeProxy"; import { TelemetryChannelClient } from "vs/server/src/common/telemetry"; import { split } from "vs/server/src/common/util"; @@ -76,13 +75,7 @@ registerSingleton(ITelemetryService, TelemetryService); * been initialized so we can initialize our own client-side code. */ export const initialize = async (services: ServiceCollection): Promise => { - const target = window as any; - target.ide = coderApi(services); - target.vscode = vscodeApi(services); - const event = new CustomEvent("ide-ready"); - (event as any).ide = target.ide; - (event as any).vscode = target.vscode; window.dispatchEvent(event); if (!window.isSecureContext) { diff --git a/src/node/connection.ts b/src/node/connection.ts index 98bebd33..793b02c3 100644 --- a/src/node/connection.ts +++ b/src/node/connection.ts @@ -132,8 +132,10 @@ export class ExtensionHostConnection extends Connection { proc.on("error", () => this.dispose()); proc.on("exit", () => this.dispose()); - proc.stdout.setEncoding("utf8").on("data", (d) => this.log.info("Extension host stdout", d)); - proc.stderr.setEncoding("utf8").on("data", (d) => this.log.error("Extension host stderr", d)); + if (proc.stdout && proc.stderr) { + proc.stdout.setEncoding("utf8").on("data", (d) => this.log.info("Extension host stdout", d)); + proc.stderr.setEncoding("utf8").on("data", (d) => this.log.error("Extension host stderr", d)); + } proc.on("message", (event) => { if (event && event.type === "__$console") { const severity = (this.log)[event.severity] ? event.severity : "info"; diff --git a/src/node/server.ts b/src/node/server.ts index bce26612..e3b10fb9 100644 --- a/src/node/server.ts +++ b/src/node/server.ts @@ -44,7 +44,7 @@ import product from 'vs/platform/product/common/product'; import { IProductService } from "vs/platform/product/common/productService"; import { ConnectionType, ConnectionTypeRequest } from "vs/platform/remote/common/remoteAgentConnection"; import { RemoteAgentConnectionContext } from "vs/platform/remote/common/remoteAgentEnvironment"; -import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from "vs/platform/remote/common/remoteAgentFileSystemChannel"; +import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from "vs/workbench/services/remote/common/remoteAgentFileSystemChannel"; import { IRequestService } from "vs/platform/request/common/request"; import { RequestChannel } from "vs/platform/request/common/requestIpc"; import { RequestService } from "vs/platform/request/node/requestService"; @@ -177,7 +177,7 @@ export abstract class Server { */ public address(): string { const address = this.server.address(); - const endpoint = typeof address !== "string" + const endpoint = address && typeof address !== "string" ? (address.address === "::" ? "localhost" : address.address) + ":" + address.port : address; return `${this.protocol}://${endpoint}`; @@ -234,7 +234,7 @@ export abstract class Server { private onRequest = async (request: http.IncomingMessage, response: http.ServerResponse): Promise => { try { - const parsedUrl = request.url ? url.parse(request.url, true) : { query: {}}; + const parsedUrl = url.parse(request.url || "", true); const payload = await this.preHandleRequest(request, parsedUrl); response.writeHead(payload.redirect ? HttpCode.Redirect : payload.code || HttpCode.Ok, { "Content-Type": payload.mime || getMediaMime(payload.filePath), @@ -259,7 +259,7 @@ export abstract class Server { response.writeHead(typeof error.code === "number" ? error.code : HttpCode.ServerError); response.end(error.message); } - } + }; private async preHandleRequest(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise { const secure = (request.connection as tls.TLSSocket).encrypted; @@ -335,7 +335,7 @@ export abstract class Server { socket.destroy(); console.error(error.message); } - } + }; private preHandleWebSocket(request: http.IncomingMessage, socket: net.Socket): Promise { socket.on("error", () => socket.destroy()); @@ -360,7 +360,7 @@ export abstract class Server { `Sec-WebSocket-Accept: ${reply}`, ].join("\r\n") + "\r\n\r\n"); - const parsedUrl = request.url ? url.parse(request.url, true) : { query: {}}; + const parsedUrl = url.parse(request.url || "", true); return this.handleWebSocket(socket, parsedUrl); } @@ -616,9 +616,11 @@ export class MainServer extends Server { NLS_CONFIGURATION: await getNlsConfiguration(environment.args.locale || await getLocaleFromConfig(environment.userDataPath), environment.userDataPath), }; - content = content.replace(/{{COMMIT}}/g, product.commit || ""); - for (const key in options) { - content = content.replace(`"{{${key}}}"`, `'${JSON.stringify(options[key as keyof Options])}'`); + if (content) { + content = content.replace(/{{COMMIT}}/g, product.commit || ""); + for (const key in options) { + content = content.replace(`"{{${key}}}"`, `'${JSON.stringify(options[key as keyof Options])}'`); + } } return { content, filePath }; From d574012871e58e503801f869fab5e3d3a4052390 Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 12 Feb 2020 16:49:34 -0600 Subject: [PATCH 3/4] Fix duplicate files opening with folder parameter When using a query parameter without a scheme, the scheme defaults to `file`. This results in the files in the explorer being technically different from the file picker files because they are file:// instead of vscode-remote://, causing the same file to open twice and causing numerous issues. Normally the file explorer wouldn't even load at all in this case but we provide a file service for file:// URLs as a failsafe for certain files that wouldn't load correctly in the past. These files load fine now using the vscode-remote scheme, so I'm also removing that service. Related: #1351. Fixes #1294. --- scripts/vscode.patch | 50 ++++++++++++++++++++++++++++++++++++-------- src/node/server.ts | 29 +++++++++++++++---------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/scripts/vscode.patch b/scripts/vscode.patch index f301d4a7..1f111ad8 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -76,6 +76,46 @@ index 2c64061da7..c0ef8faedd 100644 } catch (err) { // Do nothing. If we can't read the file we have no // language pack config. +diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts +index a599f5a7eb..ec7ccd43f8 100644 +--- a/src/vs/code/browser/workbench/workbench.ts ++++ b/src/vs/code/browser/workbench/workbench.ts +@@ -298,35 +298,6 @@ class WorkspaceProvider implements IWorkspaceProvider { + let workspace: IWorkspace; + let payload = Object.create(null); + +- const query = new URL(document.location.href).searchParams; +- query.forEach((value, key) => { +- switch (key) { +- +- // Folder +- case WorkspaceProvider.QUERY_PARAM_FOLDER: +- workspace = { folderUri: URI.parse(value) }; +- foundWorkspace = true; +- break; +- +- // Workspace +- case WorkspaceProvider.QUERY_PARAM_WORKSPACE: +- workspace = { workspaceUri: URI.parse(value) }; +- foundWorkspace = true; +- break; +- +- // Empty +- case WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW: +- workspace = undefined; +- foundWorkspace = true; +- break; +- +- // Payload +- case WorkspaceProvider.QUERY_PARAM_PAYLOAD: +- payload = JSON.parse(value); +- break; +- } +- }); +- + // If no workspace is provided through the URL, check for config attribute from server + if (!foundWorkspace) { + if (config.folderUri) { diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index abd1e33b18..bf75952ce1 100644 --- a/src/vs/platform/environment/common/environment.ts @@ -680,7 +720,7 @@ index 4781f22676..25143a97c0 100644 throw new Error(`Cannot load module '${request}'`); } diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts -index 94e7052574..4219adda2c 100644 +index 94e7052574..7e5563b417 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -49,6 +49,7 @@ import { IndexedDBLogProvider } from 'vs/workbench/services/log/browser/indexedD @@ -699,14 +739,6 @@ index 94e7052574..4219adda2c 100644 } private registerListeners(workbench: Workbench, storageService: BrowserStorageService): void { -@@ -245,6 +247,7 @@ class BrowserMain extends Disposable { - // Remote file system - const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(remoteAgentService)); - fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); -+ fileService.registerProvider(Schemas.file, remoteFileSystemProvider); - - if (!this.configuration.userDataProvider) { - const remoteUserDataUri = this.getRemoteUserDataUri(); diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index c509716fc4..e416413084 100644 --- a/src/vs/workbench/common/resources.ts diff --git a/src/node/server.ts b/src/node/server.ts index e3b10fb9..5db95f7a 100644 --- a/src/node/server.ts +++ b/src/node/server.ts @@ -10,7 +10,6 @@ import * as tls from "tls"; import * as url from "url"; import * as util from "util"; import { Emitter } from "vs/base/common/event"; -import { sanitizeFilePath } from "vs/base/common/extpath"; import { Schemas } from "vs/base/common/network"; import { URI, UriComponents } from "vs/base/common/uri"; import { generateUuid } from "vs/base/common/uuid"; @@ -574,6 +573,7 @@ export class MainServer extends Server { } private async getRoot(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise { + const remoteAuthority = request.headers.host as string; const filePath = path.join(this.serverRoot, "browser/workbench.html"); let [content, startPath] = await Promise.all([ util.promisify(fs.readFile)(filePath, "utf8"), @@ -582,14 +582,14 @@ export class MainServer extends Server { { path: parsedUrl.query.folder, workspace: false }, (await this.readSettings()).lastVisited, { path: this.options.openUri } - ]), + ], remoteAuthority), this.servicesPromise, ]); if (startPath) { this.writeSettings({ lastVisited: { - path: startPath.uri.fsPath, + path: startPath.uri, workspace: startPath.workspace }, }); @@ -598,14 +598,13 @@ export class MainServer extends Server { const logger = this.services.get(ILogService) as ILogService; logger.info("request.url", `"${request.url}"`); - const remoteAuthority = request.headers.host as string; const transformer = getUriTransformer(remoteAuthority); const environment = this.services.get(IEnvironmentService) as IEnvironmentService; const options: Options = { WORKBENCH_WEB_CONFIGURATION: { - workspaceUri: startPath && startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined, - folderUri: startPath && !startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined, + workspaceUri: startPath && startPath.workspace ? URI.parse(startPath.uri) : undefined, + folderUri: startPath && !startPath.workspace ? URI.parse(startPath.uri) : undefined, remoteAuthority, logLevel: getLogLevel(environment), }, @@ -631,9 +630,8 @@ export class MainServer extends Server { * workspace or a directory are acceptable. Otherwise it must be a file if a * workspace or a directory otherwise. */ - private async getFirstValidPath(startPaths: Array): Promise<{ uri: URI, workspace?: boolean} | undefined> { + private async getFirstValidPath(startPaths: Array, remoteAuthority: string): Promise<{ uri: string, workspace?: boolean} | undefined> { const logger = this.services.get(ILogService) as ILogService; - const cwd = process.env.VSCODE_CWD || process.cwd(); for (let i = 0; i < startPaths.length; ++i) { const startPath = startPaths[i]; if (!startPath) { @@ -641,11 +639,20 @@ export class MainServer extends Server { } const paths = typeof startPath.path === "string" ? [startPath.path] : (startPath.path || []); for (let j = 0; j < paths.length; ++j) { - const uri = URI.file(sanitizeFilePath(paths[j], cwd)); + const uri = url.parse(paths[j]); try { - const stat = await util.promisify(fs.stat)(uri.fsPath); + if (!uri.pathname) { + throw new Error(`${paths[j]} is not valid`); + } + const stat = await util.promisify(fs.stat)(uri.pathname); if (typeof startPath.workspace === "undefined" || startPath.workspace !== stat.isDirectory()) { - return { uri, workspace: !stat.isDirectory() }; + return { uri: url.format({ + protocol: uri.protocol || "vscode-remote", + hostname: remoteAuthority.split(":")[0], + port: remoteAuthority.split(":")[1], + pathname: uri.pathname, + slashes: true, + }), workspace: !stat.isDirectory() }; } } catch (error) { logger.warn(error.message); From c8fc54bfb1ba0fae592dee33a5f68843d9b41a4a Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 12 Feb 2020 18:03:53 -0600 Subject: [PATCH 4/4] Update VS Code version for CI --- scripts/ci.bash | 2 +- scripts/test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci.bash b/scripts/ci.bash index e33a22c0..4a037848 100755 --- a/scripts/ci.bash +++ b/scripts/ci.bash @@ -21,7 +21,7 @@ function main() { # Get the version information. If a specific version wasn't set, generate it # from the tag and VS Code version. - local vscode_version=${VSCODE_VERSION:-1.41.1} + local vscode_version=${VSCODE_VERSION:-1.42.0} local code_server_version=${VERSION:-${TRAVIS_TAG:-${DRONE_TAG:-daily}}} # Remove everything that isn't the current VS Code source for caching diff --git a/scripts/test.sh b/scripts/test.sh index b8496130..08f78570 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -11,7 +11,7 @@ main() { version=$(./binaries/code-server* --version | head -1) echo "Got '$version' for the version" case $version in - *-vsc1.41.1) exit 0 ;; + *-vsc1.42.0) exit 0 ;; *) exit 1 ;; esac }