chore(vscode): update to 1.55.2
This commit is contained in:
80
lib/vscode/src/vs/code/browser/workbench/workbench-web.html
Normal file
80
lib/vscode/src/vs/code/browser/workbench/workbench-web.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
performance.mark('code/didStartRenderer')
|
||||
</script>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- 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">
|
||||
|
||||
<!-- Workbench Configuration -->
|
||||
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONFIGURATION}}">
|
||||
|
||||
<!-- Workbench Auth Session -->
|
||||
<meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}">
|
||||
|
||||
<!-- Workbench Icon/Manifest/CSS -->
|
||||
<link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/manifest.json">
|
||||
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.api.css">
|
||||
|
||||
</head>
|
||||
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Startup (do not modify order of script tags!) -->
|
||||
<script>
|
||||
var baseUrl = '{{WORKBENCH_WEB_BASE_URL}}';
|
||||
self.require = {
|
||||
baseUrl: `${baseUrl}/out`,
|
||||
recordStats: true,
|
||||
trustedTypesPolicy: window.trustedTypes?.createPolicy('amdLoader', {
|
||||
createScriptURL(value) {
|
||||
if(value.startsWith(baseUrl)) {
|
||||
return value;
|
||||
}
|
||||
throw new Error(`Invalid script url: ${value}`)
|
||||
}
|
||||
}),
|
||||
paths: {
|
||||
'vscode-textmate': `${baseUrl}/node_modules/vscode-textmate/release/main`,
|
||||
'vscode-oniguruma': `${baseUrl}/node_modules/vscode-oniguruma/release/main`,
|
||||
'xterm': `${baseUrl}/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${baseUrl}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-unicode11': `${baseUrl}/node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`,
|
||||
'xterm-addon-webgl': `${baseUrl}/node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js`,
|
||||
'tas-client-umd': `${baseUrl}/node_modules/tas-client-umd/lib/tas-client-umd.js`,
|
||||
'iconv-lite-umd': `${baseUrl}/node_modules/iconv-lite-umd/lib/iconv-lite-umd.js`,
|
||||
'jschardet': `${baseUrl}/node_modules/jschardet/dist/jschardet.min.js`,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="{{WORKBENCH_WEB_BASE_URL}}/out/vs/loader.js"></script>
|
||||
<script>
|
||||
performance.mark('code/willLoadWorkbenchMain');
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if ("{{WORKBENCH_DEV}}" === "true") {
|
||||
const workbench = document.createElement('script');
|
||||
workbench.innerText = "require(['vs/code/browser/workbench/workbench'], function() {});";
|
||||
document.body.appendChild(workbench);
|
||||
} else {
|
||||
const nls = document.createElement('script');
|
||||
nls.setAttribute('src', '{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.api.nls.js');
|
||||
document.body.appendChild(nls);
|
||||
|
||||
const api = document.createElement('script');
|
||||
api.setAttribute('src', '{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.api.js');
|
||||
document.body.appendChild(api);
|
||||
|
||||
const workbench = document.createElement('script');
|
||||
workbench.setAttribute('src', '{{WORKBENCH_WEB_BASE_URL}}/out/vs/code/browser/workbench/workbench.js');
|
||||
document.body.appendChild(workbench);
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -7,7 +7,7 @@ import * as fs from 'fs';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
@ -32,9 +32,14 @@ interface LanguagePackFile {
|
||||
|
||||
export class LanguagePackCachedDataCleaner extends Disposable {
|
||||
|
||||
private readonly _DataMaxAge = this._productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months
|
||||
|
||||
constructor(
|
||||
@INativeEnvironmentService private readonly _environmentService: INativeEnvironmentService,
|
||||
@ILogService private readonly _logService: ILogService
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@IProductService private readonly _productService: IProductService
|
||||
) {
|
||||
super();
|
||||
// We have no Language pack support for dev version (run from source)
|
||||
@ -48,9 +53,6 @@ export class LanguagePackCachedDataCleaner extends Disposable {
|
||||
let handle: any = setTimeout(async () => {
|
||||
handle = undefined;
|
||||
this._logService.info('Starting to clean up unused language packs.');
|
||||
const maxAge = product.nameLong.indexOf('Insiders') >= 0
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months
|
||||
try {
|
||||
const installed: IStringDictionary<boolean> = Object.create(null);
|
||||
const metaData: LanguagePackFile = JSON.parse(await fs.promises.readFile(path.join(this._environmentService.userDataPath, 'languagepacks.json'), 'utf8'));
|
||||
@ -84,7 +86,7 @@ export class LanguagePackCachedDataCleaner extends Disposable {
|
||||
const stat = await fs.promises.stat(candidate);
|
||||
if (stat.isDirectory()) {
|
||||
const diff = now - stat.mtime.getTime();
|
||||
if (diff > maxAge) {
|
||||
if (diff > this._DataMaxAge) {
|
||||
this._logService.info('Removing language pack cache entry: ', path.join(packEntry, entry));
|
||||
await pfs.rimraf(candidate);
|
||||
}
|
||||
|
@ -8,18 +8,19 @@ import { basename, dirname, join } from 'vs/base/common/path';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { readdir, rimraf } from 'vs/base/node/pfs';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export class NodeCachedDataCleaner {
|
||||
|
||||
private static readonly _DataMaxAge = product.nameLong.indexOf('Insiders') >= 0
|
||||
private readonly _DataMaxAge = this.productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months
|
||||
|
||||
private readonly _disposables = new DisposableStore();
|
||||
|
||||
constructor(
|
||||
private readonly nodeCachedDataDir: string | undefined
|
||||
private readonly nodeCachedDataDir: string | undefined,
|
||||
@IProductService private readonly productService: IProductService
|
||||
) {
|
||||
this._manageCachedDataSoon();
|
||||
}
|
||||
@ -61,7 +62,7 @@ export class NodeCachedDataCleaner {
|
||||
// * only when old enough
|
||||
if (stats.isDirectory()) {
|
||||
const diff = now - stats.mtime.getTime();
|
||||
if (diff > NodeCachedDataCleaner._DataMaxAge) {
|
||||
if (diff > this._DataMaxAge) {
|
||||
return rimraf(path);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import { StaticRouter, ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { ExtensionManagementChannel, ExtensionTipsChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
@ -23,7 +23,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/browser/requestService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { combinedAppender, NullTelemetryService, ITelemetryAppender, NullAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties';
|
||||
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc';
|
||||
@ -58,7 +58,7 @@ import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
|
||||
import { LoggerService } from 'vs/platform/log/node/loggerService';
|
||||
import { UserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSyncLog';
|
||||
import { UserDataAutoSyncService } from 'vs/platform/userDataSync/electron-sandbox/userDataAutoSyncService';
|
||||
import { NativeStorageService2 } from 'vs/platform/storage/electron-sandbox/storageService2';
|
||||
import { NativeStorageService } from 'vs/platform/storage/electron-sandbox/storageService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
|
||||
import { UserDataSyncResourceEnablementService } from 'vs/platform/userDataSync/common/userDataSyncResourceEnablementService';
|
||||
@ -81,9 +81,12 @@ import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/err
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { TerminalIpcChannels } from 'vs/platform/terminal/common/terminal';
|
||||
import { LocalPtyService } from 'vs/platform/terminal/electron-browser/localPtyService';
|
||||
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
|
||||
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||
import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyncServiceIpc';
|
||||
import { IChecksumService } from 'vs/platform/checksum/common/checksumService';
|
||||
import { ChecksumService } from 'vs/platform/checksum/node/checksumService';
|
||||
import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService';
|
||||
|
||||
class SharedProcessMain extends Disposable {
|
||||
|
||||
@ -129,7 +132,7 @@ class SharedProcessMain extends Disposable {
|
||||
|
||||
// Instantiate Contributions
|
||||
this._register(combinedDisposable(
|
||||
new NodeCachedDataCleaner(this.configuration.nodeCachedDataDir),
|
||||
instantiationService.createInstance(NodeCachedDataCleaner, this.configuration.nodeCachedDataDir),
|
||||
instantiationService.createInstance(LanguagePackCachedDataCleaner),
|
||||
instantiationService.createInstance(StorageDataCleaner, this.configuration.backupWorkspacesPath),
|
||||
instantiationService.createInstance(LogsDataCleaner),
|
||||
@ -141,9 +144,12 @@ class SharedProcessMain extends Disposable {
|
||||
private async initServices(): Promise<IInstantiationService> {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
// Product
|
||||
const productService = { _serviceBrand: undefined, ...product };
|
||||
services.set(IProductService, productService);
|
||||
|
||||
// Environment
|
||||
const environmentService = new NativeEnvironmentService(this.configuration.args);
|
||||
services.set(IEnvironmentService, environmentService);
|
||||
const environmentService = new NativeEnvironmentService(this.configuration.args, productService);
|
||||
services.set(INativeEnvironmentService, environmentService);
|
||||
|
||||
// Log
|
||||
@ -175,18 +181,18 @@ class SharedProcessMain extends Disposable {
|
||||
await configurationService.initialize();
|
||||
|
||||
// Storage (global access only)
|
||||
const storageService = new NativeStorageService2(undefined, mainProcessService, environmentService);
|
||||
const storageService = new NativeStorageService(undefined, mainProcessService, environmentService);
|
||||
services.set(IStorageService, storageService);
|
||||
|
||||
await storageService.initialize();
|
||||
this._register(toDisposable(() => storageService.flush()));
|
||||
|
||||
// Product
|
||||
services.set(IProductService, { _serviceBrand: undefined, ...product });
|
||||
|
||||
// Request
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
|
||||
// Checksum
|
||||
services.set(IChecksumService, new SyncDescriptor(ChecksumService));
|
||||
|
||||
// Native Host
|
||||
const nativeHostService = ProxyChannel.toService<INativeHostService>(mainProcessService.getChannel('nativeHost'), { context: this.configuration.windowId });
|
||||
services.set(INativeHostService, nativeHostService);
|
||||
@ -208,19 +214,19 @@ class SharedProcessMain extends Disposable {
|
||||
|
||||
let telemetryService: ITelemetryService;
|
||||
let telemetryAppender: ITelemetryAppender;
|
||||
if (!extensionDevelopmentLocationURI && !environmentService.disableTelemetry && product.enableTelemetry) {
|
||||
if (!extensionDevelopmentLocationURI && !environmentService.disableTelemetry && productService.enableTelemetry) {
|
||||
telemetryAppender = new TelemetryLogAppender(loggerService, environmentService);
|
||||
|
||||
// Application Insights
|
||||
if (product.aiConfig && product.aiConfig.asimovKey && isBuilt) {
|
||||
const appInsightsAppender = new AppInsightsAppender('monacoworkbench', null, product.aiConfig.asimovKey);
|
||||
if (productService.aiConfig && productService.aiConfig.asimovKey && isBuilt) {
|
||||
const appInsightsAppender = new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey);
|
||||
this._register(toDisposable(() => appInsightsAppender.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
telemetryAppender = combinedAppender(appInsightsAppender, telemetryAppender);
|
||||
}
|
||||
|
||||
telemetryService = new TelemetryService({
|
||||
appender: telemetryAppender,
|
||||
commonProperties: resolveCommonProperties(fileService, release(), process.arch, product.commit, product.version, this.configuration.machineId, product.msftInternalDomains, installSourcePath),
|
||||
commonProperties: resolveCommonProperties(fileService, release(), process.arch, productService.commit, productService.version, this.configuration.machineId, productService.msftInternalDomains, installSourcePath),
|
||||
sendErrorTelemetry: true,
|
||||
piiPaths: [appRoot, extensionsPath]
|
||||
}, configurationService);
|
||||
@ -232,6 +238,10 @@ class SharedProcessMain extends Disposable {
|
||||
this.server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(telemetryAppender));
|
||||
services.set(ITelemetryService, telemetryService);
|
||||
|
||||
// Custom Endpoint Telemetry
|
||||
const customEndpointTelemetryService = new CustomEndpointTelemetryService(configurationService, telemetryService);
|
||||
services.set(ICustomEndpointTelemetryService, customEndpointTelemetryService);
|
||||
|
||||
// Extension Management
|
||||
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
|
||||
|
||||
@ -263,8 +273,7 @@ class SharedProcessMain extends Disposable {
|
||||
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
|
||||
|
||||
// Terminal
|
||||
const localPtyService = this._register(new LocalPtyService(logService));
|
||||
services.set(ILocalPtyService, localPtyService);
|
||||
services.set(ILocalPtyService, this._register(new PtyHostService(logService)));
|
||||
|
||||
return new InstantiationService(services);
|
||||
}
|
||||
@ -287,10 +296,18 @@ class SharedProcessMain extends Disposable {
|
||||
const extensionTipsChannel = new ExtensionTipsChannel(accessor.get(IExtensionTipsService));
|
||||
this.server.registerChannel('extensionTipsService', extensionTipsChannel);
|
||||
|
||||
// Checksum
|
||||
const checksumChannel = ProxyChannel.fromService(accessor.get(IChecksumService));
|
||||
this.server.registerChannel('checksum', checksumChannel);
|
||||
|
||||
// Settings Sync
|
||||
const userDataSyncMachineChannel = new UserDataSyncMachinesServiceChannel(accessor.get(IUserDataSyncMachinesService));
|
||||
this.server.registerChannel('userDataSyncMachines', userDataSyncMachineChannel);
|
||||
|
||||
// Custom Endpoint Telemetry
|
||||
const customEndpointTelemetryChannel = ProxyChannel.fromService(accessor.get(ICustomEndpointTelemetryService));
|
||||
this.server.registerChannel('customEndpointTelemetry', customEndpointTelemetryChannel);
|
||||
|
||||
const userDataSyncAccountChannel = new UserDataSyncAccountServiceChannel(accessor.get(IUserDataSyncAccountService));
|
||||
this.server.registerChannel('userDataSyncAccount', userDataSyncAccountChannel);
|
||||
|
||||
|
@ -33,7 +33,7 @@ import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtil
|
||||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ProxyAuthHandler } from 'vs/code/electron-main/auth';
|
||||
import { FileProtocolHandler } from 'vs/code/electron-main/protocol';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@ -80,13 +80,14 @@ import { EncryptionMainService, IEncryptionMainService } from 'vs/platform/encry
|
||||
import { ActiveWindowManager } from 'vs/platform/windows/node/windowTracker';
|
||||
import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from 'vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { DisplayMainService, IDisplayMainService } from 'vs/platform/display/electron-main/displayMainService';
|
||||
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
|
||||
import { isEqualOrParent } from 'vs/base/common/extpath';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { ISignService } from 'vs/platform/sign/common/sign';
|
||||
|
||||
/**
|
||||
* The main VS Code application. There will only ever be one instance,
|
||||
@ -105,7 +106,8 @@ export class CodeApplication extends Disposable {
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IProductService private readonly productService: IProductService
|
||||
) {
|
||||
super();
|
||||
|
||||
@ -418,7 +420,7 @@ export class CodeApplication extends Disposable {
|
||||
// This will help Windows to associate the running program with
|
||||
// any shortcut that is pinned to the taskbar and prevent showing
|
||||
// two icons in the taskbar for the same app.
|
||||
const win32AppUserModelId = product.win32AppUserModelId;
|
||||
const win32AppUserModelId = this.productService.win32AppUserModelId;
|
||||
if (isWindows && win32AppUserModelId) {
|
||||
app.setAppUserModelId(win32AppUserModelId);
|
||||
}
|
||||
@ -559,9 +561,6 @@ export class CodeApplication extends Disposable {
|
||||
// Keyboard Layout
|
||||
services.set(IKeyboardLayoutMainService, new SyncDescriptor(KeyboardLayoutMainService));
|
||||
|
||||
// Display
|
||||
services.set(IDisplayMainService, new SyncDescriptor(DisplayMainService));
|
||||
|
||||
// Native Host
|
||||
services.set(INativeHostMainService, new SyncDescriptor(NativeHostMainService, [sharedProcess]));
|
||||
|
||||
@ -590,10 +589,10 @@ export class CodeApplication extends Disposable {
|
||||
services.set(IURLService, new SyncDescriptor(NativeURLService));
|
||||
|
||||
// Telemetry
|
||||
if (!this.environmentMainService.isExtensionDevelopment && !this.environmentMainService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
if (!this.environmentMainService.isExtensionDevelopment && !this.environmentMainService.args['disable-telemetry'] && !!this.productService.enableTelemetry) {
|
||||
const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender')));
|
||||
const appender = new TelemetryAppenderClient(channel);
|
||||
const commonProperties = resolveCommonProperties(this.fileService, release(), process.arch, product.commit, product.version, machineId, product.msftInternalDomains, this.environmentMainService.installSourcePath);
|
||||
const commonProperties = resolveCommonProperties(this.fileService, release(), process.arch, this.productService.commit, this.productService.version, machineId, this.productService.msftInternalDomains, this.environmentMainService.installSourcePath);
|
||||
const piiPaths = [this.environmentMainService.appRoot, this.environmentMainService.extensionsPath];
|
||||
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, sendErrorTelemetry: true };
|
||||
|
||||
@ -629,14 +628,14 @@ export class CodeApplication extends Disposable {
|
||||
const encryptionChannel = ProxyChannel.fromService(accessor.get(IEncryptionMainService));
|
||||
mainProcessElectronServer.registerChannel('encryption', encryptionChannel);
|
||||
|
||||
// Signing
|
||||
const signChannel = ProxyChannel.fromService(accessor.get(ISignService));
|
||||
mainProcessElectronServer.registerChannel('sign', signChannel);
|
||||
|
||||
// Keyboard Layout
|
||||
const keyboardLayoutChannel = ProxyChannel.fromService(accessor.get(IKeyboardLayoutMainService));
|
||||
mainProcessElectronServer.registerChannel('keyboardLayout', keyboardLayoutChannel);
|
||||
|
||||
// Display
|
||||
const displayChannel = ProxyChannel.fromService(accessor.get(IDisplayMainService));
|
||||
mainProcessElectronServer.registerChannel('display', displayChannel);
|
||||
|
||||
// Native host (main & shared process)
|
||||
this.nativeHostMainService = accessor.get(INativeHostMainService);
|
||||
const nativeHostChannel = ProxyChannel.fromService(this.nativeHostMainService);
|
||||
@ -751,6 +750,7 @@ export class CodeApplication extends Disposable {
|
||||
cli: { ...environmentService.args },
|
||||
urisToOpen: [windowOpenableFromProtocolLink],
|
||||
gotoLineMode: true
|
||||
/* remoteAuthority will be determined based on windowOpenableFromProtocolLink */
|
||||
});
|
||||
|
||||
window.focus(); // this should help ensuring that the right window gets focus when multiple are opened
|
||||
@ -765,7 +765,8 @@ export class CodeApplication extends Disposable {
|
||||
context: OpenContext.API,
|
||||
cli: { ...environmentService.args },
|
||||
forceEmpty: true,
|
||||
gotoLineMode: true
|
||||
gotoLineMode: true,
|
||||
remoteAuthority: getRemoteAuthority(uri)
|
||||
});
|
||||
|
||||
await window.ready();
|
||||
@ -789,7 +790,7 @@ export class CodeApplication extends Disposable {
|
||||
urlService.registerHandler(new URLHandlerChannelClient(urlHandlerChannel));
|
||||
|
||||
// Watch Electron URLs and forward them to the UrlService
|
||||
this._register(new ElectronURLListener(pendingProtocolLinksToHandle, urlService, windowsMainService, this.environmentMainService));
|
||||
this._register(new ElectronURLListener(pendingProtocolLinksToHandle, urlService, windowsMainService, this.environmentMainService, this.productService));
|
||||
|
||||
// Open our first window
|
||||
const args = this.environmentMainService.args;
|
||||
@ -800,6 +801,7 @@ export class CodeApplication extends Disposable {
|
||||
const hasFileURIs = !!args['file-uri'];
|
||||
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
|
||||
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
|
||||
const remoteAuthority = args.remote || undefined;
|
||||
|
||||
// check for a pending window to open from URI
|
||||
// e.g. when running code with --open-uri from
|
||||
@ -811,6 +813,7 @@ export class CodeApplication extends Disposable {
|
||||
urisToOpen: pendingWindowOpenablesFromProtocolLinks,
|
||||
gotoLineMode: true,
|
||||
initialStartup: true
|
||||
/* remoteAuthority will be determined based on pendingWindowOpenablesFromProtocolLinks */
|
||||
});
|
||||
}
|
||||
|
||||
@ -823,7 +826,8 @@ export class CodeApplication extends Disposable {
|
||||
forceEmpty: true,
|
||||
noRecentEntry,
|
||||
waitMarkerFileURI,
|
||||
initialStartup: true
|
||||
initialStartup: true,
|
||||
remoteAuthority
|
||||
});
|
||||
}
|
||||
|
||||
@ -835,7 +839,8 @@ export class CodeApplication extends Disposable {
|
||||
urisToOpen: macOpenFiles.map(file => this.getWindowOpenableFromPathSync(file)),
|
||||
noRecentEntry,
|
||||
waitMarkerFileURI,
|
||||
initialStartup: true
|
||||
initialStartup: true,
|
||||
/* remoteAuthority will be determined based on macOpenFiles */
|
||||
});
|
||||
}
|
||||
|
||||
@ -848,21 +853,22 @@ export class CodeApplication extends Disposable {
|
||||
noRecentEntry,
|
||||
waitMarkerFileURI,
|
||||
gotoLineMode: args.goto,
|
||||
initialStartup: true
|
||||
initialStartup: true,
|
||||
remoteAuthority
|
||||
});
|
||||
}
|
||||
|
||||
private shouldBlockURI(uri: URI): boolean {
|
||||
if (uri.authority === Schemas.file && isWindows) {
|
||||
const res = dialog.showMessageBoxSync({
|
||||
title: product.nameLong,
|
||||
title: this.productService.nameLong,
|
||||
type: 'question',
|
||||
buttons: [
|
||||
mnemonicButtonLabel(localize({ key: 'open', comment: ['&& denotes a mnemonic'] }, "&&Yes")),
|
||||
mnemonicButtonLabel(localize({ key: 'cancel', comment: ['&& denotes a mnemonic'] }, "&&No")),
|
||||
],
|
||||
cancelId: 1,
|
||||
message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri.fsPath, this.environmentMainService), product.nameShort),
|
||||
message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri.fsPath, this.environmentMainService), this.productService.nameShort),
|
||||
detail: localize('confirmOpenDetail', "If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"),
|
||||
noLink: true
|
||||
});
|
||||
@ -948,16 +954,22 @@ export class CodeApplication extends Disposable {
|
||||
type SharedProcessErrorClassification = {
|
||||
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
reason: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
visible: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
};
|
||||
type SharedProcessErrorEvent = {
|
||||
type: WindowError;
|
||||
reason: string | undefined;
|
||||
visible: boolean;
|
||||
};
|
||||
telemetryService.publicLog2<SharedProcessErrorEvent, SharedProcessErrorClassification>('sharedprocesserror', { type, reason: typeof details !== 'string' ? details.reason : undefined });
|
||||
telemetryService.publicLog2<SharedProcessErrorEvent, SharedProcessErrorClassification>('sharedprocesserror', {
|
||||
type,
|
||||
reason: typeof details !== 'string' ? details?.reason : undefined,
|
||||
visible: sharedProcess.isVisible()
|
||||
});
|
||||
}));
|
||||
|
||||
// Windows: install mutex
|
||||
const win32MutexName = product.win32MutexName;
|
||||
const win32MutexName = this.productService.win32MutexName;
|
||||
if (isWindows && win32MutexName) {
|
||||
try {
|
||||
const WindowsMutex = (require.__$__nodeRequire('windows-mutex') as typeof import('windows-mutex')).Mutex;
|
||||
@ -1027,7 +1039,7 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
recordingStopped = true; // only once
|
||||
|
||||
const path = await contentTracing.stopRecording(joinPath(this.environmentMainService.userHome, `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`).fsPath);
|
||||
const path = await contentTracing.stopRecording(joinPath(this.environmentMainService.userHome, `${this.productService.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`).fsPath);
|
||||
|
||||
if (!timeout) {
|
||||
dialogMainService.showMessageBox({
|
||||
|
@ -12,7 +12,7 @@ import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||
import { INativeHostMainService } from 'vs/platform/native/electron-main/nativeHostMainService';
|
||||
import { IEncryptionMainService } from 'vs/platform/encryption/electron-main/encryptionMainService';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
interface ElectronAuthenticationResponseDetails extends AuthenticationResponseDetails {
|
||||
@ -56,7 +56,7 @@ enum ProxyAuthState {
|
||||
|
||||
export class ProxyAuthHandler extends Disposable {
|
||||
|
||||
private static PROXY_CREDENTIALS_SERVICE_KEY = `${product.urlProtocol}.proxy-credentials`;
|
||||
private readonly PROXY_CREDENTIALS_SERVICE_KEY = `${this.productService.urlProtocol}.proxy-credentials`;
|
||||
|
||||
private pendingProxyResolve: Promise<Credentials | undefined> | undefined = undefined;
|
||||
|
||||
@ -68,7 +68,8 @@ export class ProxyAuthHandler extends Disposable {
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
|
||||
@INativeHostMainService private readonly nativeHostMainService: INativeHostMainService,
|
||||
@IEncryptionMainService private readonly encryptionMainService: IEncryptionMainService
|
||||
@IEncryptionMainService private readonly encryptionMainService: IEncryptionMainService,
|
||||
@IProductService private readonly productService: IProductService
|
||||
) {
|
||||
super();
|
||||
|
||||
@ -153,7 +154,7 @@ export class ProxyAuthHandler extends Disposable {
|
||||
let storedUsername: string | undefined = undefined;
|
||||
let storedPassword: string | undefined = undefined;
|
||||
try {
|
||||
const encryptedSerializedProxyCredentials = await this.nativeHostMainService.getPassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash);
|
||||
const encryptedSerializedProxyCredentials = await this.nativeHostMainService.getPassword(undefined, this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash);
|
||||
if (encryptedSerializedProxyCredentials) {
|
||||
const credentials: Credentials = JSON.parse(await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials));
|
||||
|
||||
@ -211,9 +212,9 @@ export class ProxyAuthHandler extends Disposable {
|
||||
try {
|
||||
if (reply.remember) {
|
||||
const encryptedSerializedCredentials = await this.encryptionMainService.encrypt(JSON.stringify(credentials));
|
||||
await this.nativeHostMainService.setPassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials);
|
||||
await this.nativeHostMainService.setPassword(undefined, this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials);
|
||||
} else {
|
||||
await this.nativeHostMainService.deletePassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash);
|
||||
await this.nativeHostMainService.deletePassword(undefined, this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logService.error(error); // handle gracefully
|
||||
|
@ -23,7 +23,6 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { ILogService, ConsoleMainLogger, MultiplexLogService, getLogLevel, ILoggerService } from 'vs/platform/log/common/log';
|
||||
import { StateService } from 'vs/platform/state/node/stateService';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
|
||||
@ -54,6 +53,7 @@ import { EnvironmentMainService, IEnvironmentMainService } from 'vs/platform/env
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { LoggerService } from 'vs/platform/log/node/loggerService';
|
||||
import { cwd } from 'vs/base/common/process';
|
||||
|
||||
/**
|
||||
* The main VS Code entry point.
|
||||
@ -84,7 +84,7 @@ class CodeMain {
|
||||
const args = this.resolveArgs();
|
||||
|
||||
// Create services
|
||||
const [instantiationService, instanceEnvironment, environmentService, configurationService, stateService, bufferLogService] = this.createServices(args);
|
||||
const [instantiationService, instanceEnvironment, environmentService, configurationService, stateService, bufferLogService, productService] = this.createServices(args);
|
||||
|
||||
try {
|
||||
|
||||
@ -94,7 +94,7 @@ class CodeMain {
|
||||
} catch (error) {
|
||||
|
||||
// Show a dialog for errors that can be resolved by the user
|
||||
this.handleStartupDataDirError(environmentService, error);
|
||||
this.handleStartupDataDirError(environmentService, productService.nameLong, error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
@ -108,7 +108,7 @@ class CodeMain {
|
||||
// Create the main IPC server by trying to be the server
|
||||
// If this throws an error it means we are not the first
|
||||
// instance of VS Code running and so we would quit.
|
||||
const mainProcessNodeIpcServer = await this.doStartup(args, logService, environmentService, lifecycleMainService, instantiationService, true);
|
||||
const mainProcessNodeIpcServer = await this.doStartup(args, logService, environmentService, lifecycleMainService, instantiationService, productService, true);
|
||||
|
||||
// Delay creation of spdlog for perf reasons (https://github.com/microsoft/vscode/issues/72906)
|
||||
bufferLogService.logger = new SpdLogLogger('main', join(environmentService.logsPath, 'main.log'), true, bufferLogService.getLevel());
|
||||
@ -126,20 +126,23 @@ class CodeMain {
|
||||
}
|
||||
}
|
||||
|
||||
private createServices(args: NativeParsedArgs): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogService] {
|
||||
private createServices(args: NativeParsedArgs): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogService, IProductService] {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
// Product
|
||||
const productService = { _serviceBrand: undefined, ...product };
|
||||
services.set(IProductService, productService);
|
||||
|
||||
// Environment
|
||||
const environmentService = new EnvironmentMainService(args);
|
||||
const instanceEnvironment = this.patchEnvironment(environmentService); // Patch `process.env` with the instance's environment
|
||||
services.set(IEnvironmentService, environmentService);
|
||||
services.set(IEnvironmentMainService, environmentService);
|
||||
const environmentMainService = new EnvironmentMainService(args, productService);
|
||||
const instanceEnvironment = this.patchEnvironment(environmentMainService); // Patch `process.env` with the instance's environment
|
||||
services.set(IEnvironmentMainService, environmentMainService);
|
||||
|
||||
// Log: We need to buffer the spdlog logs until we are sure
|
||||
// we are the only instance running, otherwise we'll have concurrent
|
||||
// log file access on Windows (https://github.com/microsoft/vscode/issues/41218)
|
||||
const bufferLogService = new BufferLogService();
|
||||
const logService = new MultiplexLogService([new ConsoleMainLogger(getLogLevel(environmentService)), bufferLogService]);
|
||||
const logService = new MultiplexLogService([new ConsoleMainLogger(getLogLevel(environmentMainService)), bufferLogService]);
|
||||
process.once('exit', () => logService.dispose());
|
||||
services.set(ILogService, logService);
|
||||
|
||||
@ -153,14 +156,14 @@ class CodeMain {
|
||||
services.set(ILoggerService, new LoggerService(logService, fileService));
|
||||
|
||||
// Configuration
|
||||
const configurationService = new ConfigurationService(environmentService.settingsResource, fileService);
|
||||
const configurationService = new ConfigurationService(environmentMainService.settingsResource, fileService);
|
||||
services.set(IConfigurationService, configurationService);
|
||||
|
||||
// Lifecycle
|
||||
services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService));
|
||||
|
||||
// State
|
||||
const stateService = new StateService(environmentService, logService);
|
||||
const stateService = new StateService(environmentMainService, logService);
|
||||
services.set(IStateService, stateService);
|
||||
|
||||
// Request
|
||||
@ -172,13 +175,10 @@ class CodeMain {
|
||||
// Signing
|
||||
services.set(ISignService, new SyncDescriptor(SignService));
|
||||
|
||||
// Product
|
||||
services.set(IProductService, { _serviceBrand: undefined, ...product });
|
||||
|
||||
// Tunnel
|
||||
services.set(ITunnelService, new SyncDescriptor(TunnelService));
|
||||
|
||||
return [new InstantiationService(services, true), instanceEnvironment, environmentService, configurationService, stateService, bufferLogService];
|
||||
return [new InstantiationService(services, true), instanceEnvironment, environmentMainService, configurationService, stateService, bufferLogService, productService];
|
||||
}
|
||||
|
||||
private patchEnvironment(environmentMainService: IEnvironmentMainService): IProcessEnvironment {
|
||||
@ -219,7 +219,7 @@ class CodeMain {
|
||||
return Promise.all([environmentServiceInitialization, configurationServiceInitialization, stateServiceInitialization]);
|
||||
}
|
||||
|
||||
private async doStartup(args: NativeParsedArgs, logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, retry: boolean): Promise<NodeIPCServer> {
|
||||
private async doStartup(args: NativeParsedArgs, logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise<NodeIPCServer> {
|
||||
|
||||
// Try to setup a server for running. If that succeeds it means
|
||||
// we are the first instance to startup. Otherwise it is likely
|
||||
@ -235,7 +235,7 @@ class CodeMain {
|
||||
if (error.code !== 'EADDRINUSE') {
|
||||
|
||||
// Show a dialog for errors that can be resolved by the user
|
||||
this.handleStartupDataDirError(environmentMainService, error);
|
||||
this.handleStartupDataDirError(environmentMainService, productService.nameLong, error);
|
||||
|
||||
// Any other runtime error is just printed to the console
|
||||
throw error;
|
||||
@ -251,8 +251,9 @@ class CodeMain {
|
||||
if (!retry || isWindows || error.code !== 'ECONNREFUSED') {
|
||||
if (error.code === 'EPERM') {
|
||||
this.showStartupWarningDialog(
|
||||
localize('secondInstanceAdmin', "A second instance of {0} is already running as administrator.", product.nameShort),
|
||||
localize('secondInstanceAdminDetail', "Please close the other instance and try again.")
|
||||
localize('secondInstanceAdmin', "A second instance of {0} is already running as administrator.", productService.nameShort),
|
||||
localize('secondInstanceAdminDetail', "Please close the other instance and try again."),
|
||||
productService.nameLong
|
||||
);
|
||||
}
|
||||
|
||||
@ -270,7 +271,7 @@ class CodeMain {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return this.doStartup(args, logService, environmentMainService, lifecycleMainService, instantiationService, false);
|
||||
return this.doStartup(args, logService, environmentMainService, lifecycleMainService, instantiationService, productService, false);
|
||||
}
|
||||
|
||||
// Tests from CLI require to be the only instance currently
|
||||
@ -289,8 +290,9 @@ class CodeMain {
|
||||
if (!args.wait && !args.status) {
|
||||
startupWarningDialogHandle = setTimeout(() => {
|
||||
this.showStartupWarningDialog(
|
||||
localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", product.nameShort),
|
||||
localize('secondInstanceNoResponseDetail', "Please close all other instances and try again.")
|
||||
localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", productService.nameShort),
|
||||
localize('secondInstanceNoResponseDetail', "Please close all other instances and try again."),
|
||||
productService.nameLong
|
||||
);
|
||||
}, 10000);
|
||||
}
|
||||
@ -300,7 +302,7 @@ class CodeMain {
|
||||
// Process Info
|
||||
if (args.status) {
|
||||
return instantiationService.invokeFunction(async () => {
|
||||
const diagnosticsService = new DiagnosticsService(NullTelemetryService);
|
||||
const diagnosticsService = new DiagnosticsService(NullTelemetryService, productService);
|
||||
const mainProcessInfo = await launchService.getMainProcessInfo();
|
||||
const remoteDiagnostics = await launchService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true });
|
||||
const diagnostics = await diagnosticsService.getDiagnostics(mainProcessInfo, remoteDiagnostics);
|
||||
@ -344,23 +346,24 @@ class CodeMain {
|
||||
return mainProcessNodeIpcServer;
|
||||
}
|
||||
|
||||
private handleStartupDataDirError(environmentMainService: IEnvironmentMainService, error: NodeJS.ErrnoException): void {
|
||||
private handleStartupDataDirError(environmentMainService: IEnvironmentMainService, title: string, error: NodeJS.ErrnoException): void {
|
||||
if (error.code === 'EACCES' || error.code === 'EPERM') {
|
||||
const directories = coalesce([environmentMainService.userDataPath, environmentMainService.extensionsPath, XDG_RUNTIME_DIR]).map(folder => getPathLabel(folder, environmentMainService));
|
||||
|
||||
this.showStartupWarningDialog(
|
||||
localize('startupDataDirError', "Unable to write program user data."),
|
||||
localize('startupUserDataAndExtensionsDirErrorDetail', "{0}\n\nPlease make sure the following directories are writeable:\n\n{1}", toErrorMessage(error), directories.join('\n'))
|
||||
localize('startupUserDataAndExtensionsDirErrorDetail', "{0}\n\nPlease make sure the following directories are writeable:\n\n{1}", toErrorMessage(error), directories.join('\n')),
|
||||
title
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private showStartupWarningDialog(message: string, detail: string): void {
|
||||
private showStartupWarningDialog(message: string, detail: string, title: string): void {
|
||||
// use sync variant here because we likely exit after this method
|
||||
// due to startup issues and otherwise the dialog seems to disappear
|
||||
// https://github.com/microsoft/vscode/issues/104493
|
||||
dialog.showMessageBoxSync({
|
||||
title: product.nameLong,
|
||||
title,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message,
|
||||
@ -451,7 +454,7 @@ class CodeMain {
|
||||
}
|
||||
|
||||
private doValidatePaths(args: string[], gotoLineMode?: boolean): string[] {
|
||||
const cwd = process.env['VSCODE_CWD'] || process.cwd();
|
||||
const currentWorkingDir = cwd();
|
||||
const result = args.map(arg => {
|
||||
let pathCandidate = String(arg);
|
||||
|
||||
@ -462,10 +465,10 @@ class CodeMain {
|
||||
}
|
||||
|
||||
if (pathCandidate) {
|
||||
pathCandidate = this.preparePath(cwd, pathCandidate);
|
||||
pathCandidate = this.preparePath(currentWorkingDir, pathCandidate);
|
||||
}
|
||||
|
||||
const sanitizedFilePath = sanitizeFilePath(pathCandidate, cwd);
|
||||
const sanitizedFilePath = sanitizeFilePath(pathCandidate, currentWorkingDir);
|
||||
|
||||
const filePathBasename = basename(sanitizedFilePath);
|
||||
if (filePathBasename /* can be empty if code is opened on root */ && !isValidBasename(filePathBasename)) {
|
||||
|
@ -13,12 +13,14 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { isLinux, isPreferringBrowserCodeLoad } from 'vs/base/common/platform';
|
||||
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||
import { extname } from 'vs/base/common/resources';
|
||||
|
||||
type ProtocolCallback = { (result: string | Electron.FilePathWithHeaders | { error: number }): void };
|
||||
|
||||
export class FileProtocolHandler extends Disposable {
|
||||
|
||||
private readonly validRoots = TernarySearchTree.forUris<boolean>(() => !isLinux);
|
||||
private readonly validExtensions = new Set(['.png', '.jpg', '.jpeg', '.gif', '.bmp']); // https://github.com/microsoft/vscode/issues/119384
|
||||
|
||||
constructor(
|
||||
@INativeEnvironmentService environmentService: INativeEnvironmentService,
|
||||
@ -85,14 +87,23 @@ export class FileProtocolHandler extends Disposable {
|
||||
const fileUri = URI.parse(request.url);
|
||||
|
||||
// isPreferringBrowserCodeLoad: false
|
||||
// => ensure the file path is in our expected roots
|
||||
if (!isPreferringBrowserCodeLoad) {
|
||||
|
||||
// first check by validRoots
|
||||
if (this.validRoots.findSubstr(fileUri)) {
|
||||
return callback({
|
||||
path: fileUri.fsPath
|
||||
});
|
||||
}
|
||||
|
||||
// then check by validExtensions
|
||||
if (this.validExtensions.has(extname(fileUri))) {
|
||||
return callback({
|
||||
path: fileUri.fsPath
|
||||
});
|
||||
}
|
||||
|
||||
// finally block to load the resource
|
||||
this.logService.error(`${Schemas.file}: Refused to load resource ${fileUri.fsPath} from ${Schemas.file}: protocol (original URL: ${request.url})`);
|
||||
|
||||
return callback({ error: -3 /* ABORTED */ });
|
||||
@ -114,14 +125,24 @@ export class FileProtocolHandler extends Disposable {
|
||||
// ensure the root is valid and properly tell Chrome where the
|
||||
// resource is at.
|
||||
const fileUri = FileAccess.asFileUri(uri);
|
||||
|
||||
// first check by validRoots
|
||||
if (this.validRoots.findSubstr(fileUri)) {
|
||||
return callback({
|
||||
path: fileUri.fsPath
|
||||
});
|
||||
} else {
|
||||
this.logService.error(`${Schemas.vscodeFileResource}: Refused to load resource ${fileUri.fsPath} from ${Schemas.vscodeFileResource}: protocol (original URL: ${request.url})`);
|
||||
|
||||
return callback({ error: -3 /* ABORTED */ });
|
||||
}
|
||||
|
||||
// then check by validExtensions
|
||||
if (this.validExtensions.has(extname(fileUri))) {
|
||||
return callback({
|
||||
path: fileUri.fsPath
|
||||
});
|
||||
}
|
||||
|
||||
// finally block to load the resource
|
||||
this.logService.error(`${Schemas.vscodeFileResource}: Refused to load resource ${fileUri.fsPath} from ${Schemas.vscodeFileResource}: protocol (original URL: ${request.url})`);
|
||||
|
||||
return callback({ error: -3 /* ABORTED */ });
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,12 @@ interface SearchResult {
|
||||
state?: string;
|
||||
}
|
||||
|
||||
enum IssueSource {
|
||||
VSCode = 'vscode',
|
||||
Extension = 'extension',
|
||||
Marketplace = 'marketplace'
|
||||
}
|
||||
|
||||
export interface IssueReporterConfiguration extends IWindowConfiguration {
|
||||
windowId: number;
|
||||
disableExtensions: boolean;
|
||||
@ -53,6 +59,7 @@ export interface IssueReporterConfiguration extends IWindowConfiguration {
|
||||
commit: string | undefined;
|
||||
date: string | undefined;
|
||||
reportIssueUrl: string | undefined;
|
||||
reportMarketplaceIssueUrl: string | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,17 +333,18 @@ export class IssueReporter extends Disposable {
|
||||
hide(problemSourceHelpText);
|
||||
}
|
||||
|
||||
const fileOnExtension = JSON.parse(value);
|
||||
this.issueReporterModel.update({ fileOnExtension: fileOnExtension });
|
||||
let fileOnExtension, fileOnMarketplace = false;
|
||||
if (value === IssueSource.Extension) {
|
||||
fileOnExtension = true;
|
||||
} else if (value === IssueSource.Marketplace) {
|
||||
fileOnMarketplace = true;
|
||||
}
|
||||
|
||||
this.issueReporterModel.update({ fileOnExtension, fileOnMarketplace });
|
||||
this.render();
|
||||
|
||||
const title = (<HTMLInputElement>this.getElementById('issue-title')).value;
|
||||
if (fileOnExtension) {
|
||||
this.searchExtensionIssues(title);
|
||||
} else {
|
||||
const description = this.issueReporterModel.getData().issueDescription;
|
||||
this.searchVSCodeIssues(title, description);
|
||||
}
|
||||
this.searchIssues(title, fileOnExtension, fileOnMarketplace);
|
||||
});
|
||||
|
||||
this.addEventListener('description', 'input', (e: Event) => {
|
||||
@ -353,23 +361,19 @@ export class IssueReporter extends Disposable {
|
||||
this.addEventListener('issue-title', 'input', (e: Event) => {
|
||||
const title = (<HTMLInputElement>e.target).value;
|
||||
const lengthValidationMessage = this.getElementById('issue-title-length-validation-error');
|
||||
if (title && this.getIssueUrlWithTitle(title).length > MAX_URL_LENGTH) {
|
||||
const issueUrl = this.getIssueUrl();
|
||||
if (title && this.getIssueUrlWithTitle(title, issueUrl).length > MAX_URL_LENGTH) {
|
||||
show(lengthValidationMessage);
|
||||
} else {
|
||||
hide(lengthValidationMessage);
|
||||
}
|
||||
|
||||
const fileOnExtension = this.issueReporterModel.fileOnExtension();
|
||||
if (fileOnExtension === undefined) {
|
||||
const issueSource = this.getElementById<HTMLSelectElement>('issue-source');
|
||||
if (!issueSource || issueSource.value === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileOnExtension) {
|
||||
this.searchExtensionIssues(title);
|
||||
} else {
|
||||
const description = this.issueReporterModel.getData().issueDescription;
|
||||
this.searchVSCodeIssues(title, description);
|
||||
}
|
||||
const { fileOnExtension, fileOnMarketplace } = this.issueReporterModel.getData();
|
||||
this.searchIssues(title, fileOnExtension, fileOnMarketplace);
|
||||
});
|
||||
|
||||
this.previewButton.onDidClick(() => this.createIssue());
|
||||
@ -489,6 +493,19 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private searchIssues(title: string, fileOnExtension: boolean | undefined, fileOnMarketplace: boolean | undefined): void {
|
||||
if (fileOnExtension) {
|
||||
return this.searchExtensionIssues(title);
|
||||
}
|
||||
|
||||
if (fileOnMarketplace) {
|
||||
return this.searchMarketplaceIssues(title);
|
||||
}
|
||||
|
||||
const description = this.issueReporterModel.getData().issueDescription;
|
||||
this.searchVSCodeIssues(title, description);
|
||||
}
|
||||
|
||||
private searchExtensionIssues(title: string): void {
|
||||
const url = this.getExtensionGitHubUrl();
|
||||
if (title) {
|
||||
@ -509,6 +526,15 @@ export class IssueReporter extends Disposable {
|
||||
this.clearSearchResults();
|
||||
}
|
||||
|
||||
private searchMarketplaceIssues(title: string): void {
|
||||
if (title) {
|
||||
const gitHubInfo = this.parseGitHubUrl(this.configuration.product.reportMarketplaceIssueUrl!);
|
||||
if (gitHubInfo) {
|
||||
return this.searchGitHub(`${gitHubInfo.owner}/${gitHubInfo.repositoryName}`, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private clearSearchResults(): void {
|
||||
const similarIssues = this.getElementById('similar-issues')!;
|
||||
similarIssues.innerText = '';
|
||||
@ -636,7 +662,7 @@ export class IssueReporter extends Disposable {
|
||||
reset(typeSelect,
|
||||
makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")),
|
||||
makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request")),
|
||||
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue"))
|
||||
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue")),
|
||||
);
|
||||
|
||||
typeSelect.value = issueType.toString();
|
||||
@ -666,19 +692,15 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
sourceSelect.innerText = '';
|
||||
if (issueType === IssueType.FeatureRequest) {
|
||||
sourceSelect.append(...[
|
||||
this.makeOption('', localize('selectSource', "Select source"), true),
|
||||
this.makeOption('false', localize('vscode', "Visual Studio Code"), false),
|
||||
this.makeOption('true', localize('extension', "An extension"), false)
|
||||
]);
|
||||
} else {
|
||||
sourceSelect.append(...[
|
||||
this.makeOption('', localize('selectSource', "Select source"), true),
|
||||
this.makeOption('false', localize('vscode', "Visual Studio Code"), false),
|
||||
this.makeOption('true', localize('extension', "An extension"), false),
|
||||
this.makeOption('', localize('unknown', "Don't Know"), false)
|
||||
]);
|
||||
sourceSelect.append(this.makeOption('', localize('selectSource', "Select source"), true));
|
||||
sourceSelect.append(this.makeOption('vscode', localize('vscode', "Visual Studio Code"), false));
|
||||
sourceSelect.append(this.makeOption('extension', localize('extension', "An extension"), false));
|
||||
if (this.configuration.product.reportMarketplaceIssueUrl) {
|
||||
sourceSelect.append(this.makeOption('marketplace', localize('marketplace', "Extensions marketplace"), false));
|
||||
}
|
||||
|
||||
if (issueType !== IssueType.FeatureRequest) {
|
||||
sourceSelect.append(this.makeOption('', localize('unknown', "Don't know"), false));
|
||||
}
|
||||
|
||||
if (selected !== -1 && selected < sourceSelect.options.length) {
|
||||
@ -691,7 +713,7 @@ export class IssueReporter extends Disposable {
|
||||
|
||||
private renderBlocks(): void {
|
||||
// Depending on Issue Type, we render different blocks and text
|
||||
const { issueType, fileOnExtension } = this.issueReporterModel.getData();
|
||||
const { issueType, fileOnExtension, fileOnMarketplace } = this.issueReporterModel.getData();
|
||||
const blockContainer = this.getElementById('block-container');
|
||||
const systemBlock = document.querySelector('.block-system');
|
||||
const processBlock = document.querySelector('.block-process');
|
||||
@ -715,29 +737,35 @@ export class IssueReporter extends Disposable {
|
||||
hide(extensionSelector);
|
||||
|
||||
if (issueType === IssueType.Bug) {
|
||||
show(blockContainer);
|
||||
show(systemBlock);
|
||||
show(problemSource);
|
||||
show(experimentsBlock);
|
||||
|
||||
if (!fileOnMarketplace) {
|
||||
show(blockContainer);
|
||||
show(systemBlock);
|
||||
show(experimentsBlock);
|
||||
}
|
||||
|
||||
if (fileOnExtension) {
|
||||
show(extensionSelector);
|
||||
} else {
|
||||
} else if (!fileOnMarketplace) {
|
||||
show(extensionsBlock);
|
||||
}
|
||||
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
|
||||
reset(descriptionSubtitle, localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
|
||||
} else if (issueType === IssueType.PerformanceIssue) {
|
||||
show(blockContainer);
|
||||
show(systemBlock);
|
||||
show(processBlock);
|
||||
show(workspaceBlock);
|
||||
show(problemSource);
|
||||
show(experimentsBlock);
|
||||
|
||||
if (!fileOnMarketplace) {
|
||||
show(blockContainer);
|
||||
show(systemBlock);
|
||||
show(processBlock);
|
||||
show(workspaceBlock);
|
||||
show(experimentsBlock);
|
||||
}
|
||||
|
||||
if (fileOnExtension) {
|
||||
show(extensionSelector);
|
||||
} else {
|
||||
} else if (!fileOnMarketplace) {
|
||||
show(extensionsBlock);
|
||||
}
|
||||
|
||||
@ -845,13 +873,13 @@ export class IssueReporter extends Disposable {
|
||||
const issueTitle = (<HTMLInputElement>this.getElementById('issue-title')).value;
|
||||
const issueBody = this.issueReporterModel.serialize();
|
||||
|
||||
const issueUrl = this.issueReporterModel.fileOnExtension() ? this.getExtensionGitHubUrl() : this.configuration.product.reportIssueUrl!;
|
||||
const issueUrl = this.getIssueUrl();
|
||||
const gitHubDetails = this.parseGitHubUrl(issueUrl);
|
||||
if (this.configuration.data.githubAccessToken && gitHubDetails) {
|
||||
return this.submitToGitHub(issueTitle, issueBody, gitHubDetails);
|
||||
}
|
||||
|
||||
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value);
|
||||
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value, issueUrl);
|
||||
let url = baseUrl + `&body=${encodeURIComponent(issueBody)}`;
|
||||
|
||||
if (url.length > MAX_URL_LENGTH) {
|
||||
@ -881,6 +909,14 @@ export class IssueReporter extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private getIssueUrl(): string {
|
||||
return this.issueReporterModel.fileOnExtension()
|
||||
? this.getExtensionGitHubUrl()
|
||||
: this.issueReporterModel.getData().fileOnMarketplace
|
||||
? this.configuration.product.reportMarketplaceIssueUrl!
|
||||
: this.configuration.product.reportIssueUrl!;
|
||||
}
|
||||
|
||||
private parseGitHubUrl(url: string): undefined | { repositoryName: string, owner: string } {
|
||||
// Assumes a GitHub url to a particular repo, https://github.com/repositoryName/owner.
|
||||
// Repository name and owner cannot contain '/'
|
||||
@ -909,16 +945,12 @@ export class IssueReporter extends Disposable {
|
||||
return repositoryUrl;
|
||||
}
|
||||
|
||||
private getIssueUrlWithTitle(issueTitle: string): string {
|
||||
let repositoryUrl = this.configuration.product.reportIssueUrl;
|
||||
private getIssueUrlWithTitle(issueTitle: string, repositoryUrl: string): string {
|
||||
if (this.issueReporterModel.fileOnExtension()) {
|
||||
const extensionGitHubUrl = this.getExtensionGitHubUrl();
|
||||
if (extensionGitHubUrl) {
|
||||
repositoryUrl = extensionGitHubUrl + '/issues/new';
|
||||
}
|
||||
repositoryUrl = repositoryUrl + '/issues/new';
|
||||
}
|
||||
|
||||
const queryStringPrefix = this.configuration.product.reportIssueUrl && this.configuration.product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
const queryStringPrefix = repositoryUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
return `${repositoryUrl}${queryStringPrefix}title=${encodeURIComponent(issueTitle)}`;
|
||||
}
|
||||
|
||||
@ -1156,7 +1188,7 @@ export class IssueReporter extends Disposable {
|
||||
),
|
||||
...extensions.map(extension => $('tr', undefined,
|
||||
$('td', undefined, extension.name),
|
||||
$('td', undefined, extension.publisher.substr(0, 3)),
|
||||
$('td', undefined, extension.publisher?.substr(0, 3) ?? 'N/A'),
|
||||
$('td', undefined, extension.version),
|
||||
))
|
||||
);
|
||||
|
@ -26,6 +26,7 @@ export interface IssueReporterData {
|
||||
enabledNonThemeExtesions?: IssueReporterExtensionData[];
|
||||
extensionsDisabled?: boolean;
|
||||
fileOnExtension?: boolean;
|
||||
fileOnMarketplace?: boolean;
|
||||
selectedExtension?: IssueReporterExtensionData;
|
||||
actualSearchResults?: ISettingSearchResult[];
|
||||
query?: string;
|
||||
@ -110,30 +111,30 @@ ${this.getInfos()}
|
||||
let info = '';
|
||||
|
||||
if (this._data.issueType === IssueType.Bug || this._data.issueType === IssueType.PerformanceIssue) {
|
||||
if (this._data.includeSystemInfo && this._data.systemInfo) {
|
||||
if (!this._data.fileOnMarketplace && this._data.includeSystemInfo && this._data.systemInfo) {
|
||||
info += this.generateSystemInfoMd();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._data.issueType === IssueType.PerformanceIssue) {
|
||||
|
||||
if (this._data.includeProcessInfo) {
|
||||
if (!this._data.fileOnMarketplace && this._data.includeProcessInfo) {
|
||||
info += this.generateProcessInfoMd();
|
||||
}
|
||||
|
||||
if (this._data.includeWorkspaceInfo) {
|
||||
if (!this._data.fileOnMarketplace && this._data.includeWorkspaceInfo) {
|
||||
info += this.generateWorkspaceInfoMd();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._data.issueType === IssueType.Bug || this._data.issueType === IssueType.PerformanceIssue) {
|
||||
if (!this._data.fileOnExtension && this._data.includeExtensions) {
|
||||
if (!this._data.fileOnMarketplace && !this._data.fileOnExtension && this._data.includeExtensions) {
|
||||
info += this.generateExtensionsMd();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._data.issueType === IssueType.Bug || this._data.issueType === IssueType.PerformanceIssue) {
|
||||
if (this._data.includeExperiments && this._data.experimentInfo) {
|
||||
if (!this._data.fileOnMarketplace && this._data.includeExperiments && this._data.experimentInfo) {
|
||||
info += this.generateExperimentsInfoMd();
|
||||
}
|
||||
}
|
||||
@ -238,7 +239,7 @@ ${this._data.experimentInfo}
|
||||
const tableHeader = `Extension|Author (truncated)|Version
|
||||
---|---|---`;
|
||||
const table = this._data.enabledNonThemeExtesions.map(e => {
|
||||
return `${e.name}|${e.publisher.substr(0, 3)}|${e.version}`;
|
||||
return `${e.name}|${e.publisher?.substr(0, 3) ?? 'N/A'}|${e.version}`;
|
||||
}).join('\n');
|
||||
|
||||
return `<details><summary>Extensions (${this._data.enabledNonThemeExtesions.length})</summary>
|
||||
|
@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { homedir } from 'os';
|
||||
import { constants, existsSync, statSync, unlinkSync, chmodSync, truncateSync, readFileSync } from 'fs';
|
||||
import { existsSync, statSync, unlinkSync, chmodSync, truncateSync, readFileSync } from 'fs';
|
||||
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
|
||||
import { buildHelpMessage, buildVersionMessage, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
@ -23,7 +23,6 @@ function shouldSpawnCliProcess(argv: NativeParsedArgs): boolean {
|
||||
return !!argv['install-source']
|
||||
|| !!argv['list-extensions']
|
||||
|| !!argv['install-extension']
|
||||
|| !!argv['install-builtin-extension']
|
||||
|| !!argv['uninstall-extension']
|
||||
|| !!argv['locate-extension']
|
||||
|| !!argv['telemetry'];
|
||||
@ -84,8 +83,8 @@ export async function main(argv: string[]): Promise<any> {
|
||||
let restoreMode = false;
|
||||
if (!!args['file-chmod']) {
|
||||
targetMode = statSync(target).mode;
|
||||
if (!(targetMode & constants.S_IWUSR)) {
|
||||
chmodSync(target, targetMode | constants.S_IWUSR);
|
||||
if (!(targetMode & 0o200 /* File mode indicating writable by owner */)) {
|
||||
chmodSync(target, targetMode | 0o200);
|
||||
restoreMode = true;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IExtensionManagementCLIService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
@ -46,6 +46,7 @@ import { ILocalizationsService } from 'vs/platform/localizations/common/localiza
|
||||
import { setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { cwd } from 'vs/base/common/process';
|
||||
|
||||
class CliMain extends Disposable {
|
||||
|
||||
@ -94,9 +95,12 @@ class CliMain extends Disposable {
|
||||
private async initServices(): Promise<[IInstantiationService, AppInsightsAppender[]]> {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
// Product
|
||||
const productService = { _serviceBrand: undefined, ...product };
|
||||
services.set(IProductService, productService);
|
||||
|
||||
// Environment
|
||||
const environmentService = new NativeEnvironmentService(this.argv);
|
||||
services.set(IEnvironmentService, environmentService);
|
||||
const environmentService = new NativeEnvironmentService(this.argv, productService);
|
||||
services.set(INativeEnvironmentService, environmentService);
|
||||
|
||||
// Init folders
|
||||
@ -131,9 +135,6 @@ class CliMain extends Disposable {
|
||||
const stateService = new StateService(environmentService, logService);
|
||||
services.set(IStateService, stateService);
|
||||
|
||||
// Product
|
||||
services.set(IProductService, { _serviceBrand: undefined, ...product });
|
||||
|
||||
const { appRoot, extensionsPath, extensionDevelopmentLocationURI, isBuilt, installSourcePath } = environmentService;
|
||||
|
||||
// Request
|
||||
@ -149,15 +150,15 @@ class CliMain extends Disposable {
|
||||
|
||||
// Telemetry
|
||||
const appenders: AppInsightsAppender[] = [];
|
||||
if (isBuilt && !extensionDevelopmentLocationURI && !environmentService.disableTelemetry && product.enableTelemetry) {
|
||||
if (product.aiConfig && product.aiConfig.asimovKey) {
|
||||
appenders.push(new AppInsightsAppender('monacoworkbench', null, product.aiConfig.asimovKey));
|
||||
if (isBuilt && !extensionDevelopmentLocationURI && !environmentService.disableTelemetry && productService.enableTelemetry) {
|
||||
if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
||||
appenders.push(new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey));
|
||||
}
|
||||
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appender: combinedAppender(...appenders),
|
||||
sendErrorTelemetry: false,
|
||||
commonProperties: resolveCommonProperties(fileService, release(), process.arch, product.commit, product.version, stateService.getItem('telemetry.machineId'), product.msftInternalDomains, installSourcePath),
|
||||
commonProperties: resolveCommonProperties(fileService, release(), process.arch, productService.commit, productService.version, stateService.getItem('telemetry.machineId'), productService.msftInternalDomains, installSourcePath),
|
||||
piiPaths: [appRoot, extensionsPath]
|
||||
};
|
||||
|
||||
@ -217,7 +218,7 @@ class CliMain extends Disposable {
|
||||
}
|
||||
|
||||
private asExtensionIdOrVSIX(inputs: string[]): (string | URI)[] {
|
||||
return inputs.map(input => /\.vsix$/i.test(input) ? URI.file(isAbsolute(input) ? input : join(process.cwd(), input)) : input);
|
||||
return inputs.map(input => /\.vsix$/i.test(input) ? URI.file(isAbsolute(input) ? input : join(cwd(), input)) : input);
|
||||
}
|
||||
|
||||
private async setInstallSource(environmentService: INativeEnvironmentService, fileService: IFileService, installSource: string): Promise<void> {
|
||||
|
Reference in New Issue
Block a user