mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 09:10:30 -04:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ConfigureLocaleAction } from 'vs/workbench/contrib/localizations/browser/localizationsActions';
|
||||
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { IExtensionManagementService, DidInstallExtensionEvent, IExtensionGalleryService, IGalleryExtension, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { minimumTranslatedStrings } from 'vs/workbench/contrib/localizations/browser/minimalTranslations';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
// Register action to configure locale and related settings
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureLocaleAction, ConfigureLocaleAction.ID, ConfigureLocaleAction.LABEL), 'Configure Display Language');
|
||||
|
||||
export class LocalizationWorkbenchContribution extends Disposable implements IWorkbenchContribution {
|
||||
constructor(
|
||||
@ILocalizationsService private readonly localizationService: ILocalizationsService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
|
||||
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService
|
||||
) {
|
||||
super();
|
||||
this.updateLocaleDefintionSchema();
|
||||
this.checkAndInstall();
|
||||
this._register(this.localizationService.onDidLanguagesChange(() => this.updateLocaleDefintionSchema()));
|
||||
this._register(this.extensionManagementService.onDidInstallExtension(e => this.onDidInstallExtension(e)));
|
||||
}
|
||||
|
||||
private updateLocaleDefintionSchema(): void {
|
||||
this.localizationService.getLanguageIds()
|
||||
.then(languageIds => {
|
||||
let lowercaseLanguageIds: string[] = [];
|
||||
languageIds.forEach((languageId) => {
|
||||
let lowercaseLanguageId = languageId.toLowerCase();
|
||||
if (lowercaseLanguageId !== languageId) {
|
||||
lowercaseLanguageIds.push(lowercaseLanguageId);
|
||||
}
|
||||
});
|
||||
registerLocaleDefinitionSchema([...languageIds, ...lowercaseLanguageIds]);
|
||||
});
|
||||
}
|
||||
|
||||
private onDidInstallExtension(e: DidInstallExtensionEvent): void {
|
||||
const donotAskUpdateKey = 'langugage.update.donotask';
|
||||
if (!this.storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL) && e.local && e.operation === InstallOperation.Install && e.local.manifest.contributes && e.local.manifest.contributes.localizations && e.local.manifest.contributes.localizations.length) {
|
||||
const locale = e.local.manifest.contributes.localizations[0].languageId;
|
||||
if (platform.language !== locale) {
|
||||
const updateAndRestart = platform.locale !== locale;
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
updateAndRestart ? localize('updateLocale', "Would you like to change VS Code's UI language to {0} and restart?", e.local.manifest.contributes.localizations[0].languageName || e.local.manifest.contributes.localizations[0].languageId)
|
||||
: localize('activateLanguagePack', "In order to use VS Code in {0}, VS Code needs to restart.", e.local.manifest.contributes.localizations[0].languageName || e.local.manifest.contributes.localizations[0].languageId),
|
||||
[{
|
||||
label: updateAndRestart ? localize('yes', "Yes") : localize('restart now', "Restart Now"),
|
||||
run: () => {
|
||||
const file = URI.file(join(this.environmentService.appSettingsHome, 'locale.json'));
|
||||
const updatePromise = updateAndRestart ? this.jsonEditingService.write(file, { key: 'locale', value: locale }, true) : Promise.resolve(undefined);
|
||||
updatePromise.then(() => this.windowsService.relaunch({}), e => this.notificationService.error(e));
|
||||
}
|
||||
}, {
|
||||
label: localize('neverAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
|
||||
}],
|
||||
{ sticky: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private checkAndInstall(): void {
|
||||
const language = platform.language;
|
||||
const locale = platform.locale;
|
||||
const languagePackSuggestionIgnoreList = <string[]>JSON.parse(this.storageService.get('extensionsAssistant/languagePackSuggestionIgnore', StorageScope.GLOBAL, '[]'));
|
||||
|
||||
if (!this.galleryService.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!language || !locale || language === 'en' || language.indexOf('en-') === 0) {
|
||||
return;
|
||||
}
|
||||
if (language === locale || languagePackSuggestionIgnoreList.indexOf(language) > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLanguageInstalled(locale)
|
||||
.then(installed => {
|
||||
if (installed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.galleryService.query({ text: `tag:lp-${locale}` }).then(tagResult => {
|
||||
if (tagResult.total === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extensionToInstall = tagResult.total === 1 ? tagResult.firstPage[0] : tagResult.firstPage.filter(e => e.publisher === 'MS-CEINTL' && e.name.indexOf('vscode-language-pack') === 0)[0];
|
||||
const extensionToFetchTranslationsFrom = extensionToInstall || tagResult.firstPage[0];
|
||||
|
||||
if (!extensionToFetchTranslationsFrom.assets.manifest) {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.all([this.galleryService.getManifest(extensionToFetchTranslationsFrom, CancellationToken.None), this.galleryService.getCoreTranslation(extensionToFetchTranslationsFrom, locale)])
|
||||
.then(([manifest, translation]) => {
|
||||
const loc = manifest && manifest.contributes && manifest.contributes.localizations && manifest.contributes.localizations.filter(x => x.languageId.toLowerCase() === locale)[0];
|
||||
const languageName = loc ? (loc.languageName || locale) : locale;
|
||||
const languageDisplayName = loc ? (loc.localizedLanguageName || loc.languageName || locale) : locale;
|
||||
const translationsFromPack = translation && translation.contents ? translation.contents['vs/workbench/contrib/localizations/browser/minimalTranslations'] : {};
|
||||
const promptMessageKey = extensionToInstall ? 'installAndRestartMessage' : 'showLanguagePackExtensions';
|
||||
const useEnglish = !translationsFromPack[promptMessageKey];
|
||||
|
||||
const translations = {};
|
||||
Object.keys(minimumTranslatedStrings).forEach(key => {
|
||||
if (!translationsFromPack[key] || useEnglish) {
|
||||
translations[key] = minimumTranslatedStrings[key].replace('{0}', languageName);
|
||||
} else {
|
||||
translations[key] = `${translationsFromPack[key].replace('{0}', languageDisplayName)} (${minimumTranslatedStrings[key].replace('{0}', languageName)})`;
|
||||
}
|
||||
});
|
||||
|
||||
const logUserReaction = (userReaction: string) => {
|
||||
/* __GDPR__
|
||||
"languagePackSuggestion:popup" : {
|
||||
"userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"language": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('languagePackSuggestion:popup', { userReaction, language });
|
||||
};
|
||||
|
||||
const searchAction = {
|
||||
label: translations['searchMarketplace'],
|
||||
run: () => {
|
||||
logUserReaction('search');
|
||||
this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true)
|
||||
.then(viewlet => viewlet as IExtensionsViewlet)
|
||||
.then(viewlet => {
|
||||
viewlet.search(`tag:lp-${locale}`);
|
||||
viewlet.focus();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const installAndRestartAction = {
|
||||
label: translations['installAndRestart'],
|
||||
run: () => {
|
||||
logUserReaction('installAndRestart');
|
||||
this.installExtension(extensionToInstall).then(() => this.windowsService.relaunch({}));
|
||||
}
|
||||
};
|
||||
|
||||
const promptMessage = translations[promptMessageKey];
|
||||
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
promptMessage,
|
||||
[extensionToInstall ? installAndRestartAction : searchAction,
|
||||
{
|
||||
label: localize('neverAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
languagePackSuggestionIgnoreList.push(language);
|
||||
this.storageService.store(
|
||||
'extensionsAssistant/languagePackSuggestionIgnore',
|
||||
JSON.stringify(languagePackSuggestionIgnoreList),
|
||||
StorageScope.GLOBAL
|
||||
);
|
||||
logUserReaction('neverShowAgain');
|
||||
}
|
||||
}],
|
||||
{
|
||||
onCancel: () => {
|
||||
logUserReaction('cancelled');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private isLanguageInstalled(language: string | undefined): Promise<boolean> {
|
||||
return this.extensionManagementService.getInstalled(ExtensionType.User)
|
||||
.then(installed => installed.some(i =>
|
||||
!!(i.manifest
|
||||
&& i.manifest.contributes
|
||||
&& i.manifest.contributes.localizations
|
||||
&& i.manifest.contributes.localizations.length
|
||||
&& i.manifest.contributes.localizations.some(l => l.languageId.toLowerCase() === language))));
|
||||
}
|
||||
|
||||
private installExtension(extension: IGalleryExtension): Promise<void> {
|
||||
return this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID)
|
||||
.then(viewlet => viewlet as IExtensionsViewlet)
|
||||
.then(viewlet => viewlet.search(`@id:${extension.identifier.id}`))
|
||||
.then(() => this.extensionManagementService.installFromGallery(extension))
|
||||
.then(() => undefined, err => this.notificationService.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
function registerLocaleDefinitionSchema(languages: string[]): void {
|
||||
const localeDefinitionFileSchemaId = 'vscode://schemas/locale';
|
||||
const jsonRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||
// Keep en-US since we generated files with that content.
|
||||
jsonRegistry.registerSchema(localeDefinitionFileSchemaId, {
|
||||
id: localeDefinitionFileSchemaId,
|
||||
allowComments: true,
|
||||
description: 'Locale Definition file',
|
||||
type: 'object',
|
||||
default: {
|
||||
'locale': 'en'
|
||||
},
|
||||
required: ['locale'],
|
||||
properties: {
|
||||
locale: {
|
||||
type: 'string',
|
||||
enum: languages,
|
||||
description: localize('JsonSchema.locale', 'The UI Language to use.')
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registerLocaleDefinitionSchema(platform.language ? [platform.language] : []);
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(LocalizationWorkbenchContribution, LifecyclePhase.Eventually);
|
||||
|
||||
ExtensionsRegistry.registerExtensionPoint({
|
||||
extensionPoint: 'localizations',
|
||||
jsonSchema: {
|
||||
description: localize('vscode.extension.contributes.localizations', "Contributes localizations to the editor"),
|
||||
type: 'array',
|
||||
default: [],
|
||||
items: {
|
||||
type: 'object',
|
||||
required: ['languageId', 'translations'],
|
||||
defaultSnippets: [{ body: { languageId: '', languageName: '', localizedLanguageName: '', translations: [{ id: 'vscode', path: '' }] } }],
|
||||
properties: {
|
||||
languageId: {
|
||||
description: localize('vscode.extension.contributes.localizations.languageId', 'Id of the language into which the display strings are translated.'),
|
||||
type: 'string'
|
||||
},
|
||||
languageName: {
|
||||
description: localize('vscode.extension.contributes.localizations.languageName', 'Name of the language in English.'),
|
||||
type: 'string'
|
||||
},
|
||||
localizedLanguageName: {
|
||||
description: localize('vscode.extension.contributes.localizations.languageNameLocalized', 'Name of the language in contributed language.'),
|
||||
type: 'string'
|
||||
},
|
||||
translations: {
|
||||
description: localize('vscode.extension.contributes.localizations.translations', 'List of translations associated to the language.'),
|
||||
type: 'array',
|
||||
default: [{ id: 'vscode', path: '' }],
|
||||
items: {
|
||||
type: 'object',
|
||||
required: ['id', 'path'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: localize('vscode.extension.contributes.localizations.translations.id', "Id of VS Code or Extension for which this translation is contributed to. Id of VS Code is always `vscode` and of extension should be in format `publisherId.extensionName`."),
|
||||
pattern: '^((vscode)|([a-z0-9A-Z][a-z0-9\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\-A-Z]*))$',
|
||||
patternErrorMessage: localize('vscode.extension.contributes.localizations.translations.id.pattern', "Id should be `vscode` or in format `publisherId.extensionName` for translating VS code or an extension respectively.")
|
||||
},
|
||||
path: {
|
||||
type: 'string',
|
||||
description: localize('vscode.extension.contributes.localizations.translations.path', "A relative path to a file containing translations for the language.")
|
||||
}
|
||||
},
|
||||
defaultSnippets: [{ body: { id: '', path: '' } }],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { language } from 'vs/base/common/platform';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
||||
export class ConfigureLocaleAction extends Action {
|
||||
public static readonly ID = 'workbench.action.configureLocale';
|
||||
public static readonly LABEL = localize('configureLocale', "Configure Display Language");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@ILocalizationsService private readonly localizationService: ILocalizationsService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IDialogService private readonly dialogService: IDialogService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
private async getLanguageOptions(): Promise<IQuickPickItem[]> {
|
||||
// Contributed languages are those installed via extension packs, so does not include English
|
||||
const availableLanguages = ['en', ...await this.localizationService.getLanguageIds(LanguageType.Contributed)];
|
||||
availableLanguages.sort();
|
||||
|
||||
return availableLanguages
|
||||
.map(language => { return { label: language }; })
|
||||
.concat({ label: localize('installAdditionalLanguages', "Install additional languages...") });
|
||||
}
|
||||
|
||||
public async run(event?: any): Promise<void> {
|
||||
const languageOptions = await this.getLanguageOptions();
|
||||
const currentLanguageIndex = firstIndex(languageOptions, l => l.label === language);
|
||||
|
||||
try {
|
||||
const selectedLanguage = await this.quickInputService.pick(languageOptions,
|
||||
{
|
||||
canPickMany: false,
|
||||
placeHolder: localize('chooseDisplayLanguage', "Select Display Language"),
|
||||
activeItem: languageOptions[currentLanguageIndex]
|
||||
});
|
||||
|
||||
if (selectedLanguage === languageOptions[languageOptions.length - 1]) {
|
||||
return this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true)
|
||||
.then((viewlet: IExtensionsViewlet) => {
|
||||
viewlet.search('@category:"language packs"');
|
||||
viewlet.focus();
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedLanguage) {
|
||||
const file = URI.file(join(this.environmentService.appSettingsHome, 'locale.json'));
|
||||
await this.jsonEditingService.write(file, { key: 'locale', value: selectedLanguage.label }, true);
|
||||
const restart = await this.dialogService.confirm({
|
||||
type: 'info',
|
||||
message: localize('relaunchDisplayLanguageMessage', "A restart is required for the change in display language to take effect."),
|
||||
detail: localize('relaunchDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", this.environmentService.appNameLong),
|
||||
primaryButton: localize('restart', "&&Restart")
|
||||
});
|
||||
|
||||
if (restart.confirmed) {
|
||||
this.windowsService.relaunch({});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.notificationService.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
// The strings localized in this file will get pulled into the manifest of the language packs.
|
||||
// So that they are available for VS Code to use without downloading the entire language pack.
|
||||
|
||||
export const minimumTranslatedStrings = {
|
||||
showLanguagePackExtensions: localize('showLanguagePackExtensions', "Search language packs in the Marketplace to change the display language to {0}."),
|
||||
searchMarketplace: localize('searchMarketplace', "Search Marketplace"),
|
||||
installAndRestartMessage: localize('installAndRestartMessage', "Install language pack to change the display language to {0}."),
|
||||
installAndRestart: localize('installAndRestart', "Install and Restart")
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user