From fd85ae4f4a21ef4dc9fcebdb5d89875530fc29c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 11:16:32 +0100 Subject: [PATCH 01/11] Avoid recompiling remote native node modules (#112644) * avoid recompiling remote native node modules fixes #112320 * fix build * update cache * empty * chore: remove rebuild step * chore: update salt * product compile should use same CC CXX Co-authored-by: deepak1556 --- build/.cachesalt | 2 +- .../linux/product-build-linux.yml | 23 ++++++++----------- build/azure-pipelines/product-compile.yml | 12 ++++++++-- build/npm/postinstall.js | 9 +++++++- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/build/.cachesalt b/build/.cachesalt index 2d4b0cf2154..cf053dd3b9b 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2020-12-15T15:34:44.634Z +2020-12-17T07:59:24.060Z diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 5b258aec975..f5f1cd2d384 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -76,12 +76,19 @@ steps: - script: | set -e - if [ -z "$CC" ] || [ -z "$CXX" ] - then + export npm_config_arch=$(NPM_ARCH) + + if [ -z "$CC" ] || [ -z "$CXX" ]; then export CC=$(which gcc-5) export CXX=$(which g++-5) fi - export npm_config_arch=$(NPM_ARCH) + + if [ "$VSCODE_ARCH" == "x64" ]; then + export VSCODE_REMOTE_CC=$(which gcc-4.8) + export VSCODE_REMOTE_CXX=$(which g++-4.8) + export VSCODE_REMOTE_NODE_GYP=$(which node-gyp) + fi + for i in {1..3}; do # try 3 times, for Terrapin yarn --frozen-lockfile && break if [ $i -eq 3 ]; then @@ -103,16 +110,6 @@ steps: vstsFeed: "npm-vscode" condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - - script: | - set -e - export CC=$(which gcc-4.8) - export CXX=$(which g++-4.8) - export npm_config_node_gyp=$(which node-gyp) - cd remote && rm -rf node_modules/ - yarn - displayName: Rebuild remote modules with gcc-4.8 - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - - script: | set -e node build/azure-pipelines/mixin diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index f72cf0151b0..5ef2bfd6ba4 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -70,11 +70,19 @@ steps: - script: | set -e - if [ -z "$CC" ] || [ -z "$CXX" ] - then + export npm_config_arch=$(NPM_ARCH) + + if [ -z "$CC" ] || [ -z "$CXX" ]; then export CC=$(which gcc-5) export CXX=$(which g++-5) fi + + if [ "$VSCODE_ARCH" == "x64" ]; then + export VSCODE_REMOTE_CC=$(which gcc-4.8) + export VSCODE_REMOTE_CXX=$(which g++-4.8) + export VSCODE_REMOTE_NODE_GYP=$(which node-gyp) + fi + for i in {1..3}; do # try 3 times, for Terrapin yarn --frozen-lockfile && break if [ $i -eq 3 ]; then diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index 8f8b0019a77..88d10e2f2ff 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -34,7 +34,14 @@ function yarnInstall(location, opts) { yarnInstall('extensions'); // node modules shared by all extensions if (!(process.platform === 'win32' && (process.arch === 'arm64' || process.env['npm_config_arch'] === 'arm64'))) { - yarnInstall('remote'); // node modules used by vscode server + const env = { ...process.env }; + if (process.env['VSCODE_REMOTE_CC']) { env['CC'] = process.env['VSCODE_REMOTE_CC']; } + if (process.env['VSCODE_REMOTE_CXX']) { env['CXX'] = process.env['VSCODE_REMOTE_CXX']; } + if (process.env['VSCODE_REMOTE_NODE_GYP']) { env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; } + + console.log('remote yarn install env', JSON.stringify(env, undefined, ' ')); + + yarnInstall('remote', { env }); // node modules used by vscode server yarnInstall('remote/web'); // node modules used by vscode web } From 29eb3fbc6a15b38c5f36ad3c2d0f0fa5cb1d6b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 11:31:05 +0100 Subject: [PATCH 02/11] build: tarball compilation output first --- .../darwin/product-build-darwin.yml | 9 +++++++-- .../linux/product-build-alpine.yml | 9 +++++++-- .../azure-pipelines/linux/product-build-linux.yml | 9 +++++++-- build/azure-pipelines/product-compile.yml | 15 ++++++--------- build/azure-pipelines/web/product-build-web.yml | 9 +++++++-- .../azure-pipelines/win32/product-build-win32.yml | 10 ++++++++-- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index d0c44fbe3ab..e8a2e31721c 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -15,10 +15,15 @@ steps: - task: DownloadPipelineArtifact@2 inputs: - artifact: CompilationOutput - path: $(System.DefaultWorkingDirectory) + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output + - script: | set -e cat << EOF > ~/.netrc diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 7cbac392f4b..c04220403f8 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -15,10 +15,15 @@ steps: - task: DownloadPipelineArtifact@2 inputs: - artifact: CompilationOutput - path: $(System.DefaultWorkingDirectory) + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output + - task: Docker@1 displayName: "Pull image" inputs: diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index baa8b2fd73b..9dfc6a964d5 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -15,10 +15,15 @@ steps: - task: DownloadPipelineArtifact@2 inputs: - artifact: CompilationOutput - path: $(System.DefaultWorkingDirectory) + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output + - script: | set -e cat << EOF > ~/.netrc diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 301d5afbf1e..0399b0212e4 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -106,17 +106,14 @@ steps: displayName: Create build condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + # we gotta tarball everything in order to preserve file permissions - script: | set -e - cat << EOF > .artifactignore - **/* - !.build/** - !out-*/** - EOF - displayName: Prepare .artifactignore + tar -czf $(Build.ArtifactStagingDirectory)/compilation.tar.gz .build out-* + displayName: Compress compilation artifact - task: PublishPipelineArtifact@1 inputs: - targetPath: $(System.DefaultWorkingDirectory) - artifactName: CompilationOutput - displayName: Publish compilation output + targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz + artifactName: Compilation + displayName: Publish compilation artifact diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 0276e46fbfe..4ffb93f4571 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -15,10 +15,15 @@ steps: - task: DownloadPipelineArtifact@2 inputs: - artifact: CompilationOutput - path: $(System.DefaultWorkingDirectory) + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output + - script: | set -e cat << EOF > ~/.netrc diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index b396ee44f3e..3af69dbaf50 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -20,10 +20,16 @@ steps: - task: DownloadPipelineArtifact@2 inputs: - artifact: CompilationOutput - path: $(System.DefaultWorkingDirectory) + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz } + displayName: Extract compilation output + - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" From 4f4ba9288514bf7b8ef82e3cd01d2a094454bf27 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 17 Dec 2020 11:45:24 +0100 Subject: [PATCH 03/11] debug console: use menuService #112551 --- .../workbench/contrib/debug/browser/repl.ts | 183 +++++++++++++----- 1 file changed, 130 insertions(+), 53 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index a6335cde82d..5f286e5fabf 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/repl'; import { URI as uri } from 'vs/base/common/uri'; -import { IAction, IActionViewItem, Action, Separator } from 'vs/base/common/actions'; +import { IAction, IActionViewItem } from 'vs/base/common/actions'; import * as dom from 'vs/base/browser/dom'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -26,7 +26,7 @@ import { memoize } from 'vs/base/common/decorators'; import { dispose, IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { IDebugService, DEBUG_SCHEME, CONTEXT_IN_DEBUG_REPL, IDebugSession, State, IReplElement, IDebugConfiguration, REPL_VIEW_ID, CONTEXT_MULTI_SESSION_REPL } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugService, DEBUG_SCHEME, CONTEXT_IN_DEBUG_REPL, IDebugSession, State, IReplElement, IDebugConfiguration, REPL_VIEW_ID, CONTEXT_MULTI_SESSION_REPL, CONTEXT_DEBUG_STATE, getStateLabel } from 'vs/workbench/contrib/debug/common/debug'; import { HistoryNavigator } from 'vs/base/common/history'; import { IHistoryNavigationWidget } from 'vs/base/browser/history'; import { createAndBindHistoryNavigationWidgetScopedContextKeyService } from 'vs/platform/browser/contextScopedHistoryWidget'; @@ -60,7 +60,8 @@ import { EDITOR_FONT_DEFAULTS, EditorOption } from 'vs/editor/common/config/edit import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor/mouseCursor'; import { ReplFilter, ReplFilterState, ReplFilterActionViewItem } from 'vs/workbench/contrib/debug/browser/replFilter'; import { debugConsoleClearAll, debugConsoleEvaluationPrompt } from 'vs/workbench/contrib/debug/browser/debugIcons'; -import { registerAction2, MenuId, MenuItemAction, Action2 } from 'vs/platform/actions/common/actions'; +import { registerAction2, MenuId, Action2, IMenuService, IMenu } from 'vs/platform/actions/common/actions'; +import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; const $ = dom.$; @@ -100,6 +101,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { private filterState: ReplFilterState; private filterActionViewItem: ReplFilterActionViewItem | undefined; private multiSessionRepl: IContextKey; + private menu: IMenu; constructor( options: IViewPaneOptions, @@ -114,14 +116,16 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { @IContextMenuService contextMenuService: IContextMenuService, @IConfigurationService configurationService: IConfigurationService, @ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService, - @IClipboardService private readonly clipboardService: IClipboardService, @IEditorService private readonly editorService: IEditorService, @IKeybindingService keybindingService: IKeybindingService, @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, + @IMenuService menuService: IMenuService ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + this.menu = menuService.createMenu(MenuId.DebugConsoleContext, contextKeyService); + this._register(this.menu); this.history = new HistoryNavigator(JSON.parse(this.storageService.get(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE, '[]')), 50); this.filter = new ReplFilter(); this.filterState = new ReplFilterState(this); @@ -459,6 +463,14 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { this.replInput.layout({ width: width - 30, height: replInputHeight }); } + collapseAll(): void { + this.tree.collapseAll(); + } + + getReplInput(): CodeEditorWidget { + return this.replInput; + } + focus(): void { setTimeout(() => this.replInput.focus(), 0); } @@ -615,44 +627,12 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { private onContextMenu(e: ITreeContextMenuEvent): void { const actions: IAction[] = []; - actions.push(new Action('debug.replCopy', localize('copy', "Copy"), undefined, true, async () => { - const nativeSelection = window.getSelection(); - if (nativeSelection) { - await this.clipboardService.writeText(nativeSelection.toString()); - } - return Promise.resolve(); - })); - actions.push(new Action('workbench.debug.action.copyAll', localize('copyAll', "Copy All"), undefined, true, async () => { - await this.clipboardService.writeText(this.getVisibleContent()); - return Promise.resolve(); - })); - actions.push(new Action('debug.replPaste', localize('paste', "Paste"), undefined, this.debugService.state !== State.Inactive, async () => { - const clipboardText = await this.clipboardService.readText(); - if (clipboardText) { - this.replInput.setValue(this.replInput.getValue().concat(clipboardText)); - this.replInput.focus(); - const model = this.replInput.getModel(); - const lineNumber = model ? model.getLineCount() : 0; - const column = model?.getLineMaxColumn(lineNumber); - if (typeof lineNumber === 'number' && typeof column === 'number') { - this.replInput.setPosition({ lineNumber, column }); - } - } - })); - actions.push(new Separator()); - actions.push(new Action('debug.collapseRepl', localize('collapse', "Collapse All"), undefined, true, () => { - this.tree.collapseAll(); - this.replInput.focus(); - return Promise.resolve(); - })); - actions.push(new Separator()); - actions.push(this.instantiationService.createInstance(MenuItemAction, clearReplCommand, undefined, {})); - + const actionsDisposable = createAndFillInContextMenuActions(this.menu, { arg: e.element, shouldForwardArgs: false }, actions); this.contextMenuService.showContextMenu({ getAnchor: () => e.anchor, getActions: () => actions, getActionsContext: () => e.element, - onHide: () => dispose(actions) + onHide: () => dispose(actionsDisposable) }); } @@ -864,26 +844,123 @@ registerAction2(class extends ViewAction { } }); -const clearReplCommand = { - id: 'workbench.debug.panel.action.clearReplAction', - viewId: REPL_VIEW_ID, - title: localize('clearRepl', "Clear Console"), - f1: true, - icon: debugConsoleClearAll, - menu: { - id: MenuId.ViewTitle, - group: 'navigation', - when: ContextKeyEqualsExpr.create('view', REPL_VIEW_ID), - order: 30 - } -}; registerAction2(class extends ViewAction { constructor() { - super(clearReplCommand); + super({ + id: 'workbench.debug.panel.action.clearReplAction', + viewId: REPL_VIEW_ID, + title: localize('clearRepl', "Clear Console"), + f1: true, + icon: debugConsoleClearAll, + menu: [{ + id: MenuId.ViewTitle, + group: 'navigation', + when: ContextKeyEqualsExpr.create('view', REPL_VIEW_ID), + order: 30 + }, { + id: MenuId.DebugConsoleContext, + group: 'z_commands', + order: 20 + }] + }); } - runInView(_accessor: ServicesAccessor, view: Repl) { + runInView(_accessor: ServicesAccessor, view: Repl): void { view.clearRepl(); aria.status(localize('debugConsoleCleared', "Debug console was cleared")); } }); + +registerAction2(class extends ViewAction { + constructor() { + super({ + id: 'debug.collapseRepl', + title: localize('collapse', "Collapse All"), + viewId: REPL_VIEW_ID, + menu: { + id: MenuId.DebugConsoleContext, + group: 'z_commands', + order: 10 + } + }); + } + + runInView(_accessor: ServicesAccessor, view: Repl): void { + view.collapseAll(); + view.focus(); + } +}); + +registerAction2(class extends ViewAction { + constructor() { + super({ + id: 'debug.replPaste', + title: localize('paste', "Paste"), + viewId: REPL_VIEW_ID, + precondition: CONTEXT_DEBUG_STATE.notEqualsTo(getStateLabel(State.Inactive)), + menu: { + id: MenuId.DebugConsoleContext, + group: '2_cutcopypaste', + order: 30 + } + }); + } + + async runInView(accessor: ServicesAccessor, view: Repl): Promise { + const clipboardService = accessor.get(IClipboardService); + const clipboardText = await clipboardService.readText(); + if (clipboardText) { + const replInput = view.getReplInput(); + replInput.setValue(replInput.getValue().concat(clipboardText)); + view.focus(); + const model = replInput.getModel(); + const lineNumber = model ? model.getLineCount() : 0; + const column = model?.getLineMaxColumn(lineNumber); + if (typeof lineNumber === 'number' && typeof column === 'number') { + replInput.setPosition({ lineNumber, column }); + } + } + } +}); + +registerAction2(class extends ViewAction { + constructor() { + super({ + id: 'workbench.debug.action.copyAll', + title: localize('copyAll', "Copy All"), + viewId: REPL_VIEW_ID, + menu: { + id: MenuId.DebugConsoleContext, + group: '2_cutcopypaste', + order: 20 + } + }); + } + + async runInView(accessor: ServicesAccessor, view: Repl): Promise { + const clipboardService = accessor.get(IClipboardService); + await clipboardService.writeText(view.getVisibleContent()); + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'debug.replCopy', + title: localize('copy', "Copy"), + menu: { + id: MenuId.DebugConsoleContext, + group: '2_cutcopypaste', + order: 10 + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + const clipboardService = accessor.get(IClipboardService); + const nativeSelection = window.getSelection(); + if (nativeSelection) { + await clipboardService.writeText(nativeSelection.toString()); + } + } +}); From 3c4de451b483076e7cac8b6d09f22cd50247a1fa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 17 Dec 2020 11:56:41 +0100 Subject: [PATCH 04/11] ux - distinguish folders from workspaces when opening (#77718) --- .../workspacesHistoryMainService.ts | 60 ++++++++++--------- .../browser/actions/windowActions.ts | 34 +++++++---- .../browser/actions/workspaceActions.ts | 2 +- .../browser/workbench.contribution.ts | 4 +- src/vs/workbench/common/theme.ts | 4 +- .../files/browser/files.contribution.ts | 4 +- .../contrib/files/common/workspaceWatcher.ts | 2 +- .../search/browser/search.contribution.ts | 2 +- .../contrib/search/common/queryBuilder.ts | 2 +- .../tasks/browser/abstractTaskService.ts | 2 +- .../page/browser/welcomePage.contribution.ts | 2 +- .../preferences/browser/preferencesService.ts | 2 +- 12 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts index f174547116c..d334381b586 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { coalesce } from 'vs/base/common/arrays'; import { IStateService } from 'vs/platform/state/node/state'; -import { app, JumpListCategory } from 'electron'; +import { app, JumpListCategory, JumpListItem } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; import { getBaseLabel, getPathLabel, splitName } from 'vs/base/common/labels'; import { Event as CommonEvent, Emitter } from 'vs/base/common/event'; @@ -350,34 +350,40 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa this.removeRecentlyOpened(toRemove); // Add entries - jumpList.push({ - type: 'custom', - name: localize('recentFolders', "Recent Workspaces"), - items: coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { - const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; - const title = recent.label ? splitName(recent.label).name : this.getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); + let hasWorkspaces = false; + const items: JumpListItem[] = coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { + const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; + const title = recent.label ? splitName(recent.label).name : this.getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); - let description; - let args; - if (isSingleFolderWorkspaceIdentifier(workspace)) { - description = localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); - args = `--folder-uri "${workspace.toString()}"`; - } else { - description = localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); - args = `--file-uri "${workspace.configPath.toString()}"`; - } + let description; + let args; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + description = localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); + args = `--folder-uri "${workspace.toString()}"`; + } else { + hasWorkspaces = true; + description = localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); + args = `--file-uri "${workspace.configPath.toString()}"`; + } - return { - type: 'task', - title: title.substr(0, 255), // Windows seems to be picky around the length of entries - description: description.substr(0, 255), // (see https://github.com/microsoft/vscode/issues/111177) - program: process.execPath, - args, - iconPath: 'explorer.exe', // simulate folder icon - iconIndex: 0 - }; - })) - }); + return { + type: 'task', + title: title.substr(0, 255), // Windows seems to be picky around the length of entries + description: description.substr(0, 255), // (see https://github.com/microsoft/vscode/issues/111177) + program: process.execPath, + args, + iconPath: 'explorer.exe', // simulate folder icon + iconIndex: 0 + }; + })); + + if (items.length > 0) { + jumpList.push({ + type: 'custom', + name: hasWorkspaces ? localize('recentFoldersAndWorkspaces', "Recent Folders & Workspaces") : localize('recentFolders', "Recent Folders"), + items + }); + } } // Recent diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index a65ee1a9e52..926527871e8 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -49,12 +49,17 @@ abstract class BaseOpenRecentAction extends Action { tooltip: nls.localize('remove', "Remove from Recently Opened") }; - private readonly dirtyRecentlyOpened: IQuickInputButton = { + private readonly dirtyRecentlyOpenedFolder: IQuickInputButton = { iconClass: 'dirty-workspace ' + Codicon.closeDirty.classNames, - tooltip: nls.localize('dirtyRecentlyOpened', "Workspace With Dirty Files"), + tooltip: nls.localize('dirtyRecentlyOpenedFolder', "Folder With Unsaved Files"), alwaysVisible: true }; + private readonly dirtyRecentlyOpenedWorkspace: IQuickInputButton = { + ...this.dirtyRecentlyOpenedFolder, + tooltip: nls.localize('dirtyRecentlyOpenedWorkspace', "Workspace With Unsaved Files"), + }; + constructor( id: string, label: string, @@ -77,7 +82,9 @@ abstract class BaseOpenRecentAction extends Action { const recentlyOpened = await this.workspacesService.getRecentlyOpened(); const dirtyWorkspacesAndFolders = await this.workspacesService.getDirtyWorkspaces(); - // Identify all folders and workspaces with dirty files + let hasWorkspaces = false; + + // Identify all folders and workspaces with unsaved files const dirtyFolders = new ResourceMap(); const dirtyWorkspaces = new ResourceMap(); for (const dirtyWorkspace of dirtyWorkspacesAndFolders) { @@ -85,6 +92,7 @@ abstract class BaseOpenRecentAction extends Action { dirtyFolders.set(dirtyWorkspace, true); } else { dirtyWorkspaces.set(dirtyWorkspace.configPath, dirtyWorkspace); + hasWorkspaces = true; } } @@ -96,6 +104,7 @@ abstract class BaseOpenRecentAction extends Action { recentFolders.set(recent.folderUri, true); } else { recentWorkspaces.set(recent.workspace.configPath, recent.workspace); + hasWorkspaces = true; } } @@ -124,7 +133,7 @@ abstract class BaseOpenRecentAction extends Action { let keyMods: IKeyMods | undefined; - const workspaceSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('workspaces', "workspaces") }; + const workspaceSeparator: IQuickPickSeparator = { type: 'separator', label: hasWorkspaces ? nls.localize('workspacesAndFolders', "folders & workspaces") : nls.localize('folders', "folders") }; const fileSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('files', "files") }; const picks = [workspaceSeparator, ...workspacePicks, fileSeparator, ...filePicks]; @@ -143,13 +152,14 @@ abstract class BaseOpenRecentAction extends Action { context.removeItem(); } - // Dirty Workspace - else if (context.button === this.dirtyRecentlyOpened) { + // Dirty Folder/Workspace + else if (context.button === this.dirtyRecentlyOpenedFolder || context.button === this.dirtyRecentlyOpenedWorkspace) { + const isDirtyWorkspace = context.button === this.dirtyRecentlyOpenedWorkspace; const result = await this.dialogService.confirm({ type: 'question', - title: nls.localize('dirtyWorkspace', "Workspace with Dirty Files"), - message: nls.localize('dirtyWorkspaceConfirm', "Do you want to open the workspace to review the dirty files?"), - detail: nls.localize('dirtyWorkspaceConfirmDetail', "Workspaces with dirty files cannot be removed until all dirty files have been saved or reverted.") + title: isDirtyWorkspace ? nls.localize('dirtyWorkspace', "Workspace with Unsaved Files") : nls.localize('dirtyFolder', "Folder with Unsaved Files"), + message: isDirtyWorkspace ? nls.localize('dirtyWorkspaceConfirm', "Do you want to open the workspace to review the unsaved files?") : nls.localize('dirtyFolderConfirm', "Do you want to open the folder to review the unsaved files?"), + detail: isDirtyWorkspace ? nls.localize('dirtyWorkspaceConfirmDetail', "Workspaces with unsaved files cannot be removed until all unsaved files have been saved or reverted.") : nls.localize('dirtyFolderConfirmDetail', "Folders with unsaved files cannot be removed until all unsaved files have been saved or reverted.") }); if (result.confirmed) { @@ -170,6 +180,7 @@ abstract class BaseOpenRecentAction extends Action { let iconClasses: string[]; let fullLabel: string | undefined; let resource: URI | undefined; + let isWorkspace = false; // Folder if (isRecentFolder(recent)) { @@ -185,6 +196,7 @@ abstract class BaseOpenRecentAction extends Action { iconClasses = getIconClasses(this.modelService, this.modeService, resource, FileKind.ROOT_FOLDER); openable = { workspaceUri: resource }; fullLabel = recent.label || this.labelService.getWorkspaceLabel(recent.workspace, { verbose: true }); + isWorkspace = true; } // File @@ -200,9 +212,9 @@ abstract class BaseOpenRecentAction extends Action { return { iconClasses, label: name, - ariaLabel: isDirty ? nls.localize('recentDirtyAriaLabel', "{0}, dirty workspace", name) : name, + ariaLabel: isDirty ? isWorkspace ? nls.localize('recentDirtyWorkspaceAriaLabel', "{0}, workspace with unsaved changes", name) : nls.localize('recentDirtyFolderAriaLabel', "{0}, folder with unsaved changes", name) : name, description: parentPath, - buttons: isDirty ? [this.dirtyRecentlyOpened] : [this.removeFromRecentlyOpened], + buttons: isDirty ? [isWorkspace ? this.dirtyRecentlyOpenedWorkspace : this.dirtyRecentlyOpenedFolder] : [this.removeFromRecentlyOpened], openable, resource }; diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index b735737600f..f1cb06bdc53 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -114,7 +114,7 @@ export class CloseWorkspaceAction extends Action { async run(): Promise { if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { - this.notificationService.info(nls.localize('noWorkspaceOpened', "There is currently no workspace opened in this instance to close.")); + this.notificationService.info(nls.localize('noWorkspaceOrFolderOpened', "There is currently no workspace or folder opened in this instance to close.")); return; } diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index d5ea96380a9..270463eed94 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -330,8 +330,8 @@ import { isStandalone } from 'vs/base/browser/browser'; nls.localize('activeFolderLong', "`\${activeFolderLong}`: the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)."), nls.localize('folderName', "`\${folderName}`: name of the workspace folder the file is contained in (e.g. myFolder)."), nls.localize('folderPath', "`\${folderPath}`: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)."), - nls.localize('rootName', "`\${rootName}`: name of the workspace (e.g. myFolder or myWorkspace)."), - nls.localize('rootPath', "`\${rootPath}`: file path of the workspace (e.g. /Users/Development/myWorkspace)."), + nls.localize('rootName', "`\${rootName}`: name of the opened workspace or folder (e.g. myFolder or myWorkspace)."), + nls.localize('rootPath', "`\${rootPath}`: file path of the opened workspace or folder (e.g. /Users/Development/myWorkspace)."), nls.localize('appName', "`\${appName}`: e.g. VS Code."), nls.localize('remoteName', "`\${remoteName}`: e.g. SSH"), nls.localize('dirty', "`\${dirty}`: a dirty indicator if the active editor is dirty."), diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 53f29efbd4c..317cfd2fcd9 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -339,7 +339,7 @@ export const STATUS_BAR_FOREGROUND = registerColor('statusBar.foreground', { dark: '#FFFFFF', light: '#FFFFFF', hc: '#FFFFFF' -}, nls.localize('statusBarForeground', "Status bar foreground color when a workspace is opened. The status bar is shown in the bottom of the window.")); +}, nls.localize('statusBarForeground', "Status bar foreground color when a workspace or folder is opened. The status bar is shown in the bottom of the window.")); export const STATUS_BAR_NO_FOLDER_FOREGROUND = registerColor('statusBar.noFolderForeground', { dark: STATUS_BAR_FOREGROUND, @@ -351,7 +351,7 @@ export const STATUS_BAR_BACKGROUND = registerColor('statusBar.background', { dark: '#007ACC', light: '#007ACC', hc: null -}, nls.localize('statusBarBackground', "Status bar background color when a workspace is opened. The status bar is shown in the bottom of the window.")); +}, nls.localize('statusBarBackground', "Status bar background color when a workspace or folder is opened. The status bar is shown in the bottom of the window.")); export const STATUS_BAR_NO_FOLDER_BACKGROUND = registerColor('statusBar.noFolderBackground', { dark: '#68217A', diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index dfac8e99d7e..addb3572547 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -198,8 +198,8 @@ const hotExitConfiguration: IConfigurationPropertySchema = platform.isNative ? 'default': HotExitConfiguration.ON_EXIT, 'markdownEnumDescriptions': [ nls.localize('hotExit.off', 'Disable hot exit. A prompt will show when attempting to close a window with dirty files.'), - nls.localize('hotExit.onExit', 'Hot exit will be triggered when the last window is closed on Windows/Linux or when the `workbench.action.quit` command is triggered (command palette, keybinding, menu). All windows without folders opened will be restored upon next launch. A list of workspaces with unsaved files can be accessed via `File > Open Recent > More...`'), - nls.localize('hotExit.onExitAndWindowClose', 'Hot exit will be triggered when the last window is closed on Windows/Linux or when the `workbench.action.quit` command is triggered (command palette, keybinding, menu), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. A list of workspaces with unsaved files can be accessed via `File > Open Recent > More...`') + nls.localize('hotExit.onExit', 'Hot exit will be triggered when the last window is closed on Windows/Linux or when the `workbench.action.quit` command is triggered (command palette, keybinding, menu). All windows without folders opened will be restored upon next launch. A list of previously opened windows with unsaved files can be accessed via `File > Open Recent > More...`'), + nls.localize('hotExit.onExitAndWindowClose', 'Hot exit will be triggered when the last window is closed on Windows/Linux or when the `workbench.action.quit` command is triggered (command palette, keybinding, menu), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. A list of previously opened windows with unsaved files can be accessed via `File > Open Recent > More...`') ], 'description': nls.localize('hotExit', "Controls whether unsaved files are remembered between sessions, allowing the save prompt when exiting the editor to be skipped.", HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE) } : { diff --git a/src/vs/workbench/contrib/files/common/workspaceWatcher.ts b/src/vs/workbench/contrib/files/common/workspaceWatcher.ts index 04bfd96daba..1534bdc8608 100644 --- a/src/vs/workbench/contrib/files/common/workspaceWatcher.ts +++ b/src/vs/workbench/contrib/files/common/workspaceWatcher.ts @@ -89,7 +89,7 @@ export class WorkspaceWatcher extends Disposable { if (msg.indexOf('ENOSPC') >= 0) { this.notificationService.prompt( Severity.Warning, - localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."), + localize('enospcError', "Unable to watch for file changes in this large workspace folder. Please follow the instructions link to resolve this issue."), [{ label: localize('learnMore', "Instructions"), run: () => this.openerService.open(URI.parse('https://go.microsoft.com/fwlink/?linkid=867693')) diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index b0ccc88477d..4b99bee21d6 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -840,7 +840,7 @@ configurationRegistry.registerConfiguration({ 'search.seedOnFocus': { type: 'boolean', default: false, - description: nls.localize('search.seedOnFocus', "Update workspace search query to the editor's selected text when focusing the search view. This happens either on click or when triggering the `workbench.views.search.focus` command.") + description: nls.localize('search.seedOnFocus', "Update the search query to the editor's selected text when focusing the search view. This happens either on click or when triggering the `workbench.views.search.focus` command.") }, 'search.searchOnTypeDebouncePeriod': { type: 'number', diff --git a/src/vs/workbench/contrib/search/common/queryBuilder.ts b/src/vs/workbench/contrib/search/common/queryBuilder.ts index 7a99e055745..c7b9d17e10a 100644 --- a/src/vs/workbench/contrib/search/common/queryBuilder.ts +++ b/src/vs/workbench/contrib/search/common/queryBuilder.ts @@ -378,7 +378,7 @@ export class QueryBuilder { }); } else { // No root folder with name - const searchPathNotFoundError = nls.localize('search.noWorkspaceWithName', "No folder in workspace with name: {0}", searchPathRoot); + const searchPathNotFoundError = nls.localize('search.noWorkspaceWithName', "Workspace folder does not exist: {0}", searchPathRoot); throw new Error(searchPathNotFoundError); } } else { diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 436edea336c..474487e5674 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1977,7 +1977,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer await this.computeTasksForSingleConfig(workspaceFolder, configuration.config, runSource, custom, customizedTasks.byIdentifier, TaskConfig.TaskConfigSource.WorkspaceFile); const engine = configuration.config ? TaskConfig.ExecutionEngine.from(configuration.config) : ExecutionEngine.Terminal; if (engine === ExecutionEngine.Process) { - this.notificationService.warn(nls.localize('TaskSystem.versionWorkspaceFile', 'Only tasks version 2.0.0 permitted in .codeworkspace.')); + this.notificationService.warn(nls.localize('TaskSystem.versionWorkspaceFile', 'Only tasks version 2.0.0 permitted in workspace configuration files.')); return this.emptyWorkspaceTaskResults(workspaceFolder); } return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors }; diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts index 1a59cbb17c4..141a92340ec 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts @@ -32,7 +32,7 @@ Registry.as(ConfigurationExtensions.Configuration) localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.none' }, "Start without an editor."), localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.welcomePage' }, "Open the Welcome page (default)."), localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.readme' }, "Open the README when opening a folder that contains one, fallback to 'welcomePage' otherwise."), - localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.newUntitledFile' }, "Open a new untitled file (only applies when opening an empty workspace)."), + localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.newUntitledFile' }, "Open a new untitled file (only applies when opening an empty window)."), localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.welcomePageInEmptyWorkbench' }, "Open the Welcome page when opening an empty workbench."),], ...(product.quality !== 'stable' ? [localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.gettingStarted' }, "Open the Getting Started page (experimental).")] diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 7cf56fbc39d..15078ac482c 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -246,7 +246,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic jsonEditor; if (!this.workspaceSettingsResource) { - this.notificationService.info(nls.localize('openFolderFirst', "Open a folder first to create workspace settings")); + this.notificationService.info(nls.localize('openFolderFirst', "Open a folder or workspace first to create workspace or folder settings.")); return Promise.reject(null); } From af42aa5bff85c4ac21306c41620e4695d5d3c265 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 17 Dec 2020 12:06:39 +0100 Subject: [PATCH 05/11] show diaglog when extensions participate in file operations, have "don't show again" option and command to reset choice, add logging --- .../mainThreadFileSystemEventService.ts | 78 +++++++++++++++++-- .../workbench/api/common/extHost.protocol.ts | 7 +- .../common/extHostFileSystemEventService.ts | 12 +-- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts index 3f84fa0ee3b..83516d21d98 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts @@ -16,10 +16,18 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; import { raceCancellation } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import Severity from 'vs/base/common/severity'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; @extHostCustomer export class MainThreadFileSystemEventService { + static readonly MementoKeyAdditionalEdits = `file.particpants.additionalEdits`; + private readonly _listener = new DisposableStore(); constructor( @@ -27,7 +35,10 @@ export class MainThreadFileSystemEventService { @IFileService fileService: IFileService, @IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService, @IBulkEditService bulkEditService: IBulkEditService, - @IProgressService progressService: IProgressService + @IProgressService progressService: IProgressService, + @IDialogService dialogService: IDialogService, + @IStorageService storageService: IStorageService, + @ILogService logService: ILogService ) { const proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystemEventService); @@ -92,9 +103,55 @@ export class MainThreadFileSystemEventService { return; } - const edit = reviveWorkspaceEditDto2(data); - await bulkEditService.apply(edit, { undoRedoGroupId }); + const needsConfirmation = data.edit.edits.some(edit => edit.metadata?.needsConfirmation); + let showPreview = storageService.getBoolean(MainThreadFileSystemEventService.MementoKeyAdditionalEdits, StorageScope.GLOBAL); + + if (showPreview === undefined) { + // show a user facing message + + let message: string; + if (data.extensionNames.length === 1) { + message = localize('ask.1', "Extension '{0}' wants to make additional edits for this file operation.", data.extensionNames[0]); + } else { + message = localize('ask.N', "{0} extensions want to make additional edits for this file operation.", data.extensionNames.length); + } + + if (needsConfirmation) { + // edit which needs confirmation -> always show dialog + const answer = await dialogService.show(Severity.Info, message, [localize('preview', "Show Preview"), localize('cancel', "Skip additional edits")], { cancelId: 1 }); + showPreview = true; + if (answer.choice === 1) { + // no additional edits wanted + return; + } + } else { + // choice + const answer = await dialogService.show(Severity.Info, message, + [localize('ok', "OK"), localize('preview', "Show Preview"), localize('cancel', "Skip additional edits")], + { + cancelId: 2, + checkbox: { label: localize('again', "Don't ask again") } + } + ); + if (answer.choice === 2) { + // no additional edits wanted, don't persist cancel option + return; + } + showPreview = answer.choice === 1; + if (answer.checkboxChecked /* && answer.choice !== 2 */) { + storageService.store(MainThreadFileSystemEventService.MementoKeyAdditionalEdits, showPreview, StorageScope.GLOBAL, StorageTarget.USER); + } + } + } + + logService.info('[onWill-handler] applying additional workspace edit from extensions', data.extensionNames); + + await bulkEditService.apply( + reviveWorkspaceEditDto2(data.edit), + { undoRedoGroupId, showPreview } + ); } + private _progressLabel(operation: FileOperation): string { switch (operation) { case FileOperation.CREATE: @@ -119,10 +176,21 @@ export class MainThreadFileSystemEventService { dispose(): void { this._listener.dispose(); } - - } +registerAction2(class ResetMemento extends Action2 { + constructor() { + super({ + id: 'files.participants.resetChoice', + title: localize('label', "Reset choice for 'File operation needs preview'"), + f1: true + }); + } + run(accessor: ServicesAccessor) { + accessor.get(IStorageService).remove(MainThreadFileSystemEventService.MementoKeyAdditionalEdits, StorageScope.GLOBAL); + } +}); + Registry.as(Extensions.Configuration).registerConfiguration({ id: 'files', diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 62fab3fac66..77016c491b0 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1157,9 +1157,14 @@ export interface SourceTargetPair { target: UriComponents; } +export interface IWillRunFileOperationParticipation { + edit: IWorkspaceEditDto; + extensionNames: string[] +} + export interface ExtHostFileSystemEventServiceShape { $onFileEvent(events: FileSystemEvents): void; - $onWillRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise; + $onWillRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise; $onDidRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[]): void; } diff --git a/src/vs/workbench/api/common/extHostFileSystemEventService.ts b/src/vs/workbench/api/common/extHostFileSystemEventService.ts index 585056c21b6..6801cf0b3ca 100644 --- a/src/vs/workbench/api/common/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/common/extHostFileSystemEventService.ts @@ -8,7 +8,7 @@ import { IRelativePattern, parse } from 'vs/base/common/glob'; import { URI } from 'vs/base/common/uri'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import type * as vscode from 'vscode'; -import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, SourceTargetPair, IWorkspaceEditDto } from './extHost.protocol'; +import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, SourceTargetPair, IWorkspaceEditDto, IWillRunFileOperationParticipation } from './extHost.protocol'; import * as typeConverter from './extHostTypeConverters'; import { Disposable, WorkspaceEdit } from './extHostTypes'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -177,7 +177,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ }; } - async $onWillRunFileOperation(operation: FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise { + async $onWillRunFileOperation(operation: FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise { switch (operation) { case FileOperation.MOVE: return await this._fireWillEvent(this._onWillRenameFile, { files: files.map(f => ({ oldUri: URI.revive(f.source!), newUri: URI.revive(f.target) })) }, timeout, token); @@ -189,8 +189,9 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ return undefined; } - private async _fireWillEvent(emitter: AsyncEmitter, data: Omit, timeout: number, token: CancellationToken): Promise { + private async _fireWillEvent(emitter: AsyncEmitter, data: Omit, timeout: number, token: CancellationToken): Promise { + const extensionNames = new Set(); const edits: WorkspaceEdit[] = []; await emitter.fireAsync(data, token, async (thenable, listener) => { @@ -199,10 +200,11 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ const result = await Promise.resolve(thenable); if (result instanceof WorkspaceEdit) { edits.push(result); + extensionNames.add((>listener).extension.displayName ?? (>listener).extension.identifier.value); } if (Date.now() - now > timeout) { - this._logService.warn('SLOW file-participant', (>listener).extension?.identifier); + this._logService.warn('SLOW file-participant', (>listener).extension.identifier); } }); @@ -220,6 +222,6 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ let { edits } = typeConverter.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors); dto.edits = dto.edits.concat(edits); } - return dto; + return { edit: dto, extensionNames: Array.from(extensionNames) }; } } From b7aa0f7d406430a388e02b011222cb8e0ea565de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 12:20:41 +0100 Subject: [PATCH 06/11] fix template usage --- build/azure-pipelines/product-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index f3c9fa4b4dc..13b56bd0733 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -8,8 +8,8 @@ schedules: - master variables: - ? ${{ if and(eq(variables['VSCODE_PUBLISH'], ''), or(eq(variables['Build.Reason'], 'IndividualCI'), eq(variables['Build.Reason'], 'BatchedCI'))) }} - : VSCODE_PUBLISH: "false" + ${{ if and(eq(variables['VSCODE_PUBLISH'], ''), or(eq(variables['Build.Reason'], 'IndividualCI'), eq(variables['Build.Reason'], 'BatchedCI'))) }}: + VSCODE_PUBLISH: "false" resources: containers: From d07422ec3015a4a2e1b3bfd22538dd293b67fe3c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 17 Dec 2020 12:37:05 +0100 Subject: [PATCH 07/11] rename workspace action for duplicate --- src/vs/workbench/browser/actions/workspaceActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index f1cb06bdc53..ea67ce4c511 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -225,7 +225,7 @@ export class SaveWorkspaceAsAction extends Action { export class DuplicateWorkspaceInNewWindowAction extends Action { static readonly ID = 'workbench.action.duplicateWorkspaceInNewWindow'; - static readonly LABEL = nls.localize('duplicateWorkspaceInNewWindow', "Duplicate Workspace in New Window"); + static readonly LABEL = nls.localize('duplicateWorkspaceInNewWindow', "Duplicate As Workspace in New Window"); constructor( id: string, @@ -259,7 +259,7 @@ registry.registerWorkbenchAction(SyncActionDescriptor.from(AddRootFolderAction), registry.registerWorkbenchAction(SyncActionDescriptor.from(GlobalRemoveRootFolderAction), 'Workspaces: Remove Folder from Workspace...', workspacesCategory); registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseWorkspaceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory, EmptyWorkspaceSupportContext); registry.registerWorkbenchAction(SyncActionDescriptor.from(SaveWorkspaceAsAction), 'Workspaces: Save Workspace As...', workspacesCategory, EmptyWorkspaceSupportContext); -registry.registerWorkbenchAction(SyncActionDescriptor.from(DuplicateWorkspaceInNewWindowAction), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory); +registry.registerWorkbenchAction(SyncActionDescriptor.from(DuplicateWorkspaceInNewWindowAction), 'Workspaces: Duplicate As Workspace in New Window', workspacesCategory); // --- Menu Registration From 499623731317f03e518085b6813f213d650e9fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 12:40:59 +0100 Subject: [PATCH 08/11] fix tar --- build/azure-pipelines/win32/product-build-win32.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 3af69dbaf50..04800ad63b1 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -27,7 +27,7 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz } + exec { tar --force-local -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz } displayName: Extract compilation output - powershell: | From d981cf5b81b061f74a1d5c8c34f30812e5a148db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 13:14:52 +0100 Subject: [PATCH 09/11] Revert "Revert "Merge branch 'joao/build/compile-artifact'"" This reverts commit c8aaeb75137b8ec057d2676a22f7273a7a6a34a2. --- .../darwin/product-build-darwin.yml | 29 +++------- .../linux/product-build-alpine.yml | 29 +++------- .../linux/product-build-linux.yml | 28 +++------- build/azure-pipelines/product-compile.yml | 56 +++++++------------ build/azure-pipelines/product-hygiene.yml | 7 +-- .../azure-pipelines/web/product-build-web.yml | 28 +++------- .../win32/product-build-win32.yml | 28 +++------- 7 files changed, 57 insertions(+), 148 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 9013e5f3409..0203a1c0182 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -1,25 +1,4 @@ steps: - - script: | - mkdir -p .build - echo -n $BUILD_SOURCEVERSION > .build/commit - echo -n $VSCODE_QUALITY > .build/quality - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flags - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - - - script: | - set -e - exit 1 - displayName: Check RestoreCache - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -34,9 +13,14 @@ steps: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode + - task: DownloadPipelineArtifact@2 + inputs: + artifact: CompilationOutput + path: $(System.DefaultWorkingDirectory) + displayName: Download compilation output + - script: | set -e - cat << EOF > ~/.netrc machine github.com login vscode @@ -66,6 +50,7 @@ steps: - script: | echo -n $(VSCODE_ARCH) > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 463ead96353..7cbac392f4b 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -1,25 +1,4 @@ steps: - - script: | - mkdir -p .build - echo -n $BUILD_SOURCEVERSION > .build/commit - echo -n $VSCODE_QUALITY > .build/quality - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flags - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - - - script: | - set -e - exit 1 - displayName: Check RestoreCache - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -34,6 +13,12 @@ steps: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode + - task: DownloadPipelineArtifact@2 + inputs: + artifact: CompilationOutput + path: $(System.DefaultWorkingDirectory) + displayName: Download compilation output + - task: Docker@1 displayName: "Pull image" inputs: @@ -45,7 +30,6 @@ steps: - script: | set -e - cat << EOF > ~/.netrc machine github.com login vscode @@ -69,6 +53,7 @@ steps: - script: | echo -n "alpine" > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index f5f1cd2d384..f0b97ab4c29 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -1,25 +1,4 @@ steps: - - script: | - mkdir -p .build - echo -n $BUILD_SOURCEVERSION > .build/commit - echo -n $VSCODE_QUALITY > .build/quality - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flags - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - - - script: | - set -e - exit 1 - displayName: Check RestoreCache - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -34,6 +13,12 @@ steps: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode + - task: DownloadPipelineArtifact@2 + inputs: + artifact: CompilationOutput + path: $(System.DefaultWorkingDirectory) + displayName: Download compilation output + - script: | set -e cat << EOF > ~/.netrc @@ -59,6 +44,7 @@ steps: - script: | echo -n $(VSCODE_ARCH) > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 5ef2bfd6ba4..17583e21087 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -1,36 +1,17 @@ steps: - - script: | - mkdir -p .build - echo -n $BUILD_SOURCEVERSION > .build/commit - echo -n $VSCODE_QUALITY > .build/quality - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flag - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - dryRun: true - - task: NodeTool@0 inputs: versionSpec: "12.18.3" - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: versionSpec: "1.x" - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - task: AzureKeyVault@1 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | set -e @@ -43,22 +24,22 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" displayName: Prepare tooling - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | set -e git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") displayName: Merge distro - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | npx https://aka.ms/enablesecurefeed standAlone displayName: Switch to Terrapin packages timeoutInMinutes: 5 - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true'), eq(variables['ENABLE_TERRAPIN'], 'true')) + condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true')) - script: | + mkdir -p .build echo -n $(VSCODE_ARCH) > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 @@ -66,7 +47,6 @@ steps: keyfile: ".build/arch, .build/terrapin, build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock" targetfolder: "**/node_modules, !**/node_modules/**/node_modules" vstsFeed: "npm-vscode" - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | set -e @@ -95,21 +75,20 @@ steps: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 displayName: Install dependencies - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true'), ne(variables['CacheRestored'], 'true')) + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: keyfile: ".build/arch, .build/terrapin, build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock" targetfolder: "**/node_modules, !**/node_modules/**/node_modules" vstsFeed: "npm-vscode" - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true'), ne(variables['CacheRestored'], 'true')) + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) # Mixin must run before optimize, because the CSS loader will inline small SVGs - script: | set -e node build/azure-pipelines/mixin displayName: Mix in quality - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | set -e @@ -119,14 +98,13 @@ steps: yarn gulp minify-vscode-reh yarn gulp minify-vscode-reh-web displayName: Compile - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - script: | set -e AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \ node build/azure-pipelines/upload-sourcemaps displayName: Upload sourcemaps - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true'), ne(variables['VSCODE_PUBLISH'], 'false')) + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - script: | set -e @@ -134,13 +112,19 @@ steps: AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ node build/azure-pipelines/common/createBuild.js $VERSION displayName: Create build - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true'), ne(variables['VSCODE_PUBLISH'], 'false')) + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + - script: | + set -e + cat << EOF > .artifactignore + **/* + !.build/** + !out-*/** + EOF + displayName: Prepare .artifactignore + + - task: PublishPipelineArtifact@1 inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) + targetPath: $(System.DefaultWorkingDirectory) + artifactName: CompilationOutput + displayName: Publish compilation output diff --git a/build/azure-pipelines/product-hygiene.yml b/build/azure-pipelines/product-hygiene.yml index df73b27b6a6..4f634314b4d 100644 --- a/build/azure-pipelines/product-hygiene.yml +++ b/build/azure-pipelines/product-hygiene.yml @@ -1,9 +1,4 @@ steps: - - script: | - mkdir -p .build - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flag - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -36,7 +31,9 @@ steps: displayName: Merge distro - script: | + mkdir -p .build echo -n $(VSCODE_ARCH) > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 5d92bdb4025..0276e46fbfe 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -1,25 +1,4 @@ steps: - - script: | - mkdir -p .build - echo -n $BUILD_SOURCEVERSION > .build/commit - echo -n $VSCODE_QUALITY > .build/quality - echo -n $ENABLE_TERRAPIN > .build/terrapin - displayName: Prepare compilation cache flag - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - - - script: | - set -e - exit 1 - displayName: Check RestoreCache - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -34,6 +13,12 @@ steps: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode + - task: DownloadPipelineArtifact@2 + inputs: + artifact: CompilationOutput + path: $(System.DefaultWorkingDirectory) + displayName: Download compilation output + - script: | set -e cat << EOF > ~/.netrc @@ -59,6 +44,7 @@ steps: - script: | echo -n "web" > .build/arch + echo -n $ENABLE_TERRAPIN > .build/terrapin displayName: Prepare yarn cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 97a7e790b87..b396ee44f3e 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -1,25 +1,4 @@ steps: - - powershell: | - mkdir .build -ea 0 - "$env:BUILD_SOURCEVERSION" | Out-File -Encoding ascii -NoNewLine .build\commit - "$env:VSCODE_QUALITY" | Out-File -Encoding ascii -NoNewLine .build\quality - "$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin - displayName: Prepare compilation cache flags - - - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 - inputs: - keyfile: "build/.cachesalt, .build/commit, .build/quality, .build/terrapin" - targetfolder: ".build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min" - vstsFeed: "npm-vscode" - platformIndependent: true - alias: "Compilation" - - - powershell: | - $ErrorActionPreference = "Stop" - exit 1 - displayName: Check RestoreCache - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) - - task: NodeTool@0 inputs: versionSpec: "12.18.3" @@ -39,6 +18,12 @@ steps: azureSubscription: "vscode-builds-subscription" KeyVaultName: vscode + - task: DownloadPipelineArtifact@2 + inputs: + artifact: CompilationOutput + path: $(System.DefaultWorkingDirectory) + displayName: Download compilation output + - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" @@ -62,6 +47,7 @@ steps: - powershell: | "$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch + "$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin displayName: Prepare yarn cache flags - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 From 0e68af72989eca26383062624a91e23491682ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 17 Dec 2020 13:20:24 +0100 Subject: [PATCH 10/11] fixes #112603 --- src/vs/workbench/contrib/scm/browser/activity.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/activity.ts b/src/vs/workbench/contrib/scm/browser/activity.ts index 87764bb2879..2c8425de65e 100644 --- a/src/vs/workbench/contrib/scm/browser/activity.ts +++ b/src/vs/workbench/contrib/scm/browser/activity.ts @@ -164,8 +164,6 @@ export class SCMStatusController implements IWorkbenchContribution { } private renderActivityCount(): void { - this.badgeDisposable.clear(); - const countBadgeType = this.configurationService.getValue<'all' | 'focused' | 'off'>('scm.countBadge'); let count = 0; @@ -180,7 +178,7 @@ export class SCMStatusController implements IWorkbenchContribution { const badge = new NumberBadge(count, num => localize('scmPendingChangesBadge', '{0} pending changes', num)); this.badgeDisposable.value = this.activityService.showViewActivity(VIEW_PANE_ID, { badge, clazz: 'scm-viewlet-label' }); } else { - this.badgeDisposable.clear(); + this.badgeDisposable.value = undefined; } } From 4fae21b64d3e69f4919da43115b00b7958ebbae0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 17 Dec 2020 14:01:40 +0100 Subject: [PATCH 11/11] don't show dialogs when running tests --- .../api/browser/mainThreadFileSystemEventService.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts index 83516d21d98..e2c55d88adf 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts @@ -22,6 +22,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @extHostCustomer export class MainThreadFileSystemEventService { @@ -38,7 +39,8 @@ export class MainThreadFileSystemEventService { @IProgressService progressService: IProgressService, @IDialogService dialogService: IDialogService, @IStorageService storageService: IStorageService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @IEnvironmentService envService: IEnvironmentService ) { const proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystemEventService); @@ -106,6 +108,11 @@ export class MainThreadFileSystemEventService { const needsConfirmation = data.edit.edits.some(edit => edit.metadata?.needsConfirmation); let showPreview = storageService.getBoolean(MainThreadFileSystemEventService.MementoKeyAdditionalEdits, StorageScope.GLOBAL); + if (envService.extensionTestsLocationURI) { + // don't show dialog in tests + showPreview = false; + } + if (showPreview === undefined) { // show a user facing message