diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1c9c3..d6a16eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Added -- Adds the ability to sync between a GitKraken Cloud workspace and its associated VS Code workspace - - Adds options when creating the VS Code workspace to sync when repositories are added to its associated GitKraken Cloud workspace: `Always`, `Never`, and `Ask every time` +- Adds the ability to link a GitKraken Cloud workspace with its associated VS Code workspace + - Adds options when creating the VS Code workspace to automatically add repositories that were added to its associated GitKraken Cloud workspace: `Enable`, `Disable`, and `Ask every time` - Adds a new command `Open VS Code Workspace` to open the existing VS Code workspace associated with a GitKraken Cloud workspace. This command replaces the existing `Create VS Code Workspace` command for that workspace - When a VS Code workspace associated with a GitKraken Cloud workspace is opened, the associated GitKraken Cloud workspace is highlighted in green in the _GitKraken Workspaces_ view - Adds support for deep links to comparisons. Deep links of this format take the form `vscode://eamodio.gitlens/r/{repoId}/compare/{ref1}[..|...]{ref2}?[url={remoteUrl}|path={repoPath}]` and open the comparison in the _Search & Compare_ view diff --git a/package.json b/package.json index f0b8298..a12d30a 100644 --- a/package.json +++ b/package.json @@ -6960,8 +6960,8 @@ "icon": "$(window)" }, { - "command": "gitlens.views.workspaces.changeLocalSync", - "title": "Change Workspace Sync Setting...", + "command": "gitlens.views.workspaces.changeAutoAddSetting", + "title": "Change Workspace Auto-Add Setting...", "category": "GitLens" }, { @@ -9523,7 +9523,7 @@ "when": "false" }, { - "command": "gitlens.views.workspaces.changeLocalSync", + "command": "gitlens.views.workspaces.changeAutoAddSetting", "when": "false" }, { @@ -11191,7 +11191,7 @@ "group": "2_gitlens_quickopen@5" }, { - "command": "gitlens.views.workspaces.changeLocalSync", + "command": "gitlens.views.workspaces.changeAutoAddSetting", "when": "viewItem =~ /(gitlens:workspace\\b(?=.*?\\b\\+(cloud|local)\\b)(?=.*?\\b\\+current\\b)(?=.*?\\b\\+hasPath\\b)|gitlens:repositories\\b(?=.*?\\b\\+synced\\b))/", "group": "2_gitlens_quickopen@6" }, diff --git a/src/constants.ts b/src/constants.ts index 10d258a..59ae310 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -404,7 +404,7 @@ export type TreeViewCommands = `gitlens.views.${ | 'copy' | 'refresh' | 'addRepos' - | 'changeLocalSync' + | 'changeAutoAddSetting' | 'convert' | 'create' | 'createLocal' diff --git a/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts b/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts index ac1ae31..e88456b 100644 --- a/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts +++ b/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts @@ -1,5 +1,5 @@ import { Uri } from 'vscode'; -import type { LocalWorkspaceFileData, WorkspaceSyncSetting } from '../../../plus/workspaces/models'; +import type { LocalWorkspaceFileData, WorkspaceAutoAddSetting } from '../../../plus/workspaces/models'; import type { WorkspacesPathMappingProvider } from '../../../plus/workspaces/workspacesPathMappingProvider'; export class WorkspacesWebPathMappingProvider implements WorkspacesPathMappingProvider { @@ -35,14 +35,14 @@ export class WorkspacesWebPathMappingProvider implements WorkspacesPathMappingPr async writeCodeWorkspaceFile( _uri: Uri, _workspaceRepoFilePaths: string[], - _options?: { workspaceId?: string; workspaceSyncSetting?: WorkspaceSyncSetting }, + _options?: { workspaceId?: string; workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise { return false; } async updateCodeWorkspaceFileSettings( _uri: Uri, - _options: { workspaceSyncSetting?: WorkspaceSyncSetting }, + _options: { workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise { return false; } diff --git a/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts b/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts index cb7aa9b..feff0a7 100644 --- a/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts +++ b/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts @@ -3,7 +3,7 @@ import type { CloudWorkspacesPathMap, CodeWorkspaceFileContents, LocalWorkspaceFileData, - WorkspaceSyncSetting, + WorkspaceAutoAddSetting, } from '../../../plus/workspaces/models'; import type { WorkspacesPathMappingProvider } from '../../../plus/workspaces/workspacesPathMappingProvider'; import { Logger } from '../../../system/logger'; @@ -178,7 +178,7 @@ export class WorkspacesLocalPathMappingProvider implements WorkspacesPathMapping async writeCodeWorkspaceFile( uri: Uri, workspaceRepoFilePaths: string[], - options?: { workspaceId?: string; workspaceSyncSetting?: WorkspaceSyncSetting }, + options?: { workspaceId?: string; workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise { let codeWorkspaceFileContents: CodeWorkspaceFileContents; let data; @@ -194,8 +194,8 @@ export class WorkspacesLocalPathMappingProvider implements WorkspacesPathMapping codeWorkspaceFileContents.settings['gitkraken.workspaceId'] = options.workspaceId; } - if (options?.workspaceSyncSetting != null) { - codeWorkspaceFileContents.settings['gitkraken.workspaceSyncSetting'] = options.workspaceSyncSetting; + if (options?.workspaceAutoAddSetting != null) { + codeWorkspaceFileContents.settings['gitkraken.workspaceAutoAddSetting'] = options.workspaceAutoAddSetting; } const outputData = new Uint8Array(Buffer.from(JSON.stringify(codeWorkspaceFileContents))); @@ -214,7 +214,7 @@ export class WorkspacesLocalPathMappingProvider implements WorkspacesPathMapping async updateCodeWorkspaceFileSettings( uri: Uri, - options: { workspaceSyncSetting?: WorkspaceSyncSetting }, + options: { workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise { let codeWorkspaceFileContents: CodeWorkspaceFileContents; let data; @@ -225,8 +225,8 @@ export class WorkspacesLocalPathMappingProvider implements WorkspacesPathMapping return false; } - if (options.workspaceSyncSetting != null) { - codeWorkspaceFileContents.settings['gitkraken.workspaceSyncSetting'] = options.workspaceSyncSetting; + if (options.workspaceAutoAddSetting != null) { + codeWorkspaceFileContents.settings['gitkraken.workspaceAutoAddSetting'] = options.workspaceAutoAddSetting; } const outputData = new Uint8Array(Buffer.from(JSON.stringify(codeWorkspaceFileContents))); diff --git a/src/plus/workspaces/models.ts b/src/plus/workspaces/models.ts index d9ce4f9..cb0f433 100644 --- a/src/plus/workspaces/models.ts +++ b/src/plus/workspaces/models.ts @@ -7,10 +7,10 @@ export enum WorkspaceType { Cloud = 'cloud', } -export enum WorkspaceSyncSetting { - Never = 'never', - Always = 'always', - Ask = 'ask', +export enum WorkspaceAutoAddSetting { + Disabled = 'disabled', + Enabled = 'enabled', + Prompt = 'prompt', } export type CodeWorkspaceFileContents = { diff --git a/src/plus/workspaces/workspacesPathMappingProvider.ts b/src/plus/workspaces/workspacesPathMappingProvider.ts index b61c6b6..b7c185f 100644 --- a/src/plus/workspaces/workspacesPathMappingProvider.ts +++ b/src/plus/workspaces/workspacesPathMappingProvider.ts @@ -1,5 +1,5 @@ import type { Uri } from 'vscode'; -import type { LocalWorkspaceFileData, WorkspaceSyncSetting } from './models'; +import type { LocalWorkspaceFileData, WorkspaceAutoAddSetting } from './models'; export interface WorkspacesPathMappingProvider { getCloudWorkspaceRepoPath(cloudWorkspaceId: string, repoId: string): Promise; @@ -26,11 +26,11 @@ export interface WorkspacesPathMappingProvider { writeCodeWorkspaceFile( uri: Uri, workspaceRepoFilePaths: string[], - options?: { workspaceId?: string; workspaceSyncSetting?: WorkspaceSyncSetting }, + options?: { workspaceId?: string; workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise; updateCodeWorkspaceFileSettings( uri: Uri, - options: { workspaceSyncSetting?: WorkspaceSyncSetting }, + options: { workspaceAutoAddSetting?: WorkspaceAutoAddSetting }, ): Promise; } diff --git a/src/plus/workspaces/workspacesService.ts b/src/plus/workspaces/workspacesService.ts index 3a49e56..d628315 100644 --- a/src/plus/workspaces/workspacesService.ts +++ b/src/plus/workspaces/workspacesService.ts @@ -32,7 +32,7 @@ import { cloudWorkspaceProviderTypeToRemoteProviderId, LocalWorkspace, WorkspaceAddRepositoriesChoice, - WorkspaceSyncSetting, + WorkspaceAutoAddSetting, } from './models'; import { WorkspacesApi } from './workspacesApi'; import type { WorkspacesPathMappingProvider } from './workspacesPathMappingProvider'; @@ -49,7 +49,7 @@ export class WorkspacesService implements Disposable { private _workspacesApi: WorkspacesApi; private _workspacesPathProvider: WorkspacesPathMappingProvider; private _currentWorkspaceId: string | undefined; - private _currentWorkspaceSyncSetting: WorkspaceSyncSetting = WorkspaceSyncSetting.Never; + private _currentWorkspaceAutoAddSetting: WorkspaceAutoAddSetting = WorkspaceAutoAddSetting.Disabled; constructor( private readonly container: Container, @@ -58,9 +58,9 @@ export class WorkspacesService implements Disposable { this._workspacesApi = new WorkspacesApi(this.container, this.server); this._workspacesPathProvider = getSupportedWorkspacesPathMappingProvider(); this._currentWorkspaceId = workspace.getConfiguration('gitkraken')?.get('workspaceId'); - this._currentWorkspaceSyncSetting = - workspace.getConfiguration('gitkraken')?.get('workspaceSyncSetting') ?? - WorkspaceSyncSetting.Never; + this._currentWorkspaceAutoAddSetting = + workspace.getConfiguration('gitkraken')?.get('workspaceAutoAddSetting') ?? + WorkspaceAutoAddSetting.Disabled; this._disposable = Disposable.from(container.subscription.onDidChange(this.onSubscriptionChanged, this)); } @@ -213,7 +213,7 @@ export class WorkspacesService implements Disposable { ); if (currentWorkspace != null) { - await this.syncCurrentWorkspace(currentWorkspace); + await this.addMissingCurrentWorkspaceRepos(currentWorkspace); } getWorkspacesResponse.cloudWorkspaces = this._cloudWorkspaces ?? []; @@ -229,8 +229,8 @@ export class WorkspacesService implements Disposable { return descriptors?.map(d => ({ ...d, workspaceId: workspaceId })) ?? []; } - async syncCurrentWorkspace(workspace: CloudWorkspace | LocalWorkspace): Promise { - if (this._currentWorkspaceSyncSetting === WorkspaceSyncSetting.Never || !workspace.current) return; + async addMissingCurrentWorkspaceRepos(workspace: CloudWorkspace | LocalWorkspace): Promise { + if (this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Disabled || !workspace.current) return; if (!(await workspace.getRepositoryDescriptors())?.length) return; @@ -242,7 +242,7 @@ export class WorkspacesService implements Disposable { const repositoriesToAdd = repositories.filter(r => !currentWorkspaceRepositoryIdMap.has(r.id)); if (repositoriesToAdd.length === 0) return; let chosenRepoPaths: string[] = []; - if (this._currentWorkspaceSyncSetting === WorkspaceSyncSetting.Ask) { + if (this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Prompt) { const addChoice = await window.showInformationMessage( 'New repositories found in the cloud workspace matching this workspace. Would you like to add them?', { modal: true }, @@ -1010,12 +1010,12 @@ export class WorkspacesService implements Disposable { if (newWorkspaceUri == null) return; - const newWorkspaceSyncSetting = await window.showInformationMessage( - 'Would you like to sync your new workspace file with its cloud workspace?', + const newWorkspaceAutoAddSetting = await window.showInformationMessage( + 'Would you like to enable auto-add for this workspace? This will automatically add new repositories from the cloud workspace to this workspace when it is opened.', { modal: true }, - { title: 'Always', option: WorkspaceSyncSetting.Always }, - { title: 'Never', option: WorkspaceSyncSetting.Never }, - { title: 'Ask every time', option: WorkspaceSyncSetting.Ask }, + { title: 'Enable', option: WorkspaceAutoAddSetting.Enabled }, + { title: 'Disable', option: WorkspaceAutoAddSetting.Disabled }, + { title: 'Ask every time', option: WorkspaceAutoAddSetting.Prompt }, ); const created = await this._workspacesPathProvider.writeCodeWorkspaceFile( @@ -1023,7 +1023,7 @@ export class WorkspacesService implements Disposable { workspaceFolderPaths, { workspaceId: workspaceId, - workspaceSyncSetting: newWorkspaceSyncSetting?.option ?? WorkspaceSyncSetting.Never, + workspaceAutoAddSetting: newWorkspaceAutoAddSetting?.option ?? WorkspaceAutoAddSetting.Disabled, }, ); @@ -1047,39 +1047,58 @@ export class WorkspacesService implements Disposable { void this.openCodeWorkspaceFile(workspaceId, { location: open.location }); } - async changeCurrentCodeWorkspaceSyncSetting(): Promise { + async chooseCurrentCodeWorkspaceAutoAddSetting(): Promise { if ( workspace.workspaceFile == null || this._currentWorkspaceId == null || - this._currentWorkspaceSyncSetting == null + this._currentWorkspaceAutoAddSetting == null ) { return; } - let syncOptions = [ - { title: 'Always', option: WorkspaceSyncSetting.Always }, - { title: 'Never', option: WorkspaceSyncSetting.Never }, - { title: 'Ask every time', option: WorkspaceSyncSetting.Ask }, + let autoAddOptions = [ + { + title: 'Enable', + option: WorkspaceAutoAddSetting.Enabled, + ...(this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Enabled + ? { description: 'current' } + : {}), + }, + { + title: 'Disable', + option: WorkspaceAutoAddSetting.Disabled, + ...(this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Disabled + ? { description: 'current' } + : {}), + }, + { + title: 'Ask every time', + option: WorkspaceAutoAddSetting.Prompt, + ...(this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Prompt + ? { description: 'current' } + : {}), + }, ]; - syncOptions = syncOptions.filter(s => s.option !== this._currentWorkspaceSyncSetting); + autoAddOptions = autoAddOptions.filter(s => s.option !== this._currentWorkspaceAutoAddSetting); - // Show a quickpick without the current sync setting as an option - const newWorkspaceSyncOption = await window.showQuickPick( - syncOptions.map(s => s.title), + // Show a quickpick without the current auto-add setting as an option + const newWorkspaceAutoAddOption = await window.showQuickPick( + autoAddOptions.map(s => s.title), { - placeHolder: 'Choose a new sync setting for this workspace', + placeHolder: 'Choose an option to automatically add missing repositories to this workspace', + title: 'Automatically add repositories', }, ); - if (newWorkspaceSyncOption == null) return; + if (newWorkspaceAutoAddOption == null) return; - const newWorkspaceSyncSetting = syncOptions.find(s => s.title === newWorkspaceSyncOption)?.option; - if (newWorkspaceSyncSetting == null) return; + const newWorkspaceAtuoAddSetting = autoAddOptions.find(s => s.title === newWorkspaceAutoAddOption)?.option; + if (newWorkspaceAtuoAddSetting == null) return; const updated = await this._workspacesPathProvider.updateCodeWorkspaceFileSettings(workspace.workspaceFile, { - workspaceSyncSetting: newWorkspaceSyncSetting, + workspaceAutoAddSetting: newWorkspaceAtuoAddSetting, }); if (!updated) return; - this._currentWorkspaceSyncSetting = newWorkspaceSyncSetting; + this._currentWorkspaceAutoAddSetting = newWorkspaceAtuoAddSetting; } async openCodeWorkspaceFile(workspaceId: string, options?: { location?: OpenWorkspaceLocation }): Promise { diff --git a/src/views/workspacesView.ts b/src/views/workspacesView.ts index 954fbd6..9d72bcc 100644 --- a/src/views/workspacesView.ts +++ b/src/views/workspacesView.ts @@ -129,9 +129,9 @@ export class WorkspacesView extends ViewBase<'workspaces', WorkspacesViewNode, R this, ), registerViewCommand( - this.getQualifiedCommand('changeLocalSync'), + this.getQualifiedCommand('changeAutoAddSetting'), async () => { - await this.container.workspaces.changeCurrentCodeWorkspaceSyncSetting(); + await this.container.workspaces.chooseCurrentCodeWorkspaceAutoAddSetting(); }, this, ),