From 6c3356abcdec41e68b2faf44712c6913890e8888 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Sat, 18 Jan 2025 02:58:50 -0500 Subject: [PATCH] Reorganizes code structure - Splits models & utils into separate files to reduce coupling - Relocates VS Code-specific utilities into system/-webview/ --- eslint.config.mjs | 26 +- src/ai/aiProviderService.ts | 9 +- src/ai/openAICompatibleProvider.ts | 2 +- src/ai/openaiProvider.ts | 2 +- src/ai/vscodeProvider.ts | 2 +- src/annotations/annotationProvider.ts | 2 +- src/annotations/annotations.ts | 2 +- src/annotations/blameAnnotationProvider.ts | 2 +- src/annotations/fileAnnotationController.ts | 12 +- .../gutterBlameAnnotationProvider.ts | 2 +- .../gutterChangesAnnotationProvider.ts | 2 +- src/annotations/lineAnnotationController.ts | 4 +- src/api/actionRunners.ts | 8 +- src/autolinks/autolinks.ts | 4 +- src/autolinks/autolinks.utils.ts | 2 +- src/avatars.ts | 4 +- src/cache.ts | 3 +- src/codelens/codeLensController.ts | 4 +- src/codelens/codeLensProvider.ts | 6 +- src/commands/addAuthors.ts | 4 +- src/commands/browseRepoAtRevision.ts | 13 +- src/commands/closeUnchangedFiles.ts | 4 +- src/commands/cloudIntegrations.ts | 4 +- src/commands/commandBase.ts | 119 ++++ src/commands/commandBase.utils.ts | 6 + src/commands/commandContext.ts | 85 +++ .../{base.ts => commandContext.utils.ts} | 240 +------ src/commands/compareWith.ts | 7 +- src/commands/copyCurrentBranch.ts | 5 +- src/commands/copyDeepLink.ts | 14 +- src/commands/copyMessageToClipboard.ts | 10 +- src/commands/copyRelativePathToClipboard.ts | 8 +- src/commands/copyShaToClipboard.ts | 14 +- src/commands/createPullRequestOnRemote.ts | 6 +- src/commands/diffFolderWithRevision.ts | 7 +- src/commands/diffFolderWithRevisionFrom.ts | 7 +- src/commands/diffLineWithPrevious.ts | 7 +- src/commands/diffLineWithWorking.ts | 7 +- src/commands/diffWith.ts | 8 +- src/commands/diffWithNext.ts | 7 +- src/commands/diffWithPrevious.ts | 9 +- src/commands/diffWithRevision.ts | 9 +- src/commands/diffWithRevisionFrom.ts | 9 +- src/commands/diffWithWorking.ts | 9 +- src/commands/externalDiff.ts | 11 +- src/commands/generateCommitMessage.ts | 7 +- src/commands/ghpr/openOrCreateWorktree.ts | 9 +- src/commands/git/branch.ts | 13 +- src/commands/git/cherry-pick.ts | 4 +- src/commands/git/coauthors.ts | 2 +- src/commands/git/fetch.ts | 2 +- src/commands/git/log.ts | 4 +- src/commands/git/merge.ts | 6 +- src/commands/git/pull.ts | 2 +- src/commands/git/push.ts | 6 +- src/commands/git/rebase.ts | 8 +- src/commands/git/reset.ts | 2 +- src/commands/git/revert.ts | 2 +- src/commands/git/search.ts | 4 +- src/commands/git/stash.ts | 6 +- src/commands/git/status.ts | 2 +- src/commands/git/switch.ts | 12 +- src/commands/git/tag.ts | 10 +- src/commands/git/worktree.ts | 26 +- src/commands/gitWizard.ts | 4 +- src/commands/inspect.ts | 11 +- src/commands/inviteToLiveShare.ts | 7 +- src/commands/logging.ts | 6 +- .../openAssociatedPullRequestOnRemote.ts | 5 +- src/commands/openBranchOnRemote.ts | 10 +- src/commands/openBranchesOnRemote.ts | 8 +- src/commands/openChangedFiles.ts | 6 +- src/commands/openCommitOnRemote.ts | 15 +- src/commands/openComparisonOnRemote.ts | 6 +- src/commands/openCurrentBranchOnRemote.ts | 7 +- src/commands/openDirectoryCompare.ts | 8 +- src/commands/openFileAtRevision.ts | 11 +- src/commands/openFileAtRevisionFrom.ts | 5 +- src/commands/openFileFromRemote.ts | 6 +- src/commands/openFileOnRemote.ts | 17 +- src/commands/openOnRemote.ts | 8 +- src/commands/openOnlyChangedFiles.ts | 6 +- src/commands/openPullRequestOnRemote.ts | 10 +- src/commands/openRepoOnRemote.ts | 8 +- src/commands/openRevisionFile.ts | 5 +- src/commands/openWorkingFile.ts | 7 +- src/commands/patches.ts | 15 +- src/commands/quickCommand.steps.ts | 48 +- src/commands/quickCommand.ts | 2 +- src/commands/quickWizard.base.ts | 6 +- src/commands/quickWizard.ts | 4 +- src/commands/quickWizard.utils.ts | 4 +- src/commands/rebaseEditor.ts | 4 +- src/commands/refreshHover.ts | 4 +- src/commands/remoteProviders.ts | 7 +- src/commands/repositories.ts | 4 +- src/commands/resetViewsLayout.ts | 4 +- src/commands/resets.ts | 6 +- src/commands/searchCommits.ts | 9 +- src/commands/showCommitsInView.ts | 5 +- src/commands/showLastQuickPick.ts | 4 +- src/commands/showQuickBranchHistory.ts | 9 +- src/commands/showQuickCommit.ts | 8 +- src/commands/showQuickCommitFile.ts | 10 +- src/commands/showQuickFileHistory.ts | 9 +- src/commands/showQuickRepoStatus.ts | 4 +- src/commands/showQuickStashList.ts | 4 +- src/commands/showView.ts | 6 +- src/commands/stashApply.ts | 7 +- src/commands/stashSave.ts | 8 +- src/commands/switchAIModel.ts | 4 +- src/commands/switchMode.ts | 6 +- src/commands/toggleCodeLens.ts | 4 +- src/commands/toggleFileAnnotations.ts | 6 +- src/commands/toggleLineBlame.ts | 4 +- src/commands/walkthroughs.ts | 6 +- src/constants.storage.ts | 2 +- src/constants.telemetry.ts | 2 +- src/container.ts | 18 +- .../repositoryWebPathMappingProvider.ts | 2 +- .../workspacesWebPathMappingProvider.ts | 3 +- src/env/node/fetch.ts | 2 +- src/env/node/git/commitMessageProvider.ts | 2 +- src/env/node/git/git.ts | 8 +- src/env/node/git/localGitProvider.ts | 79 ++- src/env/node/git/sub-providers/branches.ts | 14 +- .../node/git/sub-providers/contributors.ts | 6 +- src/env/node/git/sub-providers/remotes.ts | 6 +- src/env/node/git/sub-providers/staging.ts | 2 +- src/env/node/git/sub-providers/stash.ts | 24 +- src/env/node/git/sub-providers/status.ts | 14 +- src/env/node/git/sub-providers/tags.ts | 6 +- src/env/node/git/sub-providers/worktrees.ts | 2 +- src/env/node/git/vslsGitProvider.ts | 4 +- .../repositoryLocalPathMappingProvider.ts | 4 +- .../workspacesLocalPathMappingProvider.ts | 9 +- src/env/node/providers.ts | 2 +- src/errors.ts | 4 +- src/eventBus.ts | 2 +- src/extension.ts | 14 +- src/features.ts | 2 +- src/git/actions.ts | 2 +- src/git/actions/commit.ts | 21 +- src/git/actions/worktree.ts | 2 +- src/git/cache.ts | 2 +- src/git/formatters/commitFormatter.ts | 12 +- src/git/formatters/statusFormatter.ts | 6 +- src/git/fsProvider.ts | 2 +- src/git/gitProvider.ts | 8 +- src/git/gitProviderService.ts | 27 +- src/git/gitUri.ts | 10 +- src/git/models/branch.ts | 43 +- src/git/models/branch.utils.ts | 306 --------- src/git/models/commit.ts | 45 +- src/git/models/contributor.ts | 54 +- src/git/models/contributor.utils.ts | 41 -- src/git/models/diff.ts | 2 +- src/git/models/file.ts | 316 +-------- src/git/models/fileChange.ts | 152 +++++ src/git/models/fileStatus.ts | 31 + src/git/models/graph.ts | 43 -- src/git/models/issue.ts | 238 ++----- src/git/models/issueOrPullRequest.ts | 20 + .../models.ts => git/models/pathMapping.ts} | 0 src/git/models/pullRequest.ts | 363 ++-------- src/git/models/pullRequest.utils.ts | 34 - src/git/models/reflog.ts | 4 +- src/git/models/remote.ts | 112 +--- src/git/models/remote.utils.ts | 18 - src/git/models/remoteResource.ts | 29 - src/git/models/repository.ts | 20 +- .../models/repositoryIdentities.ts | 0 src/git/models/status.ts | 340 +--------- src/git/models/statusFile.ts | 276 ++++++++ src/git/models/tag.ts | 24 +- src/git/models/user.ts | 19 - src/git/models/worktree.ts | 17 +- src/git/parsers/blameParser.ts | 6 +- src/git/parsers/diffParser.ts | 12 +- src/git/parsers/logParser.ts | 13 +- src/git/parsers/statusParser.ts | 35 +- src/git/parsers/tagParser.ts | 4 +- .../repositoryPathMappingProvider.ts | 0 src/git/remotes/azure-devops.ts | 2 +- src/git/remotes/bitbucket-server.ts | 4 +- src/git/remotes/bitbucket.ts | 4 +- src/git/remotes/custom.ts | 2 +- src/git/remotes/gerrit.ts | 4 +- src/git/remotes/gitea.ts | 4 +- src/git/remotes/github.ts | 8 +- src/git/remotes/gitlab.ts | 8 +- src/git/remotes/google-source.ts | 2 +- src/git/remotes/remoteProvider.ts | 6 +- src/git/remotes/remoteProviders.ts | 2 +- src/git/search.ts | 2 +- src/git/sub-providers/remotes.ts | 2 +- src/git/utils/-webview/branch.issue.utils.ts | 115 ++++ src/git/utils/-webview/branch.utils.ts | 80 +++ .../-webview}/contributor.quickpick.ts | 6 +- src/git/utils/-webview/file.utils.ts | 33 + src/git/utils/-webview/fileChange.utils.ts | 24 + src/git/utils/{vscode => -webview}/icons.ts | 34 +- src/git/utils/-webview/issue.utils.ts | 44 ++ src/git/utils/-webview/pullRequest.utils.ts | 127 ++++ src/git/utils/-webview/reference.utils.ts | 43 ++ .../-webview}/repository.utils.ts | 57 +- src/git/utils/{vscode => -webview}/sorting.ts | 6 +- .../-webview}/worktree.quickpick.ts | 16 +- .../-webview}/worktree.utils.ts | 10 +- .../__tests__/pullRequest.utils.test.ts | 0 src/git/utils/branch.utils.ts | 105 +++ src/git/{models => utils}/commit.utils.ts | 13 +- src/git/utils/contributor.utils.ts | 80 +++ src/git/utils/fetch.utils.ts | 10 + src/git/utils/file.utils.ts | 12 + src/git/utils/fileStatus.utils.ts | 49 ++ src/git/utils/issue.utils.ts | 80 +++ src/git/utils/issueOrPullRequest.utils.ts | 23 + src/git/utils/pullRequest.utils.ts | 142 ++++ src/git/{models => utils}/reference.utils.ts | 54 +- src/git/utils/remote.utils.ts | 102 +++ src/git/utils/remoteResource.utils.ts | 31 + src/git/{models => utils}/revision.utils.ts | 4 +- src/git/utils/status.utils.ts | 55 ++ src/git/utils/tag.utils.ts | 9 + src/git/utils/user.utils.ts | 20 + src/git/utils/worktree.utils.ts | 3 + src/hovers/hovers.ts | 4 +- src/hovers/lineHoverController.ts | 2 +- src/messages.ts | 6 +- src/partners.ts | 2 +- src/plus/drafts/actions.ts | 2 +- src/plus/drafts/draftsService.ts | 38 +- src/{gk => plus/drafts}/models/drafts.ts | 16 +- .../drafts/utils/-webview/drafts.utils.ts | 41 ++ .../gk/{account => }/__debug__accountDebug.ts | 20 +- .../{account => }/authenticationConnection.ts | 18 +- .../{account => }/authenticationProvider.ts | 14 +- src/plus/gk/models/checkin.ts | 50 ++ .../gk/{account => models}/organization.ts | 0 src/plus/gk/models/promo.ts | 18 + src/plus/gk/models/subscription.ts | 52 ++ .../gk/{account => }/organizationService.ts | 16 +- src/plus/gk/serverConnection.ts | 2 +- .../gk/{account => }/subscriptionService.ts | 72 +- src/plus/gk/utils.ts | 26 - src/plus/gk/utils/-webview/acount.utils.ts | 54 ++ src/plus/gk/utils/-webview/plus.utils.ts | 111 ++++ .../gk/{checkin.ts => utils/checkin.utils.ts} | 63 +- .../promos.ts => utils/promo.utils.ts} | 18 +- .../subscription.utils.ts} | 54 +- src/plus/graph/statusbar.ts | 8 +- .../integrationAuthentication.ts | 2 +- .../integrations/authentication/models.ts | 2 +- src/plus/integrations/integration.ts | 11 +- src/plus/integrations/integrationService.ts | 8 +- .../integrations/providers/azureDevOps.ts | 3 +- src/plus/integrations/providers/bitbucket.ts | 3 +- src/plus/integrations/providers/github.ts | 7 +- .../integrations/providers/github/github.ts | 11 +- .../providers/github/github.utils.ts | 2 +- .../providers/github/githubGitProvider.ts | 48 +- .../integrations/providers/github/models.ts | 2 +- .../github/sub-providers/branches.ts | 10 +- .../github/sub-providers/contributors.ts | 2 +- .../providers/github/sub-providers/remotes.ts | 2 +- .../providers/github/sub-providers/status.ts | 3 +- .../providers/github/sub-providers/tags.ts | 5 +- src/plus/integrations/providers/gitlab.ts | 7 +- .../integrations/providers/gitlab/gitlab.ts | 4 +- .../providers/gitlab/gitlab.utils.ts | 2 +- src/plus/integrations/providers/jira.ts | 3 +- src/plus/integrations/providers/models.ts | 2 +- src/plus/integrations/providers/utils.ts | 3 +- src/plus/launchpad/enrichmentService.ts | 41 +- src/plus/launchpad/launchpad.ts | 12 +- src/plus/launchpad/launchpadIndicator.ts | 8 +- src/plus/launchpad/launchpadProvider.ts | 32 +- src/plus/launchpad/models/enrichedItem.ts | 37 ++ .../{models.ts => models/launchpad.ts} | 0 .../-webview/launchpad.utils.ts} | 10 +- src/plus/repos/repositoryIdentityService.ts | 6 +- src/plus/startWork/startWork.ts | 10 +- src/plus/utils.ts | 177 ----- src/plus/workspaces/models.ts | 623 ------------------ src/plus/workspaces/models/cloudWorkspace.ts | 220 +++++++ src/plus/workspaces/models/localWorkspace.ts | 87 +++ src/plus/workspaces/models/workspaces.ts | 333 ++++++++++ src/plus/workspaces/workspacesApi.ts | 7 +- .../workspacesPathMappingProvider.ts | 3 +- src/plus/workspaces/workspacesService.ts | 32 +- src/quickpicks/aiModelPicker.ts | 4 +- src/quickpicks/branchPicker.ts | 2 +- src/quickpicks/commitPicker.ts | 6 +- src/quickpicks/contributorsPicker.ts | 8 +- src/quickpicks/items/commits.ts | 8 +- src/quickpicks/items/gitWizard.ts | 10 +- src/quickpicks/modePicker.ts | 2 +- src/quickpicks/organizationMembersPicker.ts | 2 +- src/quickpicks/referencePicker.ts | 8 +- src/quickpicks/remotePicker.ts | 2 +- src/quickpicks/remoteProviderPicker.ts | 14 +- src/quickpicks/repositoryPicker.ts | 2 +- src/quickpicks/revisionFilesPicker.ts | 6 +- src/repositories.ts | 2 +- src/statusbar/statusBarController.ts | 6 +- .../{vscode => -webview}/asyncDebouncer.ts | 0 .../{vscode => -webview}/cancellation.ts | 0 src/system/{vscode => -webview}/command.ts | 2 +- .../{vscode => -webview}/configuration.ts | 0 src/system/{vscode => -webview}/context.ts | 0 src/system/{vscode => -webview}/formatPath.ts | 0 src/system/{vscode => -webview}/keyboard.ts | 0 src/system/{vscode => -webview}/path.ts | 0 src/system/{vscode => -webview}/scm.ts | 0 src/system/{vscode => -webview}/serialize.ts | 2 + src/system/{vscode => -webview}/storage.ts | 0 src/system/-webview/timeline.ts | 18 + src/system/{vscode => -webview}/uriMap.ts | 0 src/system/{vscode => -webview}/utils.ts | 0 src/system/{vscode => -webview}/vscode.ts | 0 src/system/__tests__/path.test.ts | 2 +- src/system/decorators/{ => -webview}/gate.ts | 2 +- .../decorators/{ => -webview}/memoize.ts | 0 .../decorators/{ => -webview}/resolver.ts | 10 +- src/telemetry/telemetry.ts | 2 +- src/telemetry/usageTracker.ts | 2 +- src/telemetry/walkthroughStateProvider.ts | 4 +- src/terminal/linkProvider.ts | 6 +- src/trackers/documentTracker.ts | 8 +- src/trackers/lineTracker.ts | 2 +- src/trackers/trackedDocument.ts | 4 +- src/uris/deepLinks/deepLink.ts | 2 +- src/uris/deepLinks/deepLinkService.ts | 21 +- src/uris/uriService.ts | 4 +- src/views/branchesView.ts | 12 +- src/views/commitsView.ts | 14 +- src/views/contributorsView.ts | 10 +- src/views/draftsView.ts | 10 +- src/views/fileHistoryView.ts | 6 +- src/views/launchpadView.ts | 12 +- src/views/lineHistoryView.ts | 6 +- src/views/nodes/UncommittedFileNode.ts | 2 +- src/views/nodes/UncommittedFilesNode.ts | 3 +- .../abstract/repositoriesSubscribeableNode.ts | 2 +- .../nodes/abstract/repositoryFolderNode.ts | 6 +- .../nodes/abstract/subscribeableViewNode.ts | 2 +- src/views/nodes/abstract/viewFileNode.ts | 2 +- src/views/nodes/abstract/viewNode.ts | 12 +- src/views/nodes/abstract/viewRefNode.ts | 2 +- src/views/nodes/autolinkedItemNode.ts | 4 +- src/views/nodes/branchNode.ts | 14 +- .../nodes/branchTrackingStatusFilesNode.ts | 2 +- src/views/nodes/branchTrackingStatusNode.ts | 10 +- src/views/nodes/branchesNode.ts | 4 +- src/views/nodes/commitFileNode.ts | 4 +- src/views/nodes/commitNode.ts | 4 +- src/views/nodes/common.ts | 2 +- src/views/nodes/compareBranchNode.ts | 2 +- src/views/nodes/compareResultsNode.ts | 4 +- src/views/nodes/contributorNode.ts | 4 +- src/views/nodes/contributorsNode.ts | 4 +- src/views/nodes/draftNode.ts | 4 +- src/views/nodes/fileHistoryNode.ts | 6 +- src/views/nodes/fileHistoryTrackerNode.ts | 10 +- src/views/nodes/fileRevisionAsCommitNode.ts | 4 +- src/views/nodes/launchpadViewGroupingNode.ts | 2 +- src/views/nodes/lineHistoryNode.ts | 8 +- src/views/nodes/lineHistoryTrackerNode.ts | 8 +- .../nodes/mergeConflictCurrentChangesNode.ts | 6 +- src/views/nodes/mergeConflictFileNode.ts | 4 +- src/views/nodes/mergeConflictFilesNode.ts | 2 +- .../nodes/mergeConflictIncomingChangesNode.ts | 6 +- src/views/nodes/pausedOperationStatusNode.ts | 2 +- src/views/nodes/pullRequestNode.ts | 11 +- src/views/nodes/reflogRecordNode.ts | 2 +- src/views/nodes/remoteNode.ts | 2 +- src/views/nodes/repositoriesNode.ts | 2 +- src/views/nodes/repositoryNode.ts | 17 +- src/views/nodes/resultsCommitsNode.ts | 4 +- src/views/nodes/resultsFileNode.ts | 6 +- src/views/nodes/resultsFilesNode.ts | 2 +- src/views/nodes/searchResultsNode.ts | 2 +- src/views/nodes/stashNode.ts | 2 +- src/views/nodes/statusFileNode.ts | 7 +- src/views/nodes/statusFilesNode.ts | 3 +- src/views/nodes/tagNode.ts | 4 +- .../nodes/workspaceMissingRepositoryNode.ts | 8 +- src/views/nodes/workspaceNode.ts | 5 +- src/views/nodes/worktreeNode.ts | 10 +- src/views/nodes/worktreesNode.ts | 2 +- src/views/pullRequestView.ts | 6 +- src/views/remotesView.ts | 12 +- src/views/repositoriesView.ts | 12 +- src/views/searchAndCompareView.ts | 10 +- src/views/stashesView.ts | 10 +- src/views/tagsView.ts | 10 +- src/views/viewBase.ts | 4 +- src/views/viewCommands.ts | 37 +- src/views/viewDecorationProvider.ts | 2 +- src/views/views.ts | 6 +- src/views/workspacesView.ts | 10 +- src/views/worktreesView.ts | 10 +- src/vsls/host.ts | 2 +- src/vsls/vsls.ts | 4 +- .../apps/commitDetails/commitDetails.ts | 2 +- .../components/commit-details-app.ts | 2 +- .../components/gl-commit-details.ts | 4 +- .../components/gl-inspect-patch.ts | 2 +- .../apps/home/components/promo-banner.ts | 2 +- src/webviews/apps/plus/graph/GraphWrapper.tsx | 4 +- .../apps/plus/home/components/branch-card.ts | 2 +- .../components/gl-draft-details.ts | 2 +- .../components/gl-patch-create.ts | 6 +- .../patchDetails/components/gl-tree-base.ts | 2 +- .../apps/plus/patchDetails/patchDetails.ts | 4 +- .../plus/shared/components/account-chip.ts | 6 +- .../components/feature-gate-plus-state.ts | 4 +- .../shared/components/integrations-chip.ts | 2 +- src/webviews/apps/plus/timeline/timeline.ts | 2 +- .../apps/shared/components/feature-badge.ts | 8 +- .../apps/shared/components/feature-gate.ts | 2 +- src/webviews/apps/shared/components/promo.ts | 2 +- .../shared/components/status/git-status.ts | 26 +- .../apps/shared/components/tree/base.ts | 4 +- src/webviews/apps/shared/ipc.ts | 2 +- src/webviews/apps/tsconfig.json | 19 +- .../commitDetails/commitDetailsWebview.ts | 42 +- src/webviews/commitDetails/protocol.ts | 8 +- src/webviews/commitDetails/registration.ts | 2 +- src/webviews/home/homeWebview.ts | 36 +- src/webviews/home/protocol.ts | 4 +- src/webviews/plus/graph/graphWebview.ts | 68 +- src/webviews/plus/graph/protocol.ts | 2 +- src/webviews/plus/graph/registration.ts | 8 +- .../plus/patchDetails/patchDetailsWebview.ts | 32 +- src/webviews/plus/patchDetails/protocol.ts | 10 +- .../plus/patchDetails/registration.ts | 8 +- .../plus/patchDetails/repositoryChangeset.ts | 2 +- src/webviews/plus/timeline/registration.ts | 6 +- src/webviews/plus/timeline/timelineWebview.ts | 10 +- src/webviews/protocol.ts | 2 +- src/webviews/rebase/rebaseEditor.ts | 6 +- src/webviews/settings/registration.ts | 2 +- src/webviews/settings/settingsWebview.ts | 10 +- src/webviews/webviewCommandRegistrar.ts | 4 +- src/webviews/webviewController.ts | 4 +- src/webviews/webviewsController.ts | 4 +- tsconfig.browser.json | 2 +- tsconfig.node.json | 2 +- tsconfig.test.json | 2 +- 451 files changed, 4641 insertions(+), 4479 deletions(-) create mode 100644 src/commands/commandBase.ts create mode 100644 src/commands/commandBase.utils.ts create mode 100644 src/commands/commandContext.ts rename src/commands/{base.ts => commandContext.utils.ts} (60%) delete mode 100644 src/git/models/branch.utils.ts delete mode 100644 src/git/models/contributor.utils.ts create mode 100644 src/git/models/fileChange.ts create mode 100644 src/git/models/fileStatus.ts create mode 100644 src/git/models/issueOrPullRequest.ts rename src/{pathMapping/models.ts => git/models/pathMapping.ts} (100%) delete mode 100644 src/git/models/pullRequest.utils.ts delete mode 100644 src/git/models/remote.utils.ts rename src/{gk => git}/models/repositoryIdentities.ts (100%) create mode 100644 src/git/models/statusFile.ts rename src/{ => git}/pathMapping/repositoryPathMappingProvider.ts (100%) create mode 100644 src/git/utils/-webview/branch.issue.utils.ts create mode 100644 src/git/utils/-webview/branch.utils.ts rename src/git/{models => utils/-webview}/contributor.quickpick.ts (78%) create mode 100644 src/git/utils/-webview/file.utils.ts create mode 100644 src/git/utils/-webview/fileChange.utils.ts rename src/git/utils/{vscode => -webview}/icons.ts (88%) create mode 100644 src/git/utils/-webview/issue.utils.ts create mode 100644 src/git/utils/-webview/pullRequest.utils.ts create mode 100644 src/git/utils/-webview/reference.utils.ts rename src/git/{models => utils/-webview}/repository.utils.ts (73%) rename src/git/utils/{vscode => -webview}/sorting.ts (98%) rename src/git/{models => utils/-webview}/worktree.quickpick.ts (85%) rename src/git/{models => utils/-webview}/worktree.utils.ts (91%) rename src/git/{models => utils}/__tests__/pullRequest.utils.test.ts (100%) create mode 100644 src/git/utils/branch.utils.ts rename src/git/{models => utils}/commit.utils.ts (57%) create mode 100644 src/git/utils/contributor.utils.ts create mode 100644 src/git/utils/fetch.utils.ts create mode 100644 src/git/utils/file.utils.ts create mode 100644 src/git/utils/fileStatus.utils.ts create mode 100644 src/git/utils/issue.utils.ts create mode 100644 src/git/utils/issueOrPullRequest.utils.ts create mode 100644 src/git/utils/pullRequest.utils.ts rename src/git/{models => utils}/reference.utils.ts (84%) create mode 100644 src/git/utils/remote.utils.ts create mode 100644 src/git/utils/remoteResource.utils.ts rename src/git/{models => utils}/revision.utils.ts (97%) create mode 100644 src/git/utils/status.utils.ts create mode 100644 src/git/utils/tag.utils.ts create mode 100644 src/git/utils/user.utils.ts create mode 100644 src/git/utils/worktree.utils.ts rename src/{gk => plus/drafts}/models/drafts.ts (92%) create mode 100644 src/plus/drafts/utils/-webview/drafts.utils.ts rename src/plus/gk/{account => }/__debug__accountDebug.ts (96%) rename src/plus/gk/{account => }/authenticationConnection.ts (94%) rename src/plus/gk/{account => }/authenticationProvider.ts (95%) create mode 100644 src/plus/gk/models/checkin.ts rename src/plus/gk/{account => models}/organization.ts (100%) create mode 100644 src/plus/gk/models/promo.ts create mode 100644 src/plus/gk/models/subscription.ts rename src/plus/gk/{account => }/organizationService.ts (94%) rename src/plus/gk/{account => }/subscriptionService.ts (96%) delete mode 100644 src/plus/gk/utils.ts create mode 100644 src/plus/gk/utils/-webview/acount.utils.ts create mode 100644 src/plus/gk/utils/-webview/plus.utils.ts rename src/plus/gk/{checkin.ts => utils/checkin.utils.ts} (80%) rename src/plus/gk/{account/promos.ts => utils/promo.utils.ts} (83%) rename src/plus/gk/{account/subscription.ts => utils/subscription.utils.ts} (85%) create mode 100644 src/plus/launchpad/models/enrichedItem.ts rename src/plus/launchpad/{models.ts => models/launchpad.ts} (100%) rename src/plus/launchpad/{utils.ts => utils/-webview/launchpad.utils.ts} (54%) delete mode 100644 src/plus/utils.ts delete mode 100644 src/plus/workspaces/models.ts create mode 100644 src/plus/workspaces/models/cloudWorkspace.ts create mode 100644 src/plus/workspaces/models/localWorkspace.ts create mode 100644 src/plus/workspaces/models/workspaces.ts rename src/system/{vscode => -webview}/asyncDebouncer.ts (100%) rename src/system/{vscode => -webview}/cancellation.ts (100%) rename src/system/{vscode => -webview}/command.ts (98%) rename src/system/{vscode => -webview}/configuration.ts (100%) rename src/system/{vscode => -webview}/context.ts (100%) rename src/system/{vscode => -webview}/formatPath.ts (100%) rename src/system/{vscode => -webview}/keyboard.ts (100%) rename src/system/{vscode => -webview}/path.ts (100%) rename src/system/{vscode => -webview}/scm.ts (100%) rename src/system/{vscode => -webview}/serialize.ts (93%) rename src/system/{vscode => -webview}/storage.ts (100%) create mode 100644 src/system/-webview/timeline.ts rename src/system/{vscode => -webview}/uriMap.ts (100%) rename src/system/{vscode => -webview}/utils.ts (100%) rename src/system/{vscode => -webview}/vscode.ts (100%) rename src/system/decorators/{ => -webview}/gate.ts (96%) rename src/system/decorators/{ => -webview}/memoize.ts (100%) rename src/system/decorators/{ => -webview}/resolver.ts (87%) diff --git a/eslint.config.mjs b/eslint.config.mjs index f601d87eb3f3c..f508dbb18524b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -317,7 +317,7 @@ export default ts.config( { name: 'extension:node', files: ['src/**/*'], - ignores: ['src/webviews/apps/**/*', 'src/env/browser/**/*'], + ignores: ['**/webview/**/*', 'src/test/**/*', 'src/webviews/apps/**/*', 'src/env/browser/**/*'], languageOptions: { globals: { ...globals.node, @@ -358,7 +358,7 @@ export default ts.config( { name: 'extension:browser', files: ['src/**/*'], - ignores: ['src/webviews/apps/**/*', 'src/env/node/**/*'], + ignores: ['**/webview/**/*', 'src/test/**/*', 'src/webviews/apps/**/*', 'src/env/node/**/*'], languageOptions: { globals: { ...globals.worker, @@ -381,19 +381,19 @@ export default ts.config( // Keep in sync with `src/webviews/apps/tsconfig.json` files: [ 'src/webviews/apps/**/*', - 'src/@types/**/*', - 'src/env/browser/**/*', - 'src/plus/gk/account/promos.ts', - 'src/plus/gk/account/subscription.ts', 'src/webviews/**/protocol.ts', + 'src/**/models/**/*.ts', + 'src/**/utils/**/*.ts', + 'src/@types/**/*', 'src/config.ts', 'src/constants.ts', 'src/constants.*.ts', + 'src/env/browser/**/*', 'src/features.ts', - 'src/subscription.ts', - 'src/system/*.ts', - 'src/system/decorators/log.ts', + 'src/system/**/*.ts', + '**/webview/**/*', ], + ignores: ['**/-webview/**/*'], languageOptions: { globals: { ...globals.browser, @@ -414,13 +414,13 @@ export default ts.config( { patterns: [ { - group: ['react-dom'], - importNames: ['Container'], - message: 'Use our Container instead', + group: ['Container'], + message: "Can't use `Container` in webviews", + allowTypeImports: true, }, { group: ['vscode'], - message: "Can't use vscode in webviews", + message: "Can't use `vscode` in webviews", allowTypeImports: true, }, ], diff --git a/src/ai/aiProviderService.ts b/src/ai/aiProviderService.ts index dabef0712bfaf..21daa0b995a64 100644 --- a/src/ai/aiProviderService.ts +++ b/src/ai/aiProviderService.ts @@ -5,17 +5,18 @@ import type { AIGenerateDraftEventData, Sources, TelemetryEvents } from '../cons import type { Container } from '../container'; import { CancellationError } from '../errors'; import type { GitCommit } from '../git/models/commit'; -import { assertsCommitHasFullDetails, isCommit } from '../git/models/commit'; +import { isCommit } from '../git/models/commit'; import type { GitRevisionReference } from '../git/models/reference'; import type { Repository } from '../git/models/repository'; import { isRepository } from '../git/models/repository'; import { uncommitted, uncommittedStaged } from '../git/models/revision'; +import { assertsCommitHasFullDetails } from '../git/utils/commit.utils'; import { showAIModelPicker } from '../quickpicks/aiModelPicker'; +import { configuration } from '../system/-webview/configuration'; +import type { Storage } from '../system/-webview/storage'; +import { supportedInVSCodeVersion } from '../system/-webview/utils'; import { getSettledValue } from '../system/promise'; import { getPossessiveForm } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; -import type { Storage } from '../system/vscode/storage'; -import { supportedInVSCodeVersion } from '../system/vscode/utils'; import type { TelemetryService } from '../telemetry/telemetry'; import { AnthropicProvider } from './anthropicProvider'; import { GeminiProvider } from './geminiProvider'; diff --git a/src/ai/openAICompatibleProvider.ts b/src/ai/openAICompatibleProvider.ts index dc0027adbe181..a1a0dab930f52 100644 --- a/src/ai/openAICompatibleProvider.ts +++ b/src/ai/openAICompatibleProvider.ts @@ -4,9 +4,9 @@ import type { AIProviders } from '../constants.ai'; import type { TelemetryEvents } from '../constants.telemetry'; import type { Container } from '../container'; import { CancellationError } from '../errors'; +import { configuration } from '../system/-webview/configuration'; import { sum } from '../system/iterable'; import { interpolate } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; import type { AIModel, AIProvider } from './aiProviderService'; import { getMaxCharacters, getOrPromptApiKey, showDiffTruncationWarning } from './aiProviderService'; import { diff --git a/src/ai/openaiProvider.ts b/src/ai/openaiProvider.ts index 9c32efae13877..e9b02e6f20656 100644 --- a/src/ai/openaiProvider.ts +++ b/src/ai/openaiProvider.ts @@ -1,4 +1,4 @@ -import { configuration } from '../system/vscode/configuration'; +import { configuration } from '../system/-webview/configuration'; import type { AIModel } from './aiProviderService'; import { OpenAICompatibleProvider } from './openAICompatibleProvider'; diff --git a/src/ai/vscodeProvider.ts b/src/ai/vscodeProvider.ts index 3b600f2ffdb85..4fb73754f29d6 100644 --- a/src/ai/vscodeProvider.ts +++ b/src/ai/vscodeProvider.ts @@ -2,9 +2,9 @@ import type { CancellationToken, LanguageModelChat, LanguageModelChatSelector } import { CancellationTokenSource, LanguageModelChatMessage, lm } from 'vscode'; import type { TelemetryEvents } from '../constants.telemetry'; import type { Container } from '../container'; +import { configuration } from '../system/-webview/configuration'; import { sum } from '../system/iterable'; import { capitalize, getPossessiveForm, interpolate } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; import type { AIModel, AIProvider } from './aiProviderService'; import { getMaxCharacters, showDiffTruncationWarning } from './aiProviderService'; import { diff --git a/src/annotations/annotationProvider.ts b/src/annotations/annotationProvider.ts index 01b0abfd20905..a59bdbd88ded5 100644 --- a/src/annotations/annotationProvider.ts +++ b/src/annotations/annotationProvider.ts @@ -3,10 +3,10 @@ import { Disposable, window } from 'vscode'; import type { FileAnnotationType } from '../config'; import type { AnnotationStatus } from '../constants'; import type { Container } from '../container'; +import { getTabUri } from '../system/-webview/utils'; import { Logger } from '../system/logger'; import type { Deferred } from '../system/promise'; import { defer } from '../system/promise'; -import { getTabUri } from '../system/vscode/utils'; import type { TrackedGitDocument } from '../trackers/trackedDocument'; import type { Decoration } from './annotations'; diff --git a/src/annotations/annotations.ts b/src/annotations/annotations.ts index b43ea1222193c..37c6a77730295 100644 --- a/src/annotations/annotations.ts +++ b/src/annotations/annotations.ts @@ -13,9 +13,9 @@ import type { Colors } from '../constants.colors'; import type { CommitFormatOptions } from '../git/formatters/commitFormatter'; import { CommitFormatter } from '../git/formatters/commitFormatter'; import type { GitCommit } from '../git/models/commit'; +import { configuration } from '../system/-webview/configuration'; import { scale, toRgba } from '../system/color'; import { getWidth, interpolate, pad } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; import type { BlameFontOptions } from './gutterBlameAnnotationProvider'; export interface ComputedHeatmap { diff --git a/src/annotations/blameAnnotationProvider.ts b/src/annotations/blameAnnotationProvider.ts index d87fcd8b3f4fc..0d59824031ff7 100644 --- a/src/annotations/blameAnnotationProvider.ts +++ b/src/annotations/blameAnnotationProvider.ts @@ -6,8 +6,8 @@ import { GitUri } from '../git/gitUri'; import type { GitBlame } from '../git/models/blame'; import type { GitCommit } from '../git/models/commit'; import { changesMessage, detailsMessage } from '../hovers/hovers'; +import { configuration } from '../system/-webview/configuration'; import { log } from '../system/decorators/log'; -import { configuration } from '../system/vscode/configuration'; import type { TrackedGitDocument } from '../trackers/trackedDocument'; import type { DidChangeStatusCallback } from './annotationProvider'; import { AnnotationProviderBase } from './annotationProvider'; diff --git a/src/annotations/fileAnnotationController.ts b/src/annotations/fileAnnotationController.ts index 763433c09e58b..7b8dbd620345a 100644 --- a/src/annotations/fileAnnotationController.ts +++ b/src/annotations/fileAnnotationController.ts @@ -25,18 +25,18 @@ import type { AnnotationsToggleMode, FileAnnotationType } from '../config'; import type { AnnotationStatus } from '../constants'; import type { Colors, CoreColors } from '../constants.colors'; import type { Container } from '../container'; +import { registerCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import type { KeyboardScope } from '../system/-webview/keyboard'; +import { UriSet } from '../system/-webview/uriMap'; +import { isTrackableTextEditor } from '../system/-webview/utils'; import { debug, log } from '../system/decorators/log'; import { once } from '../system/event'; import type { Deferrable } from '../system/function'; import { debounce } from '../system/function'; import { find } from '../system/iterable'; import { basename } from '../system/path'; -import { registerCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; -import type { KeyboardScope } from '../system/vscode/keyboard'; -import { UriSet } from '../system/vscode/uriMap'; -import { isTrackableTextEditor } from '../system/vscode/utils'; import type { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent, diff --git a/src/annotations/gutterBlameAnnotationProvider.ts b/src/annotations/gutterBlameAnnotationProvider.ts index 4e84829f7f57b..52d0d7fc6ecf5 100644 --- a/src/annotations/gutterBlameAnnotationProvider.ts +++ b/src/annotations/gutterBlameAnnotationProvider.ts @@ -6,6 +6,7 @@ import type { Container } from '../container'; import type { CommitFormatOptions } from '../git/formatters/commitFormatter'; import { CommitFormatter } from '../git/formatters/commitFormatter'; import type { GitCommit } from '../git/models/commit'; +import { configuration } from '../system/-webview/configuration'; import { filterMap } from '../system/array'; import { log } from '../system/decorators/log'; import { first } from '../system/iterable'; @@ -13,7 +14,6 @@ import { getLogScope } from '../system/logger.scope'; import { maybeStopWatch } from '../system/stopwatch'; import type { TokenOptions } from '../system/string'; import { getTokensFromTemplate, getWidth } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; import type { TrackedGitDocument } from '../trackers/trackedDocument'; import type { AnnotationContext, AnnotationState, DidChangeStatusCallback } from './annotationProvider'; import { applyHeatmap, getGutterDecoration, getGutterRenderOptions } from './annotations'; diff --git a/src/annotations/gutterChangesAnnotationProvider.ts b/src/annotations/gutterChangesAnnotationProvider.ts index 6e2bb39c24f74..3226a09229a85 100644 --- a/src/annotations/gutterChangesAnnotationProvider.ts +++ b/src/annotations/gutterChangesAnnotationProvider.ts @@ -4,11 +4,11 @@ import type { Container } from '../container'; import type { GitCommit } from '../git/models/commit'; import type { GitDiffFile } from '../git/models/diff'; import { localChangesMessage } from '../hovers/hovers'; +import { configuration } from '../system/-webview/configuration'; import { log } from '../system/decorators/log'; import { getLogScope } from '../system/logger.scope'; import { getSettledValue } from '../system/promise'; import { maybeStopWatch } from '../system/stopwatch'; -import { configuration } from '../system/vscode/configuration'; import type { TrackedGitDocument } from '../trackers/trackedDocument'; import type { AnnotationContext, AnnotationState, DidChangeStatusCallback } from './annotationProvider'; import { AnnotationProviderBase } from './annotationProvider'; diff --git a/src/annotations/lineAnnotationController.ts b/src/annotations/lineAnnotationController.ts index c29bed0f67005..145219026ac62 100644 --- a/src/annotations/lineAnnotationController.ts +++ b/src/annotations/lineAnnotationController.ts @@ -5,6 +5,8 @@ import type { Container } from '../container'; import { CommitFormatter } from '../git/formatters/commitFormatter'; import type { PullRequest } from '../git/models/pullRequest'; import { detailsMessage } from '../hovers/hovers'; +import { configuration } from '../system/-webview/configuration'; +import { isTrackableTextEditor } from '../system/-webview/utils'; import { debug, log } from '../system/decorators/log'; import { once } from '../system/event'; import { debounce } from '../system/function'; @@ -12,8 +14,6 @@ import { Logger } from '../system/logger'; import { getLogScope, setLogScopeExit } from '../system/logger.scope'; import type { MaybePausedResult } from '../system/promise'; import { getSettledValue, pauseOnCancelOrTimeoutMap } from '../system/promise'; -import { configuration } from '../system/vscode/configuration'; -import { isTrackableTextEditor } from '../system/vscode/utils'; import type { LinesChangeEvent, LineState } from '../trackers/lineTracker'; import { getInlineDecoration } from './annotations'; import type { BlameFontOptions } from './gutterBlameAnnotationProvider'; diff --git a/src/api/actionRunners.ts b/src/api/actionRunners.ts index bd0fc5ef2180a..2f8dd99511038 100644 --- a/src/api/actionRunners.ts +++ b/src/api/actionRunners.ts @@ -3,12 +3,12 @@ import { Disposable, EventEmitter, window } from 'vscode'; import type { Config } from '../config'; import { actionCommandPrefix } from '../constants.commands'; import type { Container } from '../container'; +import { registerCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { getScopedCounter } from '../system/counter'; import { sortCompare } from '../system/string'; -import { registerCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; import type { Action, ActionContext, ActionRunner } from './gitlens'; type Actions = ActionContext['type']; diff --git a/src/autolinks/autolinks.ts b/src/autolinks/autolinks.ts index 7aad6ac8a73ad..95acf7ff33016 100644 --- a/src/autolinks/autolinks.ts +++ b/src/autolinks/autolinks.ts @@ -5,8 +5,9 @@ import type { IntegrationId } from '../constants.integrations'; import { IssueIntegrationId } from '../constants.integrations'; import type { Container } from '../container'; import type { GitRemote } from '../git/models/remote'; -import { getIssueOrPullRequestHtmlIcon, getIssueOrPullRequestMarkdownIcon } from '../git/utils/vscode/icons'; +import { getIssueOrPullRequestHtmlIcon, getIssueOrPullRequestMarkdownIcon } from '../git/utils/-webview/icons'; import type { HostingIntegration, IssueIntegration } from '../plus/integrations/integration'; +import { configuration } from '../system/-webview/configuration'; import { fromNow } from '../system/date'; import { debug } from '../system/decorators/log'; import { encodeUrl } from '../system/encoding'; @@ -15,7 +16,6 @@ import { Logger } from '../system/logger'; import { escapeMarkdown } from '../system/markdown'; import { getSettledValue, isPromise } from '../system/promise'; import { capitalize, encodeHtmlWeak, getSuperscript } from '../system/string'; -import { configuration } from '../system/vscode/configuration'; import type { Autolink, CacheableAutolinkReference, diff --git a/src/autolinks/autolinks.utils.ts b/src/autolinks/autolinks.utils.ts index 71dc07d0003e5..1be9c216a6702 100644 --- a/src/autolinks/autolinks.utils.ts +++ b/src/autolinks/autolinks.utils.ts @@ -1,5 +1,5 @@ import { IssueIntegrationId } from '../constants.integrations'; -import type { IssueOrPullRequest } from '../git/models/issue'; +import type { IssueOrPullRequest } from '../git/models/issueOrPullRequest'; import type { ProviderReference } from '../git/models/remoteProvider'; import type { ResourceDescriptor } from '../plus/integrations/integration'; import { escapeMarkdown } from '../system/markdown'; diff --git a/src/avatars.ts b/src/avatars.ts index 84956a0cb565b..ceaf934dc2875 100644 --- a/src/avatars.ts +++ b/src/avatars.ts @@ -5,11 +5,11 @@ import type { StoredAvatar } from './constants.storage'; import { Container } from './container'; import type { CommitAuthor } from './git/models/author'; import { getGitHubNoReplyAddressParts } from './git/remotes/github'; +import { configuration } from './system/-webview/configuration'; +import { getContext } from './system/-webview/context'; import { debounce } from './system/function'; import { filterMap } from './system/iterable'; import { base64, equalsIgnoreCase } from './system/string'; -import { configuration } from './system/vscode/configuration'; -import { getContext } from './system/vscode/context'; import type { ContactPresenceStatus } from './vsls/vsls'; const maxSmallIntegerV8 = 2 ** 30 - 1; // Max number that can be stored in V8's smis (small integers) diff --git a/src/cache.ts b/src/cache.ts index 102df4bc84501..91b0cbaad9080 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -3,7 +3,8 @@ import type { Disposable } from './api/gitlens'; import type { Container } from './container'; import type { Account } from './git/models/author'; import type { DefaultBranch } from './git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest } from './git/models/issue'; +import type { Issue } from './git/models/issue'; +import type { IssueOrPullRequest } from './git/models/issueOrPullRequest'; import type { PullRequest } from './git/models/pullRequest'; import type { RepositoryMetadata } from './git/models/repositoryMetadata'; import type { HostingIntegration, IntegrationBase, ResourceDescriptor } from './plus/integrations/integration'; diff --git a/src/codelens/codeLensController.ts b/src/codelens/codeLensController.ts index 402ab55de04da..d3de563606aee 100644 --- a/src/codelens/codeLensController.ts +++ b/src/codelens/codeLensController.ts @@ -1,12 +1,12 @@ import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable, languages } from 'vscode'; import type { Container } from '../container'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { log } from '../system/decorators/log'; import { once } from '../system/event'; import { getLoggableName, Logger } from '../system/logger'; import { getLogScope, setLogScopeExit, startLogScope } from '../system/logger.scope'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; import type { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent } from '../trackers/documentTracker'; import type { GitCodeLensProvider } from './codeLensProvider'; diff --git a/src/codelens/codeLensProvider.ts b/src/codelens/codeLensProvider.ts index 4580501f38393..7a7140b4844d3 100644 --- a/src/codelens/codeLensProvider.ts +++ b/src/codelens/codeLensProvider.ts @@ -26,14 +26,14 @@ import type { GitUri } from '../git/gitUri'; import type { GitBlame } from '../git/models/blame'; import type { GitCommit } from '../git/models/commit'; import { RemoteResourceType } from '../git/models/remoteResource'; +import { createCommand, executeCoreCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { isVirtualUri } from '../system/-webview/utils'; import { is, once } from '../system/function'; import { filterMap, find, first, join, map } from '../system/iterable'; import { getLoggableName, Logger } from '../system/logger'; import { startLogScope } from '../system/logger.scope'; import { pluralize } from '../system/string'; -import { createCommand, executeCoreCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { isVirtualUri } from '../system/vscode/utils'; class GitRecentChangeCodeLens extends CodeLens { constructor( diff --git a/src/commands/addAuthors.ts b/src/commands/addAuthors.ts index 38d087d6cc676..cb7945741a25b 100644 --- a/src/commands/addAuthors.ts +++ b/src/commands/addAuthors.ts @@ -2,8 +2,8 @@ import type { SourceControl } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class AddAuthorsCommand extends GlCommandBase { diff --git a/src/commands/browseRepoAtRevision.ts b/src/commands/browseRepoAtRevision.ts index 71ba436a14c4b..bb5a42d0cfee3 100644 --- a/src/commands/browseRepoAtRevision.ts +++ b/src/commands/browseRepoAtRevision.ts @@ -3,12 +3,13 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { showGenericErrorMessage } from '../messages'; +import { command, executeCoreCommand } from '../system/-webview/command'; +import { openWorkspace } from '../system/-webview/utils'; import { Logger } from '../system/logger'; import { basename } from '../system/path'; -import { command, executeCoreCommand } from '../system/vscode/command'; -import { openWorkspace } from '../system/vscode/utils'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; export interface BrowseRepoAtRevisionCommandArgs { uri?: Uri; @@ -41,10 +42,10 @@ export class BrowseRepoAtRevisionCommand extends ActiveEditorCommand { break; } - return this.execute(context.editor!, context.uri, args); + return this.execute(context.editor, context.uri, args); } - async execute(editor: TextEditor, uri?: Uri, args?: BrowseRepoAtRevisionCommandArgs) { + async execute(editor: TextEditor | undefined, uri?: Uri, args?: BrowseRepoAtRevisionCommandArgs) { args = { ...args }; try { diff --git a/src/commands/closeUnchangedFiles.ts b/src/commands/closeUnchangedFiles.ts index 7ac51fc5789e7..c478f107c682b 100644 --- a/src/commands/closeUnchangedFiles.ts +++ b/src/commands/closeUnchangedFiles.ts @@ -4,10 +4,10 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { UriComparer } from '../system/comparers'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export interface CloseUnchangedFilesCommandArgs { uris?: Uri[]; diff --git a/src/commands/cloudIntegrations.ts b/src/commands/cloudIntegrations.ts index 71d5ef78e8b98..be31a5e9713b3 100644 --- a/src/commands/cloudIntegrations.ts +++ b/src/commands/cloudIntegrations.ts @@ -2,9 +2,9 @@ import { GlCommand } from '../constants.commands'; import type { SupportedCloudIntegrationIds } from '../constants.integrations'; import type { Source } from '../constants.telemetry'; import type { Container } from '../container'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export interface ManageCloudIntegrationsCommandArgs extends Source {} diff --git a/src/commands/commandBase.ts b/src/commands/commandBase.ts new file mode 100644 index 0000000000000..a02c8f0e074b5 --- /dev/null +++ b/src/commands/commandBase.ts @@ -0,0 +1,119 @@ +import type { TextEditor, TextEditorEdit } from 'vscode'; +import { commands, Disposable } from 'vscode'; +import type { GlCommands } from '../constants.commands'; +import { registerCommand } from '../system/-webview/command'; +import { sequentialize } from '../system/function'; +import type { CommandContext } from './commandContext'; +import type { CommandContextParsingOptions } from './commandContext.utils'; +import { parseCommandContext } from './commandContext.utils'; + +export abstract class GlCommandBase implements Disposable { + protected readonly contextParsingOptions: CommandContextParsingOptions = { expectsEditor: false }; + + private readonly _disposable: Disposable; + + constructor(command: GlCommands | GlCommands[]) { + if (typeof command === 'string') { + this._disposable = registerCommand(command, (...args: any[]) => this._execute(command, ...args), this); + + return; + } + + const subscriptions = command.map(cmd => + registerCommand(cmd, (...args: any[]) => this._execute(cmd, ...args), this), + ); + this._disposable = Disposable.from(...subscriptions); + } + + dispose() { + this._disposable.dispose(); + } + + protected preExecute(_context: CommandContext, ...args: any[]): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this.execute(...args); + } + + abstract execute(...args: any[]): any; + + protected _execute(command: string, ...args: any[]): Promise { + const [context, rest] = parseCommandContext(command, { ...this.contextParsingOptions }, ...args); + + // If there an array of contexts, then we want to execute the command for each + if (Array.isArray(context)) { + return sequentialize( + this.preExecute, + context.map<[CommandContext, ...any[]]>((c: CommandContext) => [c, ...rest]), + this, + ); + } + + return this.preExecute(context, ...rest); + } +} + +export abstract class ActiveEditorCommand extends GlCommandBase { + protected override readonly contextParsingOptions: CommandContextParsingOptions = { expectsEditor: true }; + + protected override preExecute(context: CommandContext, ...args: any[]): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this.execute(context.editor, context.uri, ...args); + } + + protected override _execute(command: string, ...args: any[]): any { + return super._execute(command, undefined, ...args); + } + + abstract override execute(editor?: TextEditor, ...args: any[]): any; +} + +let lastCommand: { command: string; args: any[] } | undefined = undefined; +export function getLastCommand() { + return lastCommand; +} + +export abstract class ActiveEditorCachedCommand extends ActiveEditorCommand { + protected override _execute(command: string, ...args: any[]): any { + lastCommand = { + command: command, + args: args, + }; + return super._execute(command, ...args); + } + + abstract override execute(editor: TextEditor, ...args: any[]): any; +} + +export abstract class EditorCommand implements Disposable { + private readonly _disposable: Disposable; + + constructor(command: GlCommands | GlCommands[]) { + if (!Array.isArray(command)) { + command = [command]; + } + + const subscriptions = []; + for (const cmd of command) { + subscriptions.push( + commands.registerTextEditorCommand( + cmd, + (editor: TextEditor, edit: TextEditorEdit, ...args: any[]) => + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + this.executeCore(cmd, editor, edit, ...args), + this, + ), + ); + } + this._disposable = Disposable.from(...subscriptions); + } + + dispose() { + this._disposable.dispose(); + } + + private executeCore(_command: string, editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any { + return this.execute(editor, edit, ...args); + } + + abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any; +} diff --git a/src/commands/commandBase.utils.ts b/src/commands/commandBase.utils.ts new file mode 100644 index 0000000000000..e9a35d722ac4e --- /dev/null +++ b/src/commands/commandBase.utils.ts @@ -0,0 +1,6 @@ +import type { TextEditor, Uri } from 'vscode'; + +export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined { + // Always use the editor.uri (if we have one), so we are correct for a split diff + return editor?.document?.uri ?? uri; +} diff --git a/src/commands/commandContext.ts b/src/commands/commandContext.ts new file mode 100644 index 0000000000000..9080aeb6a6075 --- /dev/null +++ b/src/commands/commandContext.ts @@ -0,0 +1,85 @@ +import type { + GitTimelineItem, + SourceControl, + SourceControlResourceGroup, + SourceControlResourceState, + TextEditor, + Uri, +} from 'vscode'; +import type { ViewNode } from '../views/nodes/abstract/viewNode'; + +export type CommandContext = + | CommandEditorLineContext + | CommandGitTimelineItemContext + | CommandScmContext + | CommandScmGroupsContext + | CommandScmStatesContext + | CommandUnknownContext + | CommandUriContext + | CommandUrisContext + // | CommandViewContext + | CommandViewNodeContext + | CommandViewNodesContext; + +export interface CommandContextBase { + command: string; + editor?: TextEditor; + uri?: Uri; + + readonly args: unknown[]; +} + +export interface CommandEditorLineContext extends CommandContextBase { + readonly type: 'editorLine'; + readonly line: number; + readonly uri: Uri; +} + +export interface CommandGitTimelineItemContext extends CommandContextBase { + readonly type: 'timeline-item:git'; + readonly item: GitTimelineItem; + readonly uri: Uri; +} + +export interface CommandScmContext extends CommandContextBase { + readonly type: 'scm'; + readonly scm: SourceControl; +} + +export interface CommandScmGroupsContext extends CommandContextBase { + readonly type: 'scm-groups'; + readonly scmResourceGroups: SourceControlResourceGroup[]; +} + +export interface CommandScmStatesContext extends CommandContextBase { + readonly type: 'scm-states'; + readonly scmResourceStates: SourceControlResourceState[]; +} + +export interface CommandUnknownContext extends CommandContextBase { + readonly type: 'unknown'; +} + +export interface CommandUriContext extends CommandContextBase { + readonly type: 'uri'; +} + +export interface CommandUrisContext extends CommandContextBase { + readonly type: 'uris'; + readonly uris: Uri[]; +} + +// export interface CommandViewContext extends CommandBaseContext { +// readonly type: 'view'; +// } + +export interface CommandViewNodeContext extends CommandContextBase { + readonly type: 'viewItem'; + readonly node: ViewNode; +} + +export interface CommandViewNodesContext extends CommandContextBase { + readonly type: 'viewItems'; + readonly node: ViewNode; + readonly nodes: ViewNode[]; +} diff --git a/src/commands/base.ts b/src/commands/commandContext.utils.ts similarity index 60% rename from src/commands/base.ts rename to src/commands/commandContext.utils.ts index 39e065cfd9f6b..4afc9aa96123c 100644 --- a/src/commands/base.ts +++ b/src/commands/commandContext.utils.ts @@ -1,14 +1,5 @@ -import type { - GitTimelineItem, - SourceControl, - SourceControlResourceGroup, - SourceControlResourceState, - TextEditor, - TextEditorEdit, - TimelineItem, -} from 'vscode'; -import { commands, Disposable, Uri, window } from 'vscode'; -import type { GlCommands } from '../constants.commands'; +import type { GitTimelineItem, SourceControl, TextEditor } from 'vscode'; +import { Uri, window } from 'vscode'; import type { StoredNamedRef } from '../constants.storage'; import type { GitBranch } from '../git/models/branch'; import { isBranch } from '../git/models/branch'; @@ -23,84 +14,18 @@ import { isRemote } from '../git/models/remote'; import { Repository } from '../git/models/repository'; import type { GitTag } from '../git/models/tag'; import { isTag } from '../git/models/tag'; -import { CloudWorkspace, LocalWorkspace } from '../plus/workspaces/models'; -import { sequentialize } from '../system/function'; -import { registerCommand } from '../system/vscode/command'; -import { isScm, isScmResourceGroup, isScmResourceState } from '../system/vscode/scm'; +import { CloudWorkspace } from '../plus/workspaces/models/cloudWorkspace'; +import { LocalWorkspace } from '../plus/workspaces/models/localWorkspace'; +import { isScm, isScmResourceGroup, isScmResourceState } from '../system/-webview/scm'; +import { isGitTimelineItem } from '../system/-webview/timeline'; import { ViewNode } from '../views/nodes/abstract/viewNode'; import { ViewRefFileNode, ViewRefNode } from '../views/nodes/abstract/viewRefNode'; - -export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined { - // Always use the editor.uri (if we have one), so we are correct for a split diff - return editor?.document?.uri ?? uri; -} - -export interface CommandContextParsingOptions { - expectsEditor: boolean; -} - -export interface CommandBaseContext { - command: string; - editor?: TextEditor; - uri?: Uri; - - readonly args: unknown[]; -} - -export interface CommandEditorLineContext extends CommandBaseContext { - readonly type: 'editorLine'; - readonly line: number; - readonly uri: Uri; -} - -export interface CommandGitTimelineItemContext extends CommandBaseContext { - readonly type: 'timeline-item:git'; - readonly item: GitTimelineItem; - readonly uri: Uri; -} - -export interface CommandScmContext extends CommandBaseContext { - readonly type: 'scm'; - readonly scm: SourceControl; -} - -export interface CommandScmGroupsContext extends CommandBaseContext { - readonly type: 'scm-groups'; - readonly scmResourceGroups: SourceControlResourceGroup[]; -} - -export interface CommandScmStatesContext extends CommandBaseContext { - readonly type: 'scm-states'; - readonly scmResourceStates: SourceControlResourceState[]; -} - -export interface CommandUnknownContext extends CommandBaseContext { - readonly type: 'unknown'; -} - -export interface CommandUriContext extends CommandBaseContext { - readonly type: 'uri'; -} - -export interface CommandUrisContext extends CommandBaseContext { - readonly type: 'uris'; - readonly uris: Uri[]; -} - -// export interface CommandViewContext extends CommandBaseContext { -// readonly type: 'view'; -// } - -export interface CommandViewNodeContext extends CommandBaseContext { - readonly type: 'viewItem'; - readonly node: ViewNode; -} - -export interface CommandViewNodesContext extends CommandBaseContext { - readonly type: 'viewItems'; - readonly node: ViewNode; - readonly nodes: ViewNode[]; -} +import type { + CommandContext, + CommandEditorLineContext, + CommandGitTimelineItemContext, + CommandViewNodeContext, +} from './commandContext'; export function isCommandContextEditorLine(context: CommandContext): context is CommandEditorLineContext { return context.type === 'editorLine'; @@ -227,79 +152,8 @@ export function isCommandContextViewNodeHasWorkspace( return workspace instanceof CloudWorkspace || workspace instanceof LocalWorkspace; } -export type CommandContext = - | CommandEditorLineContext - | CommandGitTimelineItemContext - | CommandScmContext - | CommandScmGroupsContext - | CommandScmStatesContext - | CommandUnknownContext - | CommandUriContext - | CommandUrisContext - // | CommandViewContext - | CommandViewNodeContext - | CommandViewNodesContext; - -function isTimelineItem(item: any): item is TimelineItem { - if (item == null) return false; - - return (item as TimelineItem).timestamp != null && (item as TimelineItem).label != null; -} - -function isGitTimelineItem(item: any): item is GitTimelineItem { - if (item == null) return false; - - return ( - isTimelineItem(item) && - (item as GitTimelineItem).ref != null && - (item as GitTimelineItem).previousRef != null && - (item as GitTimelineItem).message != null - ); -} - -export abstract class GlCommandBase implements Disposable { - protected readonly contextParsingOptions: CommandContextParsingOptions = { expectsEditor: false }; - - private readonly _disposable: Disposable; - - constructor(command: GlCommands | GlCommands[]) { - if (typeof command === 'string') { - this._disposable = registerCommand(command, (...args: any[]) => this._execute(command, ...args), this); - - return; - } - - const subscriptions = command.map(cmd => - registerCommand(cmd, (...args: any[]) => this._execute(cmd, ...args), this), - ); - this._disposable = Disposable.from(...subscriptions); - } - - dispose() { - this._disposable.dispose(); - } - - protected preExecute(_context: CommandContext, ...args: any[]): Promise { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return this.execute(...args); - } - - abstract execute(...args: any[]): any; - - protected _execute(command: string, ...args: any[]): Promise { - const [context, rest] = parseCommandContext(command, { ...this.contextParsingOptions }, ...args); - - // If there an array of contexts, then we want to execute the command for each - if (Array.isArray(context)) { - return sequentialize( - this.preExecute, - context.map<[CommandContext, ...any[]]>((c: CommandContext) => [c, ...rest]), - this, - ); - } - - return this.preExecute(context, ...rest); - } +export interface CommandContextParsingOptions { + expectsEditor: boolean; } export function parseCommandContext( @@ -435,69 +289,3 @@ export function parseCommandContext( return [{ command: command, type: 'unknown', args: originalArgs, editor: editor, uri: editor?.document.uri }, args]; } - -export abstract class ActiveEditorCommand extends GlCommandBase { - protected override readonly contextParsingOptions: CommandContextParsingOptions = { expectsEditor: true }; - - protected override preExecute(context: CommandContext, ...args: any[]): Promise { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return this.execute(context.editor, context.uri, ...args); - } - - protected override _execute(command: string, ...args: any[]): any { - return super._execute(command, undefined, ...args); - } - - abstract override execute(editor?: TextEditor, ...args: any[]): any; -} - -let lastCommand: { command: string; args: any[] } | undefined = undefined; -export function getLastCommand() { - return lastCommand; -} - -export abstract class ActiveEditorCachedCommand extends ActiveEditorCommand { - protected override _execute(command: string, ...args: any[]): any { - lastCommand = { - command: command, - args: args, - }; - return super._execute(command, ...args); - } - - abstract override execute(editor: TextEditor, ...args: any[]): any; -} - -export abstract class EditorCommand implements Disposable { - private readonly _disposable: Disposable; - - constructor(command: GlCommands | GlCommands[]) { - if (!Array.isArray(command)) { - command = [command]; - } - - const subscriptions = []; - for (const cmd of command) { - subscriptions.push( - commands.registerTextEditorCommand( - cmd, - (editor: TextEditor, edit: TextEditorEdit, ...args: any[]) => - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - this.executeCore(cmd, editor, edit, ...args), - this, - ), - ); - } - this._disposable = Disposable.from(...subscriptions); - } - - dispose() { - this._disposable.dispose(); - } - - private executeCore(_command: string, editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any { - return this.execute(editor, edit, ...args); - } - - abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any; -} diff --git a/src/commands/compareWith.ts b/src/commands/compareWith.ts index f88fc7ec22082..a1defe36bad1b 100644 --- a/src/commands/compareWith.ts +++ b/src/commands/compareWith.ts @@ -3,10 +3,11 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; export interface CompareWithCommandArgs { ref1?: string; diff --git a/src/commands/copyCurrentBranch.ts b/src/commands/copyCurrentBranch.ts index ae99ee4f17a26..0e277bcf41c5e 100644 --- a/src/commands/copyCurrentBranch.ts +++ b/src/commands/copyCurrentBranch.ts @@ -5,9 +5,10 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; @command() export class CopyCurrentBranchCommand extends ActiveEditorCommand { diff --git a/src/commands/copyDeepLink.ts b/src/commands/copyDeepLink.ts index 97b0007abea7b..1ba2286517466 100644 --- a/src/commands/copyDeepLink.ts +++ b/src/commands/copyDeepLink.ts @@ -3,21 +3,21 @@ import { GlCommand } from '../constants.commands'; import type { StoredNamedRef } from '../constants.storage'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { getBranchNameAndRemote } from '../git/models/branch.utils'; import type { GitReference } from '../git/models/reference'; -import { createReference } from '../git/models/reference.utils'; +import { getBranchNameAndRemote } from '../git/utils/branch.utils'; +import { createReference } from '../git/utils/reference.utils'; import { showGenericErrorMessage } from '../messages'; import { ReferencesQuickPickIncludes, showReferencePicker } from '../quickpicks/referencePicker'; import { showRemotePicker } from '../quickpicks/remotePicker'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; import { normalizePath } from '../system/path'; -import { command } from '../system/vscode/command'; import { DeepLinkType, deepLinkTypeToString, refTypeToDeepLinkType } from '../uris/deepLinks/deepLink'; -import type { CommandContext } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import { - ActiveEditorCommand, - getCommandUri, isCommandContextEditorLine, isCommandContextViewNodeHasBranch, isCommandContextViewNodeHasCommit, @@ -25,7 +25,7 @@ import { isCommandContextViewNodeHasRemote, isCommandContextViewNodeHasTag, isCommandContextViewNodeHasWorkspace, -} from './base'; +} from './commandContext.utils'; export interface CopyDeepLinkCommandArgs { refOrRepoPath?: GitReference | string; diff --git a/src/commands/copyMessageToClipboard.ts b/src/commands/copyMessageToClipboard.ts index 369e349cf5957..d7f74492f7fe5 100644 --- a/src/commands/copyMessageToClipboard.ts +++ b/src/commands/copyMessageToClipboard.ts @@ -5,17 +5,17 @@ import type { Container } from '../container'; import { copyMessageToClipboard } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; import { first } from '../system/iterable'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import { - ActiveEditorCommand, - getCommandUri, isCommandContextViewNodeHasBranch, isCommandContextViewNodeHasCommit, isCommandContextViewNodeHasTag, -} from './base'; +} from './commandContext.utils'; export interface CopyMessageToClipboardCommandArgs { message?: string; diff --git a/src/commands/copyRelativePathToClipboard.ts b/src/commands/copyRelativePathToClipboard.ts index e1cd59d767b9c..588d319621b0c 100644 --- a/src/commands/copyRelativePathToClipboard.ts +++ b/src/commands/copyRelativePathToClipboard.ts @@ -2,9 +2,11 @@ import type { TextEditor, Uri } from 'vscode'; import { env } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasFileCommit } from './base'; +import { command } from '../system/-webview/command'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasFileCommit } from './commandContext.utils'; @command() export class CopyRelativePathToClipboardCommand extends ActiveEditorCommand { diff --git a/src/commands/copyShaToClipboard.ts b/src/commands/copyShaToClipboard.ts index b8ef9b67de84e..bc74ea8011832 100644 --- a/src/commands/copyShaToClipboard.ts +++ b/src/commands/copyShaToClipboard.ts @@ -3,20 +3,20 @@ import { env } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { shortenRevision } from '../git/models/revision.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { first } from '../system/iterable'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import type { CommandContext } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import { - ActiveEditorCommand, - getCommandUri, isCommandContextViewNodeHasBranch, isCommandContextViewNodeHasCommit, isCommandContextViewNodeHasTag, -} from './base'; +} from './commandContext.utils'; export interface CopyShaToClipboardCommandArgs { sha?: string; diff --git a/src/commands/createPullRequestOnRemote.ts b/src/commands/createPullRequestOnRemote.ts index 0d5e7c47df547..9fd7881f8ff70 100644 --- a/src/commands/createPullRequestOnRemote.ts +++ b/src/commands/createPullRequestOnRemote.ts @@ -1,14 +1,14 @@ import { window } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { getRemoteNameFromBranchName } from '../git/models/branch.utils'; import type { GitRemote } from '../git/models/remote'; import type { RemoteResource } from '../git/models/remoteResource'; import { RemoteResourceType } from '../git/models/remoteResource'; import type { RemoteProvider } from '../git/remotes/remoteProvider'; +import { getRemoteNameFromBranchName } from '../git/utils/branch.utils'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; -import { command, executeCommand } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command, executeCommand } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface CreatePullRequestOnRemoteCommandArgs { diff --git a/src/commands/diffFolderWithRevision.ts b/src/commands/diffFolderWithRevision.ts index bc6102a8590c6..2af0f948e5203 100644 --- a/src/commands/diffFolderWithRevision.ts +++ b/src/commands/diffFolderWithRevision.ts @@ -5,15 +5,16 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { openFolderCompare } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; -import { shortenRevision } from '../git/models/revision.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { showCommitPicker } from '../quickpicks/commitPicker'; import { CommandQuickPickItem } from '../quickpicks/items/common'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; import { pad } from '../system/string'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface DiffFolderWithRevisionCommandArgs { uri?: Uri; diff --git a/src/commands/diffFolderWithRevisionFrom.ts b/src/commands/diffFolderWithRevisionFrom.ts index 0241675106bcb..c96b1bb34535c 100644 --- a/src/commands/diffFolderWithRevisionFrom.ts +++ b/src/commands/diffFolderWithRevisionFrom.ts @@ -5,14 +5,15 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { openFolderCompare } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; -import { shortenRevision } from '../git/models/revision.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { ReferencesQuickPickIncludes, showReferencePicker } from '../quickpicks/referencePicker'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; import { pad } from '../system/string'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface DiffFolderWithRevisionFromCommandArgs { uri?: Uri; diff --git a/src/commands/diffLineWithPrevious.ts b/src/commands/diffLineWithPrevious.ts index 8892b38fc8051..388e68e02fb24 100644 --- a/src/commands/diffLineWithPrevious.ts +++ b/src/commands/diffLineWithPrevious.ts @@ -4,10 +4,11 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { showCommitHasNoPreviousCommitWarningMessage, showGenericErrorMessage } from '../messages'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffLineWithPreviousCommandArgs { diff --git a/src/commands/diffLineWithWorking.ts b/src/commands/diffLineWithWorking.ts index 2eda07f20ca76..2c21da440daaf 100644 --- a/src/commands/diffLineWithWorking.ts +++ b/src/commands/diffLineWithWorking.ts @@ -6,10 +6,11 @@ import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { uncommittedStaged } from '../git/models/revision'; import { showFileNotUnderSourceControlWarningMessage, showGenericErrorMessage } from '../messages'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffLineWithWorkingCommandArgs { diff --git a/src/commands/diffWith.ts b/src/commands/diffWith.ts index 9978b20953926..82ce3739be7ff 100644 --- a/src/commands/diffWith.ts +++ b/src/commands/diffWith.ts @@ -6,14 +6,14 @@ import type { Container } from '../container'; import type { GitCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; import { deletedOrMissing } from '../git/models/revision'; -import { isShaLike, isUncommitted, shortenRevision } from '../git/models/revision.utils'; +import { isShaLike, isUncommitted, shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; +import { openDiffEditor } from '../system/-webview/utils'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; import { basename } from '../system/path'; -import { command } from '../system/vscode/command'; -import { openDiffEditor } from '../system/vscode/utils'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export interface DiffWithCommandArgsRevision { sha: string; diff --git a/src/commands/diffWithNext.ts b/src/commands/diffWithNext.ts index 39311b8e35984..815502edd7b27 100644 --- a/src/commands/diffWithNext.ts +++ b/src/commands/diffWithNext.ts @@ -4,10 +4,11 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { showGenericErrorMessage } from '../messages'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffWithNextCommandArgs { diff --git a/src/commands/diffWithPrevious.ts b/src/commands/diffWithPrevious.ts index 9504a3b1d56af..7651516e27ecb 100644 --- a/src/commands/diffWithPrevious.ts +++ b/src/commands/diffWithPrevious.ts @@ -5,11 +5,12 @@ import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { deletedOrMissing } from '../git/models/revision'; import { showCommitHasNoPreviousCommitWarningMessage, showGenericErrorMessage } from '../messages'; +import { command, executeCommand } from '../system/-webview/command'; +import { findOrOpenEditor } from '../system/-webview/utils'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import { findOrOpenEditor } from '../system/vscode/utils'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffWithPreviousCommandArgs { diff --git a/src/commands/diffWithRevision.ts b/src/commands/diffWithRevision.ts index 0fc336563229d..3b8309c1a139f 100644 --- a/src/commands/diffWithRevision.ts +++ b/src/commands/diffWithRevision.ts @@ -3,17 +3,18 @@ import { GlyphChars, quickPickTitleMaxChars } from '../constants'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { shortenRevision } from '../git/models/revision.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { showCommitPicker } from '../quickpicks/commitPicker'; import { CommandQuickPickItem } from '../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive } from '../quickpicks/items/directive'; +import { command, executeCommand } from '../system/-webview/command'; +import { splitPath } from '../system/-webview/path'; import { Logger } from '../system/logger'; import { pad } from '../system/string'; -import { command, executeCommand } from '../system/vscode/command'; -import { splitPath } from '../system/vscode/path'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; import type { DiffWithCommandArgs } from './diffWith'; import type { DiffWithRevisionFromCommandArgs } from './diffWithRevisionFrom'; diff --git a/src/commands/diffWithRevisionFrom.ts b/src/commands/diffWithRevisionFrom.ts index 69e087bb55fb4..e35c9c5fc75ec 100644 --- a/src/commands/diffWithRevisionFrom.ts +++ b/src/commands/diffWithRevisionFrom.ts @@ -3,15 +3,16 @@ import { GlyphChars, quickPickTitleMaxChars } from '../constants'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { isBranchReference } from '../git/models/reference.utils'; -import { shortenRevision } from '../git/models/revision.utils'; +import { isBranchReference } from '../git/utils/reference.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showNoRepositoryWarningMessage } from '../messages'; import { showStashPicker } from '../quickpicks/commitPicker'; import { showReferencePicker } from '../quickpicks/referencePicker'; +import { command, executeCommand } from '../system/-webview/command'; import { basename } from '../system/path'; import { pad } from '../system/string'; -import { command, executeCommand } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffWithRevisionFromCommandArgs { diff --git a/src/commands/diffWithWorking.ts b/src/commands/diffWithWorking.ts index 5aabd8374f915..6709670abd33c 100644 --- a/src/commands/diffWithWorking.ts +++ b/src/commands/diffWithWorking.ts @@ -3,14 +3,15 @@ import { window } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { createReference } from '../git/models/reference.utils'; import { deletedOrMissing, uncommittedStaged } from '../git/models/revision'; +import { createReference } from '../git/utils/reference.utils'; import { showGenericErrorMessage } from '../messages'; import { showRevisionFilesPicker } from '../quickpicks/revisionFilesPicker'; +import { command, executeCommand } from '../system/-webview/command'; +import { findOrOpenEditor } from '../system/-webview/utils'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import { findOrOpenEditor } from '../system/vscode/utils'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; import type { DiffWithCommandArgs } from './diffWith'; export interface DiffWithWorkingCommandArgs { diff --git a/src/commands/externalDiff.ts b/src/commands/externalDiff.ts index cd192cfbfbbd6..fac7232d3f3ff 100644 --- a/src/commands/externalDiff.ts +++ b/src/commands/externalDiff.ts @@ -5,15 +5,16 @@ import { ScmResourceGroupType, ScmStatus } from '../@types/vscode.git.resources. import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { isUncommitted } from '../git/models/revision.utils'; +import { isUncommitted } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { filterMap } from '../system/array'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import type { CommandContext } from './base'; -import { GlCommandBase, isCommandContextViewNodeHasFileCommit, isCommandContextViewNodeHasFileRefs } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasFileCommit, isCommandContextViewNodeHasFileRefs } from './commandContext.utils'; interface ExternalDiffFile { uri: Uri; diff --git a/src/commands/generateCommitMessage.ts b/src/commands/generateCommitMessage.ts index 88397144dcb75..b2064157f446b 100644 --- a/src/commands/generateCommitMessage.ts +++ b/src/commands/generateCommitMessage.ts @@ -6,10 +6,11 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCoreCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCoreCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; export interface GenerateCommitMessageCommandArgs { repoPath?: string; diff --git a/src/commands/ghpr/openOrCreateWorktree.ts b/src/commands/ghpr/openOrCreateWorktree.ts index 890fe1aa0b9d3..6b9805b700b7f 100644 --- a/src/commands/ghpr/openOrCreateWorktree.ts +++ b/src/commands/ghpr/openOrCreateWorktree.ts @@ -4,14 +4,15 @@ import { GlCommand } from '../../constants.commands'; import type { Container } from '../../container'; import { create as createWorktree, open as openWorktree } from '../../git/actions/worktree'; import type { GitBranchReference } from '../../git/models/reference'; -import { createReference, getReferenceFromBranch } from '../../git/models/reference.utils'; import type { GitRemote } from '../../git/models/remote'; -import { getWorktreeForBranch } from '../../git/models/worktree.utils'; import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; +import { getReferenceFromBranch } from '../../git/utils/-webview/reference.utils'; +import { getWorktreeForBranch } from '../../git/utils/-webview/worktree.utils'; +import { createReference } from '../../git/utils/reference.utils'; +import { command } from '../../system/-webview/command'; import { Logger } from '../../system/logger'; import { waitUntilNextTick } from '../../system/promise'; -import { command } from '../../system/vscode/command'; -import { GlCommandBase } from '../base'; +import { GlCommandBase } from '../commandBase'; interface GHPRPullRequestNode { readonly pullRequestModel: GHPRPullRequest; diff --git a/src/commands/git/branch.ts b/src/commands/git/branch.ts index 0bbad16067f6b..236e31d3138ab 100644 --- a/src/commands/git/branch.ts +++ b/src/commands/git/branch.ts @@ -1,12 +1,17 @@ import { QuickInputButtons } from 'vscode'; import type { Container } from '../../container'; -import { addAssociatedIssueToBranch, getNameWithoutRemote } from '../../git/models/branch.utils'; import type { IssueShape } from '../../git/models/issue'; import type { GitBranchReference, GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isBranchReference, isRevisionReference } from '../../git/models/reference.utils'; import { Repository } from '../../git/models/repository'; import type { GitWorktree } from '../../git/models/worktree'; -import { getWorktreesByBranch } from '../../git/models/worktree.utils'; +import { addAssociatedIssueToBranch } from '../../git/utils/-webview/branch.issue.utils'; +import { getWorktreesByBranch } from '../../git/utils/-webview/worktree.utils'; +import { + getReferenceLabel, + getReferenceNameWithoutRemote, + isBranchReference, + isRevisionReference, +} from '../../git/utils/reference.utils'; import { showGenericErrorMessage } from '../../messages'; import { getIssueOwner } from '../../plus/integrations/providers/utils'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; @@ -382,7 +387,7 @@ export class BranchGitCommand extends QuickCommand { value: state.name ?? // if it's a remote branch, pre-fill the name (isBranchReference(state.reference) && state.reference.remote - ? getNameWithoutRemote(state.reference) + ? getReferenceNameWithoutRemote(state.reference) : undefined), }); if (result === StepResultBreak) continue; diff --git a/src/commands/git/cherry-pick.ts b/src/commands/git/cherry-pick.ts index 7f8ffbd08f14d..363118d2e39c8 100644 --- a/src/commands/git/cherry-pick.ts +++ b/src/commands/git/cherry-pick.ts @@ -2,9 +2,9 @@ import type { Container } from '../../container'; import type { GitBranch } from '../../git/models/branch'; import type { GitLog } from '../../git/models/log'; import type { GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isRevisionReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; -import { createRevisionRange } from '../../git/models/revision.utils'; +import { getReferenceLabel, isRevisionReference } from '../../git/utils/reference.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; diff --git a/src/commands/git/coauthors.ts b/src/commands/git/coauthors.ts index 9f82722104269..69bfa4fb1910d 100644 --- a/src/commands/git/coauthors.ts +++ b/src/commands/git/coauthors.ts @@ -1,8 +1,8 @@ import type { Container } from '../../container'; import type { GitContributor } from '../../git/models/contributor'; import type { Repository } from '../../git/models/repository'; +import { executeCoreCommand } from '../../system/-webview/command'; import { normalizePath } from '../../system/path'; -import { executeCoreCommand } from '../../system/vscode/command'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { PartialStepState, StepGenerator, StepState } from '../quickCommand'; import { endSteps, QuickCommand, StepResultBreak } from '../quickCommand'; diff --git a/src/commands/git/fetch.ts b/src/commands/git/fetch.ts index bed959f0d98aa..d55a9c783bed8 100644 --- a/src/commands/git/fetch.ts +++ b/src/commands/git/fetch.ts @@ -1,8 +1,8 @@ import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; import type { GitBranchReference } from '../../git/models/reference'; -import { getReferenceLabel, isBranchReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getReferenceLabel, isBranchReference } from '../../git/utils/reference.utils'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; import { isStringArray } from '../../system/array'; diff --git a/src/commands/git/log.ts b/src/commands/git/log.ts index 3fbc3497753d8..3d094aa0cd596 100644 --- a/src/commands/git/log.ts +++ b/src/commands/git/log.ts @@ -4,10 +4,10 @@ import { showDetailsView } from '../../git/actions/commit'; import { GitCommit } from '../../git/models/commit'; import type { GitLog } from '../../git/models/log'; import type { GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isRevisionRangeReference, isRevisionReference } from '../../git/models/reference.utils'; import { Repository } from '../../git/models/repository'; +import { getReferenceLabel, isRevisionRangeReference, isRevisionReference } from '../../git/utils/reference.utils'; +import { formatPath } from '../../system/-webview/formatPath'; import { pad } from '../../system/string'; -import { formatPath } from '../../system/vscode/formatPath'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { PartialStepState, StepGenerator, StepResult } from '../quickCommand'; import { endSteps, QuickCommand, StepResultBreak } from '../quickCommand'; diff --git a/src/commands/git/merge.ts b/src/commands/git/merge.ts index c8af0bba8db2d..a48e7f89a9fe2 100644 --- a/src/commands/git/merge.ts +++ b/src/commands/git/merge.ts @@ -3,10 +3,10 @@ import type { Container } from '../../container'; import type { GitBranch } from '../../git/models/branch'; import type { GitLog } from '../../git/models/log'; import type { GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isRevisionReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; -import { createRevisionRange } from '../../git/models/revision.utils'; -import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/account/subscription'; +import { getReferenceLabel, isRevisionReference } from '../../git/utils/reference.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; +import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/utils/subscription.utils'; import { createQuickPickSeparator } from '../../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive'; diff --git a/src/commands/git/pull.ts b/src/commands/git/pull.ts index 4fbad8ce567f4..eccc952e0a9a1 100644 --- a/src/commands/git/pull.ts +++ b/src/commands/git/pull.ts @@ -2,8 +2,8 @@ import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; import { isBranch } from '../../git/models/branch'; import type { GitBranchReference } from '../../git/models/reference'; -import { getReferenceLabel, isBranchReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getReferenceLabel, isBranchReference } from '../../git/utils/reference.utils'; import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; diff --git a/src/commands/git/push.ts b/src/commands/git/push.ts index 39be773cb8ab6..fd548d442a4c7 100644 --- a/src/commands/git/push.ts +++ b/src/commands/git/push.ts @@ -1,17 +1,17 @@ import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; import { Features } from '../../features'; -import { getRemoteNameFromBranchName } from '../../git/models/branch.utils'; import type { GitBranchReference, GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isBranchReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getRemoteNameFromBranchName } from '../../git/utils/branch.utils'; +import { getReferenceLabel, isBranchReference } from '../../git/utils/reference.utils'; import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; +import { configuration } from '../../system/-webview/configuration'; import { isStringArray } from '../../system/array'; import { fromNow } from '../../system/date'; import { pad, pluralize } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { AsyncStepResultGenerator, diff --git a/src/commands/git/rebase.ts b/src/commands/git/rebase.ts index b2beaba1c656f..9df26b2c73c78 100644 --- a/src/commands/git/rebase.ts +++ b/src/commands/git/rebase.ts @@ -3,17 +3,17 @@ import type { Container } from '../../container'; import type { GitBranch } from '../../git/models/branch'; import type { GitLog } from '../../git/models/log'; import type { GitReference } from '../../git/models/reference'; -import { getReferenceLabel, isRevisionReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; -import { createRevisionRange } from '../../git/models/revision.utils'; -import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/account/subscription'; +import { getReferenceLabel, isRevisionReference } from '../../git/utils/reference.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; +import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/utils/subscription.utils'; import { createQuickPickSeparator } from '../../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; +import { getEditorCommand } from '../../system/-webview/utils'; import { pluralize } from '../../system/string'; -import { getEditorCommand } from '../../system/vscode/utils'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { AsyncStepResultGenerator, diff --git a/src/commands/git/reset.ts b/src/commands/git/reset.ts index facbdc681722e..09c7913c81d34 100644 --- a/src/commands/git/reset.ts +++ b/src/commands/git/reset.ts @@ -2,8 +2,8 @@ import type { Container } from '../../container'; import type { GitBranch } from '../../git/models/branch'; import type { GitLog } from '../../git/models/log'; import type { GitReference, GitRevisionReference, GitTagReference } from '../../git/models/reference'; -import { getReferenceLabel } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; import { showGenericErrorMessage } from '../../messages'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; diff --git a/src/commands/git/revert.ts b/src/commands/git/revert.ts index a96a3217d9a90..480be51136aee 100644 --- a/src/commands/git/revert.ts +++ b/src/commands/git/revert.ts @@ -2,8 +2,8 @@ import type { Container } from '../../container'; import type { GitBranch } from '../../git/models/branch'; import type { GitLog } from '../../git/models/log'; import type { GitRevisionReference } from '../../git/models/reference'; -import { getReferenceLabel } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; diff --git a/src/commands/git/search.ts b/src/commands/git/search.ts index 058f0e0f8dafe..660869ba71ea4 100644 --- a/src/commands/git/search.ts +++ b/src/commands/git/search.ts @@ -13,10 +13,10 @@ import { showContributorsPicker } from '../../quickpicks/contributorsPicker'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import { ActionQuickPickItem } from '../../quickpicks/items/common'; import { isDirectiveQuickPickItem } from '../../quickpicks/items/directive'; +import { configuration } from '../../system/-webview/configuration'; +import { getContext } from '../../system/-webview/context'; import { first, join, map } from '../../system/iterable'; import { pluralize } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext } from '../../system/vscode/context'; import { SearchResultsNode } from '../../views/nodes/searchResultsNode'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { diff --git a/src/commands/git/stash.ts b/src/commands/git/stash.ts index 0d60488725a46..0a5721f96e3c9 100644 --- a/src/commands/git/stash.ts +++ b/src/commands/git/stash.ts @@ -6,16 +6,16 @@ import { reveal, showDetailsView } from '../../git/actions/stash'; import { StashApplyError, StashApplyErrorReason, StashPushError, StashPushErrorReason } from '../../git/errors'; import type { GitStashCommit } from '../../git/models/commit'; import type { GitStashReference } from '../../git/models/reference'; -import { getReferenceLabel } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; import { showGenericErrorMessage } from '../../messages'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; +import { getContext } from '../../system/-webview/context'; +import { formatPath } from '../../system/-webview/formatPath'; import { Logger } from '../../system/logger'; import { pad } from '../../system/string'; -import { getContext } from '../../system/vscode/context'; -import { formatPath } from '../../system/vscode/formatPath'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { AsyncStepResultGenerator, diff --git a/src/commands/git/status.ts b/src/commands/git/status.ts index 1408d89db6f83..48407591d7167 100644 --- a/src/commands/git/status.ts +++ b/src/commands/git/status.ts @@ -1,8 +1,8 @@ import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; -import { createReference, getReferenceLabel } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; import type { GitStatus } from '../../git/models/status'; +import { createReference, getReferenceLabel } from '../../git/utils/reference.utils'; import { CommandQuickPickItem } from '../../quickpicks/items/common'; import { GitWizardQuickPickItem } from '../../quickpicks/items/gitWizard'; import { pad } from '../../system/string'; diff --git a/src/commands/git/switch.ts b/src/commands/git/switch.ts index 92e7d4e918ab4..0f9d1f30a774c 100644 --- a/src/commands/git/switch.ts +++ b/src/commands/git/switch.ts @@ -1,13 +1,17 @@ import { ProgressLocation, window } from 'vscode'; import type { Container } from '../../container'; -import { getNameWithoutRemote } from '../../git/models/branch.utils'; import type { GitReference } from '../../git/models/reference'; -import { getReferenceLabel, getReferenceTypeLabel, isBranchReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { + getReferenceLabel, + getReferenceNameWithoutRemote, + getReferenceTypeLabel, + isBranchReference, +} from '../../git/utils/reference.utils'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import { createQuickPickSeparator } from '../../quickpicks/items/common'; +import { executeCommand } from '../../system/-webview/command'; import { isStringArray } from '../../system/array'; -import { executeCommand } from '../../system/vscode/command'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { PartialStepState, StepGenerator, StepResultGenerator, StepSelection, StepState } from '../quickCommand'; import { canPickStepContinue, endSteps, isCrossCommandReference, QuickCommand, StepResultBreak } from '../quickCommand'; @@ -298,7 +302,7 @@ export class SwitchGitCommand extends QuickCommand { value: state.createBranch ?? // if it's a remote branch, pre-fill the name (isBranchReference(state.reference) && state.reference.remote - ? getNameWithoutRemote(state.reference) + ? getReferenceNameWithoutRemote(state.reference) : undefined), }); diff --git a/src/commands/git/tag.ts b/src/commands/git/tag.ts index d9873b4c40ae2..ef7701460291c 100644 --- a/src/commands/git/tag.ts +++ b/src/commands/git/tag.ts @@ -1,9 +1,13 @@ import { QuickInputButtons } from 'vscode'; import type { Container } from '../../container'; -import { getNameWithoutRemote } from '../../git/models/branch.utils'; import type { GitReference, GitTagReference } from '../../git/models/reference'; -import { getReferenceLabel, isRevisionReference, isTagReference } from '../../git/models/reference.utils'; import type { Repository } from '../../git/models/repository'; +import { + getReferenceLabel, + getReferenceNameWithoutRemote, + isRevisionReference, + isTagReference, +} from '../../git/utils/reference.utils'; import { showGenericErrorMessage } from '../../messages'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; @@ -265,7 +269,7 @@ export class TagGitCommand extends QuickCommand { })}`, value: state.name ?? // if it's not a tag, pre-fill the name - (!isTagReference(state.reference) ? getNameWithoutRemote(state.reference) : undefined), + (!isTagReference(state.reference) ? getReferenceNameWithoutRemote(state.reference) : undefined), }); if (result === StepResultBreak) continue; diff --git a/src/commands/git/worktree.ts b/src/commands/git/worktree.ts index f1b5850230de5..e7d4bc48514fe 100644 --- a/src/commands/git/worktree.ts +++ b/src/commands/git/worktree.ts @@ -15,31 +15,31 @@ import { WorktreeDeleteError, WorktreeDeleteErrorReason, } from '../../git/errors'; -import { getNameWithoutRemote } from '../../git/models/branch.utils'; import type { GitBranchReference, GitReference } from '../../git/models/reference'; +import type { Repository } from '../../git/models/repository'; +import { uncommitted, uncommittedStaged } from '../../git/models/revision'; +import type { GitWorktree } from '../../git/models/worktree'; +import { getReferenceFromBranch } from '../../git/utils/-webview/reference.utils'; +import { getWorktreeForBranch } from '../../git/utils/-webview/worktree.utils'; import { - getReferenceFromBranch, getReferenceLabel, + getReferenceNameWithoutRemote, isBranchReference, isRevisionReference, -} from '../../git/models/reference.utils'; -import type { Repository } from '../../git/models/repository'; -import { uncommitted, uncommittedStaged } from '../../git/models/revision'; -import { isSha } from '../../git/models/revision.utils'; -import type { GitWorktree } from '../../git/models/worktree'; -import { getWorktreeForBranch } from '../../git/models/worktree.utils'; +} from '../../git/utils/reference.utils'; +import { isSha } from '../../git/utils/revision.utils'; import { showGenericErrorMessage } from '../../messages'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import { createQuickPickSeparator } from '../../quickpicks/items/common'; import { Directive } from '../../quickpicks/items/directive'; import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; +import { configuration } from '../../system/-webview/configuration'; +import { isDescendant } from '../../system/-webview/path'; +import { getWorkspaceFriendlyPath, openWorkspace, revealInFileExplorer } from '../../system/-webview/utils'; import { basename } from '../../system/path'; import type { Deferred } from '../../system/promise'; import { pluralize, truncateLeft } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; -import { isDescendant } from '../../system/vscode/path'; -import { getWorkspaceFriendlyPath, openWorkspace, revealInFileExplorer } from '../../system/vscode/utils'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { AsyncStepResultGenerator, @@ -425,7 +425,7 @@ export class WorktreeGitCommand extends QuickCommand { } if (isRemoteBranch) { - state.createBranch = getNameWithoutRemote(state.reference); + state.createBranch = getReferenceNameWithoutRemote(state.reference); const branch = await state.repo.git.branches().getBranch(state.createBranch); if (branch != null && !branch.remote) { state.createBranch = branch.name; @@ -711,7 +711,7 @@ export class WorktreeGitCommand extends QuickCommand { } const pickedFriendlyPath = truncateLeft(getWorkspaceFriendlyPath(pickedUri), 60); - const branchName = state.reference != null ? getNameWithoutRemote(state.reference) : undefined; + const branchName = state.reference != null ? getReferenceNameWithoutRemote(state.reference) : undefined; const recommendedFriendlyPath = `/${truncateLeft(branchName?.replace(/\\/g, '/') ?? '', 65)}`; const recommendedNewBranchFriendlyPath = `/${state.createBranch || ''}`; diff --git a/src/commands/gitWizard.ts b/src/commands/gitWizard.ts index 6d27d9b957638..3a0203cb543f3 100644 --- a/src/commands/gitWizard.ts +++ b/src/commands/gitWizard.ts @@ -1,7 +1,7 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; +import { command } from '../system/-webview/command'; +import type { CommandContext } from './commandContext'; import type { BranchGitCommandArgs } from './git/branch'; import type { CherryPickGitCommandArgs } from './git/cherry-pick'; import type { CoAuthorsGitCommandArgs } from './git/coauthors'; diff --git a/src/commands/inspect.ts b/src/commands/inspect.ts index aca6d5178e449..3fb37cb2a2b04 100644 --- a/src/commands/inspect.ts +++ b/src/commands/inspect.ts @@ -4,17 +4,20 @@ import type { Container } from '../container'; import { showDetailsView } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; import type { GitRevisionReference } from '../git/models/reference'; -import { createReference, getReferenceFromRevision } from '../git/models/reference.utils'; +import { getReferenceFromRevision } from '../git/utils/-webview/reference.utils'; +import { createReference } from '../git/utils/reference.utils'; import { showFileNotUnderSourceControlWarningMessage, showGenericErrorMessage, showLineUncommittedWarningMessage, } from '../messages'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasCommit } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasCommit } from './commandContext.utils'; export interface InspectCommandArgs { ref?: GitRevisionReference; diff --git a/src/commands/inviteToLiveShare.ts b/src/commands/inviteToLiveShare.ts index 76b53f3fe424f..f6441b536238a 100644 --- a/src/commands/inviteToLiveShare.ts +++ b/src/commands/inviteToLiveShare.ts @@ -1,9 +1,10 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { GlCommandBase, isCommandContextViewNodeHasContributor } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasContributor } from './commandContext.utils'; export interface InviteToLiveShareCommandArgs { email?: string; diff --git a/src/commands/logging.ts b/src/commands/logging.ts index 13a1b3ef0ec55..088db90bc072a 100644 --- a/src/commands/logging.ts +++ b/src/commands/logging.ts @@ -1,8 +1,8 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { GlCommandBase } from './commandBase'; @command() export class EnableDebugLoggingCommand extends GlCommandBase { diff --git a/src/commands/openAssociatedPullRequestOnRemote.ts b/src/commands/openAssociatedPullRequestOnRemote.ts index 5df4a891b30e5..b65e80d2e8261 100644 --- a/src/commands/openAssociatedPullRequestOnRemote.ts +++ b/src/commands/openAssociatedPullRequestOnRemote.ts @@ -3,9 +3,10 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; import type { OpenPullRequestOnRemoteCommandArgs } from './openPullRequestOnRemote'; @command() diff --git a/src/commands/openBranchOnRemote.ts b/src/commands/openBranchOnRemote.ts index 4ec6fa13efc95..eee8651cfbe27 100644 --- a/src/commands/openBranchOnRemote.ts +++ b/src/commands/openBranchOnRemote.ts @@ -2,16 +2,18 @@ import type { TextEditor, Uri } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/models/branch.utils'; import { RemoteResourceType } from '../git/models/remoteResource'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/utils/branch.utils'; import { showGenericErrorMessage } from '../messages'; import { CommandQuickPickItem } from '../quickpicks/items/common'; import { ReferencesQuickPickIncludes, showReferencePicker } from '../quickpicks/referencePicker'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasBranch } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasBranch } from './commandContext.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenBranchOnRemoteCommandArgs { diff --git a/src/commands/openBranchesOnRemote.ts b/src/commands/openBranchesOnRemote.ts index 1d7fce3180583..eb74097973feb 100644 --- a/src/commands/openBranchesOnRemote.ts +++ b/src/commands/openBranchesOnRemote.ts @@ -5,10 +5,12 @@ import { GitUri } from '../git/gitUri'; import { RemoteResourceType } from '../git/models/remoteResource'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasRemote } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasRemote } from './commandContext.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenBranchesOnRemoteCommandArgs { diff --git a/src/commands/openChangedFiles.ts b/src/commands/openChangedFiles.ts index 4d1ad5c25b61c..0d821b46474fb 100644 --- a/src/commands/openChangedFiles.ts +++ b/src/commands/openChangedFiles.ts @@ -4,11 +4,11 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; +import { findOrOpenEditors } from '../system/-webview/utils'; import { filterMap } from '../system/array'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { findOrOpenEditors } from '../system/vscode/utils'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export interface OpenChangedFilesCommandArgs { uris?: Uri[]; diff --git a/src/commands/openCommitOnRemote.ts b/src/commands/openCommitOnRemote.ts index 015e11cdc50c7..1272376b303ed 100644 --- a/src/commands/openCommitOnRemote.ts +++ b/src/commands/openCommitOnRemote.ts @@ -4,23 +4,20 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { RemoteResourceType } from '../git/models/remoteResource'; import { deletedOrMissing } from '../git/models/revision'; -import { isUncommitted } from '../git/models/revision.utils'; +import { isUncommitted } from '../git/utils/revision.utils'; import { showCommitNotFoundWarningMessage, showFileNotUnderSourceControlWarningMessage, showGenericErrorMessage, } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { - ActiveEditorCommand, - getCommandUri, - isCommandContextGitTimelineItem, - isCommandContextViewNodeHasCommit, -} from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextGitTimelineItem, isCommandContextViewNodeHasCommit } from './commandContext.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenCommitOnRemoteCommandArgs { diff --git a/src/commands/openComparisonOnRemote.ts b/src/commands/openComparisonOnRemote.ts index 8cc46465638c4..242b3776deffd 100644 --- a/src/commands/openComparisonOnRemote.ts +++ b/src/commands/openComparisonOnRemote.ts @@ -2,10 +2,10 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { RemoteResourceType } from '../git/models/remoteResource'; import { showGenericErrorMessage } from '../messages'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenComparisonOnRemoteCommandArgs { diff --git a/src/commands/openCurrentBranchOnRemote.ts b/src/commands/openCurrentBranchOnRemote.ts index 0acf2457e73b0..604162fa831d8 100644 --- a/src/commands/openCurrentBranchOnRemote.ts +++ b/src/commands/openCurrentBranchOnRemote.ts @@ -2,13 +2,14 @@ import type { TextEditor, Uri } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/models/branch.utils'; import { RemoteResourceType } from '../git/models/remoteResource'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/utils/branch.utils'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; @command() diff --git a/src/commands/openDirectoryCompare.ts b/src/commands/openDirectoryCompare.ts index e9faecc84c734..57076f603cf65 100644 --- a/src/commands/openDirectoryCompare.ts +++ b/src/commands/openDirectoryCompare.ts @@ -5,11 +5,13 @@ import { openDirectoryCompare } from '../git/actions/commit'; import { showGenericErrorMessage } from '../messages'; import { showReferencePicker } from '../quickpicks/referencePicker'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; import { CompareResultsNode } from '../views/nodes/compareResultsNode'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasRef } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasRef } from './commandContext.utils'; export interface OpenDirectoryCompareCommandArgs { ref1?: string; diff --git a/src/commands/openFileAtRevision.ts b/src/commands/openFileAtRevision.ts index 411c2a11fb39f..78452a6c9a8da 100644 --- a/src/commands/openFileAtRevision.ts +++ b/src/commands/openFileAtRevision.ts @@ -6,19 +6,20 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { openFileAtRevision } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; -import { shortenRevision } from '../git/models/revision.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showCommitHasNoPreviousCommitWarningMessage, showGenericErrorMessage } from '../messages'; import { showCommitPicker } from '../quickpicks/commitPicker'; import { CommandQuickPickItem } from '../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive } from '../quickpicks/items/directive'; +import { command } from '../system/-webview/command'; +import { splitPath } from '../system/-webview/path'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; import { pad } from '../system/string'; -import { command } from '../system/vscode/command'; -import { splitPath } from '../system/vscode/path'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; import type { OpenFileAtRevisionFromCommandArgs } from './openFileAtRevisionFrom'; export interface OpenFileAtRevisionCommandArgs { diff --git a/src/commands/openFileAtRevisionFrom.ts b/src/commands/openFileAtRevisionFrom.ts index f2717b775edcb..2c139e387be1d 100644 --- a/src/commands/openFileAtRevisionFrom.ts +++ b/src/commands/openFileAtRevisionFrom.ts @@ -9,9 +9,10 @@ import type { GitReference } from '../git/models/reference'; import { showNoRepositoryWarningMessage } from '../messages'; import { showStashPicker } from '../quickpicks/commitPicker'; import { showReferencePicker } from '../quickpicks/referencePicker'; +import { command } from '../system/-webview/command'; import { pad } from '../system/string'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface OpenFileAtRevisionFromCommandArgs { reference?: GitReference; diff --git a/src/commands/openFileFromRemote.ts b/src/commands/openFileFromRemote.ts index 0fc643b540f32..6e3d53655fead 100644 --- a/src/commands/openFileFromRemote.ts +++ b/src/commands/openFileFromRemote.ts @@ -1,9 +1,9 @@ import { env, Range, Uri, window } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import { openEditor } from '../system/vscode/utils'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { openEditor } from '../system/-webview/utils'; +import { GlCommandBase } from './commandBase'; @command() export class OpenFileFromRemoteCommand extends GlCommandBase { diff --git a/src/commands/openFileOnRemote.ts b/src/commands/openFileOnRemote.ts index 6e17aea799165..668fa2235949d 100644 --- a/src/commands/openFileOnRemote.ts +++ b/src/commands/openFileOnRemote.ts @@ -4,23 +4,20 @@ import { GlyphChars } from '../constants'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/models/branch.utils'; import { RemoteResourceType } from '../git/models/remoteResource'; -import { isSha } from '../git/models/revision.utils'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/utils/branch.utils'; +import { isSha } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { showReferencePicker } from '../quickpicks/referencePicker'; +import { command, executeCommand } from '../system/-webview/command'; import { UriComparer } from '../system/comparers'; import { Logger } from '../system/logger'; import { pad, splitSingle } from '../system/string'; -import { command, executeCommand } from '../system/vscode/command'; import { StatusFileNode } from '../views/nodes/statusFileNode'; -import type { CommandContext } from './base'; -import { - ActiveEditorCommand, - getCommandUri, - isCommandContextViewNodeHasBranch, - isCommandContextViewNodeHasCommit, -} from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasBranch, isCommandContextViewNodeHasCommit } from './commandContext.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenFileOnRemoteCommandArgs { diff --git a/src/commands/openOnRemote.ts b/src/commands/openOnRemote.ts index 311b1f7d1a421..71e0a05608547 100644 --- a/src/commands/openOnRemote.ts +++ b/src/commands/openOnRemote.ts @@ -2,18 +2,18 @@ import { GlyphChars } from '../constants'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import type { GitRemote } from '../git/models/remote'; -import { getHighlanderProviders } from '../git/models/remote'; import type { RemoteResource } from '../git/models/remoteResource'; import { RemoteResourceType } from '../git/models/remoteResource'; -import { createRevisionRange, shortenRevision } from '../git/models/revision.utils'; import type { RemoteProvider } from '../git/remotes/remoteProvider'; +import { getHighlanderProviders } from '../git/utils/remote.utils'; +import { createRevisionRange, shortenRevision } from '../git/utils/revision.utils'; import { showGenericErrorMessage } from '../messages'; import { showRemoteProviderPicker } from '../quickpicks/remoteProviderPicker'; +import { command } from '../system/-webview/command'; import { ensureArray } from '../system/array'; import { Logger } from '../system/logger'; import { pad, splitSingle } from '../system/string'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export type OpenOnRemoteCommandArgs = | { diff --git a/src/commands/openOnlyChangedFiles.ts b/src/commands/openOnlyChangedFiles.ts index 6283562aaf3af..1004f67cd834e 100644 --- a/src/commands/openOnlyChangedFiles.ts +++ b/src/commands/openOnlyChangedFiles.ts @@ -4,12 +4,12 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; +import { findOrOpenEditors } from '../system/-webview/utils'; import { filterMap } from '../system/array'; import { UriComparer } from '../system/comparers'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { findOrOpenEditors } from '../system/vscode/utils'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; export interface OpenOnlyChangedFilesCommandArgs { uris?: Uri[]; diff --git a/src/commands/openPullRequestOnRemote.ts b/src/commands/openPullRequestOnRemote.ts index 5d7c7e664f5e6..9bd9354b9ff57 100644 --- a/src/commands/openPullRequestOnRemote.ts +++ b/src/commands/openPullRequestOnRemote.ts @@ -1,11 +1,11 @@ import { env, window } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { shortenRevision } from '../git/models/revision.utils'; -import { command } from '../system/vscode/command'; -import { openUrl } from '../system/vscode/utils'; -import type { CommandContext } from './base'; -import { GlCommandBase } from './base'; +import { shortenRevision } from '../git/utils/revision.utils'; +import { command } from '../system/-webview/command'; +import { openUrl } from '../system/-webview/utils'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; export interface OpenPullRequestOnRemoteCommandArgs { clipboard?: boolean; diff --git a/src/commands/openRepoOnRemote.ts b/src/commands/openRepoOnRemote.ts index b8e8b86a2835c..389617e4fd92a 100644 --- a/src/commands/openRepoOnRemote.ts +++ b/src/commands/openRepoOnRemote.ts @@ -5,10 +5,12 @@ import { GitUri } from '../git/gitUri'; import { RemoteResourceType } from '../git/models/remoteResource'; import { showGenericErrorMessage } from '../messages'; import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command, executeCommand } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command, executeCommand } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCommand, getCommandUri, isCommandContextViewNodeHasRemote } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasRemote } from './commandContext.utils'; import type { OpenOnRemoteCommandArgs } from './openOnRemote'; export interface OpenRepoOnRemoteCommandArgs { diff --git a/src/commands/openRevisionFile.ts b/src/commands/openRevisionFile.ts index a2318ef046ce3..c692ccfdbe1e4 100644 --- a/src/commands/openRevisionFile.ts +++ b/src/commands/openRevisionFile.ts @@ -6,9 +6,10 @@ import { openFileAtRevision } from '../git/actions/commit'; import { GitUri } from '../git/gitUri'; import { deletedOrMissing } from '../git/models/revision'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface OpenRevisionFileCommandArgs { revisionUri?: Uri; diff --git a/src/commands/openWorkingFile.ts b/src/commands/openWorkingFile.ts index 6a21829baa1b7..00bc53b75b77d 100644 --- a/src/commands/openWorkingFile.ts +++ b/src/commands/openWorkingFile.ts @@ -5,10 +5,11 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri, isGitUri } from '../git/gitUri'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; +import { findOrOpenEditor } from '../system/-webview/utils'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { findOrOpenEditor } from '../system/vscode/utils'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface OpenWorkingFileCommandArgs { uri?: Uri; diff --git a/src/commands/patches.ts b/src/commands/patches.ts index 011c9df785687..f1f10f7c119e4 100644 --- a/src/commands/patches.ts +++ b/src/commands/patches.ts @@ -9,29 +9,28 @@ import type { IntegrationId } from '../constants.integrations'; import type { Container } from '../container'; import { CancellationError } from '../errors'; import { ApplyPatchCommitError, ApplyPatchCommitErrorReason } from '../git/errors'; -import { splitCommitMessage } from '../git/models/commit.utils'; import type { GitDiff } from '../git/models/diff'; import type { Repository } from '../git/models/repository'; import { uncommitted, uncommittedStaged } from '../git/models/revision'; -import { isSha, shortenRevision } from '../git/models/revision.utils'; -import type { Draft, LocalDraft } from '../gk/models/drafts'; +import { splitCommitMessage } from '../git/utils/commit.utils'; +import { isSha, shortenRevision } from '../git/utils/revision.utils'; import { showPatchesView } from '../plus/drafts/actions'; import type { ProviderAuth } from '../plus/drafts/draftsService'; +import type { Draft, LocalDraft } from '../plus/drafts/models/drafts'; import { getProviderIdFromEntityIdentifier } from '../plus/integrations/providers/utils'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { map } from '../system/iterable'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; import type { Change, CreateDraft } from '../webviews/plus/patchDetails/protocol'; -import type { CommandContext } from './base'; +import { ActiveEditorCommand, GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; import { - ActiveEditorCommand, - GlCommandBase, isCommandContextViewNodeHasCommit, isCommandContextViewNodeHasComparison, isCommandContextViewNodeHasFileCommit, isCommandContextViewNodeHasFileRefs, -} from './base'; +} from './commandContext.utils'; export interface CreatePatchCommandArgs { to?: string; diff --git a/src/commands/quickCommand.steps.ts b/src/commands/quickCommand.steps.ts index 8f0f2bab16fff..ada199825c595 100644 --- a/src/commands/quickCommand.steps.ts +++ b/src/commands/quickCommand.steps.ts @@ -18,35 +18,35 @@ import type { GitBranch } from '../git/models/branch'; import type { GitCommit, GitStashCommit } from '../git/models/commit'; import { isCommit, isStash } from '../git/models/commit'; import type { GitContributor } from '../git/models/contributor'; -import type { ContributorQuickPickItem } from '../git/models/contributor.quickpick'; -import { createContributorQuickPickItem } from '../git/models/contributor.quickpick'; import type { GitLog } from '../git/models/log'; import type { GitBranchReference, GitReference, GitRevisionReference, GitTagReference } from '../git/models/reference'; -import { - createReference, - getReferenceLabel, - isBranchReference, - isRevisionReference, - isStashReference, - isTagReference, -} from '../git/models/reference.utils'; import type { GitRemote } from '../git/models/remote'; -import { getHighlanderProviderName } from '../git/models/remote'; import { RemoteResourceType } from '../git/models/remoteResource'; import { Repository } from '../git/models/repository'; -import { createRevisionRange, isRevisionRange } from '../git/models/revision.utils'; import type { GitStash } from '../git/models/stash'; import type { GitStatus } from '../git/models/status'; import type { GitTag } from '../git/models/tag'; import type { GitWorktree } from '../git/models/worktree'; -import type { WorktreeQuickPickItem } from '../git/models/worktree.quickpick'; -import { createWorktreeQuickPickItem } from '../git/models/worktree.quickpick'; -import { getWorktreesByBranch } from '../git/models/worktree.utils'; import { remoteUrlRegex } from '../git/parsers/remoteParser'; -import type { BranchSortOptions, TagSortOptions } from '../git/utils/vscode/sorting'; -import { sortBranches, sortContributors, sortTags, sortWorktrees } from '../git/utils/vscode/sorting'; -import { getApplicablePromo } from '../plus/gk/account/promos'; -import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../plus/gk/account/subscription'; +import type { ContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick'; +import { createContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick'; +import type { BranchSortOptions, TagSortOptions } from '../git/utils/-webview/sorting'; +import { sortBranches, sortContributors, sortTags, sortWorktrees } from '../git/utils/-webview/sorting'; +import type { WorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick'; +import { createWorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick'; +import { getWorktreesByBranch } from '../git/utils/-webview/worktree.utils'; +import { + createReference, + getReferenceLabel, + isBranchReference, + isRevisionReference, + isStashReference, + isTagReference, +} from '../git/utils/reference.utils'; +import { getHighlanderProviderName } from '../git/utils/remote.utils'; +import { createRevisionRange, isRevisionRange } from '../git/utils/revision.utils'; +import { getApplicablePromo } from '../plus/gk/utils/promo.utils'; +import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../plus/gk/utils/subscription.utils'; import type { LaunchpadCommandArgs } from '../plus/launchpad/launchpad'; import { CommitApplyFileChangesCommandQuickPickItem, @@ -101,17 +101,17 @@ import { CopyRemoteResourceCommandQuickPickItem, OpenRemoteResourceCommandQuickPickItem, } from '../quickpicks/remoteProviderPicker'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { formatPath } from '../system/-webview/formatPath'; +import { openWorkspace } from '../system/-webview/utils'; +import { getIconPathUris } from '../system/-webview/vscode'; import { filterMap, intersection, isStringArray } from '../system/array'; import { debounce } from '../system/function'; import { first, map } from '../system/iterable'; import { Logger } from '../system/logger'; import { getSettledValue } from '../system/promise'; import { pad, pluralize, truncate } from '../system/string'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { formatPath } from '../system/vscode/formatPath'; -import { openWorkspace } from '../system/vscode/utils'; -import { getIconPathUris } from '../system/vscode/vscode'; import type { ViewsWithRepositoryFolders } from '../views/viewBase'; import type { AsyncStepResultGenerator, diff --git a/src/commands/quickCommand.ts b/src/commands/quickCommand.ts index 71bced2c40df2..87e93701edff8 100644 --- a/src/commands/quickCommand.ts +++ b/src/commands/quickCommand.ts @@ -5,7 +5,7 @@ import type { Container } from '../container'; import { createQuickPickSeparator } from '../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive, isDirective } from '../quickpicks/items/directive'; -import { configuration } from '../system/vscode/configuration'; +import { configuration } from '../system/-webview/configuration'; export interface CustomStep { type: 'custom'; diff --git a/src/commands/quickWizard.base.ts b/src/commands/quickWizard.base.ts index 7192eaf101843..f81c9fc4cbf9d 100644 --- a/src/commands/quickWizard.base.ts +++ b/src/commands/quickWizard.base.ts @@ -3,12 +3,12 @@ import { InputBoxValidationSeverity, QuickInputButtons, window } from 'vscode'; import type { GlCommands } from '../constants.commands'; import { Container } from '../container'; import { Directive, isDirective, isDirectiveQuickPickItem } from '../quickpicks/items/directive'; +import { configuration } from '../system/-webview/configuration'; +import type { KeyMapping } from '../system/-webview/keyboard'; import { log } from '../system/decorators/log'; import type { Deferred } from '../system/promise'; import { isPromise } from '../system/promise'; -import { configuration } from '../system/vscode/configuration'; -import type { KeyMapping } from '../system/vscode/keyboard'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; import type { GitWizardCommandArgs } from './gitWizard'; import type { CustomStep, QuickCommand, QuickInputStep, QuickPickStep, StepSelection } from './quickCommand'; import { isCustomStep, isQuickCommand, isQuickInputStep, isQuickPickStep, StepResultBreak } from './quickCommand'; diff --git a/src/commands/quickWizard.ts b/src/commands/quickWizard.ts index aedd3727bde5f..c1903bda76a2c 100644 --- a/src/commands/quickWizard.ts +++ b/src/commands/quickWizard.ts @@ -2,8 +2,8 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import type { LaunchpadCommandArgs } from '../plus/launchpad/launchpad'; import type { AssociateIssueWithBranchCommandArgs, StartWorkCommandArgs } from '../plus/startWork/startWork'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; +import { command } from '../system/-webview/command'; +import type { CommandContext } from './commandContext'; import type { QuickWizardCommandArgsWithCompletion } from './quickWizard.base'; import { QuickWizardCommandBase } from './quickWizard.base'; diff --git a/src/commands/quickWizard.utils.ts b/src/commands/quickWizard.utils.ts index 3b0a75e74ccdb..7b7458688be32 100644 --- a/src/commands/quickWizard.utils.ts +++ b/src/commands/quickWizard.utils.ts @@ -2,8 +2,8 @@ import type { StoredRecentUsage } from '../constants.storage'; import type { Container } from '../container'; import { LaunchpadCommand } from '../plus/launchpad/launchpad'; import { AssociateIssueWithBranchCommand, StartWorkCommand } from '../plus/startWork/startWork'; -import { configuration } from '../system/vscode/configuration'; -import { getContext } from '../system/vscode/context'; +import { configuration } from '../system/-webview/configuration'; +import { getContext } from '../system/-webview/context'; import { BranchGitCommand } from './git/branch'; import { CherryPickGitCommand } from './git/cherry-pick'; import { CoAuthorsGitCommand } from './git/coauthors'; diff --git a/src/commands/rebaseEditor.ts b/src/commands/rebaseEditor.ts index b3f7b67780f3d..55a9458db5899 100644 --- a/src/commands/rebaseEditor.ts +++ b/src/commands/rebaseEditor.ts @@ -1,7 +1,7 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class DisableRebaseEditorCommand extends GlCommandBase { diff --git a/src/commands/refreshHover.ts b/src/commands/refreshHover.ts index 3ddd21064b000..daf666365a7de 100644 --- a/src/commands/refreshHover.ts +++ b/src/commands/refreshHover.ts @@ -1,7 +1,7 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command, executeCoreCommand } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command, executeCoreCommand } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class RefreshHoverCommand extends GlCommandBase { diff --git a/src/commands/remoteProviders.ts b/src/commands/remoteProviders.ts index b47d5975075db..30fbe5d7815e3 100644 --- a/src/commands/remoteProviders.ts +++ b/src/commands/remoteProviders.ts @@ -6,11 +6,12 @@ import { isRemote } from '../git/models/remote'; import type { Repository } from '../git/models/repository'; import type { RemoteProvider } from '../git/remotes/remoteProvider'; import { showRepositoryPicker } from '../quickpicks/repositoryPicker'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { first } from '../system/iterable'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { GlCommandBase, isCommandContextViewNodeHasRemote } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasRemote } from './commandContext.utils'; export interface ConnectRemoteProviderCommandArgs { remote: string; diff --git a/src/commands/repositories.ts b/src/commands/repositories.ts index 43d41063284dc..e66159da94c80 100644 --- a/src/commands/repositories.ts +++ b/src/commands/repositories.ts @@ -1,8 +1,8 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class FetchRepositoriesCommand extends GlCommandBase { diff --git a/src/commands/resetViewsLayout.ts b/src/commands/resetViewsLayout.ts index e9c58bb3d30d7..f9c549e944fff 100644 --- a/src/commands/resetViewsLayout.ts +++ b/src/commands/resetViewsLayout.ts @@ -2,8 +2,8 @@ import { GlCommand } from '../constants.commands'; import type { ViewIds } from '../constants.views'; import { viewIdsByDefaultContainerId } from '../constants.views'; import type { Container } from '../container'; -import { command, executeCoreCommand } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command, executeCoreCommand } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class ResetViewsLayoutCommand extends GlCommandBase { diff --git a/src/commands/resets.ts b/src/commands/resets.ts index 4969e227b8d47..80e2dc851f6c2 100644 --- a/src/commands/resets.ts +++ b/src/commands/resets.ts @@ -5,9 +5,9 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import type { QuickPickItemOfT } from '../quickpicks/items/common'; import { createQuickPickSeparator } from '../quickpicks/items/common'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { GlCommandBase } from './commandBase'; const resetTypes = [ 'ai', diff --git a/src/commands/searchCommits.ts b/src/commands/searchCommits.ts index 3fa65cab4f2e8..c875d53942a9d 100644 --- a/src/commands/searchCommits.ts +++ b/src/commands/searchCommits.ts @@ -2,11 +2,12 @@ import { GlCommand } from '../constants.commands'; import type { SearchQuery } from '../constants.search'; import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { SearchResultsNode } from '../views/nodes/searchResultsNode'; -import type { CommandContext } from './base'; -import { GlCommandBase, isCommandContextViewNodeHasRepository } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasRepository } from './commandContext.utils'; export interface SearchCommitsCommandArgs { search?: Partial; diff --git a/src/commands/showCommitsInView.ts b/src/commands/showCommitsInView.ts index e70f3a45a4d1a..2185b3e2dac5a 100644 --- a/src/commands/showCommitsInView.ts +++ b/src/commands/showCommitsInView.ts @@ -5,11 +5,12 @@ import { executeGitCommand } from '../git/actions'; import { GitUri } from '../git/gitUri'; import { createSearchQueryForCommits } from '../git/search'; import { showFileNotUnderSourceControlWarningMessage, showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { filterMap } from '../system/iterable'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand, getCommandUri } from './base'; +import { ActiveEditorCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; export interface ShowCommitsInViewCommandArgs { refs?: string[]; diff --git a/src/commands/showLastQuickPick.ts b/src/commands/showLastQuickPick.ts index f1ab89c56e6c6..69fdcf9e020c9 100644 --- a/src/commands/showLastQuickPick.ts +++ b/src/commands/showLastQuickPick.ts @@ -2,9 +2,9 @@ import { commands } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { getLastCommand, GlCommandBase } from './base'; +import { getLastCommand, GlCommandBase } from './commandBase'; @command() export class ShowLastQuickPickCommand extends GlCommandBase { diff --git a/src/commands/showQuickBranchHistory.ts b/src/commands/showQuickBranchHistory.ts index 045ec76ba4987..84c316fe78f6c 100644 --- a/src/commands/showQuickBranchHistory.ts +++ b/src/commands/showQuickBranchHistory.ts @@ -4,10 +4,11 @@ import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; import { GitUri } from '../git/gitUri'; import type { GitReference } from '../git/models/reference'; -import { createReference } from '../git/models/reference.utils'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCachedCommand, getCommandUri } from './base'; +import { createReference } from '../git/utils/reference.utils'; +import { command } from '../system/-webview/command'; +import { ActiveEditorCachedCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; export interface ShowQuickBranchHistoryCommandArgs { repoPath?: string; diff --git a/src/commands/showQuickCommit.ts b/src/commands/showQuickCommit.ts index 68ec5c6490925..7c7b5b86038ac 100644 --- a/src/commands/showQuickCommit.ts +++ b/src/commands/showQuickCommit.ts @@ -12,11 +12,13 @@ import { showGenericErrorMessage, showLineUncommittedWarningMessage, } from '../messages'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCachedCommand, getCommandUri, isCommandContextViewNodeHasCommit } from './base'; +import { ActiveEditorCachedCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasCommit } from './commandContext.utils'; export interface ShowQuickCommitCommandArgs { repoPath?: string; diff --git a/src/commands/showQuickCommitFile.ts b/src/commands/showQuickCommitFile.ts index efb3fac0b7c40..023855b42d131 100644 --- a/src/commands/showQuickCommitFile.ts +++ b/src/commands/showQuickCommitFile.ts @@ -7,18 +7,20 @@ import { GitUri } from '../git/gitUri'; import type { GitCommit, GitStashCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; import type { GitLog } from '../git/models/log'; -import { createReference } from '../git/models/reference.utils'; +import { createReference } from '../git/utils/reference.utils'; import { showCommitNotFoundWarningMessage, showFileNotUnderSourceControlWarningMessage, showGenericErrorMessage, showLineUncommittedWarningMessage, } from '../messages'; +import { command } from '../system/-webview/command'; import { createMarkdownCommandLink } from '../system/commands'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { ActiveEditorCachedCommand, getCommandUri, isCommandContextViewNodeHasCommit } from './base'; +import { ActiveEditorCachedCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasCommit } from './commandContext.utils'; export interface ShowQuickCommitFileCommandArgs { commit?: GitCommit | GitStashCommit; diff --git a/src/commands/showQuickFileHistory.ts b/src/commands/showQuickFileHistory.ts index 0883a5d1491c1..3d0a4220457bc 100644 --- a/src/commands/showQuickFileHistory.ts +++ b/src/commands/showQuickFileHistory.ts @@ -8,10 +8,11 @@ import type { GitLog } from '../git/models/log'; import type { GitReference } from '../git/models/reference'; import type { GitTag } from '../git/models/tag'; import type { CommandQuickPickItem } from '../quickpicks/items/common'; -import { command } from '../system/vscode/command'; -import { getScmResourceFolderUri } from '../system/vscode/scm'; -import type { CommandContext } from './base'; -import { ActiveEditorCachedCommand, getCommandUri } from './base'; +import { command } from '../system/-webview/command'; +import { getScmResourceFolderUri } from '../system/-webview/scm'; +import { ActiveEditorCachedCommand } from './commandBase'; +import { getCommandUri } from './commandBase.utils'; +import type { CommandContext } from './commandContext'; export interface ShowQuickFileHistoryCommandArgs { reference?: GitBranch | GitTag | GitReference; diff --git a/src/commands/showQuickRepoStatus.ts b/src/commands/showQuickRepoStatus.ts index 24fc5f3b024b5..9291ebab3b8c0 100644 --- a/src/commands/showQuickRepoStatus.ts +++ b/src/commands/showQuickRepoStatus.ts @@ -1,8 +1,8 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; export interface ShowQuickRepoStatusCommandArgs { repoPath?: string; diff --git a/src/commands/showQuickStashList.ts b/src/commands/showQuickStashList.ts index 004d35616615d..8544df4785fca 100644 --- a/src/commands/showQuickStashList.ts +++ b/src/commands/showQuickStashList.ts @@ -1,8 +1,8 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { executeGitCommand } from '../git/actions'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; export interface ShowQuickStashListCommandArgs { repoPath?: string; diff --git a/src/commands/showView.ts b/src/commands/showView.ts index a2f1124dde45a..0f544ff1d415b 100644 --- a/src/commands/showView.ts +++ b/src/commands/showView.ts @@ -1,11 +1,11 @@ import { window } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command, executeCoreCommand } from '../system/vscode/command'; +import { command, executeCoreCommand } from '../system/-webview/command'; import type { HomeWebviewShowingArgs } from '../webviews/home/registration'; import type { GraphWebviewShowingArgs } from '../webviews/plus/graph/registration'; -import type { CommandContext } from './base'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; @command() export class ShowViewCommand extends GlCommandBase { diff --git a/src/commands/stashApply.ts b/src/commands/stashApply.ts index 22b1b63ba56c7..fb71460270104 100644 --- a/src/commands/stashApply.ts +++ b/src/commands/stashApply.ts @@ -4,9 +4,10 @@ import { apply, pop } from '../git/actions/stash'; import type { GitStashCommit } from '../git/models/commit'; import type { GitStashReference } from '../git/models/reference'; import type { CommandQuickPickItem } from '../quickpicks/items/common'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; -import { GlCommandBase, isCommandContextViewNodeHasCommit, isCommandContextViewNodeHasRepository } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; +import { isCommandContextViewNodeHasCommit, isCommandContextViewNodeHasRepository } from './commandContext.utils'; export interface StashApplyCommandArgs { deleteAfter?: boolean; diff --git a/src/commands/stashSave.ts b/src/commands/stashSave.ts index 6814ab728535a..2adcdca462980 100644 --- a/src/commands/stashSave.ts +++ b/src/commands/stashSave.ts @@ -6,14 +6,14 @@ import type { Container } from '../container'; import { Features } from '../features'; import { push } from '../git/actions/stash'; import { GitUri } from '../git/gitUri'; -import { command } from '../system/vscode/command'; -import type { CommandContext } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; +import type { CommandContext } from './commandContext'; import { - GlCommandBase, isCommandContextViewNodeHasFile, isCommandContextViewNodeHasRepoPath, isCommandContextViewNodeHasRepository, -} from './base'; +} from './commandContext.utils'; export interface StashSaveCommandArgs { message?: string; diff --git a/src/commands/switchAIModel.ts b/src/commands/switchAIModel.ts index 7b68a7e3f4c0b..42cf9840523d7 100644 --- a/src/commands/switchAIModel.ts +++ b/src/commands/switchAIModel.ts @@ -1,7 +1,7 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class SwitchAIModelCommand extends GlCommandBase { diff --git a/src/commands/switchMode.ts b/src/commands/switchMode.ts index 00384a638b41c..5680b9786407c 100644 --- a/src/commands/switchMode.ts +++ b/src/commands/switchMode.ts @@ -2,11 +2,11 @@ import { ConfigurationTarget } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showModePicker } from '../quickpicks/modePicker'; +import { command } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { log } from '../system/decorators/log'; import { getLogScope, setLogScopeExit } from '../system/logger.scope'; -import { command } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { GlCommandBase } from './base'; +import { GlCommandBase } from './commandBase'; @command() export class SwitchModeCommand extends GlCommandBase { diff --git a/src/commands/toggleCodeLens.ts b/src/commands/toggleCodeLens.ts index e8823a50b3113..7df37ac84ec00 100644 --- a/src/commands/toggleCodeLens.ts +++ b/src/commands/toggleCodeLens.ts @@ -1,7 +1,7 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { command } from '../system/vscode/command'; -import { GlCommandBase } from './base'; +import { command } from '../system/-webview/command'; +import { GlCommandBase } from './commandBase'; @command() export class ToggleCodeLensCommand extends GlCommandBase { diff --git a/src/commands/toggleFileAnnotations.ts b/src/commands/toggleFileAnnotations.ts index 3fc62d239db1b..8b94911d39cbc 100644 --- a/src/commands/toggleFileAnnotations.ts +++ b/src/commands/toggleFileAnnotations.ts @@ -4,10 +4,10 @@ import type { ChangesAnnotationContext } from '../annotations/gutterChangesAnnot import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; +import { getEditorIfVisible, getOtherVisibleTextEditors, isTrackableTextEditor } from '../system/-webview/utils'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { getEditorIfVisible, getOtherVisibleTextEditors, isTrackableTextEditor } from '../system/vscode/utils'; -import { ActiveEditorCommand, EditorCommand } from './base'; +import { ActiveEditorCommand, EditorCommand } from './commandBase'; @command() export class ClearFileAnnotationsCommand extends EditorCommand { diff --git a/src/commands/toggleLineBlame.ts b/src/commands/toggleLineBlame.ts index b5d37af26482f..6d772490cf83d 100644 --- a/src/commands/toggleLineBlame.ts +++ b/src/commands/toggleLineBlame.ts @@ -2,9 +2,9 @@ import type { TextEditor, Uri } from 'vscode'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { showGenericErrorMessage } from '../messages'; +import { command } from '../system/-webview/command'; import { Logger } from '../system/logger'; -import { command } from '../system/vscode/command'; -import { ActiveEditorCommand } from './base'; +import { ActiveEditorCommand } from './commandBase'; @command() export class ToggleLineBlameCommand extends ActiveEditorCommand { diff --git a/src/commands/walkthroughs.ts b/src/commands/walkthroughs.ts index 014046daec8ea..f3e0945ff4754 100644 --- a/src/commands/walkthroughs.ts +++ b/src/commands/walkthroughs.ts @@ -3,9 +3,9 @@ import { urls } from '../constants'; import { GlCommand } from '../constants.commands'; import type { Source, Sources } from '../constants.telemetry'; import type { Container } from '../container'; -import { command, executeCommand } from '../system/vscode/command'; -import { openUrl, openWalkthrough as openWalkthroughCore } from '../system/vscode/utils'; -import { GlCommandBase } from './base'; +import { command, executeCommand } from '../system/-webview/command'; +import { openUrl, openWalkthrough as openWalkthroughCore } from '../system/-webview/utils'; +import { GlCommandBase } from './commandBase'; @command() export class GetStartedCommand extends GlCommandBase { diff --git a/src/constants.storage.ts b/src/constants.storage.ts index 8ba966544b93f..bf18402de97d4 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -5,7 +5,7 @@ import type { TrackedUsage, TrackedUsageKeys } from './constants.telemetry'; import type { GroupableTreeViewTypes } from './constants.views'; import type { Environment } from './container'; import type { FeaturePreviews } from './features'; -import type { Subscription } from './plus/gk/account/subscription'; +import type { Subscription } from './plus/gk/models/subscription'; import type { Integration } from './plus/integrations/integration'; import type { DeepLinkServiceState } from './uris/deepLinks/deepLink'; diff --git a/src/constants.telemetry.ts b/src/constants.telemetry.ts index 0c491a5c6ebb5..e8362fa0a1308 100644 --- a/src/constants.telemetry.ts +++ b/src/constants.telemetry.ts @@ -7,7 +7,7 @@ import type { SubscriptionState, SubscriptionStateString } from './constants.sub import type { CustomEditorTypes, TreeViewTypes, WebviewTypes, WebviewViewTypes } from './constants.views'; import type { FeaturePreviews, FeaturePreviewStatus } from './features'; import type { GitContributionTiers } from './git/models/contributor'; -import type { Subscription, SubscriptionAccount } from './plus/gk/account/subscription'; +import type { Subscription, SubscriptionAccount } from './plus/gk/models/subscription'; import type { Flatten } from './system/object'; import type { WalkthroughContextKeys } from './telemetry/walkthroughStateProvider'; import type { GraphColumnConfig } from './webviews/plus/graph/protocol'; diff --git a/src/container.ts b/src/container.ts index e1fc71beed714..ea067a73b3637 100644 --- a/src/container.ts +++ b/src/container.ts @@ -18,13 +18,13 @@ import { GlCommand } from './constants.commands'; import { EventBus } from './eventBus'; import { GitFileSystemProvider } from './git/fsProvider'; import { GitProviderService } from './git/gitProviderService'; +import type { RepositoryPathMappingProvider } from './git/pathMapping/repositoryPathMappingProvider'; import { LineHoverController } from './hovers/lineHoverController'; -import type { RepositoryPathMappingProvider } from './pathMapping/repositoryPathMappingProvider'; import { DraftService } from './plus/drafts/draftsService'; -import { AccountAuthenticationProvider } from './plus/gk/account/authenticationProvider'; -import { OrganizationService } from './plus/gk/account/organizationService'; -import { SubscriptionService } from './plus/gk/account/subscriptionService'; +import { AccountAuthenticationProvider } from './plus/gk/authenticationProvider'; +import { OrganizationService } from './plus/gk/organizationService'; import { ServerConnection } from './plus/gk/serverConnection'; +import { SubscriptionService } from './plus/gk/subscriptionService'; import { GraphStatusBarController } from './plus/graph/statusbar'; import type { CloudIntegrationService } from './plus/integrations/authentication/cloudIntegrationService'; import { IntegrationAuthenticationService } from './plus/integrations/authentication/integrationAuthentication'; @@ -37,13 +37,13 @@ import { LaunchpadProvider } from './plus/launchpad/launchpadProvider'; import { RepositoryIdentityService } from './plus/repos/repositoryIdentityService'; import { scheduleAddMissingCurrentWorkspaceRepos, WorkspacesService } from './plus/workspaces/workspacesService'; import { StatusBarController } from './statusbar/statusBarController'; +import { executeCommand } from './system/-webview/command'; +import { configuration } from './system/-webview/configuration'; +import { Keyboard } from './system/-webview/keyboard'; +import type { Storage } from './system/-webview/storage'; +import { memoize } from './system/decorators/-webview/memoize'; import { log } from './system/decorators/log'; -import { memoize } from './system/decorators/memoize'; import { Logger } from './system/logger'; -import { executeCommand } from './system/vscode/command'; -import { configuration } from './system/vscode/configuration'; -import { Keyboard } from './system/vscode/keyboard'; -import type { Storage } from './system/vscode/storage'; import { TelemetryService } from './telemetry/telemetry'; import { UsageTracker } from './telemetry/usageTracker'; import { WalkthroughStateProvider } from './telemetry/walkthroughStateProvider'; diff --git a/src/env/browser/pathMapping/repositoryWebPathMappingProvider.ts b/src/env/browser/pathMapping/repositoryWebPathMappingProvider.ts index 4de00a0c52f47..c6ff80d658469 100644 --- a/src/env/browser/pathMapping/repositoryWebPathMappingProvider.ts +++ b/src/env/browser/pathMapping/repositoryWebPathMappingProvider.ts @@ -1,6 +1,6 @@ import type { Disposable } from 'vscode'; import type { Container } from '../../../container'; -import type { RepositoryPathMappingProvider } from '../../../pathMapping/repositoryPathMappingProvider'; +import type { RepositoryPathMappingProvider } from '../../../git/pathMapping/repositoryPathMappingProvider'; export class RepositoryWebPathMappingProvider implements RepositoryPathMappingProvider, Disposable { constructor(private readonly _container: Container) {} diff --git a/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts b/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts index a8985215f618d..576475fb2a958 100644 --- a/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts +++ b/src/env/browser/pathMapping/workspacesWebPathMappingProvider.ts @@ -1,5 +1,6 @@ import type { Uri } from 'vscode'; -import type { LocalWorkspaceFileData, WorkspaceAutoAddSetting } from '../../../plus/workspaces/models'; +import type { LocalWorkspaceFileData } from '../../../plus/workspaces/models/localWorkspace'; +import type { WorkspaceAutoAddSetting } from '../../../plus/workspaces/models/workspaces'; import type { WorkspacesPathMappingProvider } from '../../../plus/workspaces/workspacesPathMappingProvider'; export class WorkspacesWebPathMappingProvider implements WorkspacesPathMappingProvider { diff --git a/src/env/node/fetch.ts b/src/env/node/fetch.ts index 0dc29826505b7..a3bb6b6e8120a 100644 --- a/src/env/node/fetch.ts +++ b/src/env/node/fetch.ts @@ -2,8 +2,8 @@ import * as process from 'process'; import * as url from 'url'; import { HttpsProxyAgent } from 'https-proxy-agent'; import fetch from 'node-fetch'; +import { configuration } from '../../system/-webview/configuration'; import { Logger } from '../../system/logger'; -import { configuration } from '../../system/vscode/configuration'; export { fetch }; export type { BodyInit, HeadersInit, RequestInfo, RequestInit, Response } from 'node-fetch'; diff --git a/src/env/node/git/commitMessageProvider.ts b/src/env/node/git/commitMessageProvider.ts index 827c23ec21d41..3b0db447f28b2 100644 --- a/src/env/node/git/commitMessageProvider.ts +++ b/src/env/node/git/commitMessageProvider.ts @@ -6,10 +6,10 @@ import type { Repository as ScmGitRepository, } from '../../../@types/vscode.git'; import type { Container } from '../../../container'; +import { configuration } from '../../../system/-webview/configuration'; import { log } from '../../../system/decorators/log'; import { Logger } from '../../../system/logger'; import { getLogScope } from '../../../system/logger.scope'; -import { configuration } from '../../../system/vscode/configuration'; class AICommitMessageProvider implements CommitMessageProvider, Disposable { icon: ThemeIcon = new ThemeIcon('sparkle'); diff --git a/src/env/node/git/git.ts b/src/env/node/git/git.ts index 4a70cec6392da..298226222a780 100644 --- a/src/env/node/git/git.ts +++ b/src/env/node/git/git.ts @@ -31,11 +31,14 @@ import { import type { GitDir } from '../../../git/gitProvider'; import type { GitDiffFilter } from '../../../git/models/diff'; import type { GitRevisionRange } from '../../../git/models/revision'; -import { isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/models/revision.utils'; import type { GitUser } from '../../../git/models/user'; import { parseGitBranchesDefaultFormat } from '../../../git/parsers/branchParser'; import { parseGitLogAllFormat, parseGitLogDefaultFormat } from '../../../git/parsers/logParser'; import { parseGitRemoteUrl } from '../../../git/parsers/remoteParser'; +import { isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/utils/revision.utils'; +import { configuration } from '../../../system/-webview/configuration'; +import { splitPath } from '../../../system/-webview/path'; +import { getEditorCommand } from '../../../system/-webview/utils'; import { splitAt } from '../../../system/array'; import { log } from '../../../system/decorators/log'; import { join } from '../../../system/iterable'; @@ -45,9 +48,6 @@ import { getLoggableScopeBlockOverride, getLogScope } from '../../../system/logg import { dirname, isAbsolute, isFolderGlob, joinPaths, normalizePath } from '../../../system/path'; import { getDurationMilliseconds } from '../../../system/string'; import { compare, fromString } from '../../../system/version'; -import { configuration } from '../../../system/vscode/configuration'; -import { splitPath } from '../../../system/vscode/path'; -import { getEditorCommand } from '../../../system/vscode/utils'; import { ensureGitTerminal } from '../../../terminal'; import type { GitLocation } from './locator'; import type { RunOptions } from './shell'; diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index 102fdadb5f82e..9844b2c238f40 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -46,13 +46,6 @@ import { GitUri, isGitUri } from '../../../git/gitUri'; import { encodeGitLensRevisionUriAuthority } from '../../../git/gitUri.authority'; import type { GitBlame, GitBlameAuthor, GitBlameLine } from '../../../git/models/blame'; import type { GitBranch } from '../../../git/models/branch'; -import { - getBranchId, - getBranchNameAndRemote, - getBranchNameWithoutRemote, - getBranchTrackingWithoutRemote, - getRemoteNameFromBranchName, -} from '../../../git/models/branch.utils'; import type { GitCommit, GitStashCommit } from '../../../git/models/commit'; import type { GitDiff, @@ -62,8 +55,9 @@ import type { GitDiffLine, GitDiffShortStat, } from '../../../git/models/diff'; -import type { GitFile, GitFileStatus } from '../../../git/models/file'; -import { GitFileChange } from '../../../git/models/file'; +import type { GitFile } from '../../../git/models/file'; +import { GitFileChange } from '../../../git/models/fileChange'; +import type { GitFileStatus } from '../../../git/models/fileStatus'; import type { GitGraph, GitGraphRow, @@ -76,31 +70,17 @@ import type { } from '../../../git/models/graph'; import type { GitLog } from '../../../git/models/log'; import type { GitBranchReference, GitReference } from '../../../git/models/reference'; -import { createReference, isBranchReference } from '../../../git/models/reference.utils'; import type { GitReflog } from '../../../git/models/reflog'; import type { GitRemote } from '../../../git/models/remote'; -import { getVisibilityCacheKey } from '../../../git/models/remote'; import { RemoteResourceType } from '../../../git/models/remoteResource'; import type { RepositoryChangeEvent } from '../../../git/models/repository'; import { Repository, RepositoryChange, RepositoryChangeComparisonMode } from '../../../git/models/repository'; import type { GitRevisionRange } from '../../../git/models/revision'; import { deletedOrMissing, uncommitted, uncommittedStaged } from '../../../git/models/revision'; -import { - isRevisionRange, - isSha, - isShaLike, - isUncommitted, - isUncommittedStaged, - shortenRevision, -} from '../../../git/models/revision.utils'; import type { GitTag } from '../../../git/models/tag'; -import { getTagId } from '../../../git/models/tag'; import type { GitTreeEntry } from '../../../git/models/tree'; import type { GitUser } from '../../../git/models/user'; -import { isUserMatch } from '../../../git/models/user'; import type { GitWorktree } from '../../../git/models/worktree'; -import { getWorktreeId } from '../../../git/models/worktree'; -import { groupWorktreesByBranch } from '../../../git/models/worktree.utils'; import { parseGitBlame } from '../../../git/parsers/blameParser'; import { parseGitApplyFiles, @@ -127,7 +107,28 @@ import { parseGitRefLog, parseGitRefLogDefaultFormat } from '../../../git/parser import { parseGitLsFiles, parseGitTree } from '../../../git/parsers/treeParser'; import type { GitSearch, GitSearchResultData, GitSearchResults } from '../../../git/search'; import { getGitArgsFromSearchQuery, getSearchQueryComparisonKey } from '../../../git/search'; -import { getRemoteIconUri } from '../../../git/utils/vscode/icons'; +import { getRemoteIconUri } from '../../../git/utils/-webview/icons'; +import { groupWorktreesByBranch } from '../../../git/utils/-webview/worktree.utils'; +import { + getBranchId, + getBranchNameAndRemote, + getBranchNameWithoutRemote, + getBranchTrackingWithoutRemote, + getRemoteNameFromBranchName, +} from '../../../git/utils/branch.utils'; +import { createReference, isBranchReference } from '../../../git/utils/reference.utils'; +import { getVisibilityCacheKey } from '../../../git/utils/remote.utils'; +import { + isRevisionRange, + isSha, + isShaLike, + isUncommitted, + isUncommittedStaged, + shortenRevision, +} from '../../../git/utils/revision.utils'; +import { getTagId } from '../../../git/utils/tag.utils'; +import { isUserMatch } from '../../../git/utils/user.utils'; +import { getWorktreeId } from '../../../git/utils/worktree.utils'; import { showBlameInvalidIgnoreRevsFileWarningMessage, showGenericErrorMessage, @@ -137,8 +138,12 @@ import { showGitVersionUnsupportedErrorMessage, } from '../../../messages'; import { asRepoComparisonKey } from '../../../repositories'; +import { TimedCancellationSource } from '../../../system/-webview/cancellation'; +import { configuration } from '../../../system/-webview/configuration'; +import { getBestPath, relative, splitPath } from '../../../system/-webview/path'; +import { isFolderUri } from '../../../system/-webview/utils'; import { filterMap } from '../../../system/array'; -import { gate } from '../../../system/decorators/gate'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug, log } from '../../../system/decorators/log'; import { debounce } from '../../../system/function'; import { filterMap as filterMapIterable, find, first, join, last, map, skip, some } from '../../../system/iterable'; @@ -157,10 +162,6 @@ import { import { any, asSettled, getSettledValue } from '../../../system/promise'; import { equalsIgnoreCase, getDurationMilliseconds, splitSingle } from '../../../system/string'; import { compare, fromString } from '../../../system/version'; -import { TimedCancellationSource } from '../../../system/vscode/cancellation'; -import { configuration } from '../../../system/vscode/configuration'; -import { getBestPath, relative, splitPath } from '../../../system/vscode/path'; -import { isFolderUri } from '../../../system/vscode/utils'; import { serializeWebviewItemContext } from '../../../system/webview'; import type { CachedBlame, CachedDiff, CachedLog, TrackedGitDocument } from '../../../trackers/trackedDocument'; import { GitDocumentState } from '../../../trackers/trackedDocument'; @@ -1820,11 +1821,19 @@ export class LocalGitProvider implements GitProvider, Disposable { for (const c of parser.parse(data)) { files = c.files.map( f => - new GitFileChange(repoPath, f.path, f.status as GitFileStatus, f.originalPath, undefined, { - additions: f.additions, - deletions: f.deletions, - changes: 0, - }), + new GitFileChange( + this.container, + repoPath, + f.path, + f.status as GitFileStatus, + f.originalPath, + undefined, + { + additions: f.additions, + deletions: f.deletions, + changes: 0, + }, + ), ); break; } @@ -2596,7 +2605,7 @@ export class LocalGitProvider implements GitProvider, Disposable { const data = await this.git.apply2(repoPath, { stdin: contents }, '--numstat', '--summary', '-z'); if (!data) return undefined; - const files = parseGitApplyFiles(data, repoPath); + const files = parseGitApplyFiles(this.container, data, repoPath); return { files: files, }; diff --git a/src/env/node/git/sub-providers/branches.ts b/src/env/node/git/sub-providers/branches.ts index 904a5f163a7a0..75b2bc97437dd 100644 --- a/src/env/node/git/sub-providers/branches.ts +++ b/src/env/node/git/sub-providers/branches.ts @@ -10,23 +10,23 @@ import type { PagingOptions, } from '../../../../git/gitProvider'; import { GitBranch } from '../../../../git/models/branch'; -import { getLocalBranchByUpstream, isDetachedHead } from '../../../../git/models/branch.utils'; import type { MergeConflict } from '../../../../git/models/mergeConflict'; import type { GitBranchReference } from '../../../../git/models/reference'; -import { getReferenceFromBranch } from '../../../../git/models/reference.utils'; -import { createRevisionRange } from '../../../../git/models/revision.utils'; import { parseGitBranches } from '../../../../git/parsers/branchParser'; import { parseMergeTreeConflict } from '../../../../git/parsers/mergeTreeParser'; -import type { BranchSortOptions } from '../../../../git/utils/vscode/sorting'; -import { sortBranches, sortContributors } from '../../../../git/utils/vscode/sorting'; +import { getReferenceFromBranch } from '../../../../git/utils/-webview/reference.utils'; +import type { BranchSortOptions } from '../../../../git/utils/-webview/sorting'; +import { sortBranches, sortContributors } from '../../../../git/utils/-webview/sorting'; +import { getLocalBranchByUpstream, isDetachedHead } from '../../../../git/utils/branch.utils'; +import { createRevisionRange } from '../../../../git/utils/revision.utils'; +import { configuration } from '../../../../system/-webview/configuration'; import { filterMap } from '../../../../system/array'; -import { gate } from '../../../../system/decorators/gate'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { log } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import { getLogScope } from '../../../../system/logger.scope'; import { PageableResult } from '../../../../system/paging'; import { getSettledValue } from '../../../../system/promise'; -import { configuration } from '../../../../system/vscode/configuration'; import type { Git } from '../git'; import type { LocalGitProvider } from '../localGitProvider'; diff --git a/src/env/node/git/sub-providers/contributors.ts b/src/env/node/git/sub-providers/contributors.ts index ac41d67c0dc5b..8e81f245e1e17 100644 --- a/src/env/node/git/sub-providers/contributors.ts +++ b/src/env/node/git/sub-providers/contributors.ts @@ -3,10 +3,10 @@ import type { GitCache } from '../../../../git/cache'; import type { GitContributorsSubProvider } from '../../../../git/gitProvider'; import type { GitContributorStats } from '../../../../git/models/contributor'; import { GitContributor } from '../../../../git/models/contributor'; -import { calculateContributionScore } from '../../../../git/models/contributor.utils'; -import { isUserMatch } from '../../../../git/models/user'; import { getContributorsParser } from '../../../../git/parsers/logParser'; -import { gate } from '../../../../system/decorators/gate'; +import { calculateContributionScore } from '../../../../git/utils/contributor.utils'; +import { isUserMatch } from '../../../../git/utils/user.utils'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { log } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import { getLogScope } from '../../../../system/logger.scope'; diff --git a/src/env/node/git/sub-providers/remotes.ts b/src/env/node/git/sub-providers/remotes.ts index f5bc80f92ad94..768e24a81fbb4 100644 --- a/src/env/node/git/sub-providers/remotes.ts +++ b/src/env/node/git/sub-providers/remotes.ts @@ -3,15 +3,15 @@ import type { Container } from '../../../../container'; import type { GitCache } from '../../../../git/cache'; import type { GitRemotesSubProvider } from '../../../../git/gitProvider'; import type { GitRemote } from '../../../../git/models/remote'; -import { sortRemotes } from '../../../../git/models/remote'; import { parseGitRemotes } from '../../../../git/parsers/remoteParser'; import { getRemoteProviderMatcher, loadRemoteProviders } from '../../../../git/remotes/remoteProviders'; import { RemotesGitProviderBase } from '../../../../git/sub-providers/remotes'; -import { gate } from '../../../../system/decorators/gate'; +import { sortRemotes } from '../../../../git/utils/remote.utils'; +import { configuration } from '../../../../system/-webview/configuration'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { log } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import { getLogScope } from '../../../../system/logger.scope'; -import { configuration } from '../../../../system/vscode/configuration'; import type { Git } from '../git'; import type { LocalGitProvider } from '../localGitProvider'; diff --git a/src/env/node/git/sub-providers/staging.ts b/src/env/node/git/sub-providers/staging.ts index bf6135160db44..d348e61d7c0f1 100644 --- a/src/env/node/git/sub-providers/staging.ts +++ b/src/env/node/git/sub-providers/staging.ts @@ -1,8 +1,8 @@ import type { Uri } from 'vscode'; import type { Container } from '../../../../container'; import type { GitStagingSubProvider } from '../../../../git/gitProvider'; +import { splitPath } from '../../../../system/-webview/path'; import { log } from '../../../../system/decorators/log'; -import { splitPath } from '../../../../system/vscode/path'; import type { Git } from '../git'; export class StagingGitSubProvider implements GitStagingSubProvider { diff --git a/src/env/node/git/sub-providers/stash.ts b/src/env/node/git/sub-providers/stash.ts index 62bb2437b7580..2f5532f847583 100644 --- a/src/env/node/git/sub-providers/stash.ts +++ b/src/env/node/git/sub-providers/stash.ts @@ -6,19 +6,21 @@ import { StashApplyError, StashApplyErrorReason } from '../../../../git/errors'; import type { GitStashSubProvider } from '../../../../git/gitProvider'; import type { GitStashCommit } from '../../../../git/models/commit'; import { GitCommit, GitCommitIdentity } from '../../../../git/models/commit'; -import type { GitFileStatus } from '../../../../git/models/file'; -import { GitFileChange, GitFileWorkingTreeStatus, mapFilesWithStats } from '../../../../git/models/file'; +import { GitFileChange } from '../../../../git/models/fileChange'; +import type { GitFileStatus } from '../../../../git/models/fileStatus'; +import { GitFileWorkingTreeStatus } from '../../../../git/models/fileStatus'; import { RepositoryChange } from '../../../../git/models/repository'; import type { GitStash } from '../../../../git/models/stash'; import type { ParserWithFilesAndMaybeStats } from '../../../../git/parsers/logParser'; import { createLogParserWithFiles, createLogParserWithFilesAndStats } from '../../../../git/parsers/logParser'; +import { mapFilesWithStats } from '../../../../git/utils/-webview/fileChange.utils'; +import { configuration } from '../../../../system/-webview/configuration'; +import { splitPath } from '../../../../system/-webview/path'; import { countStringLength } from '../../../../system/array'; -import { gate } from '../../../../system/decorators/gate'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { log } from '../../../../system/decorators/log'; import { min } from '../../../../system/iterable'; import { getSettledValue } from '../../../../system/promise'; -import { configuration } from '../../../../system/vscode/configuration'; -import { splitPath } from '../../../../system/vscode/path'; import type { Git } from '../git'; import { maxGitCliLength } from '../git'; import { RunError } from '../shell'; @@ -127,7 +129,14 @@ export class StashGitSubProvider implements GitStashSubProvider { s.parents.split(' '), message, s.files?.map( - f => new GitFileChange(repoPath, f.path, f.status as GitFileStatus, f.originalPath), + f => + new GitFileChange( + this.container, + repoPath, + f.path, + f.status as GitFileStatus, + f.originalPath, + ), ) ?? [], undefined, [], @@ -221,7 +230,7 @@ export class StashGitSubProvider implements GitStashSubProvider { files ??= []; if (stashFilesStatsResult.status === 'fulfilled' && stashFilesStatsResult.value != null) { - files = mapFilesWithStats(files, stashFilesStatsResult.value); + files = mapFilesWithStats(this.container, files, stashFilesStatsResult.value); } return files; @@ -252,6 +261,7 @@ export class StashGitSubProvider implements GitStashSubProvider { s.files?.map( f => new GitFileChange( + this.container, repoPath, f.path, (options?.untracked === 'only' diff --git a/src/env/node/git/sub-providers/status.ts b/src/env/node/git/sub-providers/status.ts index 16427f09a13c3..de5504ebb6eed 100644 --- a/src/env/node/git/sub-providers/status.ts +++ b/src/env/node/git/sub-providers/status.ts @@ -18,16 +18,17 @@ import type { GitRevertStatus, } from '../../../../git/models/pausedOperationStatus'; import type { GitBranchReference, GitTagReference } from '../../../../git/models/reference'; -import { createReference, getReferenceFromBranch } from '../../../../git/models/reference.utils'; -import type { GitStatusFile } from '../../../../git/models/status'; import { GitStatus } from '../../../../git/models/status'; +import type { GitStatusFile } from '../../../../git/models/statusFile'; import { parseGitStatus } from '../../../../git/parsers/statusParser'; -import { gate } from '../../../../system/decorators/gate'; +import { getReferenceFromBranch } from '../../../../git/utils/-webview/reference.utils'; +import { createReference } from '../../../../git/utils/reference.utils'; +import { configuration } from '../../../../system/-webview/configuration'; +import { splitPath } from '../../../../system/-webview/path'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { log } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import { getSettledValue } from '../../../../system/promise'; -import { configuration } from '../../../../system/vscode/configuration'; -import { splitPath } from '../../../../system/vscode/path'; import type { Git } from '../git'; import { GitErrors } from '../git'; import type { LocalGitProvider } from '../localGitProvider'; @@ -470,12 +471,13 @@ export class StatusGitSubProvider implements GitStatusSubProvider { const data = await this.git.status(repoPath, porcelainVersion, { similarityThreshold: configuration.get('advanced.similarityThreshold') ?? undefined, }); - const status = parseGitStatus(data, repoPath, porcelainVersion); + const status = parseGitStatus(this.container, data, repoPath, porcelainVersion); if (status?.detached) { const pausedOpStatus = await this.getPausedOperationStatus(repoPath); if (pausedOpStatus?.type === 'rebase') { return new GitStatus( + this.container, repoPath, pausedOpStatus.incoming.name, status.sha, diff --git a/src/env/node/git/sub-providers/tags.ts b/src/env/node/git/sub-providers/tags.ts index 925bf40b902e7..f1ce1ce4fc752 100644 --- a/src/env/node/git/sub-providers/tags.ts +++ b/src/env/node/git/sub-providers/tags.ts @@ -4,8 +4,8 @@ import { TagError } from '../../../../git/errors'; import type { GitTagsSubProvider, PagedResult, PagingOptions } from '../../../../git/gitProvider'; import type { GitTag } from '../../../../git/models/tag'; import { parseGitTags, parseGitTagsDefaultFormat } from '../../../../git/parsers/tagParser'; -import type { TagSortOptions } from '../../../../git/utils/vscode/sorting'; -import { sortTags } from '../../../../git/utils/vscode/sorting'; +import type { TagSortOptions } from '../../../../git/utils/-webview/sorting'; +import { sortTags } from '../../../../git/utils/-webview/sorting'; import { log } from '../../../../system/decorators/log'; import type { Git } from '../git'; @@ -42,7 +42,7 @@ export class TagsGitSubProvider implements GitTagsSubProvider { async function load(this: TagsGitSubProvider): Promise> { try { const data = await this.git.tag(repoPath, '-l', `--format=${parseGitTagsDefaultFormat}`); - return { values: parseGitTags(data, repoPath) }; + return { values: parseGitTags(this.container, data, repoPath) }; } catch (_ex) { this.cache.tags?.delete(repoPath); diff --git a/src/env/node/git/sub-providers/worktrees.ts b/src/env/node/git/sub-providers/worktrees.ts index 767cdd6e0689c..7066ae60983ec 100644 --- a/src/env/node/git/sub-providers/worktrees.ts +++ b/src/env/node/git/sub-providers/worktrees.ts @@ -13,12 +13,12 @@ import { import type { GitWorktreesSubProvider } from '../../../../git/gitProvider'; import type { GitWorktree } from '../../../../git/models/worktree'; import { parseGitWorktrees } from '../../../../git/parsers/worktreeParser'; +import { configuration } from '../../../../system/-webview/configuration'; import { log } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import { getLogScope } from '../../../../system/logger.scope'; import { joinPaths, normalizePath } from '../../../../system/path'; import { interpolate } from '../../../../system/string'; -import { configuration } from '../../../../system/vscode/configuration'; import type { Git } from '../git'; import { GitErrors } from '../git'; import type { LocalGitProvider } from '../localGitProvider'; diff --git a/src/env/node/git/vslsGitProvider.ts b/src/env/node/git/vslsGitProvider.ts index b1fae5ba6e9cf..a0e8f657f53c2 100644 --- a/src/env/node/git/vslsGitProvider.ts +++ b/src/env/node/git/vslsGitProvider.ts @@ -5,10 +5,10 @@ import { Container } from '../../../container'; import type { GitCommandOptions, GitSpawnOptions } from '../../../git/commandOptions'; import type { GitProviderDescriptor } from '../../../git/gitProvider'; import type { Repository } from '../../../git/models/repository'; +import { addVslsPrefixIfNeeded } from '../../../system/-webview/path'; +import { isFolderUri } from '../../../system/-webview/utils'; import { Logger } from '../../../system/logger'; import { getLogScope } from '../../../system/logger.scope'; -import { addVslsPrefixIfNeeded } from '../../../system/vscode/path'; -import { isFolderUri } from '../../../system/vscode/utils'; import { Git } from './git'; import { LocalGitProvider } from './localGitProvider'; diff --git a/src/env/node/pathMapping/repositoryLocalPathMappingProvider.ts b/src/env/node/pathMapping/repositoryLocalPathMappingProvider.ts index 09a8bec667fad..921d4570ea0e9 100644 --- a/src/env/node/pathMapping/repositoryLocalPathMappingProvider.ts +++ b/src/env/node/pathMapping/repositoryLocalPathMappingProvider.ts @@ -1,8 +1,8 @@ import type { Disposable } from 'vscode'; import { workspace } from 'vscode'; import type { Container } from '../../../container'; -import type { LocalRepoDataMap } from '../../../pathMapping/models'; -import type { RepositoryPathMappingProvider } from '../../../pathMapping/repositoryPathMappingProvider'; +import type { LocalRepoDataMap } from '../../../git/models/pathMapping'; +import type { RepositoryPathMappingProvider } from '../../../git/pathMapping/repositoryPathMappingProvider'; import { Logger } from '../../../system/logger'; import { SharedGKDataFolderMapper } from './sharedGKDataFolder'; diff --git a/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts b/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts index 1eef26a162288..4f2806429778e 100644 --- a/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts +++ b/src/env/node/pathMapping/workspacesLocalPathMappingProvider.ts @@ -1,10 +1,7 @@ import { Uri, workspace } from 'vscode'; -import type { - CloudWorkspacesPathMap, - CodeWorkspaceFileContents, - LocalWorkspaceFileData, - WorkspaceAutoAddSetting, -} from '../../../plus/workspaces/models'; +import type { CloudWorkspacesPathMap } from '../../../plus/workspaces/models/cloudWorkspace'; +import type { LocalWorkspaceFileData } from '../../../plus/workspaces/models/localWorkspace'; +import type { CodeWorkspaceFileContents, WorkspaceAutoAddSetting } from '../../../plus/workspaces/models/workspaces'; import type { WorkspacesPathMappingProvider } from '../../../plus/workspaces/workspacesPathMappingProvider'; import { Logger } from '../../../system/logger'; import { getSharedLegacyLocalWorkspaceMappingFileUri, SharedGKDataFolderMapper } from './sharedGKDataFolder'; diff --git a/src/env/node/providers.ts b/src/env/node/providers.ts index aeb8bb4a9a298..daf6a7b980639 100644 --- a/src/env/node/providers.ts +++ b/src/env/node/providers.ts @@ -2,7 +2,7 @@ import type { Container } from '../../container'; import type { GitCommandOptions } from '../../git/commandOptions'; import type { GitProvider } from '../../git/gitProvider'; import type { IntegrationAuthenticationService } from '../../plus/integrations/authentication/integrationAuthentication'; -import { configuration } from '../../system/vscode/configuration'; +import { configuration } from '../../system/-webview/configuration'; // import { GitHubGitProvider } from '../../plus/github/githubGitProvider'; import { Git } from './git/git'; import { LocalGitProvider } from './git/localGitProvider'; diff --git a/src/errors.ts b/src/errors.ts index f193a25b1775a..f24065f1efcbf 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -2,8 +2,8 @@ import type { Uri } from 'vscode'; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { CancellationError as _CancellationError } from 'vscode'; import type { Response } from '@env/fetch'; -import type { RequiredSubscriptionPlans, Subscription } from './plus/gk/account/subscription'; -import { isSubscriptionPaidPlan } from './plus/gk/account/subscription'; +import type { RequiredSubscriptionPlans, Subscription } from './plus/gk/models/subscription'; +import { isSubscriptionPaidPlan } from './plus/gk/utils/subscription.utils'; export class AccessDeniedError extends Error { public readonly subscription: Subscription; diff --git a/src/eventBus.ts b/src/eventBus.ts index 41bdc29404ed6..2b9e64143ce93 100644 --- a/src/eventBus.ts +++ b/src/eventBus.ts @@ -5,7 +5,7 @@ import type { GitCaches } from './git/gitProvider'; import type { GitCommit } from './git/models/commit'; import type { GitRevisionReference } from './git/models/reference'; import type { RepositoryChange } from './git/models/repository'; -import type { Draft, LocalDraft } from './gk/models/drafts'; +import type { Draft, LocalDraft } from './plus/drafts/models/drafts'; export type CommitSelectedEvent = EventBusEvent<'commit:selected'>; interface CommitSelectedEventArgs { diff --git a/src/extension.ts b/src/extension.ts index 9e34a1abb8f7d..90c59abfc323e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,24 +13,24 @@ import { SyncedStorageKeys } from './constants.storage'; import { Container } from './container'; import { isGitUri } from './git/gitUri'; import { isBranch } from './git/models/branch'; -import { getBranchNameWithoutRemote } from './git/models/branch.utils'; import { isCommit } from './git/models/commit'; import { isRepository } from './git/models/repository'; -import { setAbbreviatedShaLength } from './git/models/revision.utils'; import { isTag } from './git/models/tag'; +import { getBranchNameWithoutRemote } from './git/utils/branch.utils'; +import { setAbbreviatedShaLength } from './git/utils/revision.utils'; import { showDebugLoggingWarningMessage, showPreReleaseExpiredErrorMessage, showWhatsNewMessage } from './messages'; import { registerPartnerActionRunners } from './partners'; +import { executeCommand, registerCommands } from './system/-webview/command'; +import { configuration, Configuration } from './system/-webview/configuration'; +import { setContext } from './system/-webview/context'; +import { Storage } from './system/-webview/storage'; +import { isTextDocument, isTextEditor, isWorkspaceFolder } from './system/-webview/utils'; import { setDefaultDateLocales } from './system/date'; import { once } from './system/event'; import { BufferedLogChannel, getLoggableName, Logger } from './system/logger'; import { flatten } from './system/object'; import { Stopwatch } from './system/stopwatch'; import { compare, fromString, satisfies } from './system/version'; -import { executeCommand, registerCommands } from './system/vscode/command'; -import { configuration, Configuration } from './system/vscode/configuration'; -import { setContext } from './system/vscode/context'; -import { Storage } from './system/vscode/storage'; -import { isTextDocument, isTextEditor, isWorkspaceFolder } from './system/vscode/utils'; import { isViewNode } from './views/nodes/abstract/viewNode'; import './commands'; diff --git a/src/features.ts b/src/features.ts index d4062768c0656..94ed20a6e94a1 100644 --- a/src/features.ts +++ b/src/features.ts @@ -1,7 +1,7 @@ import type { StoredFeaturePreviewUsagePeriod } from './constants.storage'; import { proFeaturePreviewUsageDurationInDays, proFeaturePreviewUsages } from './constants.subscription'; import type { RepositoryVisibility } from './git/gitProvider'; -import type { RequiredSubscriptionPlans, Subscription } from './plus/gk/account/subscription'; +import type { RequiredSubscriptionPlans, Subscription } from './plus/gk/models/subscription'; import { capitalize } from './system/string'; export const enum Features { diff --git a/src/git/actions.ts b/src/git/actions.ts index 658ff832d5b05..3ba6f91f5e9d3 100644 --- a/src/git/actions.ts +++ b/src/git/actions.ts @@ -3,8 +3,8 @@ import type { BrowseRepoAtRevisionCommandArgs } from '../commands/browseRepoAtRe import type { GitWizardCommandArgs } from '../commands/gitWizard'; import type { QuickWizardCommandArgsWithCompletion } from '../commands/quickWizard.base'; import { GlCommand } from '../constants.commands'; +import { executeCommand, executeEditorCommand } from '../system/-webview/command'; import { defer } from '../system/promise'; -import { executeCommand, executeEditorCommand } from '../system/vscode/command'; export async function executeGitCommand(args: GitWizardCommandArgs): Promise { const deferred = defer(); diff --git a/src/git/actions/commit.ts b/src/git/actions/commit.ts index 410f045243bd3..cdcdd9c1b0e35 100644 --- a/src/git/actions/commit.ts +++ b/src/git/actions/commit.ts @@ -13,21 +13,22 @@ import { GlyphChars } from '../../constants'; import { GlCommand } from '../../constants.commands'; import { Container } from '../../container'; import { showRevisionFilesPicker } from '../../quickpicks/revisionFilesPicker'; +import { executeCommand, executeCoreGitCommand, executeEditorCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { findOrOpenEditor, findOrOpenEditors, openChangesEditor } from '../../system/-webview/utils'; import { getSettledValue } from '../../system/promise'; -import { executeCommand, executeCoreGitCommand, executeEditorCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { findOrOpenEditor, findOrOpenEditors, openChangesEditor } from '../../system/vscode/utils'; import type { ShowInCommitGraphCommandArgs } from '../../webviews/plus/graph/protocol'; import { GitUri } from '../gitUri'; import type { GitCommit } from '../models/commit'; import { isCommit } from '../models/commit'; import type { GitFile } from '../models/file'; -import { GitFileChange } from '../models/file'; +import { GitFileChange } from '../models/fileChange'; import type { GitRevisionReference } from '../models/reference'; -import { createReference, getReferenceFromRevision, getReferenceLabel } from '../models/reference.utils'; import { deletedOrMissing } from '../models/revision'; -import { createRevisionRange, isUncommitted, isUncommittedStaged, shortenRevision } from '../models/revision.utils'; import { getAheadBehindFilesQuery } from '../queryResults'; +import { getReferenceFromRevision } from '../utils/-webview/reference.utils'; +import { createReference, getReferenceLabel } from '../utils/reference.utils'; +import { createRevisionRange, isUncommitted, isUncommittedStaged, shortenRevision } from '../utils/revision.utils'; export type Ref = { repoPath: string; ref: string }; export type RefRange = { repoPath: string; rhs: string; lhs: string }; @@ -821,9 +822,9 @@ export async function showInCommitGraph( })); } -export async function openOnlyChangedFiles(commit: GitCommit): Promise; -export async function openOnlyChangedFiles(files: GitFile[]): Promise; -export async function openOnlyChangedFiles(commitOrFiles: GitCommit | GitFile[]): Promise { +export async function openOnlyChangedFiles(container: Container, commit: GitCommit): Promise; +export async function openOnlyChangedFiles(container: Container, files: GitFile[]): Promise; +export async function openOnlyChangedFiles(container: Container, commitOrFiles: GitCommit | GitFile[]): Promise { let files; if (isCommit(commitOrFiles)) { if (commitOrFiles.files == null) { @@ -832,7 +833,7 @@ export async function openOnlyChangedFiles(commitOrFiles: GitCommit | GitFile[]) files = commitOrFiles.files ?? []; } else { - files = commitOrFiles.map(f => new GitFileChange(f.repoPath!, f.path, f.status, f.originalPath)); + files = commitOrFiles.map(f => new GitFileChange(container, f.repoPath!, f.path, f.status, f.originalPath)); } if ( diff --git a/src/git/actions/worktree.ts b/src/git/actions/worktree.ts index fc5b4960dc3a1..6ac2e21be1d9f 100644 --- a/src/git/actions/worktree.ts +++ b/src/git/actions/worktree.ts @@ -1,8 +1,8 @@ import type { Uri } from 'vscode'; import type { WorktreeGitCommandArgs } from '../../commands/git/worktree'; import { Container } from '../../container'; +import type { OpenWorkspaceLocation } from '../../system/-webview/utils'; import { defer } from '../../system/promise'; -import type { OpenWorkspaceLocation } from '../../system/vscode/utils'; import { executeGitCommand } from '../actions'; import type { GitReference } from '../models/reference'; import type { Repository } from '../models/repository'; diff --git a/src/git/cache.ts b/src/git/cache.ts index 0ad7d90528505..636576e4bdabc 100644 --- a/src/git/cache.ts +++ b/src/git/cache.ts @@ -1,9 +1,9 @@ import { Disposable } from 'vscode'; import type { Container } from '../container'; +import { configuration } from '../system/-webview/configuration'; import { log } from '../system/decorators/log'; import type { PromiseOrValue } from '../system/promise'; import { PathTrie } from '../system/trie'; -import { configuration } from '../system/vscode/configuration'; import type { GitCaches, GitDir, PagedResult } from './gitProvider'; import type { GitBranch } from './models/branch'; import type { GitContributor } from './models/contributor'; diff --git a/src/git/formatters/commitFormatter.ts b/src/git/formatters/commitFormatter.ts index 69c5198f865ab..2f001369df03f 100644 --- a/src/git/formatters/commitFormatter.ts +++ b/src/git/formatters/commitFormatter.ts @@ -19,14 +19,14 @@ import { GlyphChars } from '../../constants'; import { actionCommandPrefix, GlCommand } from '../../constants.commands'; import { Container } from '../../container'; import { emojify } from '../../emojis'; -import { arePlusFeaturesEnabled } from '../../plus/gk/utils'; +import { arePlusFeaturesEnabled } from '../../plus/gk/utils/-webview/plus.utils'; +import { configuration } from '../../system/-webview/configuration'; import { createMarkdownCommandLink } from '../../system/commands'; import { join, map } from '../../system/iterable'; import { escapeMarkdown } from '../../system/markdown'; import { isPromise } from '../../system/promise'; import type { TokenOptions } from '../../system/string'; import { encodeHtmlWeak, getSuperscript } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; import type { ContactPresence } from '../../vsls/vsls'; import type { ShowInCommitGraphCommandArgs } from '../../webviews/plus/graph/protocol'; import type { PreviousLineComparisonUrisResult } from '../gitProvider'; @@ -34,13 +34,13 @@ import type { GitCommit } from '../models/commit'; import { isCommit, isStash } from '../models/commit'; import type { PullRequest } from '../models/pullRequest'; import { isPullRequest } from '../models/pullRequest'; -import { getReferenceFromRevision } from '../models/reference.utils'; import type { GitRemote } from '../models/remote'; -import { getHighlanderProviders } from '../models/remote'; import { uncommitted, uncommittedStaged } from '../models/revision'; -import { isUncommittedStaged, shortenRevision } from '../models/revision.utils'; import type { RemoteProvider } from '../remotes/remoteProvider'; -import { getIssueOrPullRequestMarkdownIcon } from '../utils/vscode/icons'; +import { getIssueOrPullRequestMarkdownIcon } from '../utils/-webview/icons'; +import { getReferenceFromRevision } from '../utils/-webview/reference.utils'; +import { getHighlanderProviders } from '../utils/remote.utils'; +import { isUncommittedStaged, shortenRevision } from '../utils/revision.utils'; import type { FormatOptions, RequiredTokenOptions } from './formatter'; import { Formatter } from './formatter'; diff --git a/src/git/formatters/statusFormatter.ts b/src/git/formatters/statusFormatter.ts index 5affa8bed49bb..90011b860fb81 100644 --- a/src/git/formatters/statusFormatter.ts +++ b/src/git/formatters/statusFormatter.ts @@ -3,14 +3,14 @@ import { escapeMarkdown } from '../../system/markdown'; import { basename } from '../../system/path'; import type { TokenOptions } from '../../system/string'; import type { GitFile, GitFileWithCommit } from '../models/file'; +import { isGitFileChange } from '../models/fileChange'; import { getGitFileFormattedDirectory, getGitFileFormattedPath, getGitFileOriginalRelativePath, getGitFileRelativePath, - getGitFileStatusText, - isGitFileChange, -} from '../models/file'; +} from '../utils/-webview/file.utils'; +import { getGitFileStatusText } from '../utils/fileStatus.utils'; import type { FormatOptions } from './formatter'; import { Formatter } from './formatter'; diff --git a/src/git/fsProvider.ts b/src/git/fsProvider.ts index d887f2acd4d3f..91c049ae32025 100644 --- a/src/git/fsProvider.ts +++ b/src/git/fsProvider.ts @@ -3,11 +3,11 @@ import { Disposable, EventEmitter, FileSystemError, FileType, workspace } from ' import { isLinux } from '@env/platform'; import { Schemes } from '../constants'; import type { Container } from '../container'; +import { relative } from '../system/-webview/path'; import { debug } from '../system/decorators/log'; import { map } from '../system/iterable'; import { normalizePath } from '../system/path'; import { TernarySearchTree } from '../system/searchTree'; -import { relative } from '../system/vscode/path'; import { GitUri, isGitUri } from './gitUri'; import { deletedOrMissing } from './models/revision'; import type { GitTreeEntry } from './models/tree'; diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 4501160a02c8b..413c9143d4343 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -11,7 +11,8 @@ import type { GitBranch } from './models/branch'; import type { GitCommit, GitCommitStats } from './models/commit'; import type { GitContributor, GitContributorStats } from './models/contributor'; import type { GitDiff, GitDiffFile, GitDiffFiles, GitDiffFilter, GitDiffLine, GitDiffShortStat } from './models/diff'; -import type { GitFile, GitFileChange } from './models/file'; +import type { GitFile } from './models/file'; +import type { GitFileChange } from './models/fileChange'; import type { GitGraph } from './models/graph'; import type { GitLog } from './models/log'; import type { MergeConflict } from './models/mergeConflict'; @@ -22,14 +23,15 @@ import type { GitRemote } from './models/remote'; import type { Repository, RepositoryChangeEvent } from './models/repository'; import type { GitRevisionRange } from './models/revision'; import type { GitStash } from './models/stash'; -import type { GitStatus, GitStatusFile } from './models/status'; +import type { GitStatus } from './models/status'; +import type { GitStatusFile } from './models/statusFile'; import type { GitTag } from './models/tag'; import type { GitTreeEntry } from './models/tree'; import type { GitUser } from './models/user'; import type { GitWorktree } from './models/worktree'; import type { RemoteProvider } from './remotes/remoteProvider'; import type { GitSearch } from './search'; -import type { BranchSortOptions, TagSortOptions } from './utils/vscode/sorting'; +import type { BranchSortOptions, TagSortOptions } from './utils/-webview/sorting'; export type GitCaches = | 'branches' diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index 8dd11bba5e2ae..86bba7b8bc5e6 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -19,13 +19,17 @@ import { SubscriptionPlanId } from '../constants.subscription'; import type { Container } from '../container'; import { AccessDeniedError, ProviderNotFoundError, ProviderNotSupportedError } from '../errors'; import type { FeatureAccess, Features, PlusFeatures, RepoFeatureAccess } from '../features'; -import type { Subscription } from '../plus/gk/account/subscription'; -import { isSubscriptionPaidPlan } from '../plus/gk/account/subscription'; -import type { SubscriptionChangeEvent } from '../plus/gk/account/subscriptionService'; +import type { Subscription } from '../plus/gk/models/subscription'; +import type { SubscriptionChangeEvent } from '../plus/gk/subscriptionService'; +import { isSubscriptionPaidPlan } from '../plus/gk/utils/subscription.utils'; import type { RepoComparisonKey } from '../repositories'; import { asRepoComparisonKey, Repositories } from '../repositories'; +import { registerCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { getBestPath } from '../system/-webview/path'; import { joinUnique } from '../system/array'; -import { gate } from '../system/decorators/gate'; +import { gate } from '../system/decorators/-webview/gate'; import { debug, log } from '../system/decorators/log'; import type { Deferrable } from '../system/function'; import { debounce } from '../system/function'; @@ -36,10 +40,6 @@ import { getScheme, isAbsolute, maybeUri, normalizePath } from '../system/path'; import type { Deferred } from '../system/promise'; import { asSettled, defer, getDeferredPromiseIfPending, getSettledValue } from '../system/promise'; import { VisitedPathsTrie } from '../system/trie'; -import { registerCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; -import { getBestPath } from '../system/vscode/path'; import type { GitBranchesSubProvider, GitCaches, @@ -71,25 +71,26 @@ import type { GitUri } from './gitUri'; import type { GitBlame, GitBlameLine } from './models/blame'; import type { GitBranch } from './models/branch'; import { GitCommit, GitCommitIdentity } from './models/commit'; -import { calculateDistribution } from './models/contributor'; import type { GitDiff, GitDiffFile, GitDiffFiles, GitDiffFilter, GitDiffLine, GitDiffShortStat } from './models/diff'; -import type { GitFile, GitFileChange } from './models/file'; +import type { GitFile } from './models/file'; +import type { GitFileChange } from './models/fileChange'; import type { GitGraph } from './models/graph'; import type { GitLog } from './models/log'; import type { GitBranchReference, GitReference } from './models/reference'; import type { GitReflog } from './models/reflog'; import type { GitRemote } from './models/remote'; -import { getRemoteThemeIconString, getVisibilityCacheKey } from './models/remote'; import type { Repository, RepositoryChangeEvent } from './models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from './models/repository'; import type { GitRevisionRange } from './models/revision'; import { deletedOrMissing, uncommitted, uncommittedStaged } from './models/revision'; -import { createRevisionRange, isSha, isUncommitted, isUncommittedParent } from './models/revision.utils'; import type { GitTag } from './models/tag'; import type { GitTreeEntry } from './models/tree'; import type { GitUser } from './models/user'; import type { GitSearch } from './search'; -import { sortRepositories } from './utils/vscode/sorting'; +import { sortRepositories } from './utils/-webview/sorting'; +import { calculateDistribution } from './utils/contributor.utils'; +import { getRemoteThemeIconString, getVisibilityCacheKey } from './utils/remote.utils'; +import { createRevisionRange, isSha, isUncommitted, isUncommittedParent } from './utils/revision.utils'; const emptyArray = Object.freeze([]) as unknown as any[]; const emptyDisposable = Object.freeze({ diff --git a/src/git/gitUri.ts b/src/git/gitUri.ts index e71330b1f6ae9..b6e71adf5f73e 100644 --- a/src/git/gitUri.ts +++ b/src/git/gitUri.ts @@ -3,18 +3,18 @@ import { getQueryDataFromScmGitUri } from '../@types/vscode.git.uri'; import { Schemes } from '../constants'; import { Container } from '../container'; import type { GitHubAuthorityMetadata } from '../plus/remotehub'; +import { formatPath } from '../system/-webview/formatPath'; +import { getBestPath, relativeDir, splitPath } from '../system/-webview/path'; +import { isVirtualUri } from '../system/-webview/utils'; import { UriComparer } from '../system/comparers'; +import { memoize } from '../system/decorators/-webview/memoize'; import { debug } from '../system/decorators/log'; -import { memoize } from '../system/decorators/memoize'; import { basename, normalizePath } from '../system/path'; -import { formatPath } from '../system/vscode/formatPath'; -import { getBestPath, relativeDir, splitPath } from '../system/vscode/path'; -import { isVirtualUri } from '../system/vscode/utils'; import type { RevisionUriData } from './gitProvider'; import { decodeGitLensRevisionUriAuthority, decodeRemoteHubAuthority } from './gitUri.authority'; import type { GitFile } from './models/file'; import { uncommittedStaged } from './models/revision'; -import { isUncommitted, isUncommittedStaged, shortenRevision } from './models/revision.utils'; +import { isUncommitted, isUncommittedStaged, shortenRevision } from './utils/revision.utils'; const slash = 47; //slash; diff --git a/src/git/models/branch.ts b/src/git/models/branch.ts index 6a13712da413d..e451812812aca 100644 --- a/src/git/models/branch.ts +++ b/src/git/models/branch.ts @@ -1,9 +1,10 @@ import type { EnrichedAutolink } from '../../autolinks'; import type { Container } from '../../container'; import { formatDate, fromNow } from '../../system/date'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { debug } from '../../system/decorators/log'; -import { memoize } from '../../system/decorators/memoize'; import { getLoggableName } from '../../system/logger'; +import type { MaybePausedResult } from '../../system/promise'; import { formatDetachedHeadName, getBranchId, @@ -11,27 +12,16 @@ import { getRemoteNameFromBranchName, getRemoteNameSlashIndex, isDetachedHead, -} from './branch.utils'; +} from '../utils/branch.utils'; +import { getUpstreamStatus } from '../utils/status.utils'; import type { PullRequest, PullRequestState } from './pullRequest'; import type { GitBranchReference } from './reference'; import type { GitRemote } from './remote'; -import { getUpstreamStatus } from './status'; -export interface GitTrackingState { - ahead: number; - behind: number; +export function isBranch(branch: unknown): branch is GitBranch { + return branch instanceof GitBranch; } -export type GitBranchStatus = - | 'local' - | 'detached' - | 'ahead' - | 'behind' - | 'diverged' - | 'upToDate' - | 'missingUpstream' - | 'remote'; - export class GitBranch implements GitBranchReference { readonly refType = 'branch'; readonly detached: boolean; @@ -192,6 +182,23 @@ export class GitBranch implements GitBranchReference { } } -export function isBranch(branch: any): branch is GitBranch { - return branch instanceof GitBranch; +export interface GitTrackingState { + ahead: number; + behind: number; +} + +export type GitBranchStatus = + | 'local' + | 'detached' + | 'ahead' + | 'behind' + | 'diverged' + | 'upToDate' + | 'missingUpstream' + | 'remote'; + +export interface BranchTargetInfo { + baseBranch: string | undefined; + defaultBranch: string | undefined; + targetBranch: MaybePausedResult; } diff --git a/src/git/models/branch.utils.ts b/src/git/models/branch.utils.ts deleted file mode 100644 index 37c3bc1a769b8..0000000000000 --- a/src/git/models/branch.utils.ts +++ /dev/null @@ -1,306 +0,0 @@ -import type { CancellationToken } from 'vscode'; -import type { GitConfigKeys } from '../../constants'; -import type { Container } from '../../container'; -import type { IssueResourceDescriptor, RepositoryDescriptor } from '../../plus/integrations/integration'; -import type { GitConfigEntityIdentifier } from '../../plus/integrations/providers/models'; -import { - decodeEntityIdentifiersFromGitConfig, - encodeIssueOrPullRequestForGitConfig, - getIssueFromGitConfigEntityIdentifier, -} from '../../plus/integrations/providers/utils'; -import { Logger } from '../../system/logger'; -import type { PageableResult } from '../../system/paging'; -import type { MaybePausedResult } from '../../system/promise'; -import { getSettledValue, pauseOnCancelOrTimeout } from '../../system/promise'; -import type { GitBranch } from './branch'; -import type { Issue } from './issue'; -import type { PullRequest } from './pullRequest'; -import type { GitBranchReference, GitReference } from './reference'; -import { shortenRevision } from './revision.utils'; - -const detachedHEADRegex = /^(HEAD|\(.*\))$/; - -export function formatDetachedHeadName(sha: string): string { - return `(${shortenRevision(sha)}...)`; -} - -export function getBranchId(repoPath: string, remote: boolean, name: string): string { - return `${repoPath}|${remote ? 'remotes/' : 'heads/'}${name}`; -} - -export function getBranchNameAndRemote(ref: GitBranchReference): [name: string, remote: string | undefined] { - if (ref.remote) { - const index = getRemoteNameSlashIndex(ref.name); - if (index === -1) return [ref.name, undefined]; - - return [ref.name.substring(index + 1), ref.name.substring(0, index)]; - } - - if (ref.upstream?.name != null) { - const index = getRemoteNameSlashIndex(ref.upstream.name); - if (index === -1) return [ref.name, undefined]; - - return [ref.name, ref.upstream.name.substring(0, index)]; - } - - return [ref.name, undefined]; -} - -export function getBranchNameWithoutRemote(name: string): string { - return name.substring(getRemoteNameSlashIndex(name) + 1); -} - -export async function getLocalBranchUpstreamNames(branches: PageableResult): Promise> { - const remoteBranches = new Set(); - - for await (const branch of branches.values()) { - if (!branch.remote && branch.upstream?.name != null) { - remoteBranches.add(branch.upstream.name); - } - } - - return remoteBranches; -} - -export function getRemoteNameFromBranchName(name: string): string { - return name.substring(0, getRemoteNameSlashIndex(name)); -} - -export function getRemoteNameSlashIndex(name: string): number { - return name.startsWith('remotes/') ? name.indexOf('/', 8) : name.indexOf('/'); -} - -export function isDetachedHead(name: string): boolean { - // If there is whitespace in the name assume this is not a valid branch name - // Deals with detached HEAD states - name = name.trim(); - return name.length ? detachedHEADRegex.test(name) : true; -} - -export function isOfBranchRefType(branch: GitReference | undefined) { - return branch?.refType === 'branch'; -} - -export async function getDefaultBranchName( - container: Container, - repoPath: string, - remoteName?: string, - options?: { cancellation?: CancellationToken }, -): Promise { - const name = await container.git.branches(repoPath).getDefaultBranchName(remoteName); - if (name != null) return name; - - const remote = await container.git.remotes(repoPath).getBestRemoteWithIntegration(); - if (remote == null) return undefined; - - const integration = await remote.getIntegration(); - const defaultBranch = await integration?.getDefaultBranch?.(remote.provider.repoDesc, options); - return `${remote.name}/${defaultBranch?.name}`; -} - -export async function getLocalBranchByUpstream( - remoteBranchName: string, - branches: PageableResult | Map, -): Promise { - let qualifiedRemoteBranchName; - if (remoteBranchName.startsWith('remotes/')) { - qualifiedRemoteBranchName = remoteBranchName; - remoteBranchName = remoteBranchName.substring(8); - } else { - qualifiedRemoteBranchName = `remotes/${remoteBranchName}`; - } - - function matches(branch: GitBranch): boolean { - return ( - !branch.remote && - branch.upstream?.name != null && - (branch.upstream.name === remoteBranchName || branch.upstream.name === qualifiedRemoteBranchName!) - ); - } - - const values = branches.values(); - if (Symbol.asyncIterator in values) { - for await (const branch of values) { - if (matches(branch)) return branch; - } - } else { - for (const branch of values) { - if (matches(branch)) return branch; - } - } - - return undefined; -} - -export async function getTargetBranchName( - container: Container, - branch: GitBranch, - options?: { - associatedPullRequest?: Promise; - cancellation?: CancellationToken; - timeout?: number; - }, -): Promise> { - const targetBranch = await container.git.branches(branch.repoPath).getTargetBranchName?.(branch.name); - if (targetBranch != null) return { value: targetBranch, paused: false }; - - if (options?.cancellation?.isCancellationRequested) return { value: undefined, paused: false }; - - return pauseOnCancelOrTimeout( - (options?.associatedPullRequest ?? branch?.getAssociatedPullRequest())?.then(pr => { - if (pr?.refs?.base == null) return undefined; - - const name = `${branch.getRemoteName()}/${pr.refs.base.branch}`; - void container.git.branches(branch.repoPath).setTargetBranchName?.(branch.name, name); - - return name; - }), - options?.cancellation, - options?.timeout, - ); -} - -export interface BranchTargetInfo { - baseBranch: string | undefined; - defaultBranch: string | undefined; - targetBranch: MaybePausedResult; -} - -export async function getBranchTargetInfo( - container: Container, - current: GitBranch, - options?: { - associatedPullRequest?: Promise; - cancellation?: CancellationToken; - timeout?: number; - }, -): Promise { - const [baseResult, defaultResult, targetResult] = await Promise.allSettled([ - container.git.branches(current.repoPath).getBaseBranchName?.(current.name), - getDefaultBranchName(container, current.repoPath, current.getRemoteName()), - getTargetBranchName(container, current, { - cancellation: options?.cancellation, - timeout: options?.timeout, - }), - ]); - - const baseBranchName = getSettledValue(baseResult); - const defaultBranchName = getSettledValue(defaultResult); - const targetMaybeResult = getSettledValue(targetResult); - - return { - baseBranch: baseBranchName, - defaultBranch: defaultBranchName, - targetBranch: targetMaybeResult ?? { value: undefined, paused: false }, - }; -} - -export function getBranchTrackingWithoutRemote(ref: GitBranchReference) { - return ref.upstream?.name.substring(getRemoteNameSlashIndex(ref.upstream.name) + 1); -} - -export function getNameWithoutRemote(ref: GitReference) { - if (ref.refType === 'branch') { - return ref.remote ? getBranchNameWithoutRemote(ref.name) : ref.name; - } - return ref.name; -} - -export async function getAssociatedIssuesForBranch( - container: Container, - branch: GitBranch, - options?: { - cancellation?: CancellationToken; - timeout?: number; - }, -): Promise> { - const { encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); - if (options?.cancellation?.isCancellationRequested) return { value: undefined, paused: false }; - - let associatedIssues: GitConfigEntityIdentifier[] | undefined; - if (encoded != null) { - try { - associatedIssues = decodeEntityIdentifiersFromGitConfig(encoded); - } catch (ex) { - Logger.error(ex, 'getAssociatedIssuesForBranch'); - return { value: undefined, paused: false }; - } - - if (associatedIssues != null) { - return pauseOnCancelOrTimeout( - (async () => { - return ( - await Promise.allSettled( - (associatedIssues ?? []).map(i => getIssueFromGitConfigEntityIdentifier(container, i)), - ) - ) - .map(r => getSettledValue(r)) - .filter((i): i is Issue => i != null); - })(), - options?.cancellation, - options?.timeout, - ); - } - } - - return { value: undefined, paused: false }; -} - -export async function addAssociatedIssueToBranch( - container: Container, - branch: GitBranchReference, - issue: Issue, - owner: RepositoryDescriptor | IssueResourceDescriptor, - options?: { - cancellation?: CancellationToken; - }, -) { - const { key, encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); - if (options?.cancellation?.isCancellationRequested) return; - try { - const associatedIssues: GitConfigEntityIdentifier[] = encoded - ? (JSON.parse(encoded) as GitConfigEntityIdentifier[]) - : []; - if (associatedIssues.some(i => i.entityId === issue.nodeId)) { - return; - } - associatedIssues.push(encodeIssueOrPullRequestForGitConfig(issue, owner)); - await container.git.setConfig(branch.repoPath, key, JSON.stringify(associatedIssues)); - } catch (ex) { - Logger.error(ex, 'addAssociatedIssueToBranch'); - } -} - -export async function removeAssociatedIssueFromBranch( - container: Container, - branch: GitBranchReference, - id: string, - options?: { - cancellation?: CancellationToken; - }, -) { - const { key, encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); - if (options?.cancellation?.isCancellationRequested) return; - try { - let associatedIssues: GitConfigEntityIdentifier[] = encoded - ? (JSON.parse(encoded) as GitConfigEntityIdentifier[]) - : []; - associatedIssues = associatedIssues.filter(i => i.entityId !== id); - if (associatedIssues.length === 0) { - await container.git.setConfig(branch.repoPath, key, undefined); - } else { - await container.git.setConfig(branch.repoPath, key, JSON.stringify(associatedIssues)); - } - } catch (ex) { - Logger.error(ex, 'removeAssociatedIssueFromBranch'); - } -} - -async function getConfigKeyAndEncodedAssociatedIssuesForBranch( - container: Container, - branch: GitBranchReference, -): Promise<{ key: GitConfigKeys; encoded: string | undefined }> { - const key = `branch.${branch.name}.gk-associated-issues` satisfies GitConfigKeys; - const encoded = await container.git.getConfig(branch.repoPath, key); - return { key: key, encoded: encoded }; -} diff --git a/src/git/models/commit.ts b/src/git/models/commit.ts index aeb9ac582bd6c..13254687cd165 100644 --- a/src/git/models/commit.ts +++ b/src/git/models/commit.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { Uri } from 'vscode'; import type { EnrichedAutolink } from '../../autolinks'; import { getAvatarUri, getCachedAvatarUri } from '../../avatars'; @@ -5,26 +6,35 @@ import type { GravatarDefaultStyle } from '../../config'; import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; import { formatDate, fromNow } from '../../system/date'; -import { gate } from '../../system/decorators/gate'; -import { memoize } from '../../system/decorators/memoize'; +import { gate } from '../../system/decorators/-webview/gate'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { getLoggableName } from '../../system/logger'; import { getSettledValue } from '../../system/promise'; import { pluralize } from '../../system/string'; import type { PreviousLineComparisonUrisResult } from '../gitProvider'; import { GitUri } from '../gitUri'; import type { RemoteProvider } from '../remotes/remoteProvider'; -import { getChangedFilesCount } from './commit.utils'; +import { mapFilesWithStats } from '../utils/-webview/fileChange.utils'; +import { getChangedFilesCount } from '../utils/commit.utils'; +import { isSha, isUncommitted, isUncommittedParent, isUncommittedStaged } from '../utils/revision.utils'; import type { GitFile } from './file'; -import { GitFileChange, mapFilesWithStats } from './file'; +import { GitFileChange } from './fileChange'; import type { PullRequest } from './pullRequest'; -import type { GitReference, GitRevisionReference, GitStashReference } from './reference'; +import type { GitRevisionReference, GitStashReference } from './reference'; import type { GitRemote } from './remote'; import type { Repository } from './repository'; import { uncommitted, uncommittedStaged } from './revision'; -import { isSha, isUncommitted, isUncommittedParent, isUncommittedStaged } from './revision.utils'; const stashNumberRegex = /stash@{(\d+)}/; +export function isCommit(commit: unknown): commit is GitCommit { + return commit instanceof GitCommit; +} + +export function isStash(commit: unknown): commit is GitStashCommit { + return isCommit(commit) && commit.refType === 'stash' && Boolean(commit.stashName); +} + export class GitCommit implements GitRevisionReference { private _stashUntrackedFilesLoaded = false; private _recomputeStats = false; @@ -256,7 +266,7 @@ export class GitCommit implements GitRevisionReference { const commitFilesStats = getSettledValue(commitFilesStatsResult); if (commitFilesStats?.length && this._files?.length) { - this._files = mapFilesWithStats(this._files, commitFilesStats); + this._files = mapFilesWithStats(this.container, this._files, commitFilesStats); } } @@ -264,6 +274,7 @@ export class GitCommit implements GitRevisionReference { const file = this._files.find(f => f.path === this._file!.path); if (file != null) { this._file = new GitFileChange( + this.container, file.repoPath, file.path, file.status, @@ -651,18 +662,6 @@ export class GitCommit implements GitRevisionReference { } } -export function isCommit(commit: any): commit is GitCommit { - return commit instanceof GitCommit; -} - -export function isStash(commit: any): commit is GitStashCommit { - return commit instanceof GitCommit && commit.refType === 'stash' && Boolean(commit.stashName); -} - -export function isOfCommitOrStashRefType(commit: GitReference | undefined): boolean { - return commit?.refType === 'revision' || commit?.refType === 'stash'; -} - export interface GitCommitIdentityShape { readonly name: string; readonly email: string | undefined; @@ -723,10 +722,4 @@ export interface GitStashCommit extends GitCommit { readonly number: string; } -type GitCommitWithFullDetails = GitCommit & SomeNonNullable; - -export function assertsCommitHasFullDetails(commit: GitCommit): asserts commit is GitCommitWithFullDetails { - if (!commit.hasFullDetails()) { - throw new Error(`GitCommit(${commit.sha}) is not fully loaded`); - } -} +export type GitCommitWithFullDetails = GitCommit & SomeNonNullable; diff --git a/src/git/models/contributor.ts b/src/git/models/contributor.ts index abae64bd78a92..2c4019e7ced71 100644 --- a/src/git/models/contributor.ts +++ b/src/git/models/contributor.ts @@ -1,50 +1,13 @@ +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { Uri } from 'vscode'; import { getAvatarUri } from '../../avatars'; import type { GravatarDefaultStyle } from '../../config'; import { formatDate, fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import type { GitCommitStats } from './commit'; -import type { GitUser } from './user'; -export interface GitContributorStats { - readonly count: number; - readonly contributions: number[]; -} - -export type GitContributionTiers = '[1]' | '[2-5]' | '[6-10]' | '[11-50]' | '[51-100]' | '[101+]'; - -export function calculateDistribution( - stats: GitContributorStats | undefined, - prefix: T, -): Record<`${typeof prefix}${GitContributionTiers}`, number> { - if (stats == null) return {} as unknown as Record<`${typeof prefix}${GitContributionTiers}`, number>; - - const distribution: Record<`${string}${GitContributionTiers}`, number> = { - [`${prefix}[1]`]: 0, - [`${prefix}[2-5]`]: 0, - [`${prefix}[6-10]`]: 0, - [`${prefix}[11-50]`]: 0, - [`${prefix}[51-100]`]: 0, - [`${prefix}[101+]`]: 0, - }; - - for (const c of stats.contributions) { - if (c === 1) { - distribution[`${prefix}[1]`]++; - } else if (c <= 5) { - distribution[`${prefix}[2-5]`]++; - } else if (c <= 10) { - distribution[`${prefix}[6-10]`]++; - } else if (c <= 50) { - distribution[`${prefix}[11-50]`]++; - } else if (c <= 100) { - distribution[`${prefix}[51-100]`]++; - } else { - distribution[`${prefix}[101+]`]++; - } - } - - return distribution; +export function isContributor(contributor: unknown): contributor is GitContributor { + return contributor instanceof GitContributor; } export class GitContributor { @@ -86,10 +49,9 @@ export class GitContributor { } } -export function matchContributor(c: GitContributor, user: GitUser): boolean { - return c.name === user.name && c.email === user.email && c.username === user.username; +export interface GitContributorStats { + readonly count: number; + readonly contributions: number[]; } -export function isContributor(contributor: any): contributor is GitContributor { - return contributor instanceof GitContributor; -} +export type GitContributionTiers = '[1]' | '[2-5]' | '[6-10]' | '[11-50]' | '[51-100]' | '[101+]'; diff --git a/src/git/models/contributor.utils.ts b/src/git/models/contributor.utils.ts deleted file mode 100644 index c3888f05a76f6..0000000000000 --- a/src/git/models/contributor.utils.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { GitCommitStats } from './commit'; - -export interface ContributorScoreOptions { - // Thresholds - recentThresholdInDays: number; - maxScoreNormalization: number; - - // Time-based weights - recentWeight: number; - - // Impact weights - additionsWeight: number; - deletionsWeight: number; -} - -export const defaultContributorScoreOptions: ContributorScoreOptions = { - recentThresholdInDays: 30, - recentWeight: 1.5, - additionsWeight: 0.8, - deletionsWeight: 1.2, - maxScoreNormalization: 1000, -}; - -export function calculateContributionScore( - stats: GitCommitStats | undefined, - timestamp: number, - options: ContributorScoreOptions = defaultContributorScoreOptions, -): number { - if (stats == null) return 0; - - const now = Date.now(); - const ageInDays = (now - timestamp) / (24 * 3600 * 1000); - - // Time decay factor (exponential decay) - const recencyScore = Math.exp(-ageInDays / options.recentThresholdInDays); - - // Impact score with weighted components - const impactScore = stats.additions * options.additionsWeight + stats.deletions * options.deletionsWeight; - - return Math.min(impactScore * (1 + recencyScore * options.recentWeight), options.maxScoreNormalization); -} diff --git a/src/git/models/diff.ts b/src/git/models/diff.ts index dae4bc1633938..d910b33e4f576 100644 --- a/src/git/models/diff.ts +++ b/src/git/models/diff.ts @@ -1,4 +1,4 @@ -import type { GitFileChange } from './file'; +import type { GitFileChange } from './fileChange'; export interface GitDiff { readonly contents: string; diff --git a/src/git/models/file.ts b/src/git/models/file.ts index 57d04bdf7d835..cdc80ad3f04c5 100644 --- a/src/git/models/file.ts +++ b/src/git/models/file.ts @@ -1,44 +1,5 @@ -import type { Uri } from 'vscode'; -import { ThemeIcon } from 'vscode'; -import { GlyphChars } from '../../constants'; -import { Container } from '../../container'; -import { memoize } from '../../system/decorators/memoize'; -import { pad, pluralize } from '../../system/string'; -import { formatPath } from '../../system/vscode/formatPath'; -import { relativeDir, splitPath } from '../../system/vscode/path'; import type { GitCommit } from './commit'; - -export declare type GitFileStatus = GitFileConflictStatus | GitFileIndexStatus | GitFileWorkingTreeStatus; - -export const enum GitFileConflictStatus { - AddedByBoth = 'AA', - AddedByUs = 'AU', - AddedByThem = 'UA', - DeletedByBoth = 'DD', - DeletedByUs = 'DU', - DeletedByThem = 'UD', - ModifiedByBoth = 'UU', -} - -export const enum GitFileIndexStatus { - Modified = 'M', - Added = 'A', - Deleted = 'D', - Renamed = 'R', - Copied = 'C', - Unchanged = '.', - Untracked = '?', - Ignored = '!', - UpdatedButUnmerged = 'U', -} - -export const enum GitFileWorkingTreeStatus { - Modified = 'M', - Added = 'A', - Deleted = 'D', - Untracked = '?', - Ignored = '!', -} +import type { GitFileConflictStatus, GitFileIndexStatus, GitFileStatus, GitFileWorkingTreeStatus } from './fileStatus'; export interface GitFile { readonly path: string; @@ -54,278 +15,3 @@ export interface GitFile { export interface GitFileWithCommit extends GitFile { readonly commit: GitCommit; } - -export function isGitFile(file: any | undefined): file is GitFile { - return ( - file != null && - 'fileName' in file && - typeof file.fileName === 'string' && - 'status' in file && - typeof file.status === 'string' && - file.status.length === 1 - ); -} - -export function getGitFileFormattedDirectory( - file: GitFile, - includeOriginal: boolean = false, - relativeTo?: string, -): string { - const directory = relativeDir(file.path, relativeTo); - return includeOriginal && (file.status === 'R' || file.status === 'C') && file.originalPath - ? `${directory} ${pad(GlyphChars.ArrowLeft, 1, 1)} ${file.originalPath}` - : directory; -} - -export function getGitFileFormattedPath( - file: GitFile, - options: { relativeTo?: string; suffix?: string; truncateTo?: number } = {}, -): string { - return formatPath(file.path, options); -} - -export function getGitFileOriginalRelativePath(file: GitFile, relativeTo?: string): string { - if (!file.originalPath) return ''; - - return splitPath(file.originalPath, relativeTo)[0]; -} - -export function getGitFileRelativePath(file: GitFile, relativeTo?: string): string { - return splitPath(file.path, relativeTo)[0]; -} - -const statusIconsMap = { - '.': undefined, - '!': 'icon-status-ignored.svg', - '?': 'icon-status-untracked.svg', - A: 'icon-status-added.svg', - D: 'icon-status-deleted.svg', - M: 'icon-status-modified.svg', - R: 'icon-status-renamed.svg', - C: 'icon-status-copied.svg', - AA: 'icon-status-conflict.svg', - AU: 'icon-status-conflict.svg', - UA: 'icon-status-conflict.svg', - DD: 'icon-status-conflict.svg', - DU: 'icon-status-conflict.svg', - UD: 'icon-status-conflict.svg', - UU: 'icon-status-conflict.svg', - T: 'icon-status-modified.svg', - U: 'icon-status-modified.svg', -}; - -export function getGitFileStatusIcon(status: GitFileStatus): string { - return statusIconsMap[status] ?? 'icon-status-unknown.svg'; -} - -const statusCodiconsMap = { - '.': undefined, - '!': 'diff-ignored', - '?': 'diff-added', - A: 'diff-added', - D: 'diff-removed', - M: 'diff-modified', - R: 'diff-renamed', - C: 'diff-added', - AA: 'warning', - AU: 'warning', - UA: 'warning', - DD: 'warning', - DU: 'warning', - UD: 'warning', - UU: 'warning', - T: 'diff-modified', - U: 'diff-modified', -}; - -export function getGitFileStatusThemeIcon(status: GitFileStatus): ThemeIcon | undefined { - const codicon = statusCodiconsMap[status]; - return codicon != null ? new ThemeIcon(codicon) : undefined; -} - -const statusTextMap = { - '.': 'Unchanged', - '!': 'Ignored', - '?': 'Untracked', - A: 'Added', - D: 'Deleted', - M: 'Modified', - R: 'Renamed', - C: 'Copied', - AA: 'Conflict', - AU: 'Conflict', - UA: 'Conflict', - DD: 'Conflict', - DU: 'Conflict', - UD: 'Conflict', - UU: 'Conflict', - T: 'Modified', - U: 'Updated but Unmerged', -}; - -export function getGitFileStatusText(status: GitFileStatus): string { - return statusTextMap[status] ?? 'Unknown'; -} - -export interface GitFileChangeStats { - additions: number; - deletions: number; - changes: number; -} - -export interface GitFileChangeShape { - readonly repoPath: string; - readonly path: string; - readonly status: GitFileStatus; - - readonly originalPath?: string | undefined; - readonly staged?: boolean; -} - -export class GitFileChange implements GitFileChangeShape { - constructor( - public readonly repoPath: string, - public readonly path: string, - public readonly status: GitFileStatus, - public readonly originalPath?: string | undefined, - public readonly previousSha?: string | undefined, - public readonly stats?: GitFileChangeStats | undefined, - public readonly staged?: boolean, - ) {} - - get hasConflicts() { - switch (this.status) { - case GitFileConflictStatus.AddedByThem: - case GitFileConflictStatus.AddedByUs: - case GitFileConflictStatus.AddedByBoth: - case GitFileConflictStatus.DeletedByThem: - case GitFileConflictStatus.DeletedByUs: - case GitFileConflictStatus.DeletedByBoth: - case GitFileConflictStatus.ModifiedByBoth: - return true; - - default: - return false; - } - } - - @memoize() - get uri(): Uri { - return Container.instance.git.getAbsoluteUri(this.path, this.repoPath); - } - - @memoize() - get originalUri(): Uri | undefined { - return this.originalPath ? Container.instance.git.getAbsoluteUri(this.originalPath, this.repoPath) : undefined; - } - - @memoize() - getWorkingUri(): Promise { - return Container.instance.git.getWorkingUri(this.repoPath, this.uri); - } - - formatStats( - style: 'short' | 'stats' | 'expanded', - options?: { - color?: boolean; - empty?: string; - prefix?: string; - separator?: string; - }, - ): string { - const { stats } = this; - if (stats == null) return options?.empty ?? ''; - - const { /*changes,*/ additions, deletions } = stats; - if (/*changes < 0 && */ additions < 0 && deletions < 0) return options?.empty ?? ''; - - const separator = options?.separator ?? ' '; - - const lineStats = []; - - if (additions) { - const additionsText = style === 'expanded' ? `${pluralize('line', additions)} added` : `+${additions}`; - if (options?.color && style !== 'short') { - lineStats.push( - /*html*/ `${additionsText}`, - ); - } else { - lineStats.push(additionsText); - } - } else if (style === 'stats') { - if (options?.color) { - lineStats.push( - /*html*/ `+0`, - ); - } else { - lineStats.push('+0'); - } - } - - // if (changes) { - // const changesText = style === 'expanded' ? `${pluralize('line', changes)} changed` : `~${changes}`; - // if (options?.color && style !== 'short') { - // lineStats.push( - // /*html*/ `${changesText}`, - // ); - // } else { - // lineStats.push(changesText); - // } - // } else if (style === 'stats') { - // if (options?.color) { - // lineStats.push( - // /*html*/ `~0`, - // ); - // } else { - // lineStats.push('~0'); - // } - // } - - if (deletions) { - const deletionsText = style === 'expanded' ? `${pluralize('line', deletions)} deleted` : `-${deletions}`; - if (options?.color && style !== 'short') { - lineStats.push( - /*html*/ `${deletionsText}`, - ); - } else { - lineStats.push(deletionsText); - } - } else if (style === 'stats') { - if (options?.color) { - lineStats.push( - /*html*/ `-0`, - ); - } else { - lineStats.push('-0'); - } - } - - let result = lineStats.join(separator); - if (style === 'stats' && options?.color) { - result = /*html*/ ` ${result}  `; - } - - return `${options?.prefix ?? ''}${result}`; - } -} - -export function isGitFileChange(file: any): file is GitFileChange { - return file instanceof GitFileChange; -} - -export function mapFilesWithStats(files: GitFileChange[], filesWithStats: GitFileChange[]): GitFileChange[] { - return files.map(file => { - const stats = filesWithStats.find(f => f.path === file.path)?.stats; - return stats != null - ? new GitFileChange( - file.repoPath, - file.path, - file.status, - file.originalPath, - file.previousSha, - stats, - file.staged, - ) - : file; - }); -} diff --git a/src/git/models/fileChange.ts b/src/git/models/fileChange.ts new file mode 100644 index 0000000000000..8badc21c2e892 --- /dev/null +++ b/src/git/models/fileChange.ts @@ -0,0 +1,152 @@ +import type { Uri } from 'vscode'; +import type { Container } from '../../container'; +import { memoize } from '../../system/decorators/-webview/memoize'; +import { pluralize } from '../../system/string'; +import type { GitFileStatus } from './fileStatus'; +import { GitFileConflictStatus } from './fileStatus'; + +export function isGitFileChange(file: unknown): file is GitFileChange { + return file instanceof GitFileChange; +} + +export interface GitFileChangeShape { + readonly repoPath: string; + readonly path: string; + readonly status: GitFileStatus; + + readonly originalPath?: string | undefined; + readonly staged?: boolean; +} + +export class GitFileChange implements GitFileChangeShape { + constructor( + private readonly container: Container, + public readonly repoPath: string, + public readonly path: string, + public readonly status: GitFileStatus, + public readonly originalPath?: string | undefined, + public readonly previousSha?: string | undefined, + public readonly stats?: GitFileChangeStats | undefined, + public readonly staged?: boolean, + ) {} + + get hasConflicts() { + switch (this.status) { + case GitFileConflictStatus.AddedByThem: + case GitFileConflictStatus.AddedByUs: + case GitFileConflictStatus.AddedByBoth: + case GitFileConflictStatus.DeletedByThem: + case GitFileConflictStatus.DeletedByUs: + case GitFileConflictStatus.DeletedByBoth: + case GitFileConflictStatus.ModifiedByBoth: + return true; + + default: + return false; + } + } + + @memoize() + get uri(): Uri { + return this.container.git.getAbsoluteUri(this.path, this.repoPath); + } + + @memoize() + get originalUri(): Uri | undefined { + return this.originalPath ? this.container.git.getAbsoluteUri(this.originalPath, this.repoPath) : undefined; + } + + @memoize() + getWorkingUri(): Promise { + return this.container.git.getWorkingUri(this.repoPath, this.uri); + } + + formatStats( + style: 'short' | 'stats' | 'expanded', + options?: { + color?: boolean; + empty?: string; + prefix?: string; + separator?: string; + }, + ): string { + const { stats } = this; + if (stats == null) return options?.empty ?? ''; + + const { /*changes,*/ additions, deletions } = stats; + if (/*changes < 0 && */ additions < 0 && deletions < 0) return options?.empty ?? ''; + + const separator = options?.separator ?? ' '; + + const lineStats = []; + + if (additions) { + const additionsText = style === 'expanded' ? `${pluralize('line', additions)} added` : `+${additions}`; + if (options?.color && style !== 'short') { + lineStats.push( + /*html*/ `${additionsText}`, + ); + } else { + lineStats.push(additionsText); + } + } else if (style === 'stats') { + if (options?.color) { + lineStats.push( + /*html*/ `+0`, + ); + } else { + lineStats.push('+0'); + } + } + + // if (changes) { + // const changesText = style === 'expanded' ? `${pluralize('line', changes)} changed` : `~${changes}`; + // if (options?.color && style !== 'short') { + // lineStats.push( + // /*html*/ `${changesText}`, + // ); + // } else { + // lineStats.push(changesText); + // } + // } else if (style === 'stats') { + // if (options?.color) { + // lineStats.push( + // /*html*/ `~0`, + // ); + // } else { + // lineStats.push('~0'); + // } + // } + if (deletions) { + const deletionsText = style === 'expanded' ? `${pluralize('line', deletions)} deleted` : `-${deletions}`; + if (options?.color && style !== 'short') { + lineStats.push( + /*html*/ `${deletionsText}`, + ); + } else { + lineStats.push(deletionsText); + } + } else if (style === 'stats') { + if (options?.color) { + lineStats.push( + /*html*/ `-0`, + ); + } else { + lineStats.push('-0'); + } + } + + let result = lineStats.join(separator); + if (style === 'stats' && options?.color) { + result = /*html*/ ` ${result}  `; + } + + return `${options?.prefix ?? ''}${result}`; + } +} + +export interface GitFileChangeStats { + additions: number; + deletions: number; + changes: number; +} diff --git a/src/git/models/fileStatus.ts b/src/git/models/fileStatus.ts new file mode 100644 index 0000000000000..c02b749cd6060 --- /dev/null +++ b/src/git/models/fileStatus.ts @@ -0,0 +1,31 @@ +export declare type GitFileStatus = GitFileConflictStatus | GitFileIndexStatus | GitFileWorkingTreeStatus; + +export const enum GitFileConflictStatus { + AddedByBoth = 'AA', + AddedByUs = 'AU', + AddedByThem = 'UA', + DeletedByBoth = 'DD', + DeletedByUs = 'DU', + DeletedByThem = 'UD', + ModifiedByBoth = 'UU', +} + +export const enum GitFileIndexStatus { + Modified = 'M', + Added = 'A', + Deleted = 'D', + Renamed = 'R', + Copied = 'C', + Unchanged = '.', + Untracked = '?', + Ignored = '!', + UpdatedButUnmerged = 'U', +} + +export const enum GitFileWorkingTreeStatus { + Modified = 'M', + Added = 'A', + Deleted = 'D', + Untracked = '?', + Ignored = '!', +} diff --git a/src/git/models/graph.ts b/src/git/models/graph.ts index 8be2fdb8e4573..7aee1dd6c643f 100644 --- a/src/git/models/graph.ts +++ b/src/git/models/graph.ts @@ -7,8 +7,6 @@ import type { RowStats, Tag, } from '@gitkraken/gitkraken-components'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; -import type { Brand, Unbrand } from '../../system/brand'; import type { GitBranch } from './branch'; import type { GitStashCommit } from './commit'; import type { GitRemote } from './remote'; @@ -72,44 +70,3 @@ export interface GitGraph { } export type GitGraphRowsStats = Map; - -export function convertHostingServiceTypeToGkProviderId(type: GitGraphHostingServiceType): GkProviderId | undefined { - switch (type) { - case 'github': - return 'github' satisfies Unbrand as Brand; - case 'githubEnterprise': - return 'githubEnterprise' satisfies Unbrand as Brand; - case 'gitlab': - return 'gitlab' satisfies Unbrand as Brand; - case 'gitlabSelfHosted': - return 'gitlabSelfHosted' satisfies Unbrand as Brand; - case 'bitbucket': - return 'bitbucket' satisfies Unbrand as Brand; - case 'bitbucketServer': - return 'bitbucketServer' satisfies Unbrand as Brand; - case 'azureDevops': - return 'azureDevops' satisfies Unbrand as Brand; - default: - return undefined; - } -} - -export function getGkProviderThemeIconString( - providerIdOrHostingType: GkProviderId | GitGraphHostingServiceType | undefined, -): string { - switch (providerIdOrHostingType) { - case 'azureDevops': - return 'gitlens-provider-azdo'; - case 'bitbucket': - case 'bitbucketServer': - return 'gitlens-provider-bitbucket'; - case 'github': - case 'githubEnterprise': - return 'gitlens-provider-github'; - case 'gitlab': - case 'gitlabSelfHosted': - return 'gitlens-provider-gitlab'; - default: - return 'cloud'; - } -} diff --git a/src/git/models/issue.ts b/src/git/models/issue.ts index 71f0c5be93e7e..23999b3a36632 100644 --- a/src/git/models/issue.ts +++ b/src/git/models/issue.ts @@ -1,60 +1,9 @@ -import { Uri } from 'vscode'; -import { Schemes } from '../../constants'; -import type { Container } from '../../container'; -import type { RepositoryIdentityDescriptor } from '../../gk/models/repositoryIdentities'; +import type { IssueOrPullRequest, IssueOrPullRequestState } from './issueOrPullRequest'; import type { ProviderReference } from './remoteProvider'; -import type { Repository } from './repository'; +import type { RepositoryIdentityDescriptor } from './repositoryIdentities'; -export type IssueOrPullRequestType = 'issue' | 'pullrequest'; -export type IssueOrPullRequestState = 'opened' | 'closed' | 'merged'; -export enum RepositoryAccessLevel { - Admin = 100, - Maintain = 40, - Write = 30, - Triage = 20, - Read = 10, - None = 0, -} - -export interface IssueOrPullRequest { - readonly type: IssueOrPullRequestType; - readonly provider: ProviderReference; - readonly id: string; - readonly nodeId: string | undefined; - readonly title: string; - readonly url: string; - readonly createdDate: Date; - readonly updatedDate: Date; - readonly closedDate?: Date; - readonly closed: boolean; - readonly state: IssueOrPullRequestState; - readonly commentsCount?: number; - readonly thumbsUpCount?: number; -} - -export interface IssueLabel { - color?: string; - name: string; -} - -export interface IssueMember { - id: string; - name: string; - avatarUrl?: string; - url?: string; -} - -export interface IssueRepository { - owner: string; - repo: string; - accessLevel?: RepositoryAccessLevel; - url?: string; -} - -export interface IssueProject { - id: string; - name: string; - resourceId: string; +export function isIssue(issue: unknown): issue is Issue { + return issue instanceof Issue; } export interface IssueShape extends IssueOrPullRequest { @@ -66,93 +15,6 @@ export interface IssueShape extends IssueOrPullRequest { project?: IssueProject; } -export interface SearchedIssue { - issue: IssueShape; - reasons: string[]; -} - -export function serializeIssueOrPullRequest(value: IssueOrPullRequest): IssueOrPullRequest { - const serialized: IssueOrPullRequest = { - type: value.type, - provider: { - id: value.provider.id, - name: value.provider.name, - domain: value.provider.domain, - icon: value.provider.icon, - }, - id: value.id, - nodeId: value.nodeId, - title: value.title, - url: value.url, - createdDate: value.createdDate, - updatedDate: value.updatedDate, - closedDate: value.closedDate, - closed: value.closed, - state: value.state, - }; - return serialized; -} - -export function serializeIssue(value: IssueShape): IssueShape { - const serialized: IssueShape = { - type: value.type, - provider: { - id: value.provider.id, - name: value.provider.name, - domain: value.provider.domain, - icon: value.provider.icon, - }, - id: value.id, - nodeId: value.nodeId, - title: value.title, - url: value.url, - createdDate: value.createdDate, - updatedDate: value.updatedDate, - closedDate: value.closedDate, - closed: value.closed, - state: value.state, - author: { - id: value.author.id, - name: value.author.name, - avatarUrl: value.author.avatarUrl, - url: value.author.url, - }, - repository: - value.repository == null - ? undefined - : { - owner: value.repository.owner, - repo: value.repository.repo, - url: value.repository.url, - }, - project: - value.project == null - ? undefined - : { - id: value.project.id, - name: value.project.name, - resourceId: value.project.resourceId, - }, - assignees: value.assignees.map(assignee => ({ - id: assignee.id, - name: assignee.name, - avatarUrl: assignee.avatarUrl, - url: assignee.url, - })), - labels: - value.labels == null - ? undefined - : value.labels.map(label => ({ - color: label.color, - name: label.name, - })), - commentsCount: value.commentsCount, - thumbsUpCount: value.thumbsUpCount, - body: value.body, - }; - return serialized; -} - export class Issue implements IssueShape { readonly type = 'issue'; @@ -178,66 +40,48 @@ export class Issue implements IssueShape { ) {} } -export type IssueRepositoryIdentityDescriptor = RequireSomeWithProps< - RequireSome, 'provider'>, - 'provider', - 'id' | 'domain' | 'repoDomain' | 'repoName' -> & - RequireSomeWithProps, 'remote'>, 'remote', 'domain'>; - -export function getRepositoryIdentityForIssue(issue: IssueShape | Issue): IssueRepositoryIdentityDescriptor { - if (issue.repository == null) throw new Error('Missing repository'); - - return { - remote: { - url: issue.repository.url, - domain: issue.provider.domain, - }, - name: `${issue.repository.owner}/${issue.repository.repo}`, - provider: { - id: issue.provider.id, - domain: issue.provider.domain, - repoDomain: issue.repository.owner, - repoName: issue.repository.repo, - repoOwnerDomain: issue.repository.owner, - }, - }; +export enum RepositoryAccessLevel { + Admin = 100, + Maintain = 40, + Write = 30, + Triage = 20, + Read = 10, + None = 0, } -export function getVirtualUriForIssue(issue: IssueShape | Issue): Uri | undefined { - if (issue.repository == null) throw new Error('Missing repository'); - if (issue.provider.id !== 'github') return undefined; - - const uri = Uri.parse(issue.repository.url ?? issue.url); - return uri.with({ scheme: Schemes.Virtual, authority: 'github', path: uri.path }); +export interface IssueLabel { + color?: string; + name: string; } -export async function getOrOpenIssueRepository( - container: Container, - issue: IssueShape | Issue, - options?: { promptIfNeeded?: boolean; skipVirtual?: boolean }, -): Promise { - const identity = getRepositoryIdentityForIssue(issue); - let repo = await container.repositoryIdentity.getRepository(identity, { - openIfNeeded: true, - keepOpen: false, - prompt: false, - }); +export interface IssueMember { + id: string; + name: string; + avatarUrl?: string; + url?: string; +} - if (repo == null && !options?.skipVirtual) { - const virtualUri = getVirtualUriForIssue(issue); - if (virtualUri != null) { - repo = await container.git.getOrOpenRepository(virtualUri, { closeOnOpen: true, detectNested: false }); - } - } +export interface IssueProject { + id: string; + name: string; + resourceId: string; +} - if (repo == null && options?.promptIfNeeded) { - repo = await container.repositoryIdentity.getRepository(identity, { - openIfNeeded: true, - keepOpen: false, - prompt: true, - }); - } +export interface IssueRepository { + owner: string; + repo: string; + accessLevel?: RepositoryAccessLevel; + url?: string; +} - return repo; +export interface SearchedIssue { + issue: IssueShape; + reasons: string[]; } + +export type IssueRepositoryIdentityDescriptor = RequireSomeWithProps< + RequireSome, 'provider'>, + 'provider', + 'id' | 'domain' | 'repoDomain' | 'repoName' +> & + RequireSomeWithProps, 'remote'>, 'remote', 'domain'>; diff --git a/src/git/models/issueOrPullRequest.ts b/src/git/models/issueOrPullRequest.ts new file mode 100644 index 0000000000000..df066f4e76416 --- /dev/null +++ b/src/git/models/issueOrPullRequest.ts @@ -0,0 +1,20 @@ +import type { ProviderReference } from './remoteProvider'; + +export interface IssueOrPullRequest { + readonly type: IssueOrPullRequestType; + readonly provider: ProviderReference; + readonly id: string; + readonly nodeId: string | undefined; + readonly title: string; + readonly url: string; + readonly createdDate: Date; + readonly updatedDate: Date; + readonly closedDate?: Date; + readonly closed: boolean; + readonly state: IssueOrPullRequestState; + readonly commentsCount?: number; + readonly thumbsUpCount?: number; +} + +export type IssueOrPullRequestType = 'issue' | 'pullrequest'; +export type IssueOrPullRequestState = 'opened' | 'closed' | 'merged'; diff --git a/src/pathMapping/models.ts b/src/git/models/pathMapping.ts similarity index 100% rename from src/pathMapping/models.ts rename to src/git/models/pathMapping.ts diff --git a/src/git/models/pullRequest.ts b/src/git/models/pullRequest.ts index c7c83ed41df56..57ef7ec2f95a7 100644 --- a/src/git/models/pullRequest.ts +++ b/src/git/models/pullRequest.ts @@ -1,76 +1,16 @@ -import { Uri, window } from 'vscode'; -import { Schemes } from '../../constants'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { Container } from '../../container'; -import type { RepositoryIdentityDescriptor } from '../../gk/models/repositoryIdentities'; import { formatDate, fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; -import type { LeftRightCommitCountResult } from '../gitProvider'; -import type { IssueOrPullRequest, IssueRepository, IssueOrPullRequestState as PullRequestState } from './issue'; +import { memoize } from '../../system/decorators/-webview/memoize'; +import type { IssueRepository } from './issue'; +import type { IssueOrPullRequest, IssueOrPullRequestState as PullRequestState } from './issueOrPullRequest'; import type { ProviderReference } from './remoteProvider'; -import type { Repository } from './repository'; -import { createRevisionRange, shortenRevision } from './revision.utils'; +import type { RepositoryIdentityDescriptor } from './repositoryIdentities'; export type { PullRequestState }; -export const enum PullRequestReviewDecision { - Approved = 'Approved', - ChangesRequested = 'ChangesRequested', - ReviewRequired = 'ReviewRequired', -} - -export const enum PullRequestMergeableState { - Unknown = 'Unknown', - Mergeable = 'Mergeable', - Conflicting = 'Conflicting', -} - -export const enum PullRequestStatusCheckRollupState { - Success = 'success', - Pending = 'pending', - Failed = 'failed', -} - -export const enum PullRequestMergeMethod { - Merge = 'merge', - Squash = 'squash', - Rebase = 'rebase', -} - -export const enum PullRequestReviewState { - Approved = 'APPROVED', - ChangesRequested = 'CHANGES_REQUESTED', - Commented = 'COMMENTED', - Dismissed = 'DISMISSED', - Pending = 'PENDING', - ReviewRequested = 'REVIEW_REQUESTED', -} - -export interface PullRequestRef { - owner: string; - repo: string; - branch: string; - sha: string; - exists: boolean; - url: string; -} - -export interface PullRequestRefs { - base: PullRequestRef; - head: PullRequestRef; - isCrossRepository: boolean; -} - -export interface PullRequestMember { - id: string; - name: string; - avatarUrl?: string; - url?: string; -} - -export interface PullRequestReviewer { - isCodeOwner?: boolean; - reviewer: PullRequestMember; - state: PullRequestReviewState; +export function isPullRequest(pr: unknown): pr is PullRequest { + return pr instanceof PullRequest; } export interface PullRequestShape extends IssueOrPullRequest { @@ -86,81 +26,12 @@ export interface PullRequestShape extends IssueOrPullRequest { readonly assignees?: PullRequestMember[]; } -export interface SearchedPullRequest { - pullRequest: PullRequest; - reasons: string[]; -} - -export function serializePullRequest(value: PullRequest): PullRequestShape { - const serialized: PullRequestShape = { - type: value.type, - provider: { - id: value.provider.id, - name: value.provider.name, - domain: value.provider.domain, - icon: value.provider.icon, - }, - id: value.id, - nodeId: value.nodeId, - title: value.title, - url: value.url, - createdDate: value.createdDate, - updatedDate: value.updatedDate, - closedDate: value.closedDate, - closed: value.closed, - author: { - id: value.author.id, - name: value.author.name, - avatarUrl: value.author.avatarUrl, - url: value.author.url, - }, - state: value.state, - mergedDate: value.mergedDate, - mergeableState: value.mergeableState, - refs: value.refs - ? { - head: { - exists: value.refs.head.exists, - owner: value.refs.head.owner, - repo: value.refs.head.repo, - sha: value.refs.head.sha, - branch: value.refs.head.branch, - url: value.refs.head.url, - }, - base: { - exists: value.refs.base.exists, - owner: value.refs.base.owner, - repo: value.refs.base.repo, - sha: value.refs.base.sha, - branch: value.refs.base.branch, - url: value.refs.base.url, - }, - isCrossRepository: value.refs.isCrossRepository, - } - : undefined, - isDraft: value.isDraft, - additions: value.additions, - deletions: value.deletions, - commentsCount: value.commentsCount, - thumbsUpCount: value.thumbsUpCount, - reviewDecision: value.reviewDecision, - reviewRequests: value.reviewRequests, - assignees: value.assignees, - }; - return serialized; -} - export class PullRequest implements PullRequestShape { readonly type = 'pullrequest'; constructor( public readonly provider: ProviderReference, - public readonly author: { - readonly id: string; - readonly name: string; - readonly avatarUrl?: string; - readonly url?: string; - }, + public readonly author: PullRequestMember, public readonly id: string, public readonly nodeId: string | undefined, public readonly title: string, @@ -237,183 +108,81 @@ export class PullRequest implements PullRequestShape { } } -export function isPullRequest(pr: any): pr is PullRequest { - return pr instanceof PullRequest; +export const enum PullRequestReviewDecision { + Approved = 'Approved', + ChangesRequested = 'ChangesRequested', + ReviewRequired = 'ReviewRequired', } -export interface PullRequestComparisonRefs { - repoPath: string; - base: { ref: string; label: string }; - head: { ref: string; label: string }; +export const enum PullRequestMergeableState { + Unknown = 'Unknown', + Mergeable = 'Mergeable', + Conflicting = 'Conflicting', } -export function getComparisonRefsForPullRequest(repoPath: string, prRefs: PullRequestRefs): PullRequestComparisonRefs { - const refs: PullRequestComparisonRefs = { - repoPath: repoPath, - base: { ref: prRefs.base.sha, label: `${prRefs.base.branch} (${shortenRevision(prRefs.base.sha)})` }, - head: { ref: prRefs.head.sha, label: prRefs.head.branch }, - }; - return refs; +export const enum PullRequestStatusCheckRollupState { + Success = 'success', + Pending = 'pending', + Failed = 'failed', } -export type PullRequestRepositoryIdentityDescriptor = RequireSomeWithProps< - RequireSome, 'provider'>, - 'provider', - 'id' | 'domain' | 'repoDomain' | 'repoName' -> & - RequireSomeWithProps, 'remote'>, 'remote', 'domain'>; - -export function getRepositoryIdentityForPullRequest( - pr: PullRequest, - headRepo: boolean = true, -): PullRequestRepositoryIdentityDescriptor { - if (headRepo) { - return { - remote: { - url: pr.refs?.head?.url, - domain: pr.provider.domain, - }, - name: `${pr.refs?.head?.owner ?? pr.repository.owner}/${pr.refs?.head?.repo ?? pr.repository.repo}`, - provider: { - id: pr.provider.id, - domain: pr.provider.domain, - repoDomain: pr.refs?.head?.owner ?? pr.repository.owner, - repoName: pr.refs?.head?.repo ?? pr.repository.repo, - }, - }; - } - - return { - remote: { - url: pr.refs?.base?.url ?? pr.url, - domain: pr.provider.domain, - }, - name: `${pr.refs?.base?.owner ?? pr.repository.owner}/${pr.refs?.base?.repo ?? pr.repository.repo}`, - provider: { - id: pr.provider.id, - domain: pr.provider.domain, - repoDomain: pr.refs?.base?.owner ?? pr.repository.owner, - repoName: pr.refs?.base?.repo ?? pr.repository.repo, - repoOwnerDomain: pr.refs?.base?.owner ?? pr.repository.owner, - }, - }; +export const enum PullRequestMergeMethod { + Merge = 'merge', + Squash = 'squash', + Rebase = 'rebase', } -export function getVirtualUriForPullRequest(pr: PullRequest): Uri | undefined { - if (pr.provider.id !== 'github') return undefined; - - const uri = Uri.parse(pr.refs?.base?.url ?? pr.url); - return uri.with({ scheme: Schemes.Virtual, authority: 'github', path: uri.path }); +export const enum PullRequestReviewState { + Approved = 'APPROVED', + ChangesRequested = 'CHANGES_REQUESTED', + Commented = 'COMMENTED', + Dismissed = 'DISMISSED', + Pending = 'PENDING', + ReviewRequested = 'REVIEW_REQUESTED', } -export async function getOrOpenPullRequestRepository( - container: Container, - pr: PullRequest, - options?: { promptIfNeeded?: boolean; skipVirtual?: boolean }, -): Promise { - const identity = getRepositoryIdentityForPullRequest(pr); - let repo = await container.repositoryIdentity.getRepository(identity, { - openIfNeeded: true, - keepOpen: false, - prompt: false, - }); - - if (repo == null && !options?.skipVirtual) { - const virtualUri = getVirtualUriForPullRequest(pr); - if (virtualUri != null) { - repo = await container.git.getOrOpenRepository(virtualUri, { closeOnOpen: true, detectNested: false }); - } - } - - if (repo == null) { - const baseIdentity = getRepositoryIdentityForPullRequest(pr, false); - repo = await container.repositoryIdentity.getRepository(baseIdentity, { - openIfNeeded: true, - keepOpen: false, - prompt: false, - }); - } - - if (repo == null && options?.promptIfNeeded) { - repo = await container.repositoryIdentity.getRepository(identity, { - openIfNeeded: true, - keepOpen: false, - prompt: true, - }); - } - - return repo; +export interface PullRequestComparisonRefs { + repoPath: string; + base: { ref: string; label: string }; + head: { ref: string; label: string }; } -export async function ensurePullRequestRefs( - container: Container, - pr: PullRequest, - repo: Repository, - options?: { promptMessage?: string }, - refs?: PullRequestComparisonRefs, -): Promise { - if (pr.refs == null) return undefined; - - refs ??= getComparisonRefsForPullRequest(repo.path, pr.refs); - const range = createRevisionRange(refs.base.ref, refs.head.ref, '...'); - let counts = await container.git.getLeftRightCommitCount(repo.path, range); - if (counts == null) { - if (await ensurePullRequestRemote(pr, repo, options)) { - counts = await container.git.getLeftRightCommitCount(repo.path, range); - } - } - - return counts; +export interface PullRequestMember { + id: string; + name: string; + avatarUrl?: string; + url?: string; } -export async function ensurePullRequestRemote( - pr: PullRequest, - repo: Repository, - options?: { promptMessage?: string }, -): Promise { - const identity = getRepositoryIdentityForPullRequest(pr); - if (identity.remote.url == null) return false; - - const prRemoteUrl = identity.remote.url.replace(/\.git$/, ''); - - let found = false; - for (const remote of await repo.git.remotes().getRemotes()) { - if (remote.matches(prRemoteUrl)) { - found = true; - break; - } - } - - if (found) return true; - - const confirm = { title: 'Add Remote' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showInformationMessage( - `${ - options?.promptMessage ?? `Unable to find a remote for PR #${pr.id}.` - }\nWould you like to add a remote for '${identity.provider.repoDomain}?`, - { modal: true }, - confirm, - cancel, - ); +export interface PullRequestRef { + owner: string; + repo: string; + branch: string; + sha: string; + exists: boolean; + url: string; +} - if (result === confirm) { - await repo.git - .remotes() - .addRemoteWithResult?.(identity.provider.repoDomain, identity.remote.url, { fetch: true }); - return true; - } +export interface PullRequestRefs { + base: PullRequestRef; + head: PullRequestRef; + isCrossRepository: boolean; +} - return false; +export interface PullRequestReviewer { + isCodeOwner?: boolean; + reviewer: PullRequestMember; + state: PullRequestReviewState; } -export async function getOpenedPullRequestRepo( - container: Container, - pr: PullRequest, - repoPath?: string, -): Promise { - if (repoPath) return container.git.getRepository(repoPath); +export type PullRequestRepositoryIdentityDescriptor = RequireSomeWithProps< + RequireSome, 'provider'>, + 'provider', + 'id' | 'domain' | 'repoDomain' | 'repoName' +> & + RequireSomeWithProps, 'remote'>, 'remote', 'domain'>; - const repo = await getOrOpenPullRequestRepository(container, pr, { promptIfNeeded: true }); - return repo; +export interface SearchedPullRequest { + pullRequest: PullRequest; + reasons: string[]; } diff --git a/src/git/models/pullRequest.utils.ts b/src/git/models/pullRequest.utils.ts deleted file mode 100644 index 2df6779a61573..0000000000000 --- a/src/git/models/pullRequest.utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -// pullRequest.ts pulls many dependencies through Container and some of them break the unit tests. -// To avoid this file has been created that can collect more simple functions which -// don't require Container and can be tested. - -import type { HostingIntegrationId } from '../../constants.integrations'; - -export interface PullRequestUrlIdentity { - provider?: HostingIntegrationId; - - ownerAndRepo?: string; - prNumber: string; -} - -export function isMaybeNonSpecificPullRequestSearchUrl(search: string): boolean { - return getPullRequestIdentityFromMaybeUrl(search) != null; -} - -export function getPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined { - let prNumber: string | undefined = undefined; - - let match = search.match(/(?:\/)(\d+)/); // any number starting with "/" - if (match != null) { - prNumber = match[1]; - } - - if (prNumber == null) { - match = search.match(/^#?(\d+)$/); // just a number or with a leading "#" - if (match != null) { - prNumber = match[1]; - } - } - - return prNumber == null ? undefined : { ownerAndRepo: undefined, prNumber: prNumber, provider: undefined }; -} diff --git a/src/git/models/reflog.ts b/src/git/models/reflog.ts index 805ea91888d25..bb8166e8847d4 100644 --- a/src/git/models/reflog.ts +++ b/src/git/models/reflog.ts @@ -1,7 +1,7 @@ import type { Container } from '../../container'; import { formatDate, fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; -import { shortenRevision } from './revision.utils'; +import { memoize } from '../../system/decorators/-webview/memoize'; +import { shortenRevision } from '../utils/revision.utils'; export interface GitReflog { readonly repoPath: string; diff --git a/src/git/models/remote.ts b/src/git/models/remote.ts index ba900574ebb0d..806d72323eb4e 100644 --- a/src/git/models/remote.ts +++ b/src/git/models/remote.ts @@ -1,12 +1,13 @@ -import { GlyphChars } from '../../constants'; import type { Container } from '../../container'; import type { HostingIntegration } from '../../plus/integrations/integration'; -import { memoize } from '../../system/decorators/memoize'; -import { equalsIgnoreCase, sortCompare } from '../../system/string'; +import { memoize } from '../../system/decorators/-webview/memoize'; +import { equalsIgnoreCase } from '../../system/string'; import { parseGitRemoteUrl } from '../parsers/remoteParser'; import type { RemoteProvider } from '../remotes/remoteProvider'; -export type GitRemoteType = 'fetch' | 'push'; +export function isRemote(remote: unknown): remote is GitRemote { + return remote instanceof GitRemote; +} export class GitRemote { constructor( @@ -90,105 +91,4 @@ export class GitRemote(remotes: T[]): T | undefined { - return remotes.length === 1 ? remotes[0] : remotes.find(r => r.default); -} - -export function getHighlanderProviders(remotes: GitRemote[]) { - if (remotes.length === 0) return undefined; - - const remote = getDefaultRemoteOrHighlander(remotes); - if (remote != null) return [remote.provider]; - - const providerName = remotes[0].provider.name; - if (remotes.every(r => r.provider.name === providerName)) return remotes.map(r => r.provider); - - return undefined; -} - -export function getHighlanderProviderName(remotes: GitRemote[]) { - if (remotes.length === 0) return undefined; - - const remote = getDefaultRemoteOrHighlander(remotes); - if (remote != null) return remote.provider.name; - - const providerName = remotes[0].provider.name; - // Only use the real provider name if there is only 1 type of provider - if (remotes.every(r => r.provider.name === providerName)) return providerName; - - return undefined; -} - -export function getRemoteArrowsGlyph(remote: GitRemote): GlyphChars { - let arrows; - let left; - let right; - for (const { type } of remote.urls) { - if (type === 'fetch') { - left = true; - - if (right) break; - } else if (type === 'push') { - right = true; - - if (left) break; - } - } - - if (left && right) { - arrows = GlyphChars.ArrowsRightLeft; - } else if (right) { - arrows = GlyphChars.ArrowRight; - } else if (left) { - arrows = GlyphChars.ArrowLeft; - } else { - arrows = GlyphChars.Dash; - } - - return arrows; -} - -export function getRemoteThemeIconString(remote: GitRemote | undefined): string { - return getRemoteProviderThemeIconString(remote?.provider); -} - -export function getRemoteProviderThemeIconString(provider: RemoteProvider | undefined): string { - return provider != null ? `gitlens-provider-${provider.icon}` : 'cloud'; -} - -export function getRemoteUpstreamDescription(remote: GitRemote): string { - const arrows = getRemoteArrowsGlyph(remote); - - const { provider } = remote; - if (provider != null) { - return `${arrows}${GlyphChars.Space} ${provider.name} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${provider.displayPath}`; - } - - return `${arrows}${GlyphChars.Space} ${ - remote.domain ? `${remote.domain} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ` : '' - }${remote.path}`; -} - -export function getVisibilityCacheKey(remote: GitRemote): string; -export function getVisibilityCacheKey(remotes: GitRemote[]): string; -export function getVisibilityCacheKey(remotes: GitRemote | GitRemote[]): string { - if (!Array.isArray(remotes)) return remotes.remoteKey; - return remotes - .map(r => r.remoteKey) - .sort() - .join(','); -} - -export function isRemote(remote: any): remote is GitRemote { - return remote instanceof GitRemote; -} - -export function sortRemotes(remotes: T[]) { - return remotes.sort( - (a, b) => - (a.default ? -1 : 1) - (b.default ? -1 : 1) || - (a.name === 'origin' ? -1 : 1) - (b.name === 'origin' ? -1 : 1) || - (a.name === 'upstream' ? -1 : 1) - (b.name === 'upstream' ? -1 : 1) || - sortCompare(a.name, b.name), - ); -} +export type GitRemoteType = 'fetch' | 'push'; diff --git a/src/git/models/remote.utils.ts b/src/git/models/remote.utils.ts deleted file mode 100644 index a17ec094686ff..0000000000000 --- a/src/git/models/remote.utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ThemeIcon } from 'vscode'; -import type { IconPath } from '../../@types/vscode.iconpath'; -import type { Container } from '../../container'; -import { getIconPathUris } from '../../system/vscode/vscode'; -import type { GitRemote } from './remote'; -import { getRemoteThemeIconString } from './remote'; - -export function getRemoteIconPath( - container: Container, - remote: GitRemote | undefined, - options?: { avatars?: boolean }, -): IconPath { - if (options?.avatars && remote?.provider?.icon != null) { - return getIconPathUris(container, `icon-${remote.provider.icon}.svg`); - } - - return new ThemeIcon(getRemoteThemeIconString(remote)); -} diff --git a/src/git/models/remoteResource.ts b/src/git/models/remoteResource.ts index fa14fc9dc93a8..560926dffdc74 100644 --- a/src/git/models/remoteResource.ts +++ b/src/git/models/remoteResource.ts @@ -59,32 +59,3 @@ export type RemoteResource = range?: Range; sha?: string; }; -// | { -// type: RemoteResourceType.Tag; -// tag: string; -// }; - -export function getNameFromRemoteResource(resource: RemoteResource) { - switch (resource.type) { - case RemoteResourceType.Branch: - return 'Branch'; - case RemoteResourceType.Branches: - return 'Branches'; - case RemoteResourceType.Commit: - return 'Commit'; - case RemoteResourceType.Comparison: - return 'Comparison'; - case RemoteResourceType.CreatePullRequest: - return 'Create Pull Request'; - case RemoteResourceType.File: - return 'File'; - case RemoteResourceType.Repo: - return 'Repository'; - case RemoteResourceType.Revision: - return 'File'; - // case RemoteResourceType.Tag: - // return 'Tag'; - default: - return ''; - } -} diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index 43b44a0d77e71..4898265520584 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -1,4 +1,5 @@ import type { ConfigurationChangeEvent, Event, Uri, WorkspaceFolder } from 'vscode'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { Disposable, EventEmitter, ProgressLocation, RelativePattern, window, workspace } from 'vscode'; import { md5, uuid } from '@env/crypto'; import type { CreatePullRequestActionContext } from '../../api/gitlens'; @@ -8,10 +9,12 @@ import type { FeatureAccess, PlusFeatures } from '../../features'; import { showCreatePullRequestPrompt, showGenericErrorMessage } from '../../messages'; import type { RepoComparisonKey } from '../../repositories'; import { asRepoComparisonKey } from '../../repositories'; +import { executeActionCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; import { getScopedCounter } from '../../system/counter'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { debug, log, logName } from '../../system/decorators/log'; -import { memoize } from '../../system/decorators/memoize'; import type { Deferrable } from '../../system/function'; import { debounce } from '../../system/function'; import { filter, groupByMap, join, min, some } from '../../system/iterable'; @@ -19,14 +22,12 @@ import { getLoggableName, Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; import { updateRecordValue } from '../../system/object'; import { basename, normalizePath } from '../../system/path'; -import { executeActionCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; import type { GitProviderDescriptor, GitRepositoryProvider } from '../gitProvider'; import type { GitProviderService } from '../gitProviderService'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../utils/branch.utils'; +import { getReferenceNameWithoutRemote, isBranchReference } from '../utils/reference.utils'; import type { GitBranch } from './branch'; -import { getBranchNameWithoutRemote, getNameWithoutRemote, getRemoteNameFromBranchName } from './branch.utils'; import type { GitBranchReference, GitReference } from './reference'; -import { isBranchReference } from './reference.utils'; type GitProviderRepoKeys = keyof GitRepositoryProvider | 'supports'; @@ -549,7 +550,12 @@ export class Repository implements Disposable { const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name)); for (const [remote, branches] of branchesByOrigin.entries()) { - void this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b))); + void this.runTerminalCommand( + 'push', + '-d', + remote, + ...branches.map(b => getReferenceNameWithoutRemote(b)), + ); } } } diff --git a/src/gk/models/repositoryIdentities.ts b/src/git/models/repositoryIdentities.ts similarity index 100% rename from src/gk/models/repositoryIdentities.ts rename to src/git/models/repositoryIdentities.ts diff --git a/src/git/models/status.ts b/src/git/models/status.ts index fcef76cd07af5..9a92bd05a6805 100644 --- a/src/git/models/status.ts +++ b/src/git/models/status.ts @@ -1,43 +1,18 @@ -import type { Uri } from 'vscode'; -import { GlyphChars } from '../../constants'; -import { Container } from '../../container'; -import { memoize } from '../../system/decorators/memoize'; +import type { Container } from '../../container'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { pluralize } from '../../system/string'; +import { formatDetachedHeadName, getRemoteNameFromBranchName, isDetachedHead } from '../utils/branch.utils'; +import { getUpstreamStatus } from '../utils/status.utils'; import type { GitBranchStatus, GitTrackingState } from './branch'; -import { formatDetachedHeadName, getRemoteNameFromBranchName, isDetachedHead } from './branch.utils'; -import { GitCommit, GitCommitIdentity } from './commit'; -import type { GitFile, GitFileStatus } from './file'; -import { - getGitFileFormattedDirectory, - getGitFileFormattedPath, - getGitFileStatusText, - GitFileChange, - GitFileConflictStatus, - GitFileIndexStatus, - GitFileWorkingTreeStatus, -} from './file'; +import { GitFileConflictStatus, GitFileIndexStatus, GitFileWorkingTreeStatus } from './fileStatus'; import type { GitRemote } from './remote'; -import { uncommitted, uncommittedStaged } from './revision'; -import type { GitUser } from './user'; - -export interface ComputedWorkingTreeGitStatus { - staged: number; - stagedAddsAndChanges: GitStatusFile[]; - stagedStatus: string; - - unstaged: number; - unstagedAddsAndChanges: GitStatusFile[]; - unstagedStatus: string; - - conflicted: number; - conflictedAddsAndChanges: GitStatusFile[]; - conflictedStatus: string; -} +import type { GitStatusFile } from './statusFile'; export class GitStatus { readonly detached: boolean; constructor( + private readonly container: Container, public readonly repoPath: string, public readonly branch: string, public readonly sha: string, @@ -280,7 +255,7 @@ export class GitStatus { async getRemote(): Promise { if (this.upstream == null) return undefined; - const remotes = await Container.instance.git.remotes(this.repoPath).getRemotesWithProviders(); + const remotes = await this.container.git.remotes(this.repoPath).getRemotesWithProviders(); if (remotes.length === 0) return undefined; const remoteName = getRemoteNameFromBranchName(this.upstream?.name); @@ -299,295 +274,16 @@ export class GitStatus { } } -export function getUpstreamStatus( - upstream: { name: string; missing: boolean } | undefined, - state: { ahead: number; behind: number }, - options?: { - count?: boolean; - empty?: string; - expand?: boolean; - icons?: boolean; - prefix?: string; - separator?: string; - suffix?: string; - }, -): string { - let count = true; - let expand = false; - let icons = false; - let prefix = ''; - let separator = ' '; - let suffix = ''; - if (options != null) { - ({ count = true, expand = false, icons = false, prefix = '', separator = ' ', suffix = '' } = options); - } - if (upstream == null || (state.behind === 0 && state.ahead === 0)) return options?.empty ?? ''; - - if (expand) { - let status = ''; - if (upstream.missing) { - status = 'missing'; - } else { - if (state.behind) { - status += `${pluralize('commit', state.behind, { - infix: icons ? '$(arrow-down) ' : undefined, - })} behind`; - } - if (state.ahead) { - status += `${status.length === 0 ? '' : separator}${pluralize('commit', state.ahead, { - infix: icons ? '$(arrow-up) ' : undefined, - })} ahead`; - if (suffix.includes(upstream.name.split('/')[0])) { - status += ' of'; - } - } - } - return `${prefix}${status}${suffix}`; - } - - const showCounts = count && !upstream.missing; - - return `${prefix}${showCounts ? state.behind : ''}${ - showCounts || state.behind !== 0 ? GlyphChars.ArrowDown : '' - }${separator}${showCounts ? state.ahead : ''}${showCounts || state.ahead !== 0 ? GlyphChars.ArrowUp : ''}${suffix}`; -} - -export class GitStatusFile implements GitFile { - public readonly conflictStatus: GitFileConflictStatus | undefined; - public readonly indexStatus: GitFileIndexStatus | undefined; - public readonly workingTreeStatus: GitFileWorkingTreeStatus | undefined; - - constructor( - public readonly repoPath: string, - x: string | undefined, - y: string | undefined, - public readonly path: string, - public readonly originalPath?: string, - ) { - if (x != null && y != null) { - switch (x + y) { - case '??': - this.workingTreeStatus = GitFileWorkingTreeStatus.Untracked; - break; - case '!!': - this.workingTreeStatus = GitFileWorkingTreeStatus.Ignored; - break; - case 'AA': - this.conflictStatus = GitFileConflictStatus.AddedByBoth; - break; - case 'AU': - this.conflictStatus = GitFileConflictStatus.AddedByUs; - break; - case 'UA': - this.conflictStatus = GitFileConflictStatus.AddedByThem; - break; - case 'DD': - this.conflictStatus = GitFileConflictStatus.DeletedByBoth; - break; - case 'DU': - this.conflictStatus = GitFileConflictStatus.DeletedByUs; - break; - case 'UD': - this.conflictStatus = GitFileConflictStatus.DeletedByThem; - break; - case 'UU': - this.conflictStatus = GitFileConflictStatus.ModifiedByBoth; - break; - } - } - - if (this.conflictStatus == null) { - switch (x) { - case 'A': - this.indexStatus = GitFileIndexStatus.Added; - break; - case 'D': - this.indexStatus = GitFileIndexStatus.Deleted; - break; - case 'M': - this.indexStatus = GitFileIndexStatus.Modified; - break; - case 'R': - this.indexStatus = GitFileIndexStatus.Renamed; - break; - case 'C': - this.indexStatus = GitFileIndexStatus.Copied; - break; - } - - switch (y) { - case 'A': - // case '?': - this.workingTreeStatus = GitFileWorkingTreeStatus.Added; - break; - case 'D': - this.workingTreeStatus = GitFileWorkingTreeStatus.Deleted; - break; - case 'M': - this.workingTreeStatus = GitFileWorkingTreeStatus.Modified; - break; - } - } - } - - get conflicted() { - return this.conflictStatus != null; - } - - get staged() { - return this.indexStatus != null; - } - - @memoize() - get status(): GitFileStatus { - return (this.conflictStatus ?? this.indexStatus ?? this.workingTreeStatus)!; - } - - @memoize() - get uri(): Uri { - return Container.instance.git.getAbsoluteUri(this.path, this.repoPath); - } - - get wip() { - return this.workingTreeStatus != null; - } - - getFormattedDirectory(includeOriginal: boolean = false): string { - return getGitFileFormattedDirectory(this, includeOriginal); - } - - getFormattedPath(options: { relativeTo?: string; suffix?: string; truncateTo?: number } = {}): string { - return getGitFileFormattedPath(this, options); - } - - getStatusText(): string { - return getGitFileStatusText(this.status); - } - - getPseudoCommits(container: Container, user: GitUser | undefined): GitCommit[] { - const now = new Date(); - - if (this.conflicted) { - const file = new GitFileChange( - this.repoPath, - this.path, - this.status, - this.originalPath, - 'HEAD', - undefined, - false, - ); - return [ - new GitCommit( - container, - this.repoPath, - uncommitted, - new GitCommitIdentity('You', user?.email ?? undefined, now), - new GitCommitIdentity('You', user?.email ?? undefined, now), - 'Uncommitted changes', - ['HEAD'], - 'Uncommitted changes', - { file: file, files: [file] }, - undefined, - [], - ), - ]; - } - - const commits: GitCommit[] = []; - const staged = this.staged; - - if (this.wip) { - const previousSha = staged ? uncommittedStaged : 'HEAD'; - const file = new GitFileChange( - this.repoPath, - this.path, - this.workingTreeStatus ?? this.status, - this.originalPath, - previousSha, - undefined, - false, - ); - commits.push( - new GitCommit( - container, - this.repoPath, - uncommitted, - new GitCommitIdentity('You', user?.email ?? undefined, now), - new GitCommitIdentity('You', user?.email ?? undefined, now), - 'Uncommitted changes', - [previousSha], - 'Uncommitted changes', - { file: file, files: [file] }, - undefined, - [], - ), - ); - - // Decrements the date to guarantee the staged entry (if exists) will be sorted after the working entry (most recent first) - now.setMilliseconds(now.getMilliseconds() - 1); - } - - if (staged) { - const file = new GitFileChange( - this.repoPath, - this.path, - this.indexStatus ?? this.status, - this.originalPath, - 'HEAD', - undefined, - true, - ); - commits.push( - new GitCommit( - container, - this.repoPath, - uncommittedStaged, - new GitCommitIdentity('You', user?.email ?? undefined, now), - new GitCommitIdentity('You', user?.email ?? undefined, now), - 'Uncommitted changes', - ['HEAD'], - 'Uncommitted changes', - { file: file, files: [file] }, - undefined, - [], - ), - ); - } - - return commits; - } - - getPseudoFileChanges(): GitFileChange[] { - if (this.conflicted) { - return [ - new GitFileChange(this.repoPath, this.path, this.status, this.originalPath, 'HEAD', undefined, false), - ]; - } - - const files: GitFileChange[] = []; - const staged = this.staged; - - if (this.wip) { - files.push( - new GitFileChange( - this.repoPath, - this.path, - this.status, - this.originalPath, - staged ? uncommittedStaged : 'HEAD', - undefined, - false, - ), - ); - } +export interface ComputedWorkingTreeGitStatus { + staged: number; + stagedAddsAndChanges: GitStatusFile[]; + stagedStatus: string; - if (staged) { - files.push( - new GitFileChange(this.repoPath, this.path, this.status, this.originalPath, 'HEAD', undefined, true), - ); - } + unstaged: number; + unstagedAddsAndChanges: GitStatusFile[]; + unstagedStatus: string; - return files; - } + conflicted: number; + conflictedAddsAndChanges: GitStatusFile[]; + conflictedStatus: string; } diff --git a/src/git/models/statusFile.ts b/src/git/models/statusFile.ts new file mode 100644 index 0000000000000..6853b080fc95e --- /dev/null +++ b/src/git/models/statusFile.ts @@ -0,0 +1,276 @@ +import type { Uri } from 'vscode'; +import type { Container } from '../../container'; +import { memoize } from '../../system/decorators/-webview/memoize'; +import { getGitFileFormattedDirectory, getGitFileFormattedPath } from '../utils/-webview/file.utils'; +import { getGitFileStatusText } from '../utils/fileStatus.utils'; +import { GitCommit, GitCommitIdentity } from './commit'; +import type { GitFile } from './file'; +import { GitFileChange } from './fileChange'; +import type { GitFileStatus } from './fileStatus'; +import { GitFileConflictStatus, GitFileIndexStatus, GitFileWorkingTreeStatus } from './fileStatus'; +import { uncommitted, uncommittedStaged } from './revision'; +import type { GitUser } from './user'; + +export class GitStatusFile implements GitFile { + public readonly conflictStatus: GitFileConflictStatus | undefined; + public readonly indexStatus: GitFileIndexStatus | undefined; + public readonly workingTreeStatus: GitFileWorkingTreeStatus | undefined; + + constructor( + private readonly container: Container, + public readonly repoPath: string, + x: string | undefined, + y: string | undefined, + public readonly path: string, + public readonly originalPath?: string, + ) { + if (x != null && y != null) { + switch (x + y) { + case '??': + this.workingTreeStatus = GitFileWorkingTreeStatus.Untracked; + break; + case '!!': + this.workingTreeStatus = GitFileWorkingTreeStatus.Ignored; + break; + case 'AA': + this.conflictStatus = GitFileConflictStatus.AddedByBoth; + break; + case 'AU': + this.conflictStatus = GitFileConflictStatus.AddedByUs; + break; + case 'UA': + this.conflictStatus = GitFileConflictStatus.AddedByThem; + break; + case 'DD': + this.conflictStatus = GitFileConflictStatus.DeletedByBoth; + break; + case 'DU': + this.conflictStatus = GitFileConflictStatus.DeletedByUs; + break; + case 'UD': + this.conflictStatus = GitFileConflictStatus.DeletedByThem; + break; + case 'UU': + this.conflictStatus = GitFileConflictStatus.ModifiedByBoth; + break; + } + } + + if (this.conflictStatus == null) { + switch (x) { + case 'A': + this.indexStatus = GitFileIndexStatus.Added; + break; + case 'D': + this.indexStatus = GitFileIndexStatus.Deleted; + break; + case 'M': + this.indexStatus = GitFileIndexStatus.Modified; + break; + case 'R': + this.indexStatus = GitFileIndexStatus.Renamed; + break; + case 'C': + this.indexStatus = GitFileIndexStatus.Copied; + break; + } + + switch (y) { + case 'A': + // case '?': + this.workingTreeStatus = GitFileWorkingTreeStatus.Added; + break; + case 'D': + this.workingTreeStatus = GitFileWorkingTreeStatus.Deleted; + break; + case 'M': + this.workingTreeStatus = GitFileWorkingTreeStatus.Modified; + break; + } + } + } + + get conflicted() { + return this.conflictStatus != null; + } + + get staged() { + return this.indexStatus != null; + } + + @memoize() + get status(): GitFileStatus { + return (this.conflictStatus ?? this.indexStatus ?? this.workingTreeStatus)!; + } + + @memoize() + get uri(): Uri { + return this.container.git.getAbsoluteUri(this.path, this.repoPath); + } + + get wip() { + return this.workingTreeStatus != null; + } + + getFormattedDirectory(includeOriginal: boolean = false): string { + return getGitFileFormattedDirectory(this, includeOriginal); + } + + getFormattedPath(options: { relativeTo?: string; suffix?: string; truncateTo?: number } = {}): string { + return getGitFileFormattedPath(this, options); + } + + getStatusText(): string { + return getGitFileStatusText(this.status); + } + + getPseudoCommits(container: Container, user: GitUser | undefined): GitCommit[] { + const now = new Date(); + + if (this.conflicted) { + const file = new GitFileChange( + container, + this.repoPath, + this.path, + this.status, + this.originalPath, + 'HEAD', + undefined, + false, + ); + return [ + new GitCommit( + container, + this.repoPath, + uncommitted, + new GitCommitIdentity('You', user?.email ?? undefined, now), + new GitCommitIdentity('You', user?.email ?? undefined, now), + 'Uncommitted changes', + ['HEAD'], + 'Uncommitted changes', + { file: file, files: [file] }, + undefined, + [], + ), + ]; + } + + const commits: GitCommit[] = []; + const staged = this.staged; + + if (this.wip) { + const previousSha = staged ? uncommittedStaged : 'HEAD'; + const file = new GitFileChange( + this.container, + this.repoPath, + this.path, + this.workingTreeStatus ?? this.status, + this.originalPath, + previousSha, + undefined, + false, + ); + commits.push( + new GitCommit( + container, + this.repoPath, + uncommitted, + new GitCommitIdentity('You', user?.email ?? undefined, now), + new GitCommitIdentity('You', user?.email ?? undefined, now), + 'Uncommitted changes', + [previousSha], + 'Uncommitted changes', + { file: file, files: [file] }, + undefined, + [], + ), + ); + + // Decrements the date to guarantee the staged entry (if exists) will be sorted after the working entry (most recent first) + now.setMilliseconds(now.getMilliseconds() - 1); + } + + if (staged) { + const file = new GitFileChange( + this.container, + this.repoPath, + this.path, + this.indexStatus ?? this.status, + this.originalPath, + 'HEAD', + undefined, + true, + ); + commits.push( + new GitCommit( + container, + this.repoPath, + uncommittedStaged, + new GitCommitIdentity('You', user?.email ?? undefined, now), + new GitCommitIdentity('You', user?.email ?? undefined, now), + 'Uncommitted changes', + ['HEAD'], + 'Uncommitted changes', + { file: file, files: [file] }, + undefined, + [], + ), + ); + } + + return commits; + } + + getPseudoFileChanges(): GitFileChange[] { + if (this.conflicted) { + return [ + new GitFileChange( + this.container, + this.repoPath, + this.path, + this.status, + this.originalPath, + 'HEAD', + undefined, + false, + ), + ]; + } + + const files: GitFileChange[] = []; + const staged = this.staged; + + if (this.wip) { + files.push( + new GitFileChange( + this.container, + + this.repoPath, + this.path, + this.status, + this.originalPath, + staged ? uncommittedStaged : 'HEAD', + undefined, + false, + ), + ); + } + + if (staged) { + files.push( + new GitFileChange( + this.container, + this.repoPath, + this.path, + this.status, + this.originalPath, + 'HEAD', + undefined, + true, + ), + ); + } + + return files; + } +} diff --git a/src/git/models/tag.ts b/src/git/models/tag.ts index c04626516f756..a3ae755bcd61d 100644 --- a/src/git/models/tag.ts +++ b/src/git/models/tag.ts @@ -1,11 +1,12 @@ -import { Container } from '../../container'; +import type { Container } from '../../container'; import { formatDate, fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { getLoggableName } from '../../system/logger'; -import type { GitReference, GitTagReference } from './reference'; +import { getTagId } from '../utils/tag.utils'; +import type { GitTagReference } from './reference'; -export function getTagId(repoPath: string, name: string): string { - return `${repoPath}|tag/${name}`; +export function isTag(tag: unknown): tag is GitTag { + return tag instanceof GitTag; } export class GitTag implements GitTagReference { @@ -13,6 +14,7 @@ export class GitTag implements GitTagReference { readonly id: string; constructor( + private readonly container: Container, public readonly repoPath: string, public readonly name: string, public readonly sha: string, @@ -28,8 +30,8 @@ export class GitTag implements GitTagReference { } get formattedDate(): string { - return Container.instance.TagDateFormatting.dateStyle === 'absolute' - ? this.formatDate(Container.instance.TagDateFormatting.dateFormat) + return this.container.TagDateFormatting.dateStyle === 'absolute' + ? this.formatDate(this.container.TagDateFormatting.dateFormat) : this.formatDateFromNow(); } @@ -61,11 +63,3 @@ export class GitTag implements GitTagReference { return index !== -1 ? this.name.substring(index + 1) : this.name; } } - -export function isTag(tag: any): tag is GitTag { - return tag instanceof GitTag; -} - -export function isOfTagRefType(tag: GitReference | undefined) { - return tag?.refType === 'tag'; -} diff --git a/src/git/models/user.ts b/src/git/models/user.ts index deace7fc6698e..9fc74ac5603e1 100644 --- a/src/git/models/user.ts +++ b/src/git/models/user.ts @@ -5,22 +5,3 @@ export interface GitUser { id?: string | undefined; username?: string | undefined; } - -export function isUserMatch( - user: GitUser | undefined, - name: string | undefined, - email: string | undefined, - username?: string | undefined, -): boolean { - return ( - user != null && - // Name or e-mail is provided - (user.name != null || user.email != null || user.username != null) && - // Match on name if provided - (user.name == null || user.name === name) && - // Match on email if provided - (user.email == null || user.email === email) && - // Match on username if provided - (user.username == null || user.username === username) - ); -} diff --git a/src/git/models/worktree.ts b/src/git/models/worktree.ts index faea93c9fd54f..c3f510a86f424 100644 --- a/src/git/models/worktree.ts +++ b/src/git/models/worktree.ts @@ -1,13 +1,14 @@ import type { Uri, WorkspaceFolder } from 'vscode'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { workspace } from 'vscode'; -import { Container } from '../../container'; +import type { Container } from '../../container'; +import { relative } from '../../system/-webview/path'; +import { getWorkspaceFriendlyPath } from '../../system/-webview/utils'; import { formatDate, fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { normalizePath } from '../../system/path'; -import { relative } from '../../system/vscode/path'; -import { getWorkspaceFriendlyPath } from '../../system/vscode/utils'; +import { shortenRevision } from '../utils/revision.utils'; import type { GitBranch } from './branch'; -import { shortenRevision } from './revision.utils'; import type { GitStatus } from './status'; export class GitWorktree { @@ -84,7 +85,7 @@ export class GitWorktree { // eslint-disable-next-line no-async-promise-executor this._statusPromise = new Promise(async (resolve, reject) => { try { - const status = await Container.instance.git.status(this.uri.fsPath).getStatus(); + const status = await this.container.git.status(this.uri.fsPath).getStatus(); this._status = status; resolve(status); } catch (ex) { @@ -97,10 +98,6 @@ export class GitWorktree { } } -export function getWorktreeId(repoPath: string, name: string): string { - return `${repoPath}|worktrees/${name}`; -} - export function isWorktree(worktree: any): worktree is GitWorktree { return worktree instanceof GitWorktree; } diff --git a/src/git/parsers/blameParser.ts b/src/git/parsers/blameParser.ts index b1e2d619e8d44..2866c84b9f87a 100644 --- a/src/git/parsers/blameParser.ts +++ b/src/git/parsers/blameParser.ts @@ -4,10 +4,11 @@ import { getLines } from '../../system/string'; import type { GitBlame, GitBlameAuthor } from '../models/blame'; import type { GitCommitLine } from '../models/commit'; import { GitCommit, GitCommitIdentity } from '../models/commit'; -import { GitFileChange, GitFileIndexStatus } from '../models/file'; +import { GitFileChange } from '../models/fileChange'; +import { GitFileIndexStatus } from '../models/fileStatus'; import { uncommitted } from '../models/revision'; -import { isUncommitted } from '../models/revision.utils'; import type { GitUser } from '../models/user'; +import { isUncommitted } from '../utils/revision.utils'; interface BlameEntry { sha: string; @@ -238,6 +239,7 @@ function parseBlameEntry( [], undefined, new GitFileChange( + container, repoPath, entry.path, GitFileIndexStatus.Modified, diff --git a/src/git/parsers/diffParser.ts b/src/git/parsers/diffParser.ts index db6aee419fb18..cb9be1b2a482a 100644 --- a/src/git/parsers/diffParser.ts +++ b/src/git/parsers/diffParser.ts @@ -1,8 +1,10 @@ +import type { Container } from '../../container'; import { joinPaths, normalizePath } from '../../system/path'; import { maybeStopWatch } from '../../system/stopwatch'; import type { GitDiffFile, GitDiffHunk, GitDiffHunkLine, GitDiffShortStat } from '../models/diff'; -import type { GitFile, GitFileStatus } from '../models/file'; -import { GitFileChange } from '../models/file'; +import type { GitFile } from '../models/file'; +import { GitFileChange } from '../models/fileChange'; +import type { GitFileStatus } from '../models/fileStatus'; const shortStatDiffRegex = /(\d+)\s+files? changed(?:,\s+(\d+)\s+insertions?\(\+\))?(?:,\s+(\d+)\s+deletions?\(-\))?/; @@ -164,7 +166,7 @@ export function parseGitDiffNameStatusFiles(data: string, repoPath: string): Git return files; } -export function parseGitApplyFiles(data: string, repoPath: string): GitFileChange[] { +export function parseGitApplyFiles(container: Container, data: string, repoPath: string): GitFileChange[] { using sw = maybeStopWatch('Git.parseApplyFiles', { log: false, logLevel: 'debug' }); if (!data) return []; @@ -181,7 +183,7 @@ export function parseGitApplyFiles(data: string, repoPath: string): GitFileChang const [insertions, deletions, path] = line.split('\t'); files.set( normalizePath(path), - new GitFileChange(repoPath, path, 'M' as GitFileStatus, undefined, undefined, { + new GitFileChange(container, repoPath, path, 'M' as GitFileStatus, undefined, undefined, { changes: 0, additions: parseInt(insertions, 10), deletions: parseInt(deletions, 10), @@ -206,6 +208,7 @@ export function parseGitApplyFiles(data: string, repoPath: string): GitFileChang files.set( renamePath, new GitFileChange( + container, repoPath, renamePath, 'R' as GitFileStatus, @@ -219,6 +222,7 @@ export function parseGitApplyFiles(data: string, repoPath: string): GitFileChang files.set( createOrDeletePath, new GitFileChange( + container, repoPath, file.path, (createOrDelete === 'create' ? 'A' : 'D') as GitFileStatus, diff --git a/src/git/parsers/logParser.ts b/src/git/parsers/logParser.ts index a0803ba0eccbe..4fe74a11e348a 100644 --- a/src/git/parsers/logParser.ts +++ b/src/git/parsers/logParser.ts @@ -1,19 +1,21 @@ /* eslint-disable @typescript-eslint/no-deprecated */ import type { Range } from 'vscode'; import type { Container } from '../../container'; +import { relative } from '../../system/-webview/path'; import { filterMap } from '../../system/array'; import { normalizePath } from '../../system/path'; import { maybeStopWatch } from '../../system/stopwatch'; import { getLines } from '../../system/string'; -import { relative } from '../../system/vscode/path'; import type { GitCommitLine, GitStashCommit } from '../models/commit'; import { GitCommit, GitCommitIdentity } from '../models/commit'; -import type { GitFile, GitFileChangeStats } from '../models/file'; -import { GitFileChange, GitFileIndexStatus } from '../models/file'; +import type { GitFile } from '../models/file'; +import type { GitFileChangeStats } from '../models/fileChange'; +import { GitFileChange } from '../models/fileChange'; +import { GitFileIndexStatus } from '../models/fileStatus'; import type { GitLog } from '../models/log'; import { uncommitted } from '../models/revision'; import type { GitUser } from '../models/user'; -import { isUserMatch } from '../models/user'; +import { isUserMatch } from '../utils/user.utils'; const diffRegex = /diff --git a\/(.*) b\/(.*)/; const diffRangeRegex = /^@@ -(\d+?),(\d+?) \+(\d+?),(\d+?) @@/; @@ -840,10 +842,11 @@ function parseLogEntry( const originalFileName = entry.originalPath ?? (relativeFileName !== entry.path ? entry.path : undefined); const files: { file?: GitFileChange; files?: GitFileChange[] } = { - files: entry.files?.map(f => new GitFileChange(repoPath!, f.path, f.status, f.originalPath)), + files: entry.files?.map(f => new GitFileChange(container, repoPath!, f.path, f.status, f.originalPath)), }; if (type === LogType.LogFile && relativeFileName != null) { files.file = new GitFileChange( + container, repoPath!, relativeFileName, entry.status!, diff --git a/src/git/parsers/statusParser.ts b/src/git/parsers/statusParser.ts index 081fbe37c8b57..94d8fc3ad0eb0 100644 --- a/src/git/parsers/statusParser.ts +++ b/src/git/parsers/statusParser.ts @@ -1,11 +1,18 @@ +import type { Container } from '../../container'; import { normalizePath } from '../../system/path'; import { maybeStopWatch } from '../../system/stopwatch'; -import { GitStatus, GitStatusFile } from '../models/status'; +import { GitStatus } from '../models/status'; +import { GitStatusFile } from '../models/statusFile'; const aheadStatusV1Regex = /(?:ahead ([0-9]+))/; const behindStatusV1Regex = /(?:behind ([0-9]+))/; -export function parseGitStatus(data: string, repoPath: string, porcelainVersion: number): GitStatus | undefined { +export function parseGitStatus( + container: Container, + data: string, + repoPath: string, + porcelainVersion: number, +): GitStatus | undefined { using sw = maybeStopWatch(`Git.parseStatus(${repoPath}, v=${porcelainVersion})`, { log: false, logLevel: 'debug', @@ -15,14 +22,15 @@ export function parseGitStatus(data: string, repoPath: string, porcelainVersion: const lines = data.split('\n').filter((i?: T): i is T => Boolean(i)); if (lines.length === 0) return undefined; - const status = porcelainVersion < 2 ? parseStatusV1(lines, repoPath) : parseStatusV2(lines, repoPath); + const status = + porcelainVersion < 2 ? parseStatusV1(container, lines, repoPath) : parseStatusV2(container, lines, repoPath); sw?.stop({ suffix: ` parsed ${status.files.length} files` }); return status; } -function parseStatusV1(lines: string[], repoPath: string): GitStatus { +function parseStatusV1(container: Container, lines: string[], repoPath: string): GitStatus { let branch: string | undefined; const files = []; const state = { @@ -58,14 +66,15 @@ function parseStatusV1(lines: string[], repoPath: string): GitStatus { const fileName = line.substring(3); if (rawStatus.startsWith('R') || rawStatus.startsWith('C')) { const [file1, file2] = fileName.replace(/"/g, '').split('->'); - files.push(parseStatusFile(repoPath, rawStatus, file2.trim(), file1.trim())); + files.push(parseStatusFile(container, repoPath, rawStatus, file2.trim(), file1.trim())); } else { - files.push(parseStatusFile(repoPath, rawStatus, fileName)); + files.push(parseStatusFile(container, repoPath, rawStatus, fileName)); } } } return new GitStatus( + container, normalizePath(repoPath), branch ?? '', '', @@ -75,7 +84,7 @@ function parseStatusV1(lines: string[], repoPath: string): GitStatus { ); } -function parseStatusV2(lines: string[], repoPath: string): GitStatus { +function parseStatusV2(container: Container, lines: string[], repoPath: string): GitStatus { let branch: string | undefined; const files = []; let sha: string | undefined; @@ -112,25 +121,26 @@ function parseStatusV2(lines: string[], repoPath: string): GitStatus { const lineParts = line.split(' '); switch (lineParts[0][0]) { case '1': // normal - files.push(parseStatusFile(repoPath, lineParts[1], lineParts.slice(8).join(' '))); + files.push(parseStatusFile(container, repoPath, lineParts[1], lineParts.slice(8).join(' '))); break; case '2': { // rename const file = lineParts.slice(9).join(' ').split('\t'); - files.push(parseStatusFile(repoPath, lineParts[1], file[0], file[1])); + files.push(parseStatusFile(container, repoPath, lineParts[1], file[0], file[1])); break; } case 'u': // unmerged - files.push(parseStatusFile(repoPath, lineParts[1], lineParts.slice(10).join(' '))); + files.push(parseStatusFile(container, repoPath, lineParts[1], lineParts.slice(10).join(' '))); break; case '?': // untracked - files.push(parseStatusFile(repoPath, '??', lineParts.slice(1).join(' '))); + files.push(parseStatusFile(container, repoPath, '??', lineParts.slice(1).join(' '))); break; } } } return new GitStatus( + container, normalizePath(repoPath), branch ?? '', sha ?? '', @@ -141,6 +151,7 @@ function parseStatusV2(lines: string[], repoPath: string): GitStatus { } function parseStatusFile( + container: Container, repoPath: string, rawStatus: string, fileName: string, @@ -159,5 +170,5 @@ function parseStatusFile( } } - return new GitStatusFile(repoPath, x, y, fileName, originalFileName); + return new GitStatusFile(container, repoPath, x, y, fileName, originalFileName); } diff --git a/src/git/parsers/tagParser.ts b/src/git/parsers/tagParser.ts index 1acd9943ff866..8afd805e7a987 100644 --- a/src/git/parsers/tagParser.ts +++ b/src/git/parsers/tagParser.ts @@ -1,3 +1,4 @@ +import type { Container } from '../../container'; import { maybeStopWatch } from '../../system/stopwatch'; import { GitTag } from '../models/tag'; @@ -16,7 +17,7 @@ export const parseGitTagsDefaultFormat = [ `${lb}s${rb}%(subject)`, // message ].join(''); -export function parseGitTags(data: string, repoPath: string): GitTag[] { +export function parseGitTags(container: Container, data: string, repoPath: string): GitTag[] { using sw = maybeStopWatch(`Git.parseTags(${repoPath})`, { log: false, logLevel: 'debug' }); const tags: GitTag[] = []; @@ -41,6 +42,7 @@ export function parseGitTags(data: string, repoPath: string): GitTag[] { tags.push( new GitTag( + container, repoPath, name, // Stops excessive memory usage -- https://bugs.chromium.org/p/v8/issues/detail?id=2869 diff --git a/src/pathMapping/repositoryPathMappingProvider.ts b/src/git/pathMapping/repositoryPathMappingProvider.ts similarity index 100% rename from src/pathMapping/repositoryPathMappingProvider.ts rename to src/git/pathMapping/repositoryPathMappingProvider.ts diff --git a/src/git/remotes/azure-devops.ts b/src/git/remotes/azure-devops.ts index 39c74fd39f9d7..0662d6bf2413e 100644 --- a/src/git/remotes/azure-devops.ts +++ b/src/git/remotes/azure-devops.ts @@ -1,8 +1,8 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { Brand, Unbrand } from '../../system/brand'; import type { Repository } from '../models/repository'; +import type { GkProviderId } from '../models/repositoryIdentities'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/bitbucket-server.ts b/src/git/remotes/bitbucket-server.ts index cade056486ac3..24389f47e4456 100644 --- a/src/git/remotes/bitbucket-server.ts +++ b/src/git/remotes/bitbucket-server.ts @@ -1,9 +1,9 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { Brand, Unbrand } from '../../system/brand'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/bitbucket.ts b/src/git/remotes/bitbucket.ts index 9f596eac912d9..cc55ee0e25b30 100644 --- a/src/git/remotes/bitbucket.ts +++ b/src/git/remotes/bitbucket.ts @@ -1,9 +1,9 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { Brand, Unbrand } from '../../system/brand'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/custom.ts b/src/git/remotes/custom.ts index 9bdcbdb725bbe..873a18d731e0a 100644 --- a/src/git/remotes/custom.ts +++ b/src/git/remotes/custom.ts @@ -1,9 +1,9 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; import type { RemotesUrlsConfig } from '../../config'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import { getTokensFromTemplate, interpolate } from '../../system/string'; import type { Repository } from '../models/repository'; +import type { GkProviderId } from '../models/repositoryIdentities'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/gerrit.ts b/src/git/remotes/gerrit.ts index f22aad8ff8664..761d694fdc31c 100644 --- a/src/git/remotes/gerrit.ts +++ b/src/git/remotes/gerrit.ts @@ -1,8 +1,8 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/gitea.ts b/src/git/remotes/gitea.ts index 2a0f9a238a84a..2263185ff2b45 100644 --- a/src/git/remotes/gitea.ts +++ b/src/git/remotes/gitea.ts @@ -1,8 +1,8 @@ import type { Range, Uri } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/github.ts b/src/git/remotes/github.ts index 40ae714cad893..3d4cf4f59600b 100644 --- a/src/git/remotes/github.ts +++ b/src/git/remotes/github.ts @@ -2,17 +2,17 @@ import type { Range } from 'vscode'; import { Uri } from 'vscode'; import type { Autolink, AutolinkReference, DynamicAutolinkReference, MaybeEnrichedAutolink } from '../../autolinks'; import { GlyphChars } from '../../constants'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { GitHubRepositoryDescriptor } from '../../plus/integrations/providers/github'; import type { Brand, Unbrand } from '../../system/brand'; import { fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { encodeUrl } from '../../system/encoding'; import { escapeMarkdown, unescapeMarkdown } from '../../system/markdown'; import { equalsIgnoreCase } from '../../system/string'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; -import { getIssueOrPullRequestMarkdownIcon } from '../utils/vscode/icons'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { getIssueOrPullRequestMarkdownIcon } from '../utils/-webview/icons'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/gitlab.ts b/src/git/remotes/gitlab.ts index 25567fa4776f2..8dbc8a4cff0cb 100644 --- a/src/git/remotes/gitlab.ts +++ b/src/git/remotes/gitlab.ts @@ -1,17 +1,17 @@ import type { Range, Uri } from 'vscode'; import type { Autolink, AutolinkReference, DynamicAutolinkReference, MaybeEnrichedAutolink } from '../../autolinks'; import { GlyphChars } from '../../constants'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { GitLabRepositoryDescriptor } from '../../plus/integrations/providers/gitlab'; import type { Brand, Unbrand } from '../../system/brand'; import { fromNow } from '../../system/date'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { encodeUrl } from '../../system/encoding'; import { escapeMarkdown, unescapeMarkdown } from '../../system/markdown'; import { equalsIgnoreCase } from '../../system/string'; import type { Repository } from '../models/repository'; -import { isSha } from '../models/revision.utils'; -import { getIssueOrPullRequestMarkdownIcon } from '../utils/vscode/icons'; +import type { GkProviderId } from '../models/repositoryIdentities'; +import { getIssueOrPullRequestMarkdownIcon } from '../utils/-webview/icons'; +import { isSha } from '../utils/revision.utils'; import type { RemoteProviderId } from './remoteProvider'; import { RemoteProvider } from './remoteProvider'; diff --git a/src/git/remotes/google-source.ts b/src/git/remotes/google-source.ts index 35ba78fdd3d03..75d6a95a44e59 100644 --- a/src/git/remotes/google-source.ts +++ b/src/git/remotes/google-source.ts @@ -1,5 +1,5 @@ import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; +import type { GkProviderId } from '../models/repositoryIdentities'; import { GerritRemote } from './gerrit'; import type { RemoteProviderId } from './remoteProvider'; diff --git a/src/git/remotes/remoteProvider.ts b/src/git/remotes/remoteProvider.ts index a5beda19389c9..31d7a924929ec 100644 --- a/src/git/remotes/remoteProvider.ts +++ b/src/git/remotes/remoteProvider.ts @@ -1,16 +1,16 @@ import type { Range, Uri } from 'vscode'; import { env } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../autolinks'; -import type { GkProviderId } from '../../gk/models/repositoryIdentities'; import type { ResourceDescriptor } from '../../plus/integrations/integration'; -import { memoize } from '../../system/decorators/memoize'; +import { openUrl } from '../../system/-webview/utils'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { encodeUrl } from '../../system/encoding'; import { getSettledValue } from '../../system/promise'; -import { openUrl } from '../../system/vscode/utils'; import type { ProviderReference } from '../models/remoteProvider'; import type { RemoteResource } from '../models/remoteResource'; import { RemoteResourceType } from '../models/remoteResource'; import type { Repository } from '../models/repository'; +import type { GkProviderId } from '../models/repositoryIdentities'; export type RemoteProviderId = | 'azure-devops' diff --git a/src/git/remotes/remoteProviders.ts b/src/git/remotes/remoteProviders.ts index 50ed6ed743fd2..1596ba63f7afa 100644 --- a/src/git/remotes/remoteProviders.ts +++ b/src/git/remotes/remoteProviders.ts @@ -2,8 +2,8 @@ import type { RemotesConfig } from '../../config'; import { SelfHostedIntegrationId } from '../../constants.integrations'; import type { Container } from '../../container'; import type { ConfiguredIntegrationDescriptor } from '../../plus/integrations/authentication/models'; +import { configuration } from '../../system/-webview/configuration'; import { Logger } from '../../system/logger'; -import { configuration } from '../../system/vscode/configuration'; import { AzureDevOpsRemote } from './azure-devops'; import { BitbucketRemote } from './bitbucket'; import { BitbucketServerRemote } from './bitbucket-server'; diff --git a/src/git/search.ts b/src/git/search.ts index c62ae62187bbd..8490ee097f305 100644 --- a/src/git/search.ts +++ b/src/git/search.ts @@ -2,8 +2,8 @@ import type { SearchOperators, SearchOperatorsLongForm, SearchQuery } from '../c import { searchOperationRegex, searchOperatorsToLongFormMap } from '../constants.search'; import type { StoredSearchQuery } from '../constants.storage'; import type { GitRevisionReference } from './models/reference'; -import { isSha, shortenRevision } from './models/revision.utils'; import type { GitUser } from './models/user'; +import { isSha, shortenRevision } from './utils/revision.utils'; export interface GitSearchResultData { date: number; diff --git a/src/git/sub-providers/remotes.ts b/src/git/sub-providers/remotes.ts index 34d61fa198dfe..f4750e706aa1f 100644 --- a/src/git/sub-providers/remotes.ts +++ b/src/git/sub-providers/remotes.ts @@ -7,9 +7,9 @@ import { sortCompare } from '../../system/string'; import type { GitCache } from '../cache'; import type { GitProvider, GitRemotesSubProvider } from '../gitProvider'; import type { GitRemote } from '../models/remote'; -import { getDefaultRemoteOrHighlander } from '../models/remote'; import { RepositoryChange } from '../models/repository'; import type { RemoteProvider } from '../remotes/remoteProvider'; +import { getDefaultRemoteOrHighlander } from '../utils/remote.utils'; export abstract class RemotesGitProviderBase implements GitRemotesSubProvider { constructor( diff --git a/src/git/utils/-webview/branch.issue.utils.ts b/src/git/utils/-webview/branch.issue.utils.ts new file mode 100644 index 0000000000000..b579a6590e91b --- /dev/null +++ b/src/git/utils/-webview/branch.issue.utils.ts @@ -0,0 +1,115 @@ +import type { CancellationToken } from 'vscode'; +import type { GitConfigKeys } from '../../../constants'; +import type { Container } from '../../../container'; +import type { IssueResourceDescriptor, RepositoryDescriptor } from '../../../plus/integrations/integration'; +import type { GitConfigEntityIdentifier } from '../../../plus/integrations/providers/models'; +import { + decodeEntityIdentifiersFromGitConfig, + encodeIssueOrPullRequestForGitConfig, + getIssueFromGitConfigEntityIdentifier, +} from '../../../plus/integrations/providers/utils'; +import { Logger } from '../../../system/logger'; +import type { MaybePausedResult } from '../../../system/promise'; +import { getSettledValue, pauseOnCancelOrTimeout } from '../../../system/promise'; +import type { GitBranch } from '../../models/branch'; +import type { Issue } from '../../models/issue'; +import type { GitBranchReference } from '../../models/reference'; + +export async function addAssociatedIssueToBranch( + container: Container, + branch: GitBranchReference, + issue: Issue, + owner: RepositoryDescriptor | IssueResourceDescriptor, + options?: { + cancellation?: CancellationToken; + }, +) { + const { key, encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); + if (options?.cancellation?.isCancellationRequested) return; + try { + const associatedIssues: GitConfigEntityIdentifier[] = encoded + ? (JSON.parse(encoded) as GitConfigEntityIdentifier[]) + : []; + if (associatedIssues.some(i => i.entityId === issue.nodeId)) { + return; + } + associatedIssues.push(encodeIssueOrPullRequestForGitConfig(issue, owner)); + await container.git.setConfig(branch.repoPath, key, JSON.stringify(associatedIssues)); + } catch (ex) { + Logger.error(ex, 'addAssociatedIssueToBranch'); + } +} + +export async function getAssociatedIssuesForBranch( + container: Container, + branch: GitBranch, + options?: { + cancellation?: CancellationToken; + timeout?: number; + }, +): Promise> { + const { encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); + if (options?.cancellation?.isCancellationRequested) return { value: undefined, paused: false }; + + let associatedIssues: GitConfigEntityIdentifier[] | undefined; + if (encoded != null) { + try { + associatedIssues = decodeEntityIdentifiersFromGitConfig(encoded); + } catch (ex) { + Logger.error(ex, 'getAssociatedIssuesForBranch'); + return { value: undefined, paused: false }; + } + + if (associatedIssues != null) { + return pauseOnCancelOrTimeout( + (async () => { + return ( + await Promise.allSettled( + (associatedIssues ?? []).map(i => getIssueFromGitConfigEntityIdentifier(container, i)), + ) + ) + .map(r => getSettledValue(r)) + .filter((i): i is Issue => i != null); + })(), + options?.cancellation, + options?.timeout, + ); + } + } + + return { value: undefined, paused: false }; +} + +export async function removeAssociatedIssueFromBranch( + container: Container, + branch: GitBranchReference, + id: string, + options?: { + cancellation?: CancellationToken; + }, +) { + const { key, encoded } = await getConfigKeyAndEncodedAssociatedIssuesForBranch(container, branch); + if (options?.cancellation?.isCancellationRequested) return; + try { + let associatedIssues: GitConfigEntityIdentifier[] = encoded + ? (JSON.parse(encoded) as GitConfigEntityIdentifier[]) + : []; + associatedIssues = associatedIssues.filter(i => i.entityId !== id); + if (associatedIssues.length === 0) { + await container.git.setConfig(branch.repoPath, key, undefined); + } else { + await container.git.setConfig(branch.repoPath, key, JSON.stringify(associatedIssues)); + } + } catch (ex) { + Logger.error(ex, 'removeAssociatedIssueFromBranch'); + } +} + +async function getConfigKeyAndEncodedAssociatedIssuesForBranch( + container: Container, + branch: GitBranchReference, +): Promise<{ key: GitConfigKeys; encoded: string | undefined }> { + const key = `branch.${branch.name}.gk-associated-issues` satisfies GitConfigKeys; + const encoded = await container.git.getConfig(branch.repoPath, key); + return { key: key, encoded: encoded }; +} diff --git a/src/git/utils/-webview/branch.utils.ts b/src/git/utils/-webview/branch.utils.ts new file mode 100644 index 0000000000000..44f557e6e712d --- /dev/null +++ b/src/git/utils/-webview/branch.utils.ts @@ -0,0 +1,80 @@ +import type { CancellationToken } from 'vscode'; +import type { Container } from '../../../container'; +import type { MaybePausedResult } from '../../../system/promise'; +import { getSettledValue, pauseOnCancelOrTimeout } from '../../../system/promise'; +import type { BranchTargetInfo, GitBranch } from '../../models/branch'; +import type { PullRequest } from '../../models/pullRequest'; + +export async function getBranchTargetInfo( + container: Container, + current: GitBranch, + options?: { + associatedPullRequest?: Promise; + cancellation?: CancellationToken; + timeout?: number; + }, +): Promise { + const [baseResult, defaultResult, targetResult] = await Promise.allSettled([ + container.git.branches(current.repoPath).getBaseBranchName?.(current.name), + getDefaultBranchName(container, current.repoPath, current.getRemoteName()), + getTargetBranchName(container, current, { + cancellation: options?.cancellation, + timeout: options?.timeout, + }), + ]); + + const baseBranchName = getSettledValue(baseResult); + const defaultBranchName = getSettledValue(defaultResult); + const targetMaybeResult = getSettledValue(targetResult); + + return { + baseBranch: baseBranchName, + defaultBranch: defaultBranchName, + targetBranch: targetMaybeResult ?? { value: undefined, paused: false }, + }; +} + +export async function getDefaultBranchName( + container: Container, + repoPath: string, + remoteName?: string, + options?: { cancellation?: CancellationToken }, +): Promise { + const name = await container.git.branches(repoPath).getDefaultBranchName(remoteName); + if (name != null) return name; + + const remote = await container.git.remotes(repoPath).getBestRemoteWithIntegration(); + if (remote == null) return undefined; + + const integration = await remote.getIntegration(); + const defaultBranch = await integration?.getDefaultBranch?.(remote.provider.repoDesc, options); + return `${remote.name}/${defaultBranch?.name}`; +} + +export async function getTargetBranchName( + container: Container, + branch: GitBranch, + options?: { + associatedPullRequest?: Promise; + cancellation?: CancellationToken; + timeout?: number; + }, +): Promise> { + const targetBranch = await container.git.branches(branch.repoPath).getTargetBranchName?.(branch.name); + if (targetBranch != null) return { value: targetBranch, paused: false }; + + if (options?.cancellation?.isCancellationRequested) return { value: undefined, paused: false }; + + return pauseOnCancelOrTimeout( + (options?.associatedPullRequest ?? branch?.getAssociatedPullRequest())?.then(pr => { + if (pr?.refs?.base == null) return undefined; + + const name = `${branch.getRemoteName()}/${pr.refs.base.branch}`; + void container.git.branches(branch.repoPath).setTargetBranchName?.(branch.name, name); + + return name; + }), + options?.cancellation, + options?.timeout, + ); +} diff --git a/src/git/models/contributor.quickpick.ts b/src/git/utils/-webview/contributor.quickpick.ts similarity index 78% rename from src/git/models/contributor.quickpick.ts rename to src/git/utils/-webview/contributor.quickpick.ts index 751a628c80dd8..c88f31e14a1f2 100644 --- a/src/git/models/contributor.quickpick.ts +++ b/src/git/utils/-webview/contributor.quickpick.ts @@ -1,7 +1,7 @@ import type { QuickInputButton } from 'vscode'; -import type { QuickPickItemOfT } from '../../quickpicks/items/common'; -import { configuration } from '../../system/vscode/configuration'; -import type { GitContributor } from './contributor'; +import type { QuickPickItemOfT } from '../../../quickpicks/items/common'; +import { configuration } from '../../../system/-webview/configuration'; +import type { GitContributor } from '../../models/contributor'; export type ContributorQuickPickItem = QuickPickItemOfT; diff --git a/src/git/utils/-webview/file.utils.ts b/src/git/utils/-webview/file.utils.ts new file mode 100644 index 0000000000000..6341de0b66fc9 --- /dev/null +++ b/src/git/utils/-webview/file.utils.ts @@ -0,0 +1,33 @@ +import { GlyphChars } from '../../../constants'; +import { formatPath } from '../../../system/-webview/formatPath'; +import { relativeDir, splitPath } from '../../../system/-webview/path'; +import { pad } from '../../../system/string'; +import type { GitFile } from '../../models/file'; + +export function getGitFileFormattedDirectory( + file: GitFile, + includeOriginal: boolean = false, + relativeTo?: string, +): string { + const directory = relativeDir(file.path, relativeTo); + return includeOriginal && (file.status === 'R' || file.status === 'C') && file.originalPath + ? `${directory} ${pad(GlyphChars.ArrowLeft, 1, 1)} ${file.originalPath}` + : directory; +} + +export function getGitFileFormattedPath( + file: GitFile, + options: { relativeTo?: string; suffix?: string; truncateTo?: number } = {}, +): string { + return formatPath(file.path, options); +} + +export function getGitFileOriginalRelativePath(file: GitFile, relativeTo?: string): string { + if (!file.originalPath) return ''; + + return splitPath(file.originalPath, relativeTo)[0]; +} + +export function getGitFileRelativePath(file: GitFile, relativeTo?: string): string { + return splitPath(file.path, relativeTo)[0]; +} diff --git a/src/git/utils/-webview/fileChange.utils.ts b/src/git/utils/-webview/fileChange.utils.ts new file mode 100644 index 0000000000000..24f16a4abfa25 --- /dev/null +++ b/src/git/utils/-webview/fileChange.utils.ts @@ -0,0 +1,24 @@ +import type { Container } from '../../../container'; +import { GitFileChange } from '../../models/fileChange'; + +export function mapFilesWithStats( + container: Container, + files: GitFileChange[], + filesWithStats: GitFileChange[], +): GitFileChange[] { + return files.map(file => { + const stats = filesWithStats.find(f => f.path === file.path)?.stats; + return stats != null + ? new GitFileChange( + container, + file.repoPath, + file.path, + file.status, + file.originalPath, + file.previousSha, + stats, + file.staged, + ) + : file; + }); +} diff --git a/src/git/utils/vscode/icons.ts b/src/git/utils/-webview/icons.ts similarity index 88% rename from src/git/utils/vscode/icons.ts rename to src/git/utils/-webview/icons.ts index bb05d4a0b78b3..f17030bf606d3 100644 --- a/src/git/utils/vscode/icons.ts +++ b/src/git/utils/-webview/icons.ts @@ -3,14 +3,15 @@ import { ColorThemeKind, ThemeColor, ThemeIcon, Uri, window } from 'vscode'; import type { IconPath } from '../../../@types/vscode.iconpath'; import type { Colors } from '../../../constants.colors'; import type { Container } from '../../../container'; -import { isLightTheme } from '../../../system/vscode/utils'; -import { getIconPathUris } from '../../../system/vscode/vscode'; +import { isLightTheme } from '../../../system/-webview/utils'; +import { getIconPathUris } from '../../../system/-webview/vscode'; import type { GitBranch } from '../../models/branch'; -import type { IssueOrPullRequest } from '../../models/issue'; +import type { GitFileStatus } from '../../models/fileStatus'; +import type { IssueOrPullRequest } from '../../models/issueOrPullRequest'; import type { GitRemote } from '../../models/remote'; -import { getRemoteThemeIconString } from '../../models/remote'; import type { Repository } from '../../models/repository'; import type { GitStatus } from '../../models/status'; +import { getRemoteThemeIconString } from '../remote.utils'; export function getBranchIconPath(container: Container, branch: GitBranch | undefined): IconPath { switch (branch?.status) { @@ -25,6 +26,31 @@ export function getBranchIconPath(container: Container, branch: GitBranch | unde } } +const statusCodiconsMap = { + '.': undefined, + '!': 'diff-ignored', + '?': 'diff-added', + A: 'diff-added', + D: 'diff-removed', + M: 'diff-modified', + R: 'diff-renamed', + C: 'diff-added', + AA: 'warning', + AU: 'warning', + UA: 'warning', + DD: 'warning', + DU: 'warning', + UD: 'warning', + UU: 'warning', + T: 'diff-modified', + U: 'diff-modified', +}; + +export function getGitFileStatusThemeIcon(status: GitFileStatus): ThemeIcon | undefined { + const codicon = statusCodiconsMap[status]; + return codicon != null ? new ThemeIcon(codicon) : undefined; +} + export function getIssueOrPullRequestHtmlIcon(issue?: IssueOrPullRequest): string { if (issue == null) { return `>> { const repos = new Map(repositories.map(r => [r.id, r])); @@ -38,33 +57,3 @@ export async function groupRepositories(repositories: Repository[]): Promise [r.repo, r.worktrees])); } - -const millisecondsPerMinute = 60 * 1000; -const millisecondsPerHour = 60 * 60 * 1000; -const millisecondsPerDay = 24 * 60 * 60 * 1000; - -export function formatLastFetched(lastFetched: number, short: boolean = true): string { - const date = new Date(lastFetched); - if (Date.now() - lastFetched < millisecondsPerDay) { - return fromNow(date); - } - - if (short) { - return formatDate(date, configuration.get('defaultDateShortFormat') ?? 'short'); - } - - let format = - configuration.get('defaultDateFormat') ?? - `dddd, MMMM Do, YYYY [at] ${configuration.get('defaultTimeFormat') ?? 'h:mma'}`; - if (!/[hHm]/.test(format)) { - format += ` [at] ${configuration.get('defaultTimeFormat') ?? 'h:mma'}`; - } - return formatDate(date, format); -} - -export function getLastFetchedUpdateInterval(lastFetched: number): number { - const timeDiff = Date.now() - lastFetched; - return timeDiff < millisecondsPerDay - ? (timeDiff < millisecondsPerHour ? millisecondsPerMinute : millisecondsPerHour) / 2 - : 0; -} diff --git a/src/git/utils/vscode/sorting.ts b/src/git/utils/-webview/sorting.ts similarity index 98% rename from src/git/utils/vscode/sorting.ts rename to src/git/utils/-webview/sorting.ts index eb5e2a4a67683..ad4c5750c74f0 100644 --- a/src/git/utils/vscode/sorting.ts +++ b/src/git/utils/-webview/sorting.ts @@ -1,15 +1,15 @@ import type { BranchSorting, ContributorSorting, RepositoriesSorting, TagSorting } from '../../../config'; +import { configuration } from '../../../system/-webview/configuration'; import { sortCompare } from '../../../system/string'; -import { configuration } from '../../../system/vscode/configuration'; import type { GitBranch } from '../../models/branch'; import type { GitContributor } from '../../models/contributor'; import { isContributor } from '../../models/contributor'; -import type { ContributorQuickPickItem } from '../../models/contributor.quickpick'; import type { Repository } from '../../models/repository'; import type { GitTag } from '../../models/tag'; import type { GitWorktree } from '../../models/worktree'; import { isWorktree } from '../../models/worktree'; -import type { WorktreeQuickPickItem } from '../../models/worktree.quickpick'; +import type { ContributorQuickPickItem } from './contributor.quickpick'; +import type { WorktreeQuickPickItem } from './worktree.quickpick'; export interface BranchSortOptions { current?: boolean; diff --git a/src/git/models/worktree.quickpick.ts b/src/git/utils/-webview/worktree.quickpick.ts similarity index 85% rename from src/git/models/worktree.quickpick.ts rename to src/git/utils/-webview/worktree.quickpick.ts index 5ef097419629b..9e484516456bf 100644 --- a/src/git/models/worktree.quickpick.ts +++ b/src/git/utils/-webview/worktree.quickpick.ts @@ -1,13 +1,13 @@ import type { QuickInputButton } from 'vscode'; import { ThemeIcon } from 'vscode'; -import { GlyphChars } from '../../constants'; -import { Container } from '../../container'; -import type { QuickPickItemOfT } from '../../quickpicks/items/common'; -import { pad } from '../../system/string'; -import { getBranchIconPath } from '../utils/vscode/icons'; -import { shortenRevision } from './revision.utils'; -import type { GitStatus } from './status'; -import type { GitWorktree } from './worktree'; +import { GlyphChars } from '../../../constants'; +import { Container } from '../../../container'; +import type { QuickPickItemOfT } from '../../../quickpicks/items/common'; +import { pad } from '../../../system/string'; +import type { GitStatus } from '../../models/status'; +import type { GitWorktree } from '../../models/worktree'; +import { shortenRevision } from "../revision.utils"; +import { getBranchIconPath } from './icons'; export interface WorktreeQuickPickItem extends QuickPickItemOfT { readonly opened: boolean; diff --git a/src/git/models/worktree.utils.ts b/src/git/utils/-webview/worktree.utils.ts similarity index 91% rename from src/git/models/worktree.utils.ts rename to src/git/utils/-webview/worktree.utils.ts index a21eecda8b139..4b8fedd01c522 100644 --- a/src/git/models/worktree.utils.ts +++ b/src/git/utils/-webview/worktree.utils.ts @@ -1,8 +1,8 @@ -import { filterMap } from '../../system/iterable'; -import { PageableResult } from '../../system/paging'; -import type { GitBranch } from './branch'; -import type { Repository } from './repository'; -import type { GitWorktree } from './worktree'; +import { filterMap } from '../../../system/iterable'; +import { PageableResult } from '../../../system/paging'; +import type { GitBranch } from '../../models/branch'; +import type { Repository } from '../../models/repository'; +import type { GitWorktree } from '../../models/worktree'; export function getOpenedWorktreesByBranch( worktreesByBranch: Map | undefined, diff --git a/src/git/models/__tests__/pullRequest.utils.test.ts b/src/git/utils/__tests__/pullRequest.utils.test.ts similarity index 100% rename from src/git/models/__tests__/pullRequest.utils.test.ts rename to src/git/utils/__tests__/pullRequest.utils.test.ts diff --git a/src/git/utils/branch.utils.ts b/src/git/utils/branch.utils.ts new file mode 100644 index 0000000000000..306967dfeb0dc --- /dev/null +++ b/src/git/utils/branch.utils.ts @@ -0,0 +1,105 @@ +import type { PageableResult } from '../../system/paging'; +import type { GitBranch } from '../models/branch'; +import type { GitBranchReference, GitReference } from '../models/reference'; +import { shortenRevision } from './revision.utils'; + +const detachedHEADRegex = /^(HEAD|\(.*\))$/; + +export function formatDetachedHeadName(sha: string): string { + return `(${shortenRevision(sha)}...)`; +} + +export function getBranchId(repoPath: string, remote: boolean, name: string): string { + return `${repoPath}|${remote ? 'remotes/' : 'heads/'}${name}`; +} + +export function getBranchNameAndRemote(ref: GitBranchReference): [name: string, remote: string | undefined] { + if (ref.remote) { + const index = getRemoteNameSlashIndex(ref.name); + if (index === -1) return [ref.name, undefined]; + + return [ref.name.substring(index + 1), ref.name.substring(0, index)]; + } + + if (ref.upstream?.name != null) { + const index = getRemoteNameSlashIndex(ref.upstream.name); + if (index === -1) return [ref.name, undefined]; + + return [ref.name, ref.upstream.name.substring(0, index)]; + } + + return [ref.name, undefined]; +} + +export function getBranchNameWithoutRemote(name: string): string { + return name.substring(getRemoteNameSlashIndex(name) + 1); +} + +export function getBranchTrackingWithoutRemote(ref: GitBranchReference) { + return ref.upstream?.name.substring(getRemoteNameSlashIndex(ref.upstream.name) + 1); +} + +export async function getLocalBranchByUpstream( + remoteBranchName: string, + branches: PageableResult | Map, +): Promise { + let qualifiedRemoteBranchName; + if (remoteBranchName.startsWith('remotes/')) { + qualifiedRemoteBranchName = remoteBranchName; + remoteBranchName = remoteBranchName.substring(8); + } else { + qualifiedRemoteBranchName = `remotes/${remoteBranchName}`; + } + + function matches(branch: GitBranch): boolean { + return ( + !branch.remote && + branch.upstream?.name != null && + (branch.upstream.name === remoteBranchName || branch.upstream.name === qualifiedRemoteBranchName!) + ); + } + + const values = branches.values(); + if (Symbol.asyncIterator in values) { + for await (const branch of values) { + if (matches(branch)) return branch; + } + } else { + for (const branch of values) { + if (matches(branch)) return branch; + } + } + + return undefined; +} + +export async function getLocalBranchUpstreamNames(branches: PageableResult): Promise> { + const remoteBranches = new Set(); + + for await (const branch of branches.values()) { + if (!branch.remote && branch.upstream?.name != null) { + remoteBranches.add(branch.upstream.name); + } + } + + return remoteBranches; +} + +export function getRemoteNameFromBranchName(name: string): string { + return name.substring(0, getRemoteNameSlashIndex(name)); +} + +export function getRemoteNameSlashIndex(name: string): number { + return name.startsWith('remotes/') ? name.indexOf('/', 8) : name.indexOf('/'); +} + +export function isDetachedHead(name: string): boolean { + // If there is whitespace in the name assume this is not a valid branch name + // Deals with detached HEAD states + name = name.trim(); + return name.length ? detachedHEADRegex.test(name) : true; +} + +export function isOfBranchRefType(branch: GitReference | undefined) { + return branch?.refType === 'branch'; +} diff --git a/src/git/models/commit.utils.ts b/src/git/utils/commit.utils.ts similarity index 57% rename from src/git/models/commit.utils.ts rename to src/git/utils/commit.utils.ts index ce81f6d3572e9..7ce38587a7136 100644 --- a/src/git/models/commit.utils.ts +++ b/src/git/utils/commit.utils.ts @@ -1,4 +1,11 @@ -import type { GitCommitStats } from './commit'; +import type { GitCommit, GitCommitStats, GitCommitWithFullDetails } from '../models/commit'; +import type { GitReference } from '../models/reference'; + +export function assertsCommitHasFullDetails(commit: GitCommit): asserts commit is GitCommitWithFullDetails { + if (!commit.hasFullDetails()) { + throw new Error(`GitCommit(${commit.sha}) is not fully loaded`); + } +} export function getChangedFilesCount(changedFiles: GitCommitStats['files'] | undefined): number { if (changedFiles == null) return 0; @@ -8,6 +15,10 @@ export function getChangedFilesCount(changedFiles: GitCommitStats['files'] | und : changedFiles.added + changedFiles.changed + changedFiles.deleted; } +export function isOfCommitOrStashRefType(commit: GitReference | undefined): boolean { + return commit?.refType === 'revision' || commit?.refType === 'stash'; +} + /** * use `\n` symbol is presented to split commit message to description and title */ diff --git a/src/git/utils/contributor.utils.ts b/src/git/utils/contributor.utils.ts new file mode 100644 index 0000000000000..d4af5231bc223 --- /dev/null +++ b/src/git/utils/contributor.utils.ts @@ -0,0 +1,80 @@ +import type { GitCommitStats } from '../models/commit'; +import type { GitContributionTiers, GitContributor, GitContributorStats } from '../models/contributor'; +import type { GitUser } from '../models/user'; + +export interface ContributorScoreOptions { + // Thresholds + recentThresholdInDays: number; + maxScoreNormalization: number; + + // Time-based weights + recentWeight: number; + + // Impact weights + additionsWeight: number; + deletionsWeight: number; +} + +export const defaultContributorScoreOptions: ContributorScoreOptions = { + recentThresholdInDays: 30, + recentWeight: 1.5, + additionsWeight: 0.8, + deletionsWeight: 1.2, + maxScoreNormalization: 1000, +}; + +export function calculateContributionScore( + stats: GitCommitStats | undefined, + timestamp: number, + options: ContributorScoreOptions = defaultContributorScoreOptions, +): number { + if (stats == null) return 0; + + const now = Date.now(); + const ageInDays = (now - timestamp) / (24 * 3600 * 1000); + + // Time decay factor (exponential decay) + const recencyScore = Math.exp(-ageInDays / options.recentThresholdInDays); + + // Impact score with weighted components + const impactScore = stats.additions * options.additionsWeight + stats.deletions * options.deletionsWeight; + + return Math.min(impactScore * (1 + recencyScore * options.recentWeight), options.maxScoreNormalization); +} + +export function calculateDistribution( + stats: GitContributorStats | undefined, + prefix: T, +): Record<`${typeof prefix}${GitContributionTiers}`, number> { + if (stats == null) return {} as unknown as Record<`${typeof prefix}${GitContributionTiers}`, number>; + + const distribution: Record<`${string}${GitContributionTiers}`, number> = { + [`${prefix}[1]`]: 0, + [`${prefix}[2-5]`]: 0, + [`${prefix}[6-10]`]: 0, + [`${prefix}[11-50]`]: 0, + [`${prefix}[51-100]`]: 0, + [`${prefix}[101+]`]: 0, + }; + + for (const c of stats.contributions) { + if (c === 1) { + distribution[`${prefix}[1]`]++; + } else if (c <= 5) { + distribution[`${prefix}[2-5]`]++; + } else if (c <= 10) { + distribution[`${prefix}[6-10]`]++; + } else if (c <= 50) { + distribution[`${prefix}[11-50]`]++; + } else if (c <= 100) { + distribution[`${prefix}[51-100]`]++; + } else { + distribution[`${prefix}[101+]`]++; + } + } + + return distribution; +} +export function matchContributor(c: GitContributor, user: GitUser): boolean { + return c.name === user.name && c.email === user.email && c.username === user.username; +} diff --git a/src/git/utils/fetch.utils.ts b/src/git/utils/fetch.utils.ts new file mode 100644 index 0000000000000..999410f8290c5 --- /dev/null +++ b/src/git/utils/fetch.utils.ts @@ -0,0 +1,10 @@ +const millisecondsPerMinute = 60 * 1000; +const millisecondsPerHour = 60 * 60 * 1000; +export const millisecondsPerDay = 24 * 60 * 60 * 1000; + +export function getLastFetchedUpdateInterval(lastFetched: number): number { + const timeDiff = Date.now() - lastFetched; + return timeDiff < millisecondsPerDay + ? (timeDiff < millisecondsPerHour ? millisecondsPerMinute : millisecondsPerHour) / 2 + : 0; +} diff --git a/src/git/utils/file.utils.ts b/src/git/utils/file.utils.ts new file mode 100644 index 0000000000000..a9cdaab169a57 --- /dev/null +++ b/src/git/utils/file.utils.ts @@ -0,0 +1,12 @@ +import type { GitFile } from '../models/file'; + +export function isGitFile(file: any | undefined): file is GitFile { + return ( + file != null && + 'fileName' in file && + typeof file.fileName === 'string' && + 'status' in file && + typeof file.status === 'string' && + file.status.length === 1 + ); +} diff --git a/src/git/utils/fileStatus.utils.ts b/src/git/utils/fileStatus.utils.ts new file mode 100644 index 0000000000000..be83c3a65ef1a --- /dev/null +++ b/src/git/utils/fileStatus.utils.ts @@ -0,0 +1,49 @@ +import type { GitFileStatus } from '../models/fileStatus'; + +const statusIconsMap = { + '.': undefined, + '!': 'icon-status-ignored.svg', + '?': 'icon-status-untracked.svg', + A: 'icon-status-added.svg', + D: 'icon-status-deleted.svg', + M: 'icon-status-modified.svg', + R: 'icon-status-renamed.svg', + C: 'icon-status-copied.svg', + AA: 'icon-status-conflict.svg', + AU: 'icon-status-conflict.svg', + UA: 'icon-status-conflict.svg', + DD: 'icon-status-conflict.svg', + DU: 'icon-status-conflict.svg', + UD: 'icon-status-conflict.svg', + UU: 'icon-status-conflict.svg', + T: 'icon-status-modified.svg', + U: 'icon-status-modified.svg', +}; + +export function getGitFileStatusIcon(status: GitFileStatus): string { + return statusIconsMap[status] ?? 'icon-status-unknown.svg'; +} + +const statusTextMap = { + '.': 'Unchanged', + '!': 'Ignored', + '?': 'Untracked', + A: 'Added', + D: 'Deleted', + M: 'Modified', + R: 'Renamed', + C: 'Copied', + AA: 'Conflict', + AU: 'Conflict', + UA: 'Conflict', + DD: 'Conflict', + DU: 'Conflict', + UD: 'Conflict', + UU: 'Conflict', + T: 'Modified', + U: 'Updated but Unmerged', +}; + +export function getGitFileStatusText(status: GitFileStatus | keyof typeof statusTextMap): string { + return statusTextMap[status] ?? 'Unknown'; +} diff --git a/src/git/utils/issue.utils.ts b/src/git/utils/issue.utils.ts new file mode 100644 index 0000000000000..22b85447d8f45 --- /dev/null +++ b/src/git/utils/issue.utils.ts @@ -0,0 +1,80 @@ +import type { Issue, IssueRepositoryIdentityDescriptor, IssueShape } from '../models/issue'; + +export function getRepositoryIdentityForIssue(issue: IssueShape | Issue): IssueRepositoryIdentityDescriptor { + if (issue.repository == null) throw new Error('Missing repository'); + + return { + remote: { + url: issue.repository.url, + domain: issue.provider.domain, + }, + name: `${issue.repository.owner}/${issue.repository.repo}`, + provider: { + id: issue.provider.id, + domain: issue.provider.domain, + repoDomain: issue.repository.owner, + repoName: issue.repository.repo, + repoOwnerDomain: issue.repository.owner, + }, + }; +} + +export function serializeIssue(value: IssueShape): IssueShape { + const serialized: IssueShape = { + type: value.type, + provider: { + id: value.provider.id, + name: value.provider.name, + domain: value.provider.domain, + icon: value.provider.icon, + }, + id: value.id, + nodeId: value.nodeId, + title: value.title, + url: value.url, + createdDate: value.createdDate, + updatedDate: value.updatedDate, + closedDate: value.closedDate, + closed: value.closed, + state: value.state, + author: { + id: value.author.id, + name: value.author.name, + avatarUrl: value.author.avatarUrl, + url: value.author.url, + }, + repository: + value.repository == null + ? undefined + : { + owner: value.repository.owner, + repo: value.repository.repo, + url: value.repository.url, + }, + project: + value.project == null + ? undefined + : { + id: value.project.id, + name: value.project.name, + resourceId: value.project.resourceId, + }, + assignees: value.assignees.map(assignee => ({ + id: assignee.id, + name: assignee.name, + avatarUrl: assignee.avatarUrl, + url: assignee.url, + })), + labels: + value.labels == null + ? undefined + : value.labels.map(label => ({ + color: label.color, + name: label.name, + })), + commentsCount: value.commentsCount, + thumbsUpCount: value.thumbsUpCount, + body: value.body, + }; + return serialized; +} diff --git a/src/git/utils/issueOrPullRequest.utils.ts b/src/git/utils/issueOrPullRequest.utils.ts new file mode 100644 index 0000000000000..2d1ae50ed972c --- /dev/null +++ b/src/git/utils/issueOrPullRequest.utils.ts @@ -0,0 +1,23 @@ +import type { IssueOrPullRequest } from '../models/issueOrPullRequest'; + +export function serializeIssueOrPullRequest(value: IssueOrPullRequest): IssueOrPullRequest { + const serialized: IssueOrPullRequest = { + type: value.type, + provider: { + id: value.provider.id, + name: value.provider.name, + domain: value.provider.domain, + icon: value.provider.icon, + }, + id: value.id, + nodeId: value.nodeId, + title: value.title, + url: value.url, + createdDate: value.createdDate, + updatedDate: value.updatedDate, + closedDate: value.closedDate, + closed: value.closed, + state: value.state, + }; + return serialized; +} diff --git a/src/git/utils/pullRequest.utils.ts b/src/git/utils/pullRequest.utils.ts new file mode 100644 index 0000000000000..60227ab98436d --- /dev/null +++ b/src/git/utils/pullRequest.utils.ts @@ -0,0 +1,142 @@ +import type { HostingIntegrationId } from '../../constants.integrations'; +import type { + PullRequest, + PullRequestComparisonRefs, + PullRequestRefs, + PullRequestRepositoryIdentityDescriptor, + PullRequestShape, +} from '../models/pullRequest'; +import { shortenRevision } from './revision.utils'; + +export interface PullRequestUrlIdentity { + provider?: HostingIntegrationId; + + ownerAndRepo?: string; + prNumber: string; +} + +export function getComparisonRefsForPullRequest(repoPath: string, prRefs: PullRequestRefs): PullRequestComparisonRefs { + const refs: PullRequestComparisonRefs = { + repoPath: repoPath, + base: { ref: prRefs.base.sha, label: `${prRefs.base.branch} (${shortenRevision(prRefs.base.sha)})` }, + head: { ref: prRefs.head.sha, label: prRefs.head.branch }, + }; + return refs; +} + +export function getPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined { + let prNumber: string | undefined = undefined; + + let match = search.match(/(?:\/)(\d+)/); // any number starting with "/" + if (match != null) { + prNumber = match[1]; + } + + if (prNumber == null) { + match = search.match(/^#?(\d+)$/); // just a number or with a leading "#" + if (match != null) { + prNumber = match[1]; + } + } + + return prNumber == null ? undefined : { ownerAndRepo: undefined, prNumber: prNumber, provider: undefined }; +} + +export function getRepositoryIdentityForPullRequest( + pr: PullRequest, + headRepo: boolean = true, +): PullRequestRepositoryIdentityDescriptor { + if (headRepo) { + return { + remote: { + url: pr.refs?.head?.url, + domain: pr.provider.domain, + }, + name: `${pr.refs?.head?.owner ?? pr.repository.owner}/${pr.refs?.head?.repo ?? pr.repository.repo}`, + provider: { + id: pr.provider.id, + domain: pr.provider.domain, + repoDomain: pr.refs?.head?.owner ?? pr.repository.owner, + repoName: pr.refs?.head?.repo ?? pr.repository.repo, + }, + }; + } + + return { + remote: { + url: pr.refs?.base?.url ?? pr.url, + domain: pr.provider.domain, + }, + name: `${pr.refs?.base?.owner ?? pr.repository.owner}/${pr.refs?.base?.repo ?? pr.repository.repo}`, + provider: { + id: pr.provider.id, + domain: pr.provider.domain, + repoDomain: pr.refs?.base?.owner ?? pr.repository.owner, + repoName: pr.refs?.base?.repo ?? pr.repository.repo, + repoOwnerDomain: pr.refs?.base?.owner ?? pr.repository.owner, + }, + }; +} + +export function isMaybeNonSpecificPullRequestSearchUrl(search: string): boolean { + return getPullRequestIdentityFromMaybeUrl(search) != null; +} + +export function serializePullRequest(value: PullRequest): PullRequestShape { + const serialized: PullRequestShape = { + type: value.type, + provider: { + id: value.provider.id, + name: value.provider.name, + domain: value.provider.domain, + icon: value.provider.icon, + }, + id: value.id, + nodeId: value.nodeId, + title: value.title, + url: value.url, + createdDate: value.createdDate, + updatedDate: value.updatedDate, + closedDate: value.closedDate, + closed: value.closed, + author: { + id: value.author.id, + name: value.author.name, + avatarUrl: value.author.avatarUrl, + url: value.author.url, + }, + state: value.state, + mergedDate: value.mergedDate, + mergeableState: value.mergeableState, + refs: value.refs + ? { + head: { + exists: value.refs.head.exists, + owner: value.refs.head.owner, + repo: value.refs.head.repo, + sha: value.refs.head.sha, + branch: value.refs.head.branch, + url: value.refs.head.url, + }, + base: { + exists: value.refs.base.exists, + owner: value.refs.base.owner, + repo: value.refs.base.repo, + sha: value.refs.base.sha, + branch: value.refs.base.branch, + url: value.refs.base.url, + }, + isCrossRepository: value.refs.isCrossRepository, + } + : undefined, + isDraft: value.isDraft, + additions: value.additions, + deletions: value.deletions, + commentsCount: value.commentsCount, + thumbsUpCount: value.thumbsUpCount, + reviewDecision: value.reviewDecision, + reviewRequests: value.reviewRequests, + assignees: value.assignees, + }; + return serialized; +} diff --git a/src/git/models/reference.utils.ts b/src/git/utils/reference.utils.ts similarity index 84% rename from src/git/models/reference.utils.ts rename to src/git/utils/reference.utils.ts index 3c31479cc777e..7912bea56c32f 100644 --- a/src/git/models/reference.utils.ts +++ b/src/git/utils/reference.utils.ts @@ -1,17 +1,14 @@ import { GlyphChars } from '../../constants'; import { capitalize } from '../../system/string'; -import type { GitBranch } from './branch'; -import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from './branch.utils'; -import type { GitCommit, GitStashCommit } from './commit'; import type { GitBranchReference, GitReference, GitRevisionReference, GitStashReference, GitTagReference, -} from './reference'; -import { isRevisionRange, isShaParent, shortenRevision } from './revision.utils'; -import type { GitTag } from './tag'; +} from '../models/reference'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from './branch.utils'; +import { isRevisionRange, isShaParent, shortenRevision } from "./revision.utils"; export function createReference( ref: string, @@ -96,44 +93,6 @@ export function createReference( } } -export function getReferenceFromBranch(branch: GitBranch) { - return createReference(branch.ref, branch.repoPath, { - id: branch.id, - refType: branch.refType, - name: branch.name, - remote: branch.remote, - upstream: branch.upstream, - }); -} - -export function getReferenceFromRevision( - revision: GitCommit | GitStashCommit | GitRevisionReference, - options?: { excludeMessage?: boolean }, -) { - if (revision.refType === 'stash') { - return createReference(revision.ref, revision.repoPath, { - refType: revision.refType, - name: revision.name, - number: revision.number, - message: options?.excludeMessage ? undefined : revision.message, - }); - } - - return createReference(revision.ref, revision.repoPath, { - refType: revision.refType, - name: revision.name, - message: options?.excludeMessage ? undefined : revision.message, - }); -} - -export function getReferenceFromTag(tag: GitTag) { - return createReference(tag.ref, tag.repoPath, { - id: tag.id, - refType: tag.refType, - name: tag.name, - }); -} - export function getReferenceLabel( refs: GitReference | GitReference[] | undefined, options?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean; quoted?: boolean } | false, @@ -237,6 +196,13 @@ export function getReferenceLabel( } } +export function getReferenceNameWithoutRemote(ref: GitReference) { + if (ref.refType === 'branch') { + return ref.remote ? getBranchNameWithoutRemote(ref.name) : ref.name; + } + return ref.name; +} + export function getReferenceTypeLabel(ref: GitReference | undefined) { switch (ref?.refType) { case 'branch': diff --git a/src/git/utils/remote.utils.ts b/src/git/utils/remote.utils.ts new file mode 100644 index 0000000000000..fe4c6584ff904 --- /dev/null +++ b/src/git/utils/remote.utils.ts @@ -0,0 +1,102 @@ +import { GlyphChars } from '../../constants'; +import { sortCompare } from '../../system/string'; +import type { GitRemote } from '../models/remote'; +import type { RemoteProvider } from '../remotes/remoteProvider'; + +export function getDefaultRemoteOrHighlander(remotes: T[]): T | undefined { + return remotes.length === 1 ? remotes[0] : remotes.find(r => r.default); +} + +export function getHighlanderProviderName(remotes: GitRemote[]) { + if (remotes.length === 0) return undefined; + + const remote = getDefaultRemoteOrHighlander(remotes); + if (remote != null) return remote.provider.name; + + const providerName = remotes[0].provider.name; + // Only use the real provider name if there is only 1 type of provider + if (remotes.every(r => r.provider.name === providerName)) return providerName; + + return undefined; +} + +export function getHighlanderProviders(remotes: GitRemote[]) { + if (remotes.length === 0) return undefined; + + const remote = getDefaultRemoteOrHighlander(remotes); + if (remote != null) return [remote.provider]; + + const providerName = remotes[0].provider.name; + if (remotes.every(r => r.provider.name === providerName)) return remotes.map(r => r.provider); + + return undefined; +} +export function getRemoteArrowsGlyph(remote: GitRemote): GlyphChars { + let arrows; + let left; + let right; + for (const { type } of remote.urls) { + if (type === 'fetch') { + left = true; + + if (right) break; + } else if (type === 'push') { + right = true; + + if (left) break; + } + } + + if (left && right) { + arrows = GlyphChars.ArrowsRightLeft; + } else if (right) { + arrows = GlyphChars.ArrowRight; + } else if (left) { + arrows = GlyphChars.ArrowLeft; + } else { + arrows = GlyphChars.Dash; + } + + return arrows; +} + +export function getRemoteThemeIconString(remote: GitRemote | undefined): string { + return getRemoteProviderThemeIconString(remote?.provider); +} + +export function getRemoteProviderThemeIconString(provider: RemoteProvider | undefined): string { + return provider != null ? `gitlens-provider-${provider.icon}` : 'cloud'; +} + +export function getRemoteUpstreamDescription(remote: GitRemote): string { + const arrows = getRemoteArrowsGlyph(remote); + + const { provider } = remote; + if (provider != null) { + return `${arrows}${GlyphChars.Space} ${provider.name} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${provider.displayPath}`; + } + + return `${arrows}${GlyphChars.Space} ${ + remote.domain ? `${remote.domain} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ` : '' + }${remote.path}`; +} + +export function getVisibilityCacheKey(remote: GitRemote): string; +export function getVisibilityCacheKey(remotes: GitRemote[]): string; +export function getVisibilityCacheKey(remotes: GitRemote | GitRemote[]): string { + if (!Array.isArray(remotes)) return remotes.remoteKey; + return remotes + .map(r => r.remoteKey) + .sort() + .join(','); +} + +export function sortRemotes(remotes: T[]) { + return remotes.sort( + (a, b) => + (a.default ? -1 : 1) - (b.default ? -1 : 1) || + (a.name === 'origin' ? -1 : 1) - (b.name === 'origin' ? -1 : 1) || + (a.name === 'upstream' ? -1 : 1) - (b.name === 'upstream' ? -1 : 1) || + sortCompare(a.name, b.name), + ); +} diff --git a/src/git/utils/remoteResource.utils.ts b/src/git/utils/remoteResource.utils.ts new file mode 100644 index 0000000000000..13a0c5c4f336c --- /dev/null +++ b/src/git/utils/remoteResource.utils.ts @@ -0,0 +1,31 @@ +import type { RemoteResource } from '../models/remoteResource'; +import { RemoteResourceType } from '../models/remoteResource'; + +// | { +// type: RemoteResourceType.Tag; +// tag: string; +// }; +export function getNameFromRemoteResource(resource: RemoteResource) { + switch (resource.type) { + case RemoteResourceType.Branch: + return 'Branch'; + case RemoteResourceType.Branches: + return 'Branches'; + case RemoteResourceType.Commit: + return 'Commit'; + case RemoteResourceType.Comparison: + return 'Comparison'; + case RemoteResourceType.CreatePullRequest: + return 'Create Pull Request'; + case RemoteResourceType.File: + return 'File'; + case RemoteResourceType.Repo: + return 'Repository'; + case RemoteResourceType.Revision: + return 'File'; + // case RemoteResourceType.Tag: + // return 'Tag'; + default: + return ''; + } +} diff --git a/src/git/models/revision.utils.ts b/src/git/utils/revision.utils.ts similarity index 97% rename from src/git/models/revision.utils.ts rename to src/git/utils/revision.utils.ts index 1f3d0bcc2ce8a..bcaeab9aef7fd 100644 --- a/src/git/models/revision.utils.ts +++ b/src/git/utils/revision.utils.ts @@ -1,5 +1,5 @@ -import type { GitRevisionRange } from './revision'; -import { deletedOrMissing, uncommitted, uncommittedStaged } from './revision'; +import type { GitRevisionRange } from '../models/revision'; +import { deletedOrMissing, uncommitted, uncommittedStaged } from '../models/revision'; const rangeRegex = /^([\w\-/]+(?:\.[\w\-/]+)*)?(\.\.\.?)([\w\-/]+(?:\.[\w\-/]+)*)?$/; const qualifiedRangeRegex = /^([\w\-/]+(?:\.[\w\-/]+)*)(\.\.\.?)([\w\-/]+(?:\.[\w\-/]+)*)$/; diff --git a/src/git/utils/status.utils.ts b/src/git/utils/status.utils.ts new file mode 100644 index 0000000000000..d586863d1bdb9 --- /dev/null +++ b/src/git/utils/status.utils.ts @@ -0,0 +1,55 @@ +import { GlyphChars } from '../../constants'; +import { pluralize } from '../../system/string'; + +export function getUpstreamStatus( + upstream: { name: string; missing: boolean } | undefined, + state: { ahead: number; behind: number }, + options?: { + count?: boolean; + empty?: string; + expand?: boolean; + icons?: boolean; + prefix?: string; + separator?: string; + suffix?: string; + }, +): string { + let count = true; + let expand = false; + let icons = false; + let prefix = ''; + let separator = ' '; + let suffix = ''; + if (options != null) { + ({ count = true, expand = false, icons = false, prefix = '', separator = ' ', suffix = '' } = options); + } + if (upstream == null || (state.behind === 0 && state.ahead === 0)) return options?.empty ?? ''; + + if (expand) { + let status = ''; + if (upstream.missing) { + status = 'missing'; + } else { + if (state.behind) { + status += `${pluralize('commit', state.behind, { + infix: icons ? '$(arrow-down) ' : undefined, + })} behind`; + } + if (state.ahead) { + status += `${status.length === 0 ? '' : separator}${pluralize('commit', state.ahead, { + infix: icons ? '$(arrow-up) ' : undefined, + })} ahead`; + if (suffix.includes(upstream.name.split('/')[0])) { + status += ' of'; + } + } + } + return `${prefix}${status}${suffix}`; + } + + const showCounts = count && !upstream.missing; + + return `${prefix}${showCounts ? state.behind : ''}${ + showCounts || state.behind !== 0 ? GlyphChars.ArrowDown : '' + }${separator}${showCounts ? state.ahead : ''}${showCounts || state.ahead !== 0 ? GlyphChars.ArrowUp : ''}${suffix}`; +} diff --git a/src/git/utils/tag.utils.ts b/src/git/utils/tag.utils.ts new file mode 100644 index 0000000000000..4325b0a9fd0da --- /dev/null +++ b/src/git/utils/tag.utils.ts @@ -0,0 +1,9 @@ +import type { GitReference } from '../models/reference'; + +export function getTagId(repoPath: string, name: string): string { + return `${repoPath}|tag/${name}`; +} + +export function isOfTagRefType(tag: GitReference | undefined) { + return tag?.refType === 'tag'; +} diff --git a/src/git/utils/user.utils.ts b/src/git/utils/user.utils.ts new file mode 100644 index 0000000000000..837b7243a28c5 --- /dev/null +++ b/src/git/utils/user.utils.ts @@ -0,0 +1,20 @@ +import type { GitUser } from '../models/user'; + +export function isUserMatch( + user: GitUser | undefined, + name: string | undefined, + email: string | undefined, + username?: string | undefined, +): boolean { + return ( + user != null && + // Name or e-mail is provided + (user.name != null || user.email != null || user.username != null) && + // Match on name if provided + (user.name == null || user.name === name) && + // Match on email if provided + (user.email == null || user.email === email) && + // Match on username if provided + (user.username == null || user.username === username) + ); +} diff --git a/src/git/utils/worktree.utils.ts b/src/git/utils/worktree.utils.ts new file mode 100644 index 0000000000000..8917e1ca827ee --- /dev/null +++ b/src/git/utils/worktree.utils.ts @@ -0,0 +1,3 @@ +export function getWorktreeId(repoPath: string, name: string): string { + return `${repoPath}|worktrees/${name}`; +} diff --git a/src/hovers/hovers.ts b/src/hovers/hovers.ts index 8e9d7d68eecda..d152286abfe5f 100644 --- a/src/hovers/hovers.ts +++ b/src/hovers/hovers.ts @@ -12,10 +12,10 @@ import type { GitDiffHunk, GitDiffLine } from '../git/models/diff'; import type { PullRequest } from '../git/models/pullRequest'; import type { GitRemote } from '../git/models/remote'; import { uncommittedStaged } from '../git/models/revision'; -import { isUncommittedStaged, shortenRevision } from '../git/models/revision.utils'; import type { RemoteProvider } from '../git/remotes/remoteProvider'; +import { isUncommittedStaged, shortenRevision } from '../git/utils/revision.utils'; +import { configuration } from '../system/-webview/configuration'; import { getSettledValue, pauseOnCancelOrTimeout, pauseOnCancelOrTimeoutMapTuplePromise } from '../system/promise'; -import { configuration } from '../system/vscode/configuration'; export async function changesMessage( container: Container, diff --git a/src/hovers/lineHoverController.ts b/src/hovers/lineHoverController.ts index 753263bf68522..f10224dc1f06a 100644 --- a/src/hovers/lineHoverController.ts +++ b/src/hovers/lineHoverController.ts @@ -1,11 +1,11 @@ import type { CancellationToken, ConfigurationChangeEvent, Position, TextDocument, TextEditor, Uri } from 'vscode'; import { Disposable, Hover, languages, Range, window } from 'vscode'; import type { Container } from '../container'; +import { configuration } from '../system/-webview/configuration'; import { UriComparer } from '../system/comparers'; import { debug } from '../system/decorators/log'; import { once } from '../system/event'; import { Logger } from '../system/logger'; -import { configuration } from '../system/vscode/configuration'; import type { LinesChangeEvent } from '../trackers/lineTracker'; import { changesMessage, detailsMessage } from './hovers'; diff --git a/src/messages.ts b/src/messages.ts index 5027cd29eac8b..b9416a89065a4 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -6,11 +6,11 @@ import { GlCommand } from './constants.commands'; import type { BlameIgnoreRevsFileError } from './git/errors'; import { BlameIgnoreRevsFileBadRevisionError } from './git/errors'; import type { GitCommit } from './git/models/commit'; +import { executeCommand, executeCoreCommand } from './system/-webview/command'; +import { configuration } from './system/-webview/configuration'; +import { openUrl } from './system/-webview/utils'; import { createMarkdownCommandLink } from './system/commands'; import { Logger } from './system/logger'; -import { executeCommand, executeCoreCommand } from './system/vscode/command'; -import { configuration } from './system/vscode/configuration'; -import { openUrl } from './system/vscode/utils'; export function showBlameInvalidIgnoreRevsFileWarningMessage( ex: BlameIgnoreRevsFileError | BlameIgnoreRevsFileBadRevisionError, diff --git a/src/partners.ts b/src/partners.ts index 52d84746c93c1..64ba8f1db6ee5 100644 --- a/src/partners.ts +++ b/src/partners.ts @@ -4,7 +4,7 @@ import type { ActionContext, HoverCommandsActionContext } from './api/gitlens'; import type { InviteToLiveShareCommandArgs } from './commands/inviteToLiveShare'; import { GlCommand } from './constants.commands'; import { Container } from './container'; -import { executeCommand, executeCoreCommand } from './system/vscode/command'; +import { executeCommand, executeCoreCommand } from './system/-webview/command'; import type { ContactPresence } from './vsls/vsls'; export async function installExtension( diff --git a/src/plus/drafts/actions.ts b/src/plus/drafts/actions.ts index 809e396f551f5..cc53e45ed3908 100644 --- a/src/plus/drafts/actions.ts +++ b/src/plus/drafts/actions.ts @@ -1,7 +1,7 @@ import type { MessageItem } from 'vscode'; import { window } from 'vscode'; import { Container } from '../../container'; -import { configuration } from '../../system/vscode/configuration'; +import { configuration } from '../../system/-webview/configuration'; import type { ShowCreateDraft, ShowViewDraft } from '../../webviews/plus/patchDetails/registration'; import type { WebviewViewShowOptions } from '../../webviews/webviewsController'; diff --git a/src/plus/drafts/draftsService.ts b/src/plus/drafts/draftsService.ts index 26881100cff32..47e56adc1a86b 100644 --- a/src/plus/drafts/draftsService.ts +++ b/src/plus/drafts/draftsService.ts @@ -8,9 +8,26 @@ import type { Container } from '../../container'; import type { GitCommit } from '../../git/models/commit'; import type { PullRequest } from '../../git/models/pullRequest'; import { isRepository, Repository } from '../../git/models/repository'; -import { isSha, isUncommitted, shortenRevision } from '../../git/models/revision.utils'; +import type { + GkRepositoryId, + RepositoryIdentity, + RepositoryIdentityRequest, + RepositoryIdentityResponse, +} from '../../git/models/repositoryIdentities'; import type { GitUser } from '../../git/models/user'; import { getRemoteProviderMatcher } from '../../git/remotes/remoteProviders'; +import { isSha, isUncommitted, shortenRevision } from '../../git/utils/revision.utils'; +import { log } from '../../system/decorators/log'; +import { Logger } from '../../system/logger'; +import type { LogScope } from '../../system/logger.scope'; +import { getLogScope } from '../../system/logger.scope'; +import { getSettledValue } from '../../system/promise'; +import type { OrganizationMember } from '../gk/models/organization'; +import type { SubscriptionAccount } from '../gk/models/subscription'; +import type { ServerConnection } from '../gk/serverConnection'; +import { providersMetadata } from '../integrations/providers/models'; +import { getEntityIdentifierInput } from '../integrations/providers/utils'; +import type { LaunchpadItem } from '../launchpad/launchpadProvider'; import type { CodeSuggestionCounts, CodeSuggestionCountsResponse, @@ -32,24 +49,7 @@ import type { DraftType, DraftUser, DraftVisibility, -} from '../../gk/models/drafts'; -import type { - GkRepositoryId, - RepositoryIdentity, - RepositoryIdentityRequest, - RepositoryIdentityResponse, -} from '../../gk/models/repositoryIdentities'; -import { log } from '../../system/decorators/log'; -import { Logger } from '../../system/logger'; -import type { LogScope } from '../../system/logger.scope'; -import { getLogScope } from '../../system/logger.scope'; -import { getSettledValue } from '../../system/promise'; -import type { OrganizationMember } from '../gk/account/organization'; -import type { SubscriptionAccount } from '../gk/account/subscription'; -import type { ServerConnection } from '../gk/serverConnection'; -import { providersMetadata } from '../integrations/providers/models'; -import { getEntityIdentifierInput } from '../integrations/providers/utils'; -import type { LaunchpadItem } from '../launchpad/launchpadProvider'; +} from './models/drafts'; export interface ProviderAuth { provider: IntegrationId; diff --git a/src/gk/models/drafts.ts b/src/plus/drafts/models/drafts.ts similarity index 92% rename from src/gk/models/drafts.ts rename to src/plus/drafts/models/drafts.ts index 0cdf719187ffd..cf5bb47e63111 100644 --- a/src/gk/models/drafts.ts +++ b/src/plus/drafts/models/drafts.ts @@ -1,10 +1,14 @@ import type { Uri } from 'vscode'; -import type { GitCommit } from '../../git/models/commit'; -import type { GitFileChangeShape } from '../../git/models/file'; -import type { GitPatch, PatchRevisionRange } from '../../git/models/patch'; -import type { Repository } from '../../git/models/repository'; -import type { GitUser } from '../../git/models/user'; -import type { GkRepositoryId, RepositoryIdentity, RepositoryIdentityRequest } from './repositoryIdentities'; +import type { GitCommit } from '../../../git/models/commit'; +import type { GitFileChangeShape } from '../../../git/models/fileChange'; +import type { GitPatch, PatchRevisionRange } from '../../../git/models/patch'; +import type { Repository } from '../../../git/models/repository'; +import type { + GkRepositoryId, + RepositoryIdentity, + RepositoryIdentityRequest, +} from '../../../git/models/repositoryIdentities'; +import type { GitUser } from '../../../git/models/user'; export interface LocalDraft { readonly draftType: 'local'; diff --git a/src/plus/drafts/utils/-webview/drafts.utils.ts b/src/plus/drafts/utils/-webview/drafts.utils.ts new file mode 100644 index 0000000000000..40502a732b6b2 --- /dev/null +++ b/src/plus/drafts/utils/-webview/drafts.utils.ts @@ -0,0 +1,41 @@ +import type { MessageItem } from 'vscode'; +import { window } from 'vscode'; +import { urls } from '../../../../constants'; +import type { Container } from '../../../../container'; +import { openUrl } from '../../../../system/-webview/utils'; + +export async function confirmDraftStorage(container: Container): Promise { + if (container.storage.get('confirm:draft:storage', false)) return true; + + while (true) { + const accept: MessageItem = { title: 'Continue' }; + const decline: MessageItem = { title: 'Cancel', isCloseAffordance: true }; + const moreInfo: MessageItem = { title: 'Learn More' }; + const security: MessageItem = { title: 'Security' }; + const result = await window.showInformationMessage( + `Cloud Patches are securely stored by GitKraken and can be accessed by anyone with the link and a GitKraken account.`, + { modal: true }, + accept, + moreInfo, + security, + decline, + ); + + if (result === accept) { + void container.storage.store('confirm:draft:storage', true).catch(); + return true; + } + + if (result === security) { + void openUrl(urls.security); + continue; + } + + if (result === moreInfo) { + void openUrl(urls.cloudPatches); + continue; + } + + return false; + } +} diff --git a/src/plus/gk/account/__debug__accountDebug.ts b/src/plus/gk/__debug__accountDebug.ts similarity index 96% rename from src/plus/gk/account/__debug__accountDebug.ts rename to src/plus/gk/__debug__accountDebug.ts index 4404eb25e340d..c3aad7b52cef3 100644 --- a/src/plus/gk/account/__debug__accountDebug.ts +++ b/src/plus/gk/__debug__accountDebug.ts @@ -1,21 +1,21 @@ import type { Disposable } from 'vscode'; import { ThemeIcon, window } from 'vscode'; -import { GlCommand } from '../../../constants.commands'; +import { GlCommand } from '../../constants.commands'; import { proFeaturePreviewUsages, proTrialLengthInDays, SubscriptionPlanId, SubscriptionState, -} from '../../../constants.subscription'; -import type { Container } from '../../../container'; -import type { QuickPickItemOfT } from '../../../quickpicks/items/common'; -import { createQuickPickSeparator } from '../../../quickpicks/items/common'; -import { registerCommand } from '../../../system/vscode/command'; -import { configuration } from '../../../system/vscode/configuration'; -import type { GKCheckInResponse, GKLicenses, GKLicenseType, GKUser } from '../checkin'; -import { getSubscriptionFromCheckIn } from '../checkin'; -import { getPreviewSubscription } from './subscription'; +} from '../../constants.subscription'; +import type { Container } from '../../container'; +import type { QuickPickItemOfT } from '../../quickpicks/items/common'; +import { createQuickPickSeparator } from '../../quickpicks/items/common'; +import { registerCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import type { GKCheckInResponse, GKLicenses, GKLicenseType, GKUser } from './models/checkin'; import type { SubscriptionService } from './subscriptionService'; +import { getSubscriptionFromCheckIn } from './utils/checkin.utils'; +import { getPreviewSubscription } from './utils/subscription.utils'; type SubscriptionServiceFacade = { getSubscription: () => SubscriptionService['_subscription']; diff --git a/src/plus/gk/account/authenticationConnection.ts b/src/plus/gk/authenticationConnection.ts similarity index 94% rename from src/plus/gk/account/authenticationConnection.ts rename to src/plus/gk/authenticationConnection.ts index 153b27df9eda1..cac3343a62bd7 100644 --- a/src/plus/gk/account/authenticationConnection.ts +++ b/src/plus/gk/authenticationConnection.ts @@ -2,15 +2,15 @@ import type { CancellationToken, Disposable, StatusBarItem } from 'vscode'; import { CancellationTokenSource, env, StatusBarAlignment, Uri, window } from 'vscode'; import { uuid } from '@env/crypto'; import type { Response } from '@env/fetch'; -import type { TrackingContext } from '../../../constants.telemetry'; -import type { Container } from '../../../container'; -import { debug } from '../../../system/decorators/log'; -import type { DeferredEvent, DeferredEventExecutor } from '../../../system/event'; -import { promisifyDeferred } from '../../../system/event'; -import { Logger } from '../../../system/logger'; -import { getLogScope } from '../../../system/logger.scope'; -import { openUrl } from '../../../system/vscode/utils'; -import type { ServerConnection } from '../serverConnection'; +import type { TrackingContext } from '../../constants.telemetry'; +import type { Container } from '../../container'; +import { openUrl } from '../../system/-webview/utils'; +import { debug } from '../../system/decorators/log'; +import type { DeferredEvent, DeferredEventExecutor } from '../../system/event'; +import { promisifyDeferred } from '../../system/event'; +import { Logger } from '../../system/logger'; +import { getLogScope } from '../../system/logger.scope'; +import type { ServerConnection } from './serverConnection'; export const LoginUriPathPrefix = 'login'; export const AuthenticationUriPathPrefix = 'did-authenticate'; diff --git a/src/plus/gk/account/authenticationProvider.ts b/src/plus/gk/authenticationProvider.ts similarity index 95% rename from src/plus/gk/account/authenticationProvider.ts rename to src/plus/gk/authenticationProvider.ts index 8733a358f1f31..29314b74c40d9 100644 --- a/src/plus/gk/account/authenticationProvider.ts +++ b/src/plus/gk/authenticationProvider.ts @@ -5,14 +5,14 @@ import type { } from 'vscode'; import { Disposable, EventEmitter, window } from 'vscode'; import { uuid } from '@env/crypto'; -import type { TrackingContext } from '../../../constants.telemetry'; -import type { Container, Environment } from '../../../container'; -import { CancellationError } from '../../../errors'; -import { debug } from '../../../system/decorators/log'; -import { Logger } from '../../../system/logger'; -import { getLogScope, setLogScopeExit } from '../../../system/logger.scope'; -import type { ServerConnection } from '../serverConnection'; +import type { TrackingContext } from '../../constants.telemetry'; +import type { Container, Environment } from '../../container'; +import { CancellationError } from '../../errors'; +import { debug } from '../../system/decorators/log'; +import { Logger } from '../../system/logger'; +import { getLogScope, setLogScopeExit } from '../../system/logger.scope'; import { AuthenticationConnection } from './authenticationConnection'; +import type { ServerConnection } from './serverConnection'; interface StoredSession { id: string; diff --git a/src/plus/gk/models/checkin.ts b/src/plus/gk/models/checkin.ts new file mode 100644 index 0000000000000..1725c22861d14 --- /dev/null +++ b/src/plus/gk/models/checkin.ts @@ -0,0 +1,50 @@ +export type GKLicenses = Partial>; + +export interface GKCheckInResponse { + readonly user: GKUser; + readonly licenses: { + readonly paidLicenses: GKLicenses; + readonly effectiveLicenses: GKLicenses; + }; + readonly nextOptInDate?: string; +} + +export interface GKUser { + readonly id: string; + readonly name: string; + readonly email: string; + readonly status: 'activated' | 'pending'; + readonly createdDate: string; + readonly firstGitLensCheckIn?: string; +} + +export interface GKLicense { + readonly latestStatus: 'active' | 'canceled' | 'cancelled' | 'expired' | 'in_trial' | 'non_renewing' | 'trial'; + readonly latestStartDate: string; + readonly latestEndDate: string; + readonly organizationId: string | undefined; + readonly reactivationCount?: number; + readonly nextOptInDate?: string; +} + +export type GKLicenseType = + | 'gitlens-pro' + | 'gitlens-teams' + | 'gitlens-hosted-enterprise' + | 'gitlens-self-hosted-enterprise' + | 'gitlens-standalone-enterprise' + | 'bundle-pro' + | 'bundle-teams' + | 'bundle-hosted-enterprise' + | 'bundle-self-hosted-enterprise' + | 'bundle-standalone-enterprise' + | 'gitkraken_v1-pro' + | 'gitkraken_v1-teams' + | 'gitkraken_v1-hosted-enterprise' + | 'gitkraken_v1-self-hosted-enterprise' + | 'gitkraken_v1-standalone-enterprise' + | 'gitkraken-v1-pro' + | 'gitkraken-v1-teams' + | 'gitkraken-v1-hosted-enterprise' + | 'gitkraken-v1-self-hosted-enterprise' + | 'gitkraken-v1-standalone-enterprise'; diff --git a/src/plus/gk/account/organization.ts b/src/plus/gk/models/organization.ts similarity index 100% rename from src/plus/gk/account/organization.ts rename to src/plus/gk/models/organization.ts diff --git a/src/plus/gk/models/promo.ts b/src/plus/gk/models/promo.ts new file mode 100644 index 0000000000000..ccc0f3e76ecf2 --- /dev/null +++ b/src/plus/gk/models/promo.ts @@ -0,0 +1,18 @@ +import type { PromoKeys, SubscriptionState } from '../../../constants.subscription'; + +export type PromoLocation = 'account' | 'badge' | 'gate' | 'home'; + +export interface Promo { + readonly key: PromoKeys; + readonly code?: string; + readonly states?: SubscriptionState[]; + readonly expiresOn?: number; + readonly startsOn?: number; + + readonly command?: { + command?: `command:${string}`; + tooltip: string; + }; + readonly locations?: PromoLocation[]; + readonly quickpick: { detail: string }; +} diff --git a/src/plus/gk/models/subscription.ts b/src/plus/gk/models/subscription.ts new file mode 100644 index 0000000000000..bb158785d0f04 --- /dev/null +++ b/src/plus/gk/models/subscription.ts @@ -0,0 +1,52 @@ +import type { SubscriptionPlanId, SubscriptionState } from '../../../constants.subscription'; +import type { Organization } from './organization'; + +export type FreeSubscriptionPlans = Extract< + SubscriptionPlanId, + SubscriptionPlanId.Community | SubscriptionPlanId.CommunityWithAccount +>; +export type PaidSubscriptionPlans = Exclude< + SubscriptionPlanId, + SubscriptionPlanId.Community | SubscriptionPlanId.CommunityWithAccount +>; +export type RequiredSubscriptionPlans = Exclude; + +export interface Subscription { + readonly plan: { + readonly actual: SubscriptionPlan; + readonly effective: SubscriptionPlan; + }; + account: SubscriptionAccount | undefined; + previewTrial?: SubscriptionPreviewTrial; + + state: SubscriptionState; + + lastValidatedAt?: number; + + readonly activeOrganization?: Organization; +} + +export interface SubscriptionPlan { + readonly id: SubscriptionPlanId; + readonly name: string; + readonly bundle: boolean; + readonly trialReactivationCount: number; + readonly nextTrialOptInDate?: string | undefined; + readonly cancelled: boolean; + readonly startedOn: string; + readonly expiresOn?: string | undefined; + readonly organizationId: string | undefined; +} + +export interface SubscriptionAccount { + readonly id: string; + readonly name: string; + readonly email: string | undefined; + readonly verified: boolean; + readonly createdOn: string; +} + +export interface SubscriptionPreviewTrial { + readonly startedOn: string; + readonly expiresOn: string; +} diff --git a/src/plus/gk/account/organizationService.ts b/src/plus/gk/organizationService.ts similarity index 94% rename from src/plus/gk/account/organizationService.ts rename to src/plus/gk/organizationService.ts index ba459a883978f..9f3b0d2ebd5bc 100644 --- a/src/plus/gk/account/organizationService.ts +++ b/src/plus/gk/organizationService.ts @@ -1,18 +1,18 @@ import { Disposable, window } from 'vscode'; -import type { Container } from '../../../container'; -import { gate } from '../../../system/decorators/gate'; -import { once } from '../../../system/function'; -import { Logger } from '../../../system/logger'; -import { getLogScope } from '../../../system/logger.scope'; -import { setContext } from '../../../system/vscode/context'; -import type { ServerConnection } from '../serverConnection'; +import type { Container } from '../../container'; +import { setContext } from '../../system/-webview/context'; +import { gate } from '../../system/decorators/-webview/gate'; +import { once } from '../../system/function'; +import { Logger } from '../../system/logger'; +import { getLogScope } from '../../system/logger.scope'; import type { FullOrganization, Organization, OrganizationMember, OrganizationSettings, OrganizationsResponse, -} from './organization'; +} from './models/organization'; +import type { ServerConnection } from './serverConnection'; import type { SubscriptionChangeEvent } from './subscriptionService'; const organizationsCacheExpiration = 24 * 60 * 60 * 1000; // 1 day diff --git a/src/plus/gk/serverConnection.ts b/src/plus/gk/serverConnection.ts index 2e32c5aeb44dc..60d1427c08edb 100644 --- a/src/plus/gk/serverConnection.ts +++ b/src/plus/gk/serverConnection.ts @@ -23,7 +23,7 @@ import { showGkRequestFailed500WarningMessage, showGkRequestTimedOutWarningMessage, } from '../../messages'; -import { memoize } from '../../system/decorators/memoize'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { Logger } from '../../system/logger'; import type { LogScope } from '../../system/logger.scope'; import { getLogScope } from '../../system/logger.scope'; diff --git a/src/plus/gk/account/subscriptionService.ts b/src/plus/gk/subscriptionService.ts similarity index 96% rename from src/plus/gk/account/subscriptionService.ts rename to src/plus/gk/subscriptionService.ts index 1e495346adeca..6f0da671e5a74 100644 --- a/src/plus/gk/account/subscriptionService.ts +++ b/src/plus/gk/subscriptionService.ts @@ -20,11 +20,11 @@ import { window, } from 'vscode'; import { getPlatform } from '@env/platform'; -import type { OpenWalkthroughCommandArgs } from '../../../commands/walkthroughs'; -import { urls } from '../../../constants'; -import type { CoreColors } from '../../../constants.colors'; -import { GlCommand } from '../../../constants.commands'; -import type { StoredFeaturePreviewUsagePeriod } from '../../../constants.storage'; +import type { OpenWalkthroughCommandArgs } from '../../commands/walkthroughs'; +import { urls } from '../../constants'; +import type { CoreColors } from '../../constants.colors'; +import { GlCommand } from '../../constants.commands'; +import type { StoredFeaturePreviewUsagePeriod } from '../../constants.storage'; import { proFeaturePreviewUsageDurationInDays, proFeaturePreviewUsages, @@ -32,7 +32,7 @@ import { proTrialLengthInDays, SubscriptionPlanId, SubscriptionState, -} from '../../../constants.subscription'; +} from '../../constants.subscription'; import type { FeaturePreviewActionEventData, FeaturePreviewDayEventData, @@ -41,37 +41,37 @@ import type { SubscriptionEventDataWithPrevious, SubscriptionFeaturePreviewsEventData, TrackingContext, -} from '../../../constants.telemetry'; -import type { Container } from '../../../container'; -import { AccountValidationError, RequestsAreBlockedTemporarilyError } from '../../../errors'; -import type { FeaturePreview, FeaturePreviews } from '../../../features'; -import { featurePreviews, getFeaturePreviewLabel, getFeaturePreviewStatus } from '../../../features'; -import type { RepositoriesChangeEvent } from '../../../git/gitProviderService'; -import { createFromDateDelta, fromNow } from '../../../system/date'; -import { gate } from '../../../system/decorators/gate'; -import { debug, log } from '../../../system/decorators/log'; -import { take } from '../../../system/event'; -import type { Deferrable } from '../../../system/function'; -import { debounce, once } from '../../../system/function'; -import { Logger } from '../../../system/logger'; -import { getLogScope, setLogScopeExit } from '../../../system/logger.scope'; -import { flatten } from '../../../system/object'; -import { pauseOnCancelOrTimeout } from '../../../system/promise'; -import { pluralize } from '../../../system/string'; -import { satisfies } from '../../../system/version'; -import { executeCommand, registerCommand } from '../../../system/vscode/command'; -import { configuration } from '../../../system/vscode/configuration'; -import { setContext } from '../../../system/vscode/context'; -import { openUrl } from '../../../system/vscode/utils'; -import type { GKCheckInResponse } from '../checkin'; -import { getSubscriptionFromCheckIn } from '../checkin'; -import type { ServerConnection } from '../serverConnection'; -import { ensurePlusFeaturesEnabled } from '../utils'; +} from '../../constants.telemetry'; +import type { Container } from '../../container'; +import { AccountValidationError, RequestsAreBlockedTemporarilyError } from '../../errors'; +import type { FeaturePreview, FeaturePreviews } from '../../features'; +import { featurePreviews, getFeaturePreviewLabel, getFeaturePreviewStatus } from '../../features'; +import type { RepositoriesChangeEvent } from '../../git/gitProviderService'; +import { executeCommand, registerCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { setContext } from '../../system/-webview/context'; +import { openUrl } from '../../system/-webview/utils'; +import { createFromDateDelta, fromNow } from '../../system/date'; +import { gate } from '../../system/decorators/-webview/gate'; +import { debug, log } from '../../system/decorators/log'; +import { take } from '../../system/event'; +import type { Deferrable } from '../../system/function'; +import { debounce, once } from '../../system/function'; +import { Logger } from '../../system/logger'; +import { getLogScope, setLogScopeExit } from '../../system/logger.scope'; +import { flatten } from '../../system/object'; +import { pauseOnCancelOrTimeout } from '../../system/promise'; +import { pluralize } from '../../system/string'; +import { satisfies } from '../../system/version'; import { LoginUriPathPrefix } from './authenticationConnection'; import { authenticationProviderScopes } from './authenticationProvider'; -import type { Organization } from './organization'; -import { getApplicablePromo } from './promos'; -import type { Subscription } from './subscription'; +import type { GKCheckInResponse } from './models/checkin'; +import type { Organization } from './models/organization'; +import type { Subscription } from './models/subscription'; +import type { ServerConnection } from './serverConnection'; +import { ensurePlusFeaturesEnabled } from './utils/-webview/plus.utils'; +import { getSubscriptionFromCheckIn } from './utils/checkin.utils'; +import { getApplicablePromo } from './utils/promo.utils'; import { assertSubscriptionState, computeSubscriptionState, @@ -87,7 +87,7 @@ import { isSubscriptionPaid, isSubscriptionTrial, SubscriptionUpdatedUriPathPrefix, -} from './subscription'; +} from './utils/subscription.utils'; export type FeaturePreviewChangeEvent = FeaturePreview; diff --git a/src/plus/gk/utils.ts b/src/plus/gk/utils.ts deleted file mode 100644 index 77140b34e4686..0000000000000 --- a/src/plus/gk/utils.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { MessageItem } from 'vscode'; -import { window } from 'vscode'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext } from '../../system/vscode/context'; - -export function arePlusFeaturesEnabled(): boolean { - return getContext('gitlens:plus:enabled', configuration.get('plusFeatures.enabled', undefined, true)); -} - -export async function ensurePlusFeaturesEnabled(): Promise { - if (arePlusFeaturesEnabled()) return true; - - const confirm: MessageItem = { title: 'Enable' }; - const cancel: MessageItem = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showInformationMessage( - 'Pro features are currently disabled. Would you like to enable them?', - { modal: true }, - confirm, - cancel, - ); - - if (result !== confirm) return false; - - await configuration.updateEffective('plusFeatures.enabled', true); - return true; -} diff --git a/src/plus/gk/utils/-webview/acount.utils.ts b/src/plus/gk/utils/-webview/acount.utils.ts new file mode 100644 index 0000000000000..fea4c61e347d9 --- /dev/null +++ b/src/plus/gk/utils/-webview/acount.utils.ts @@ -0,0 +1,54 @@ +import { window } from 'vscode'; +import type { Source } from '../../../../constants.telemetry'; +import type { Container } from '../../../../container'; + +export async function ensureAccount(container: Container, title: string, source: Source): Promise { + while (true) { + const subscription = await container.subscription.getSubscription(); + if (subscription.account?.verified === false) { + const resend = { title: 'Resend Email' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nYou must verify your email before you can continue.`, + { modal: true }, + resend, + cancel, + ); + + if (result === resend) { + if (await container.subscription.resendVerification(source)) { + continue; + } + } + + return false; + } + + if (subscription.account != null) break; + + const signUp = { title: 'Sign Up' }; + const signIn = { title: 'Sign In' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nSign up for access to Pro features and the GitKraken DevEx platform, or sign in`, + { modal: true }, + signUp, + signIn, + cancel, + ); + + if (result === signIn) { + if (await container.subscription.loginOrSignUp(false, source)) { + continue; + } + } else if (result === signUp) { + if (await container.subscription.loginOrSignUp(true, source)) { + continue; + } + } + + return false; + } + + return true; +} diff --git a/src/plus/gk/utils/-webview/plus.utils.ts b/src/plus/gk/utils/-webview/plus.utils.ts new file mode 100644 index 0000000000000..dc017bae216ea --- /dev/null +++ b/src/plus/gk/utils/-webview/plus.utils.ts @@ -0,0 +1,111 @@ +import type { MessageItem } from 'vscode'; +import { window } from 'vscode'; +import { proTrialLengthInDays } from '../../../../constants.subscription'; +import type { Source } from '../../../../constants.telemetry'; +import type { Container } from '../../../../container'; +import { configuration } from '../../../../system/-webview/configuration'; +import { getContext } from '../../../../system/-webview/context'; +import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../subscription.utils'; + +export function arePlusFeaturesEnabled(): boolean { + return getContext('gitlens:plus:enabled', configuration.get('plusFeatures.enabled', undefined, true)); +} + +export async function ensurePlusFeaturesEnabled(): Promise { + if (arePlusFeaturesEnabled()) return true; + + const confirm: MessageItem = { title: 'Enable' }; + const cancel: MessageItem = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showInformationMessage( + 'Pro features are currently disabled. Would you like to enable them?', + { modal: true }, + confirm, + cancel, + ); + + if (result !== confirm) return false; + + await configuration.updateEffective('plusFeatures.enabled', true); + return true; +} +export async function ensurePaidPlan( + container: Container, + title: string, + source: Source, + options?: { allowPreview?: boolean }, +): Promise { + while (true) { + const subscription = await container.subscription.getSubscription(); + if (subscription.account?.verified === false) { + const resend = { title: 'Resend Email' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nYou must verify your email before you can continue.`, + { modal: true }, + resend, + cancel, + ); + + if (result === resend) { + if (await container.subscription.resendVerification(source)) { + continue; + } + } + + return false; + } + + const plan = subscription.plan.effective.id; + if (isSubscriptionPaidPlan(plan)) break; + + if (options?.allowPreview && subscription.account == null && !isSubscriptionPreviewTrialExpired(subscription)) { + const startTrial = { title: 'Continue' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nDo you want to continue to get immediate access to preview local Pro features for 3 days?`, + { modal: true }, + startTrial, + cancel, + ); + + if (result !== startTrial) return false; + + void container.subscription.startPreviewTrial(source); + break; + } else if (subscription.account == null) { + const signUp = { title: 'Try GitLens Pro' }; + const signIn = { title: 'Sign In' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nDo you want to start your free ${proTrialLengthInDays}-day Pro trial for full access to all GitLens Pro features?`, + { modal: true }, + signUp, + signIn, + cancel, + ); + + if (result === signUp || result === signIn) { + if (await container.subscription.loginOrSignUp(result === signUp, source)) { + continue; + } + } + } else { + const upgrade = { title: 'Upgrade to Pro' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nDo you want to upgrade for full access to all GitLens Pro features?`, + { modal: true }, + upgrade, + cancel, + ); + + if (result === upgrade) { + void container.subscription.upgrade(source); + } + } + + return false; + } + + return true; +} diff --git a/src/plus/gk/checkin.ts b/src/plus/gk/utils/checkin.utils.ts similarity index 80% rename from src/plus/gk/checkin.ts rename to src/plus/gk/utils/checkin.utils.ts index 9d4bbf031c03f..ff7d1e542a44f 100644 --- a/src/plus/gk/checkin.ts +++ b/src/plus/gk/utils/checkin.utils.ts @@ -1,58 +1,8 @@ -import { SubscriptionPlanId } from '../../constants.subscription'; -import type { Organization } from './account/organization'; -import type { Subscription } from './account/subscription'; -import { getSubscriptionPlan, getSubscriptionPlanPriority } from './account/subscription'; - -export type GKLicenses = Partial>; - -export interface GKCheckInResponse { - readonly user: GKUser; - readonly licenses: { - readonly paidLicenses: GKLicenses; - readonly effectiveLicenses: GKLicenses; - }; - readonly nextOptInDate?: string; -} - -export interface GKUser { - readonly id: string; - readonly name: string; - readonly email: string; - readonly status: 'activated' | 'pending'; - readonly createdDate: string; - readonly firstGitLensCheckIn?: string; -} - -export interface GKLicense { - readonly latestStatus: 'active' | 'canceled' | 'cancelled' | 'expired' | 'in_trial' | 'non_renewing' | 'trial'; - readonly latestStartDate: string; - readonly latestEndDate: string; - readonly organizationId: string | undefined; - readonly reactivationCount?: number; - readonly nextOptInDate?: string; -} - -export type GKLicenseType = - | 'gitlens-pro' - | 'gitlens-teams' - | 'gitlens-hosted-enterprise' - | 'gitlens-self-hosted-enterprise' - | 'gitlens-standalone-enterprise' - | 'bundle-pro' - | 'bundle-teams' - | 'bundle-hosted-enterprise' - | 'bundle-self-hosted-enterprise' - | 'bundle-standalone-enterprise' - | 'gitkraken_v1-pro' - | 'gitkraken_v1-teams' - | 'gitkraken_v1-hosted-enterprise' - | 'gitkraken_v1-self-hosted-enterprise' - | 'gitkraken_v1-standalone-enterprise' - | 'gitkraken-v1-pro' - | 'gitkraken-v1-teams' - | 'gitkraken-v1-hosted-enterprise' - | 'gitkraken-v1-self-hosted-enterprise' - | 'gitkraken-v1-standalone-enterprise'; +import { SubscriptionPlanId } from '../../../constants.subscription'; +import type { GKCheckInResponse, GKLicense, GKLicenseType } from '../models/checkin'; +import type { Organization } from '../models/organization'; +import type { Subscription } from '../models/subscription'; +import { getSubscriptionPlan, getSubscriptionPlanPriority } from './subscription.utils'; export function getSubscriptionFromCheckIn( data: GKCheckInResponse, @@ -201,7 +151,6 @@ export function getSubscriptionFromCheckIn( activeOrganization: activeOrganization, }; } - function convertLicenseTypeToPlanId(licenseType: GKLicenseType): SubscriptionPlanId { switch (licenseType) { case 'gitlens-pro': @@ -231,7 +180,6 @@ function convertLicenseTypeToPlanId(licenseType: GKLicenseType): SubscriptionPla return SubscriptionPlanId.CommunityWithAccount; } } - function isBundleLicenseType(licenseType: GKLicenseType): boolean { switch (licenseType) { case 'bundle-pro': @@ -244,7 +192,6 @@ function isBundleLicenseType(licenseType: GKLicenseType): boolean { return false; } } - function licenseStatusPriority(status: GKLicense['latestStatus']): number { switch (status) { case 'active': diff --git a/src/plus/gk/account/promos.ts b/src/plus/gk/utils/promo.utils.ts similarity index 83% rename from src/plus/gk/account/promos.ts rename to src/plus/gk/utils/promo.utils.ts index fd7a581ab8069..d521ec9597ed5 100644 --- a/src/plus/gk/account/promos.ts +++ b/src/plus/gk/utils/promo.utils.ts @@ -1,22 +1,6 @@ import type { PromoKeys } from '../../../constants.subscription'; import { SubscriptionState } from '../../../constants.subscription'; - -export type PromoLocation = 'account' | 'badge' | 'gate' | 'home'; - -export interface Promo { - readonly key: PromoKeys; - readonly code?: string; - readonly states?: SubscriptionState[]; - readonly expiresOn?: number; - readonly startsOn?: number; - - readonly command?: { - command?: `command:${string}`; - tooltip: string; - }; - readonly locations?: PromoLocation[]; - readonly quickpick: { detail: string }; -} +import type { Promo, PromoLocation } from '../models/promo'; // Must be ordered by applicable order const promos: Promo[] = [ diff --git a/src/plus/gk/account/subscription.ts b/src/plus/gk/utils/subscription.utils.ts similarity index 85% rename from src/plus/gk/account/subscription.ts rename to src/plus/gk/utils/subscription.utils.ts index b2612e7c7a176..c2693ef06e906 100644 --- a/src/plus/gk/account/subscription.ts +++ b/src/plus/gk/utils/subscription.utils.ts @@ -1,61 +1,10 @@ -// NOTE@eamodio This file is referenced in the webviews to we can't use anything vscode or other imports that aren't available in the webviews import type { SubscriptionStateString } from '../../../constants.subscription'; import { SubscriptionPlanId, SubscriptionState } from '../../../constants.subscription'; import { createFromDateDelta, getDateDifference } from '../../../system/date'; -import type { Organization } from './organization'; +import type { PaidSubscriptionPlans, Subscription, SubscriptionPlan } from '../models/subscription'; export const SubscriptionUpdatedUriPathPrefix = 'did-update-subscription'; -export type FreeSubscriptionPlans = Extract< - SubscriptionPlanId, - SubscriptionPlanId.Community | SubscriptionPlanId.CommunityWithAccount ->; -export type PaidSubscriptionPlans = Exclude< - SubscriptionPlanId, - SubscriptionPlanId.Community | SubscriptionPlanId.CommunityWithAccount ->; -export type RequiredSubscriptionPlans = Exclude; - -export interface Subscription { - readonly plan: { - readonly actual: SubscriptionPlan; - readonly effective: SubscriptionPlan; - }; - account: SubscriptionAccount | undefined; - previewTrial?: SubscriptionPreviewTrial; - - state: SubscriptionState; - - lastValidatedAt?: number; - - readonly activeOrganization?: Organization; -} - -export interface SubscriptionPlan { - readonly id: SubscriptionPlanId; - readonly name: string; - readonly bundle: boolean; - readonly trialReactivationCount: number; - readonly nextTrialOptInDate?: string | undefined; - readonly cancelled: boolean; - readonly startedOn: string; - readonly expiresOn?: string | undefined; - readonly organizationId: string | undefined; -} - -export interface SubscriptionAccount { - readonly id: string; - readonly name: string; - readonly email: string | undefined; - readonly verified: boolean; - readonly createdOn: string; -} - -export interface SubscriptionPreviewTrial { - readonly startedOn: string; - readonly expiresOn: string; -} - export function getSubscriptionStateName(state: SubscriptionState, planId?: SubscriptionPlanId) { switch (state) { case SubscriptionState.Community: @@ -193,7 +142,6 @@ export function getSubscriptionPlanTier(id: SubscriptionPlanId) { return 'Community'; } } - const plansPriority = new Map([ [undefined, -1], [SubscriptionPlanId.Community, 0], diff --git a/src/plus/graph/statusbar.ts b/src/plus/graph/statusbar.ts index 23aeebc768efa..7c5ed60ce09cc 100644 --- a/src/plus/graph/statusbar.ts +++ b/src/plus/graph/statusbar.ts @@ -2,11 +2,11 @@ import type { ConfigurationChangeEvent, StatusBarItem } from 'vscode'; import { Disposable, MarkdownString, StatusBarAlignment, window } from 'vscode'; import { GlCommand } from '../../constants.commands'; import type { Container } from '../../container'; +import { configuration } from '../../system/-webview/configuration'; +import { getContext, onDidChangeContext } from '../../system/-webview/context'; import { once } from '../../system/function'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext, onDidChangeContext } from '../../system/vscode/context'; -import type { SubscriptionChangeEvent } from '../gk/account/subscriptionService'; -import { arePlusFeaturesEnabled } from '../gk/utils'; +import type { SubscriptionChangeEvent } from '../gk/subscriptionService'; +import { arePlusFeaturesEnabled } from '../gk/utils/-webview/plus.utils'; export class GraphStatusBarController implements Disposable { private readonly _disposable: Disposable; diff --git a/src/plus/integrations/authentication/integrationAuthentication.ts b/src/plus/integrations/authentication/integrationAuthentication.ts index 880489210fc55..ed3a69a7e8267 100644 --- a/src/plus/integrations/authentication/integrationAuthentication.ts +++ b/src/plus/integrations/authentication/integrationAuthentication.ts @@ -6,7 +6,7 @@ import { HostingIntegrationId, IssueIntegrationId, SelfHostedIntegrationId } fro import type { IntegrationAuthenticationKeys, StoredConfiguredIntegrationDescriptor } from '../../../constants.storage'; import type { Sources } from '../../../constants.telemetry'; import type { Container } from '../../../container'; -import { gate } from '../../../system/decorators/gate'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug, log } from '../../../system/decorators/log'; import type { DeferredEventExecutor } from '../../../system/event'; import { isSelfHostedIntegrationId, supportedIntegrationIds } from '../providers/models'; diff --git a/src/plus/integrations/authentication/models.ts b/src/plus/integrations/authentication/models.ts index 784fe986ab17e..9d0e637d94740 100644 --- a/src/plus/integrations/authentication/models.ts +++ b/src/plus/integrations/authentication/models.ts @@ -7,7 +7,7 @@ import { supportedOrderedCloudIntegrationIds, supportedOrderedCloudIssueIntegrationIds, } from '../../../constants.integrations'; -import { configuration } from '../../../system/vscode/configuration'; +import { configuration } from '../../../system/-webview/configuration'; export interface ProviderAuthenticationSession extends AuthenticationSession { readonly cloud: boolean; diff --git a/src/plus/integrations/integration.ts b/src/plus/integrations/integration.ts index bbef057b30676..550b62ac4aac4 100644 --- a/src/plus/integrations/integration.ts +++ b/src/plus/integrations/integration.ts @@ -9,24 +9,25 @@ import { AuthenticationError, CancellationError, RequestClientError } from '../. import type { PagedResult } from '../../git/gitProvider'; import type { Account, UnidentifiedAuthor } from '../../git/models/author'; import type { DefaultBranch } from '../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../git/models/issue'; +import type { IssueOrPullRequest } from '../../git/models/issueOrPullRequest'; import type { PullRequest, PullRequestMergeMethod, PullRequestState, SearchedPullRequest, } from '../../git/models/pullRequest'; -import type { PullRequestUrlIdentity } from '../../git/models/pullRequest.utils'; import type { RepositoryMetadata } from '../../git/models/repositoryMetadata'; +import type { PullRequestUrlIdentity } from '../../git/utils/pullRequest.utils'; import { showIntegrationDisconnectedTooManyFailedRequestsWarningMessage } from '../../messages'; -import { gate } from '../../system/decorators/gate'; +import { configuration } from '../../system/-webview/configuration'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { first } from '../../system/iterable'; import { Logger } from '../../system/logger'; import type { LogScope } from '../../system/logger.scope'; import { getLogScope } from '../../system/logger.scope'; -import { configuration } from '../../system/vscode/configuration'; -import { isSubscriptionStatePaidOrTrial } from '../gk/account/subscription'; +import { isSubscriptionStatePaidOrTrial } from '../gk/utils/subscription.utils'; import type { IntegrationAuthenticationProviderDescriptor, IntegrationAuthenticationService, diff --git a/src/plus/integrations/integrationService.ts b/src/plus/integrations/integrationService.ts index 3c01dfba9a904..4ed7d3dc5b2fb 100644 --- a/src/plus/integrations/integrationService.ts +++ b/src/plus/integrations/integrationService.ts @@ -11,15 +11,15 @@ import type { SearchedIssue } from '../../git/models/issue'; import type { SearchedPullRequest } from '../../git/models/pullRequest'; import type { GitRemote } from '../../git/models/remote'; import type { RemoteProvider, RemoteProviderId } from '../../git/remotes/remoteProvider'; -import { gate } from '../../system/decorators/gate'; +import { configuration } from '../../system/-webview/configuration'; +import { openUrl } from '../../system/-webview/utils'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { promisifyDeferred, take } from '../../system/event'; import { filter, filterMap, flatten, join } from '../../system/iterable'; import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; -import { configuration } from '../../system/vscode/configuration'; -import { openUrl } from '../../system/vscode/utils'; -import type { SubscriptionChangeEvent } from '../gk/account/subscriptionService'; +import type { SubscriptionChangeEvent } from '../gk/subscriptionService'; import type { IntegrationAuthenticationService } from './authentication/integrationAuthentication'; import type { ConfiguredIntegrationDescriptor } from './authentication/models'; import { diff --git a/src/plus/integrations/providers/azureDevOps.ts b/src/plus/integrations/providers/azureDevOps.ts index 30f860058df37..33ed8583d3d72 100644 --- a/src/plus/integrations/providers/azureDevOps.ts +++ b/src/plus/integrations/providers/azureDevOps.ts @@ -3,7 +3,8 @@ import { HostingIntegrationId } from '../../../constants.integrations'; import type { PagedResult } from '../../../git/gitProvider'; import type { Account } from '../../../git/models/author'; import type { DefaultBranch } from '../../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import type { PullRequest, PullRequestMergeMethod, diff --git a/src/plus/integrations/providers/bitbucket.ts b/src/plus/integrations/providers/bitbucket.ts index 7903857fa47e6..2ec856465b5da 100644 --- a/src/plus/integrations/providers/bitbucket.ts +++ b/src/plus/integrations/providers/bitbucket.ts @@ -2,7 +2,8 @@ import type { AuthenticationSession, CancellationToken } from 'vscode'; import { HostingIntegrationId } from '../../../constants.integrations'; import type { Account } from '../../../git/models/author'; import type { DefaultBranch } from '../../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import type { PullRequest, PullRequestMergeMethod, diff --git a/src/plus/integrations/providers/github.ts b/src/plus/integrations/providers/github.ts index 9050526a555e6..d9389d6774ace 100644 --- a/src/plus/integrations/providers/github.ts +++ b/src/plus/integrations/providers/github.ts @@ -4,17 +4,18 @@ import type { Sources } from '../../../constants.telemetry'; import type { Container } from '../../../container'; import type { Account, UnidentifiedAuthor } from '../../../git/models/author'; import type { DefaultBranch } from '../../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import type { PullRequest, PullRequestMergeMethod, PullRequestState, SearchedPullRequest, } from '../../../git/models/pullRequest'; -import type { PullRequestUrlIdentity } from '../../../git/models/pullRequest.utils'; import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata'; +import type { PullRequestUrlIdentity } from '../../../git/utils/pullRequest.utils'; import { log } from '../../../system/decorators/log'; -import { ensurePaidPlan } from '../../utils'; +import { ensurePaidPlan } from '../../gk/utils/-webview/plus.utils'; import type { IntegrationAuthenticationProviderDescriptor, IntegrationAuthenticationService, diff --git a/src/plus/integrations/providers/github/github.ts b/src/plus/integrations/providers/github/github.ts index 0d7a0b0b5c026..c6dcc7d4df8c4 100644 --- a/src/plus/integrations/providers/github/github.ts +++ b/src/plus/integrations/providers/github/github.ts @@ -19,24 +19,26 @@ import { import type { PagedResult, RepositoryVisibility } from '../../../../git/gitProvider'; import type { Account, UnidentifiedAuthor } from '../../../../git/models/author'; import type { DefaultBranch } from '../../../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../../git/models/issueOrPullRequest'; import type { PullRequest, SearchedPullRequest } from '../../../../git/models/pullRequest'; import { PullRequestMergeMethod } from '../../../../git/models/pullRequest'; import type { Provider } from '../../../../git/models/remoteProvider'; import type { RepositoryMetadata } from '../../../../git/models/repositoryMetadata'; import type { GitRevisionRange } from '../../../../git/models/revision'; +import type { GitUser } from '../../../../git/models/user'; +import { getGitHubNoReplyAddressParts } from '../../../../git/remotes/github'; import { createRevisionRange, getRevisionRangeParts, isRevisionRange, isSha, -} from '../../../../git/models/revision.utils'; -import type { GitUser } from '../../../../git/models/user'; -import { getGitHubNoReplyAddressParts } from '../../../../git/remotes/github'; +} from '../../../../git/utils/revision.utils'; import { showIntegrationRequestFailed500WarningMessage, showIntegrationRequestTimedOutWarningMessage, } from '../../../../messages'; +import { configuration } from '../../../../system/-webview/configuration'; import { debug } from '../../../../system/decorators/log'; import { uniqueBy } from '../../../../system/iterable'; import { Logger } from '../../../../system/logger'; @@ -46,7 +48,6 @@ import { maybeStopWatch } from '../../../../system/stopwatch'; import { base64 } from '../../../../system/string'; import type { Version } from '../../../../system/version'; import { fromString, satisfies } from '../../../../system/version'; -import { configuration } from '../../../../system/vscode/configuration'; import type { GitHubBlame, GitHubBlameRange, diff --git a/src/plus/integrations/providers/github/github.utils.ts b/src/plus/integrations/providers/github/github.utils.ts index 1d375b650ee75..51213f2ea48d2 100644 --- a/src/plus/integrations/providers/github/github.utils.ts +++ b/src/plus/integrations/providers/github/github.utils.ts @@ -3,7 +3,7 @@ // don't require Container and can be tested. import { HostingIntegrationId } from '../../../../constants.integrations'; -import type { PullRequestUrlIdentity } from '../../../../git/models/pullRequest.utils'; +import type { PullRequestUrlIdentity } from '../../../../git/utils/pullRequest.utils'; export function isMaybeGitHubPullRequestUrl(url: string): boolean { if (url == null) return false; diff --git a/src/plus/integrations/providers/github/githubGitProvider.ts b/src/plus/integrations/providers/github/githubGitProvider.ts index 90a0ca21821d7..d31034765bae8 100644 --- a/src/plus/integrations/providers/github/githubGitProvider.ts +++ b/src/plus/integrations/providers/github/githubGitProvider.ts @@ -41,13 +41,12 @@ import { GitUri } from '../../../../git/gitUri'; import { decodeRemoteHubAuthority } from '../../../../git/gitUri.authority'; import type { GitBlame, GitBlameAuthor, GitBlameLine } from '../../../../git/models/blame'; import type { GitBranch } from '../../../../git/models/branch'; -import { getBranchId, getBranchNameWithoutRemote } from '../../../../git/models/branch.utils'; import type { GitCommitLine, GitStashCommit } from '../../../../git/models/commit'; import { GitCommit, GitCommitIdentity } from '../../../../git/models/commit'; -import { getChangedFilesCount } from '../../../../git/models/commit.utils'; import type { GitDiffFile, GitDiffFilter, GitDiffLine, GitDiffShortStat } from '../../../../git/models/diff'; import type { GitFile } from '../../../../git/models/file'; -import { GitFileChange, GitFileIndexStatus } from '../../../../git/models/file'; +import { GitFileChange } from '../../../../git/models/fileChange'; +import { GitFileIndexStatus } from '../../../../git/models/fileStatus'; import type { GitGraph, GitGraphRow, @@ -59,14 +58,23 @@ import type { } from '../../../../git/models/graph'; import type { GitLog } from '../../../../git/models/log'; import type { GitReference } from '../../../../git/models/reference'; -import { createReference } from '../../../../git/models/reference.utils'; import type { GitReflog } from '../../../../git/models/reflog'; import type { GitRemote } from '../../../../git/models/remote'; -import { getVisibilityCacheKey } from '../../../../git/models/remote'; import type { RepositoryChangeEvent } from '../../../../git/models/repository'; import { Repository } from '../../../../git/models/repository'; import type { GitRevisionRange } from '../../../../git/models/revision'; import { deletedOrMissing, uncommitted } from '../../../../git/models/revision'; +import type { GitTag } from '../../../../git/models/tag'; +import type { GitTreeEntry } from '../../../../git/models/tree'; +import type { GitUser } from '../../../../git/models/user'; +import type { GitWorktree } from '../../../../git/models/worktree'; +import type { GitSearch, GitSearchResultData, GitSearchResults } from '../../../../git/search'; +import { getSearchQueryComparisonKey, parseSearchQuery } from '../../../../git/search'; +import { getRemoteIconUri } from '../../../../git/utils/-webview/icons'; +import { getBranchId, getBranchNameWithoutRemote } from '../../../../git/utils/branch.utils'; +import { getChangedFilesCount } from '../../../../git/utils/commit.utils'; +import { createReference } from '../../../../git/utils/reference.utils'; +import { getVisibilityCacheKey } from '../../../../git/utils/remote.utils'; import { createRevisionRange, getRevisionRangeParts, @@ -74,16 +82,12 @@ import { isSha, isShaLike, isUncommitted, -} from '../../../../git/models/revision.utils'; -import type { GitTag } from '../../../../git/models/tag'; -import { getTagId } from '../../../../git/models/tag'; -import type { GitTreeEntry } from '../../../../git/models/tree'; -import type { GitUser } from '../../../../git/models/user'; -import type { GitWorktree } from '../../../../git/models/worktree'; -import type { GitSearch, GitSearchResultData, GitSearchResults } from '../../../../git/search'; -import { getSearchQueryComparisonKey, parseSearchQuery } from '../../../../git/search'; -import { getRemoteIconUri } from '../../../../git/utils/vscode/icons'; -import { gate } from '../../../../system/decorators/gate'; +} from '../../../../git/utils/revision.utils'; +import { getTagId } from '../../../../git/utils/tag.utils'; +import { configuration } from '../../../../system/-webview/configuration'; +import { setContext } from '../../../../system/-webview/context'; +import { relative } from '../../../../system/-webview/path'; +import { gate } from '../../../../system/decorators/-webview/gate'; import { debug, log } from '../../../../system/decorators/log'; import { filterMap, first, last, map, some, union } from '../../../../system/iterable'; import { Logger } from '../../../../system/logger'; @@ -91,9 +95,6 @@ import type { LogScope } from '../../../../system/logger.scope'; import { getLogScope } from '../../../../system/logger.scope'; import { isAbsolute, isFolderGlob, maybeUri, normalizePath } from '../../../../system/path'; import { asSettled, getSettledValue } from '../../../../system/promise'; -import { configuration } from '../../../../system/vscode/configuration'; -import { setContext } from '../../../../system/vscode/context'; -import { relative } from '../../../../system/vscode/path'; import { serializeWebviewItemContext } from '../../../../system/webview'; import type { CachedBlame, CachedLog, TrackedGitDocument } from '../../../../trackers/trackedDocument'; import { GitDocumentState } from '../../../../trackers/trackedDocument'; @@ -596,7 +597,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { c.message.split('\n', 1)[0], c.parents.nodes[0]?.oid ? [c.parents.nodes[0]?.oid] : [], c.message, - new GitFileChange(root.toString(), relativePath, GitFileIndexStatus.Modified), + new GitFileChange(this.container, root.toString(), relativePath, GitFileIndexStatus.Modified), { files: c.changedFiles ?? 0, additions: c.additions ?? 0, deletions: c.deletions ?? 0 }, [], ); @@ -721,7 +722,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { c.message.split('\n', 1)[0], c.parents.nodes[0]?.oid ? [c.parents.nodes[0]?.oid] : [], c.message, - new GitFileChange(root.toString(), relativePath, GitFileIndexStatus.Modified), + new GitFileChange(this.container, root.toString(), relativePath, GitFileIndexStatus.Modified), { files: c.changedFiles ?? 0, additions: c.additions ?? 0, deletions: c.deletions ?? 0 }, [], ); @@ -875,6 +876,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { commit.files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, @@ -953,6 +955,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { const files = commit.files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, @@ -1564,6 +1567,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { return files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, @@ -1665,6 +1669,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { commit.files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, @@ -2031,6 +2036,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { const files = commit.files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, @@ -2043,6 +2049,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { ? undefined : files?.find(f => f.path === relativePath) ?? new GitFileChange( + this.container, repoPath, relativePath, GitFileIndexStatus.Modified, @@ -2647,6 +2654,7 @@ export class GitHubGitProvider implements GitProvider, Disposable { commit.files?.map( f => new GitFileChange( + this.container, repoPath, f.filename ?? '', fromCommitFileStatus(f.status) ?? GitFileIndexStatus.Modified, diff --git a/src/plus/integrations/providers/github/models.ts b/src/plus/integrations/providers/github/models.ts index c52bb32dfdf06..1d9f99f15a4ba 100644 --- a/src/plus/integrations/providers/github/models.ts +++ b/src/plus/integrations/providers/github/models.ts @@ -1,5 +1,5 @@ import type { Endpoints } from '@octokit/types'; -import { GitFileIndexStatus } from '../../../../git/models/file'; +import { GitFileIndexStatus } from '../../../../git/models/fileStatus'; import type { IssueLabel } from '../../../../git/models/issue'; import { Issue, RepositoryAccessLevel } from '../../../../git/models/issue'; import type { PullRequestState } from '../../../../git/models/pullRequest'; diff --git a/src/plus/integrations/providers/github/sub-providers/branches.ts b/src/plus/integrations/providers/github/sub-providers/branches.ts index f46295a753369..46c0494276d8f 100644 --- a/src/plus/integrations/providers/github/sub-providers/branches.ts +++ b/src/plus/integrations/providers/github/sub-providers/branches.ts @@ -7,14 +7,14 @@ import type { PagingOptions, } from '../../../../../git/gitProvider'; import { GitBranch } from '../../../../../git/models/branch'; -import { createRevisionRange } from '../../../../../git/models/revision.utils'; -import type { BranchSortOptions } from '../../../../../git/utils/vscode/sorting'; -import { sortBranches, sortContributors } from '../../../../../git/utils/vscode/sorting'; -import { gate } from '../../../../../system/decorators/gate'; +import type { BranchSortOptions } from '../../../../../git/utils/-webview/sorting'; +import { sortBranches, sortContributors } from '../../../../../git/utils/-webview/sorting'; +import { createRevisionRange } from '../../../../../git/utils/revision.utils'; +import { configuration } from '../../../../../system/-webview/configuration'; +import { gate } from '../../../../../system/decorators/-webview/gate'; import { log } from '../../../../../system/decorators/log'; import { Logger } from '../../../../../system/logger'; import { getLogScope } from '../../../../../system/logger.scope'; -import { configuration } from '../../../../../system/vscode/configuration'; import { HeadType } from '../../../../remotehub'; import type { GitHubGitProviderInternal } from '../githubGitProvider'; import { stripOrigin } from '../githubGitProvider'; diff --git a/src/plus/integrations/providers/github/sub-providers/contributors.ts b/src/plus/integrations/providers/github/sub-providers/contributors.ts index 5eca621a98321..b8d13a10badff 100644 --- a/src/plus/integrations/providers/github/sub-providers/contributors.ts +++ b/src/plus/integrations/providers/github/sub-providers/contributors.ts @@ -3,7 +3,7 @@ import type { GitCache } from '../../../../../git/cache'; import type { GitContributorsSubProvider } from '../../../../../git/gitProvider'; import type { GitContributorStats } from '../../../../../git/models/contributor'; import { GitContributor } from '../../../../../git/models/contributor'; -import { isUserMatch } from '../../../../../git/models/user'; +import { isUserMatch } from '../../../../../git/utils/user.utils'; import { log } from '../../../../../system/decorators/log'; import { Logger } from '../../../../../system/logger'; import { getLogScope } from '../../../../../system/logger.scope'; diff --git a/src/plus/integrations/providers/github/sub-providers/remotes.ts b/src/plus/integrations/providers/github/sub-providers/remotes.ts index 80adca4a70b6e..b319e33c6ee85 100644 --- a/src/plus/integrations/providers/github/sub-providers/remotes.ts +++ b/src/plus/integrations/providers/github/sub-providers/remotes.ts @@ -2,8 +2,8 @@ import { Uri } from 'vscode'; import { GitRemote } from '../../../../../git/models/remote'; import { getRemoteProviderMatcher, loadRemoteProviders } from '../../../../../git/remotes/remoteProviders'; import { RemotesGitProviderBase } from '../../../../../git/sub-providers/remotes'; +import { configuration } from '../../../../../system/-webview/configuration'; import { log } from '../../../../../system/decorators/log'; -import { configuration } from '../../../../../system/vscode/configuration'; export class RemotesGitSubProvider extends RemotesGitProviderBase { @log({ args: { 1: false } }) diff --git a/src/plus/integrations/providers/github/sub-providers/status.ts b/src/plus/integrations/providers/github/sub-providers/status.ts index 4feae103ecd6a..8f58d71d32b37 100644 --- a/src/plus/integrations/providers/github/sub-providers/status.ts +++ b/src/plus/integrations/providers/github/sub-providers/status.ts @@ -1,7 +1,7 @@ import type { Container } from '../../../../../container'; import type { GitStatusSubProvider } from '../../../../../git/gitProvider'; import { GitStatus } from '../../../../../git/models/status'; -import { gate } from '../../../../../system/decorators/gate'; +import { gate } from '../../../../../system/decorators/-webview/gate'; import { log } from '../../../../../system/decorators/log'; import { HeadType } from '../../../../remotehub'; import type { GitHubGitProviderInternal } from '../githubGitProvider'; @@ -24,6 +24,7 @@ export class StatusGitSubProvider implements GitStatusSubProvider { if (revision == null) return undefined; return new GitStatus( + this.container, repoPath, revision.name, revision.revision, diff --git a/src/plus/integrations/providers/github/sub-providers/tags.ts b/src/plus/integrations/providers/github/sub-providers/tags.ts index 2c4990a10a56e..72c9c955debcb 100644 --- a/src/plus/integrations/providers/github/sub-providers/tags.ts +++ b/src/plus/integrations/providers/github/sub-providers/tags.ts @@ -2,8 +2,8 @@ import type { Container } from '../../../../../container'; import type { GitCache } from '../../../../../git/cache'; import type { GitTagsSubProvider, PagedResult, PagingOptions } from '../../../../../git/gitProvider'; import { GitTag } from '../../../../../git/models/tag'; -import type { TagSortOptions } from '../../../../../git/utils/vscode/sorting'; -import { sortTags } from '../../../../../git/utils/vscode/sorting'; +import type { TagSortOptions } from '../../../../../git/utils/-webview/sorting'; +import { sortTags } from '../../../../../git/utils/-webview/sorting'; import { log } from '../../../../../system/decorators/log'; import { Logger } from '../../../../../system/logger'; import { getLogScope } from '../../../../../system/logger.scope'; @@ -69,6 +69,7 @@ export class TagsGitSubProvider implements GitTagsSubProvider { tags.push( new GitTag( + this.container, repoPath!, tag.name, tag.target.target?.oid ?? tag.target.oid, diff --git a/src/plus/integrations/providers/gitlab.ts b/src/plus/integrations/providers/gitlab.ts index d55c822da502c..f090888b7727f 100644 --- a/src/plus/integrations/providers/gitlab.ts +++ b/src/plus/integrations/providers/gitlab.ts @@ -5,18 +5,19 @@ import type { Sources } from '../../../constants.telemetry'; import type { Container } from '../../../container'; import type { Account } from '../../../git/models/author'; import type { DefaultBranch } from '../../../git/models/defaultBranch'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import type { PullRequest, PullRequestMergeMethod, PullRequestState, SearchedPullRequest, } from '../../../git/models/pullRequest'; -import type { PullRequestUrlIdentity } from '../../../git/models/pullRequest.utils'; import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata'; +import type { PullRequestUrlIdentity } from '../../../git/utils/pullRequest.utils'; import { log } from '../../../system/decorators/log'; import { uniqueBy } from '../../../system/iterable'; -import { ensurePaidPlan } from '../../utils'; +import { ensurePaidPlan } from '../../gk/utils/-webview/plus.utils'; import type { IntegrationAuthenticationProviderDescriptor, IntegrationAuthenticationService, diff --git a/src/plus/integrations/providers/gitlab/gitlab.ts b/src/plus/integrations/providers/gitlab/gitlab.ts index cba9ab433a586..38cf2619342b6 100644 --- a/src/plus/integrations/providers/gitlab/gitlab.ts +++ b/src/plus/integrations/providers/gitlab/gitlab.ts @@ -16,7 +16,7 @@ import { } from '../../../../errors'; import type { Account } from '../../../../git/models/author'; import type { DefaultBranch } from '../../../../git/models/defaultBranch'; -import type { IssueOrPullRequest } from '../../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../../git/models/issueOrPullRequest'; import { PullRequest } from '../../../../git/models/pullRequest'; import type { Provider } from '../../../../git/models/remoteProvider'; import type { RepositoryMetadata } from '../../../../git/models/repositoryMetadata'; @@ -24,13 +24,13 @@ import { showIntegrationRequestFailed500WarningMessage, showIntegrationRequestTimedOutWarningMessage, } from '../../../../messages'; +import { configuration } from '../../../../system/-webview/configuration'; import { debug } from '../../../../system/decorators/log'; import { Logger } from '../../../../system/logger'; import type { LogScope } from '../../../../system/logger.scope'; import { getLogScope, setLogScopeExit } from '../../../../system/logger.scope'; import { maybeStopWatch } from '../../../../system/stopwatch'; import { equalsIgnoreCase } from '../../../../system/string'; -import { configuration } from '../../../../system/vscode/configuration'; import type { GitLabCommit, GitLabIssue, diff --git a/src/plus/integrations/providers/gitlab/gitlab.utils.ts b/src/plus/integrations/providers/gitlab/gitlab.utils.ts index a4f3c308bacfa..e3757895d664b 100644 --- a/src/plus/integrations/providers/gitlab/gitlab.utils.ts +++ b/src/plus/integrations/providers/gitlab/gitlab.utils.ts @@ -3,7 +3,7 @@ // don't require Container and can be tested. import { HostingIntegrationId } from '../../../../constants.integrations'; -import type { PullRequestUrlIdentity } from '../../../../git/models/pullRequest.utils'; +import type { PullRequestUrlIdentity } from '../../../../git/utils/pullRequest.utils'; export function isMaybeGitLabPullRequestUrl(url: string): boolean { return getGitLabPullRequestIdentityFromMaybeUrl(url) != null; diff --git a/src/plus/integrations/providers/jira.ts b/src/plus/integrations/providers/jira.ts index b0835339b7f45..ef6f951bd40f3 100644 --- a/src/plus/integrations/providers/jira.ts +++ b/src/plus/integrations/providers/jira.ts @@ -2,7 +2,8 @@ import type { AuthenticationSession, CancellationToken } from 'vscode'; import type { AutolinkReference, DynamicAutolinkReference } from '../../../autolinks'; import { IssueIntegrationId } from '../../../constants.integrations'; import type { Account } from '../../../git/models/author'; -import type { Issue, IssueOrPullRequest, SearchedIssue } from '../../../git/models/issue'; +import type { Issue, SearchedIssue } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import { filterMap, flatten } from '../../../system/iterable'; import { Logger } from '../../../system/logger'; import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthentication'; diff --git a/src/plus/integrations/providers/models.ts b/src/plus/integrations/providers/models.ts index 16e3183079127..c83caa6f4fe0a 100644 --- a/src/plus/integrations/providers/models.ts +++ b/src/plus/integrations/providers/models.ts @@ -52,7 +52,7 @@ import { PullRequestStatusCheckRollupState, } from '../../../git/models/pullRequest'; import type { ProviderReference } from '../../../git/models/remoteProvider'; -import type { EnrichableItem } from '../../launchpad/enrichmentService'; +import type { EnrichableItem } from '../../launchpad/models/enrichedItem'; import type { Integration } from '../integration'; import { getEntityIdentifierInput } from './utils'; diff --git a/src/plus/integrations/providers/utils.ts b/src/plus/integrations/providers/utils.ts index 2584aa310d627..e269030086f94 100644 --- a/src/plus/integrations/providers/utils.ts +++ b/src/plus/integrations/providers/utils.ts @@ -3,7 +3,8 @@ import { EntityIdentifierProviderType, EntityType, EntityVersion } from '@gitkra import type { IntegrationId } from '../../../constants.integrations'; import { HostingIntegrationId, IssueIntegrationId, SelfHostedIntegrationId } from '../../../constants.integrations'; import type { Container } from '../../../container'; -import type { Issue, IssueOrPullRequest, IssueShape } from '../../../git/models/issue'; +import type { Issue, IssueShape } from '../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest'; import type { PullRequest } from '../../../git/models/pullRequest'; import { Logger } from '../../../system/logger'; import { equalsIgnoreCase } from '../../../system/string'; diff --git a/src/plus/launchpad/enrichmentService.ts b/src/plus/launchpad/enrichmentService.ts index 62d8d2e8ad1db..5d9571f556332 100644 --- a/src/plus/launchpad/enrichmentService.ts +++ b/src/plus/launchpad/enrichmentService.ts @@ -6,30 +6,8 @@ import { log } from '../../system/decorators/log'; import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; import type { ServerConnection } from '../gk/serverConnection'; -import { ensureAccount } from '../utils'; - -export interface EnrichableItem { - type: EnrichedItemResponse['entityType']; - id: string; - provider: EnrichedItemResponse['provider']; - url: string; - expiresAt?: string; -} - -export type EnrichedItem = { - id: string; - userId?: string; - type: EnrichedItemResponse['type']; - - provider: EnrichedItemResponse['provider']; - entityType: EnrichedItemResponse['entityType']; - entityId: string; - entityUrl: string; - - createdAt: string; - updatedAt: string; - expiresAt?: string; -}; +import { ensureAccount } from '../gk/utils/-webview/acount.utils'; +import type { EnrichableItem, EnrichedItem, EnrichedItemResponse } from './models/enrichedItem'; type EnrichedItemRequest = { provider: EnrichedItemResponse['provider']; @@ -39,21 +17,6 @@ type EnrichedItemRequest = { expiresAt?: string; }; -type EnrichedItemResponse = { - id: string; - userId?: string; - type: 'pin' | 'snooze'; - - provider: 'azure' | 'bitbucket' | 'github' | 'gitlab' | 'jira' | 'trello' | 'gitkraken'; - entityType: 'issue' | 'pr'; - entityId: string; - entityUrl: string; - - createdAt: string; - updatedAt: string; - expiresAt?: string; -}; - export class EnrichmentService implements Disposable { constructor( private readonly container: Container, diff --git a/src/plus/launchpad/launchpad.ts b/src/plus/launchpad/launchpad.ts index ed15afda9c5b9..60a3df301ab11 100644 --- a/src/plus/launchpad/launchpad.ts +++ b/src/plus/launchpad/launchpad.ts @@ -45,14 +45,14 @@ import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import { createQuickPickItemOfT, createQuickPickSeparator } from '../../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive, isDirectiveQuickPickItem } from '../../quickpicks/items/directive'; +import { createAsyncDebouncer } from '../../system/-webview/asyncDebouncer'; +import { executeCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { openUrl } from '../../system/-webview/utils'; import { getScopedCounter } from '../../system/counter'; import { fromNow } from '../../system/date'; import { some } from '../../system/iterable'; import { interpolate, pluralize } from '../../system/string'; -import { createAsyncDebouncer } from '../../system/vscode/asyncDebouncer'; -import { executeCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { openUrl } from '../../system/vscode/utils'; import { ProviderBuildStatusState, ProviderPullRequestReviewState } from '../integrations/providers/models'; import type { LaunchpadCategorizedResult, LaunchpadItem } from './launchpadProvider'; import { @@ -61,8 +61,8 @@ import { groupAndSortLaunchpadItems, supportedLaunchpadIntegrations, } from './launchpadProvider'; -import type { LaunchpadAction, LaunchpadGroup, LaunchpadTargetAction } from './models'; -import { actionGroupMap, launchpadGroupIconMap, launchpadGroupLabelMap, launchpadGroups } from './models'; +import type { LaunchpadAction, LaunchpadGroup, LaunchpadTargetAction } from './models/launchpad'; +import { actionGroupMap, launchpadGroupIconMap, launchpadGroupLabelMap, launchpadGroups } from './models/launchpad'; export interface LaunchpadItemQuickPickItem extends QuickPickItem { readonly type: 'item'; diff --git a/src/plus/launchpad/launchpadIndicator.ts b/src/plus/launchpad/launchpadIndicator.ts index 98973d8442a25..9290cd27a4055 100644 --- a/src/plus/launchpad/launchpadIndicator.ts +++ b/src/plus/launchpad/launchpadIndicator.ts @@ -6,17 +6,17 @@ import type { Colors } from '../../constants.colors'; import { GlCommand } from '../../constants.commands'; import type { HostingIntegrationId } from '../../constants.integrations'; import type { Container } from '../../container'; +import { executeCommand, registerCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; import { groupByMap } from '../../system/iterable'; import { wait } from '../../system/promise'; import { pluralize } from '../../system/string'; -import { executeCommand, registerCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; import type { ConnectionStateChangeEvent } from '../integrations/integrationService'; import type { LaunchpadCommandArgs } from './launchpad'; import type { LaunchpadItem, LaunchpadProvider, LaunchpadRefreshEvent } from './launchpadProvider'; import { groupAndSortLaunchpadItems, supportedLaunchpadIntegrations } from './launchpadProvider'; -import type { LaunchpadGroup } from './models'; -import { launchpadGroupIconMap, launchpadPriorityGroups } from './models'; +import type { LaunchpadGroup } from './models/launchpad'; +import { launchpadGroupIconMap, launchpadPriorityGroups } from './models/launchpad'; type LaunchpadIndicatorState = 'idle' | 'disconnected' | 'loading' | 'load' | 'failed'; diff --git a/src/plus/launchpad/launchpadProvider.ts b/src/plus/launchpad/launchpadProvider.ts index 469aa5af03407..80b70ae67b9cc 100644 --- a/src/plus/launchpad/launchpadProvider.ts +++ b/src/plus/launchpad/launchpadProvider.ts @@ -15,34 +15,32 @@ import { openComparisonChanges } from '../../git/actions/commit'; import type { Account } from '../../git/models/author'; import type { GitBranch } from '../../git/models/branch'; import type { PullRequest, SearchedPullRequest } from '../../git/models/pullRequest'; +import type { GitRemote } from '../../git/models/remote'; +import type { Repository } from '../../git/models/repository'; +import { getOrOpenPullRequestRepository } from '../../git/utils/-webview/pullRequest.utils'; +import type { PullRequestUrlIdentity } from '../../git/utils/pullRequest.utils'; import { getComparisonRefsForPullRequest, - getOrOpenPullRequestRepository, - getRepositoryIdentityForPullRequest, -} from '../../git/models/pullRequest'; -import type { PullRequestUrlIdentity } from '../../git/models/pullRequest.utils'; -import { getPullRequestIdentityFromMaybeUrl, + getRepositoryIdentityForPullRequest, isMaybeNonSpecificPullRequestSearchUrl, -} from '../../git/models/pullRequest.utils'; -import type { GitRemote } from '../../git/models/remote'; -import type { Repository } from '../../git/models/repository'; -import type { CodeSuggestionCounts, Draft } from '../../gk/models/drafts'; -import { gate } from '../../system/decorators/gate'; +} from '../../git/utils/pullRequest.utils'; +import { executeCommand, registerCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { setContext } from '../../system/-webview/context'; +import { openUrl } from '../../system/-webview/utils'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { filterMap, groupByMap, map, some } from '../../system/iterable'; import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; import type { TimedResult } from '../../system/promise'; import { getSettledValue, timedWithSlowThreshold } from '../../system/promise'; -import { executeCommand, registerCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { setContext } from '../../system/vscode/context'; -import { openUrl } from '../../system/vscode/utils'; import type { UriTypes } from '../../uris/deepLinks/deepLink'; import { DeepLinkActionType, DeepLinkType } from '../../uris/deepLinks/deepLink'; import { showInspectView } from '../../webviews/commitDetails/actions'; import type { ShowWipArgs } from '../../webviews/commitDetails/protocol'; +import type { CodeSuggestionCounts, Draft } from '../drafts/models/drafts'; import type { HostingIntegration, IntegrationResult, RepositoryDescriptor } from '../integrations/integration'; import type { ConnectionStateChangeEvent } from '../integrations/integrationService'; import { isMaybeGitHubPullRequestUrl } from '../integrations/providers/github/github.utils'; @@ -53,16 +51,16 @@ import { getActionablePullRequests, toProviderPullRequestWithUniqueId, } from '../integrations/providers/models'; -import type { EnrichableItem, EnrichedItem } from './enrichmentService'; import { convertRemoteProviderIdToEnrichProvider, isEnrichableRemoteProviderId } from './enrichmentService'; -import type { LaunchpadAction, LaunchpadActionCategory, LaunchpadGroup } from './models'; +import type { EnrichableItem, EnrichedItem } from './models/enrichedItem'; +import type { LaunchpadAction, LaunchpadActionCategory, LaunchpadGroup } from './models/launchpad'; import { launchpadActionCategories, launchpadCategoryToGroupMap, launchpadGroups, prActionsMap, sharedCategoryToLaunchpadActionCategoryMap, -} from './models'; +} from './models/launchpad'; export function getSuggestedActions(category: LaunchpadActionCategory, isCurrentBranch: boolean): LaunchpadAction[] { const actions = [...prActionsMap.get(category)!]; diff --git a/src/plus/launchpad/models/enrichedItem.ts b/src/plus/launchpad/models/enrichedItem.ts new file mode 100644 index 0000000000000..b2b93f9b99a5c --- /dev/null +++ b/src/plus/launchpad/models/enrichedItem.ts @@ -0,0 +1,37 @@ +export interface EnrichableItem { + type: EnrichedItemResponse['entityType']; + id: string; + provider: EnrichedItemResponse['provider']; + url: string; + expiresAt?: string; +} + +export interface EnrichedItem { + id: string; + userId?: string; + type: EnrichedItemResponse['type']; + + provider: EnrichedItemResponse['provider']; + entityType: EnrichedItemResponse['entityType']; + entityId: string; + entityUrl: string; + + createdAt: string; + updatedAt: string; + expiresAt?: string; +} + +export interface EnrichedItemResponse { + id: string; + userId?: string; + type: 'pin' | 'snooze'; + + provider: 'azure' | 'bitbucket' | 'github' | 'gitlab' | 'jira' | 'trello' | 'gitkraken'; + entityType: 'issue' | 'pr'; + entityId: string; + entityUrl: string; + + createdAt: string; + updatedAt: string; + expiresAt?: string; +} diff --git a/src/plus/launchpad/models.ts b/src/plus/launchpad/models/launchpad.ts similarity index 100% rename from src/plus/launchpad/models.ts rename to src/plus/launchpad/models/launchpad.ts diff --git a/src/plus/launchpad/utils.ts b/src/plus/launchpad/utils/-webview/launchpad.utils.ts similarity index 54% rename from src/plus/launchpad/utils.ts rename to src/plus/launchpad/utils/-webview/launchpad.utils.ts index 9f12d5960f24e..88925e820842e 100644 --- a/src/plus/launchpad/utils.ts +++ b/src/plus/launchpad/utils/-webview/launchpad.utils.ts @@ -1,8 +1,8 @@ -import type { Container } from '../../container'; -import { configuration } from '../../system/vscode/configuration'; -import type { LaunchpadSummaryResult } from './launchpadIndicator'; -import { generateLaunchpadSummary } from './launchpadIndicator'; -import type { LaunchpadGroup } from './models'; +import type { Container } from '../../../../container'; +import { configuration } from '../../../../system/-webview/configuration'; +import type { LaunchpadSummaryResult } from '../../launchpadIndicator'; +import { generateLaunchpadSummary } from '../../launchpadIndicator'; +import type { LaunchpadGroup } from '../../models/launchpad'; export async function getLaunchpadSummary(container: Container): Promise { const result = await container.launchpad.getCategorizedItems(); diff --git a/src/plus/repos/repositoryIdentityService.ts b/src/plus/repos/repositoryIdentityService.ts index 3b64b9538cfbd..64e79071affdf 100644 --- a/src/plus/repos/repositoryIdentityService.ts +++ b/src/plus/repos/repositoryIdentityService.ts @@ -3,13 +3,13 @@ import { Uri, window } from 'vscode'; import type { Container } from '../../container'; import { RemoteResourceType } from '../../git/models/remoteResource'; import type { Repository } from '../../git/models/repository'; -import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; import type { GkProviderId, RepositoryIdentityDescriptor, RepositoryIdentityProviderDescriptor, -} from '../../gk/models/repositoryIdentities'; -import { missingRepositoryId } from '../../gk/models/repositoryIdentities'; +} from '../../git/models/repositoryIdentities'; +import { missingRepositoryId } from '../../git/models/repositoryIdentities'; +import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; import { log } from '../../system/decorators/log'; import { getSettledValue } from '../../system/promise'; import type { ServerConnection } from '../gk/serverConnection'; diff --git a/src/plus/startWork/startWork.ts b/src/plus/startWork/startWork.ts index 07f4f7177b16e..582bd354986fa 100644 --- a/src/plus/startWork/startWork.ts +++ b/src/plus/startWork/startWork.ts @@ -30,22 +30,22 @@ import type { IntegrationId } from '../../constants.integrations'; import { HostingIntegrationId, IssueIntegrationId, SelfHostedIntegrationId } from '../../constants.integrations'; import type { Source, Sources, StartWorkTelemetryContext, TelemetryEvents } from '../../constants.telemetry'; import type { Container } from '../../container'; -import { addAssociatedIssueToBranch } from '../../git/models/branch.utils'; import type { Issue, IssueShape, SearchedIssue } from '../../git/models/issue'; -import { getOrOpenIssueRepository } from '../../git/models/issue'; import type { GitBranchReference } from '../../git/models/reference'; import type { Repository } from '../../git/models/repository'; +import { addAssociatedIssueToBranch } from '../../git/utils/-webview/branch.issue.utils'; +import { getOrOpenIssueRepository } from '../../git/utils/-webview/issue.utils'; import { showBranchPicker } from '../../quickpicks/branchPicker'; import type { QuickPickItemOfT } from '../../quickpicks/items/common'; import { createQuickPickItemOfT } from '../../quickpicks/items/common'; import type { DirectiveQuickPickItem } from '../../quickpicks/items/directive'; import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive'; +import { executeCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { openUrl } from '../../system/-webview/utils'; import { getScopedCounter } from '../../system/counter'; import { fromNow } from '../../system/date'; import { some } from '../../system/iterable'; -import { executeCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { openUrl } from '../../system/vscode/utils'; import { getIssueOwner } from '../integrations/providers/utils'; export type StartWorkItem = { diff --git a/src/plus/utils.ts b/src/plus/utils.ts deleted file mode 100644 index ca2547db3d045..0000000000000 --- a/src/plus/utils.ts +++ /dev/null @@ -1,177 +0,0 @@ -import type { MessageItem } from 'vscode'; -import { window } from 'vscode'; -import { urls } from '../constants'; -import { proTrialLengthInDays } from '../constants.subscription'; -import type { Source } from '../constants.telemetry'; -import type { Container } from '../container'; -import { openUrl } from '../system/vscode/utils'; -import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from './gk/account/subscription'; - -export async function ensurePaidPlan( - container: Container, - title: string, - source: Source, - options?: { allowPreview?: boolean }, -): Promise { - while (true) { - const subscription = await container.subscription.getSubscription(); - if (subscription.account?.verified === false) { - const resend = { title: 'Resend Email' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nYou must verify your email before you can continue.`, - { modal: true }, - resend, - cancel, - ); - - if (result === resend) { - if (await container.subscription.resendVerification(source)) { - continue; - } - } - - return false; - } - - const plan = subscription.plan.effective.id; - if (isSubscriptionPaidPlan(plan)) break; - - if (options?.allowPreview && subscription.account == null && !isSubscriptionPreviewTrialExpired(subscription)) { - const startTrial = { title: 'Continue' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nDo you want to continue to get immediate access to preview local Pro features for 3 days?`, - { modal: true }, - startTrial, - cancel, - ); - - if (result !== startTrial) return false; - - void container.subscription.startPreviewTrial(source); - break; - } else if (subscription.account == null) { - const signUp = { title: 'Try GitLens Pro' }; - const signIn = { title: 'Sign In' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nDo you want to start your free ${proTrialLengthInDays}-day Pro trial for full access to all GitLens Pro features?`, - { modal: true }, - signUp, - signIn, - cancel, - ); - - if (result === signUp || result === signIn) { - if (await container.subscription.loginOrSignUp(result === signUp, source)) { - continue; - } - } - } else { - const upgrade = { title: 'Upgrade to Pro' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nDo you want to upgrade for full access to all GitLens Pro features?`, - { modal: true }, - upgrade, - cancel, - ); - - if (result === upgrade) { - void container.subscription.upgrade(source); - } - } - - return false; - } - - return true; -} - -export async function ensureAccount(container: Container, title: string, source: Source): Promise { - while (true) { - const subscription = await container.subscription.getSubscription(); - if (subscription.account?.verified === false) { - const resend = { title: 'Resend Email' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nYou must verify your email before you can continue.`, - { modal: true }, - resend, - cancel, - ); - - if (result === resend) { - if (await container.subscription.resendVerification(source)) { - continue; - } - } - - return false; - } - - if (subscription.account != null) break; - - const signUp = { title: 'Sign Up' }; - const signIn = { title: 'Sign In' }; - const cancel = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showWarningMessage( - `${title}\n\nSign up for access to Pro features and the GitKraken DevEx platform, or sign in`, - { modal: true }, - signUp, - signIn, - cancel, - ); - - if (result === signIn) { - if (await container.subscription.loginOrSignUp(false, source)) { - continue; - } - } else if (result === signUp) { - if (await container.subscription.loginOrSignUp(true, source)) { - continue; - } - } - - return false; - } - - return true; -} - -export async function confirmDraftStorage(container: Container): Promise { - if (container.storage.get('confirm:draft:storage', false)) return true; - - while (true) { - const accept: MessageItem = { title: 'Continue' }; - const decline: MessageItem = { title: 'Cancel', isCloseAffordance: true }; - const moreInfo: MessageItem = { title: 'Learn More' }; - const security: MessageItem = { title: 'Security' }; - const result = await window.showInformationMessage( - `Cloud Patches are securely stored by GitKraken and can be accessed by anyone with the link and a GitKraken account.`, - { modal: true }, - accept, - moreInfo, - security, - decline, - ); - - if (result === accept) { - void container.storage.store('confirm:draft:storage', true).catch(); - return true; - } - - if (result === security) { - void openUrl(urls.security); - continue; - } - - if (result === moreInfo) { - void openUrl(urls.cloudPatches); - continue; - } - - return false; - } -} diff --git a/src/plus/workspaces/models.ts b/src/plus/workspaces/models.ts deleted file mode 100644 index 564ec8dcc46ac..0000000000000 --- a/src/plus/workspaces/models.ts +++ /dev/null @@ -1,623 +0,0 @@ -import type { Disposable } from '../../api/gitlens'; -import type { Container } from '../../container'; -import type { Repository } from '../../git/models/repository'; - -export type WorkspaceType = 'cloud' | 'local'; -export type WorkspaceAutoAddSetting = 'disabled' | 'enabled' | 'prompt'; - -export enum WorkspaceRepositoryRelation { - Direct = 'DIRECT', - ProviderProject = 'PROVIDER_PROJECT', -} - -export type CodeWorkspaceFileContents = { - folders: { path: string }[]; - settings: Record; -}; - -export type WorkspaceRepositoriesByName = Map; - -export interface RepositoryMatch { - repository: Repository; - descriptor: CloudWorkspaceRepositoryDescriptor | LocalWorkspaceRepositoryDescriptor; -} - -export interface RemoteDescriptor { - provider: string; - owner: string; - repoName: string; - url?: string; -} - -export interface GetWorkspacesResponse { - cloudWorkspaces: CloudWorkspace[]; - localWorkspaces: LocalWorkspace[]; - cloudWorkspaceInfo: string | undefined; - localWorkspaceInfo: string | undefined; -} - -export interface LoadCloudWorkspacesResponse { - cloudWorkspaces: CloudWorkspace[] | undefined; - cloudWorkspaceInfo: string | undefined; -} - -export interface LoadLocalWorkspacesResponse { - localWorkspaces: LocalWorkspace[] | undefined; - localWorkspaceInfo: string | undefined; -} - -export interface GetCloudWorkspaceRepositoriesResponse { - repositories: CloudWorkspaceRepositoryDescriptor[] | undefined; - repositoriesInfo: string | undefined; -} - -// Cloud Workspace types -export class CloudWorkspace { - readonly type = 'cloud' satisfies WorkspaceType; - - private _repositoryDescriptors: CloudWorkspaceRepositoryDescriptor[] | undefined; - private _repositoriesByName: WorkspaceRepositoriesByName | undefined; - private _localPath: string | undefined; - private _disposable: Disposable; - - constructor( - private readonly container: Container, - public readonly id: string, - public readonly name: string, - public readonly organizationId: string | undefined, - public readonly provider: CloudWorkspaceProviderType, - public readonly repoRelation: WorkspaceRepositoryRelation, - public readonly current: boolean, - public readonly azureInfo?: { - organizationId?: string; - project?: string; - }, - repositories?: CloudWorkspaceRepositoryDescriptor[], - localPath?: string, - ) { - this._repositoryDescriptors = repositories; - this._localPath = localPath; - this._disposable = this.container.git.onDidChangeRepositories(this.resetRepositoriesByName, this); - } - - dispose() { - this._disposable.dispose(); - } - - get shared(): boolean { - return this.organizationId != null; - } - - get localPath(): string | undefined { - return this._localPath; - } - - resetRepositoriesByName() { - this._repositoriesByName = undefined; - } - - async getRepositoriesByName(options?: { force?: boolean }): Promise { - if (this._repositoriesByName == null || options?.force) { - this._repositoriesByName = await this.container.workspaces.resolveWorkspaceRepositoriesByName(this.id, { - resolveFromPath: true, - usePathMapping: true, - }); - } - - return this._repositoriesByName; - } - - async getRepositoryDescriptors(options?: { force?: boolean }): Promise { - if (this._repositoryDescriptors == null || options?.force) { - this._repositoryDescriptors = await this.container.workspaces.getCloudWorkspaceRepositories(this.id); - this.resetRepositoriesByName(); - } - - return this._repositoryDescriptors; - } - - async getRepositoryDescriptor(name: string): Promise { - return (await this.getRepositoryDescriptors()).find(r => r.name === name); - } - - // TODO@axosoft-ramint this should be the entry point, not a backdoor to update the cache - addRepositories(repositories: CloudWorkspaceRepositoryDescriptor[]): void { - if (this._repositoryDescriptors == null) { - this._repositoryDescriptors = repositories; - } else { - this._repositoryDescriptors = this._repositoryDescriptors.concat(repositories); - } - - this.resetRepositoriesByName(); - } - - // TODO@axosoft-ramint this should be the entry point, not a backdoor to update the cache - removeRepositories(repoNames: string[]): void { - if (this._repositoryDescriptors == null) return; - - this._repositoryDescriptors = this._repositoryDescriptors.filter(r => !repoNames.includes(r.name)); - this.resetRepositoriesByName(); - } - - setLocalPath(localPath: string | undefined): void { - this._localPath = localPath; - } -} - -export interface CloudWorkspaceRepositoryDescriptor { - id: string; - name: string; - description: string; - repository_id: string; - provider: CloudWorkspaceProviderType | null; - provider_project_name: string | null; - provider_organization_id: string; - provider_organization_name: string | null; - url: string | null; - workspaceId: string; -} - -export enum CloudWorkspaceProviderInputType { - GitHub = 'GITHUB', - GitHubEnterprise = 'GITHUB_ENTERPRISE', - GitLab = 'GITLAB', - GitLabSelfHosted = 'GITLAB_SELF_HOSTED', - Bitbucket = 'BITBUCKET', - Azure = 'AZURE', -} - -export enum CloudWorkspaceProviderType { - GitHub = 'github', - GitHubEnterprise = 'github_enterprise', - GitLab = 'gitlab', - GitLabSelfHosted = 'gitlab_self_hosted', - Bitbucket = 'bitbucket', - Azure = 'azure', -} - -export const cloudWorkspaceProviderTypeToRemoteProviderId = { - [CloudWorkspaceProviderType.Azure]: 'azure-devops', - [CloudWorkspaceProviderType.Bitbucket]: 'bitbucket', - [CloudWorkspaceProviderType.GitHub]: 'github', - [CloudWorkspaceProviderType.GitHubEnterprise]: 'github', - [CloudWorkspaceProviderType.GitLab]: 'gitlab', - [CloudWorkspaceProviderType.GitLabSelfHosted]: 'gitlab', -}; - -export const cloudWorkspaceProviderInputTypeToRemoteProviderId = { - [CloudWorkspaceProviderInputType.Azure]: 'azure-devops', - [CloudWorkspaceProviderInputType.Bitbucket]: 'bitbucket', - [CloudWorkspaceProviderInputType.GitHub]: 'github', - [CloudWorkspaceProviderInputType.GitHubEnterprise]: 'github', - [CloudWorkspaceProviderInputType.GitLab]: 'gitlab', - [CloudWorkspaceProviderInputType.GitLabSelfHosted]: 'gitlab', -}; - -export enum WorkspaceAddRepositoriesChoice { - CurrentWindow = 'Current Window', - ParentFolder = 'Parent Folder', -} - -export const defaultWorkspaceCount = 100; -export const defaultWorkspaceRepoCount = 100; - -export interface CloudWorkspaceData { - id: string; - name: string; - description: string; - type: CloudWorkspaceType; - icon_url: string | null; - host_url: string; - status: string; - provider: string; - repo_relation: string; - azure_organization_id: string | null; - azure_project: string | null; - created_date: Date; - updated_date: Date; - created_by: string; - updated_by: string; - members: CloudWorkspaceMember[]; - organization: CloudWorkspaceOrganization; - issue_tracker: CloudWorkspaceIssueTracker; - settings: CloudWorkspaceSettings; - current_user: UserCloudWorkspaceSettings; - errors: string[]; - provider_data: ProviderCloudWorkspaceData; -} - -export type CloudWorkspaceType = 'GK_PROJECT' | 'GK_ORG_VELOCITY' | 'GK_CLI'; - -export interface CloudWorkspaceMember { - id: string; - role: string; - name: string; - username: string; - avatar_url: string; -} - -interface CloudWorkspaceOrganization { - id: string; - team_ids: string[]; -} - -interface CloudWorkspaceIssueTracker { - provider: string; - settings: CloudWorkspaceIssueTrackerSettings; -} - -interface CloudWorkspaceIssueTrackerSettings { - resource_id: string; -} - -interface CloudWorkspaceSettings { - gkOrgVelocity: GKOrgVelocitySettings; - goals: ProjectGoalsSettings; -} - -type GKOrgVelocitySettings = Record; -type ProjectGoalsSettings = Record; - -interface UserCloudWorkspaceSettings { - project_id: string; - user_id: string; - tab_settings: UserCloudWorkspaceTabSettings; -} - -interface UserCloudWorkspaceTabSettings { - issue_tracker: CloudWorkspaceIssueTracker; -} - -export interface ProviderCloudWorkspaceData { - id: string; - provider_organization_id: string; - repository: CloudWorkspaceRepositoryData; - repositories: CloudWorkspaceConnection; - pull_requests: CloudWorkspacePullRequestData[]; - issues: CloudWorkspaceIssue[]; - repository_members: CloudWorkspaceRepositoryMemberData[]; - milestones: CloudWorkspaceMilestone[]; - labels: CloudWorkspaceLabel[]; - issue_types: CloudWorkspaceIssueType[]; - provider_identity: ProviderCloudWorkspaceIdentity; - metrics: ProviderCloudWorkspaceMetrics; -} - -type ProviderCloudWorkspaceMetrics = Record; - -interface ProviderCloudWorkspaceIdentity { - avatar_url: string; - id: string; - name: string; - username: string; - pat_organization: string; - is_using_pat: boolean; - scopes: string; -} - -export interface Branch { - id: string; - node_id: string; - name: string; - commit: BranchCommit; -} - -interface BranchCommit { - id: string; - url: string; - build_status: { - context: string; - state: string; - description: string; - }; -} - -export interface CloudWorkspaceRepositoryData { - id: string; - name: string; - description: string; - repository_id: string; - provider: CloudWorkspaceProviderType | null; - provider_project_name: string | null; - provider_organization_id: string; - provider_organization_name: string | null; - url: string | null; - default_branch: string; - branches: Branch[]; - pull_requests: CloudWorkspacePullRequestData[]; - issues: CloudWorkspaceIssue[]; - members: CloudWorkspaceRepositoryMemberData[]; - milestones: CloudWorkspaceMilestone[]; - labels: CloudWorkspaceLabel[]; - issue_types: CloudWorkspaceIssueType[]; - possibly_deleted: boolean; - has_webhook: boolean; -} - -interface CloudWorkspaceRepositoryMemberData { - avatar_url: string; - name: string; - node_id: string; - username: string; -} - -type CloudWorkspaceMilestone = Record; -type CloudWorkspaceLabel = Record; -type CloudWorkspaceIssueType = Record; - -export interface CloudWorkspacePullRequestData { - id: string; - node_id: string; - number: string; - title: string; - description: string; - url: string; - milestone_id: string; - labels: CloudWorkspaceLabel[]; - author_id: string; - author_username: string; - created_date: Date; - updated_date: Date; - closed_date: Date; - merged_date: Date; - first_commit_date: Date; - first_response_date: Date; - comment_count: number; - repository: CloudWorkspaceRepositoryData; - head_commit: { - id: string; - url: string; - build_status: { - context: string; - state: string; - description: string; - }; - }; - lifecycle_stages: { - stage: string; - start_date: Date; - end_date: Date; - }[]; - reviews: CloudWorkspacePullRequestReviews[]; - head: { - name: string; - }; -} - -interface CloudWorkspacePullRequestReviews { - user_id: string; - avatar_url: string; - state: string; -} - -export interface CloudWorkspaceIssue { - id: string; - node_id: string; - title: string; - author_id: string; - assignee_ids: string[]; - milestone_id: string; - label_ids: string[]; - issue_type: string; - url: string; - created_date: Date; - updated_date: Date; - comment_count: number; - repository: CloudWorkspaceRepositoryData; -} - -export interface CloudWorkspaceConnection { - total_count: number; - page_info: { - start_cursor: string; - end_cursor: string; - has_next_page: boolean; - }; - nodes: i[]; -} - -interface CloudWorkspaceFetchedConnection extends CloudWorkspaceConnection { - is_fetching: boolean; -} - -export interface WorkspaceResponse { - data: { - project: CloudWorkspaceData; - }; -} - -export interface WorkspacesResponse { - data: { - projects: CloudWorkspaceConnection; - }; -} - -export interface WorkspaceRepositoriesResponse { - data: { - project: { - provider_data: { - repositories: CloudWorkspaceConnection; - }; - }; - }; -} - -export interface WorkspacePullRequestsResponse { - data: { - project: { - provider_data: { - pull_requests: CloudWorkspaceFetchedConnection; - }; - }; - }; -} - -export interface WorkspacesWithPullRequestsResponse { - data: { - projects: { - nodes: { - provider_data: { - pull_requests: CloudWorkspaceFetchedConnection; - }; - }[]; - }; - }; - errors?: { - message: string; - path: unknown[]; - statusCode: number; - }[]; -} - -export interface WorkspaceIssuesResponse { - data: { - project: { - provider_data: { - issues: CloudWorkspaceFetchedConnection; - }; - }; - }; -} - -export interface CreateWorkspaceResponse { - data: { - create_project: CloudWorkspaceData | null; - }; -} - -export interface DeleteWorkspaceResponse { - data: { - delete_project: CloudWorkspaceData | null; - }; - errors?: { code: number; message: string }[]; -} - -export type AddRepositoriesToWorkspaceResponse = { - data: { - add_repositories_to_project: { - id: string; - provider_data: Record; - } | null; - }; - errors?: { code: number; message: string }[]; -}; - -export interface RemoveRepositoriesFromWorkspaceResponse { - data: { - remove_repositories_from_project: { - id: string; - } | null; - }; - errors?: { code: number; message: string }[]; -} - -export interface AddWorkspaceRepoDescriptor { - owner: string; - repoName: string; -} - -// TODO@ramint Switch to using repo id once that is no longer bugged -export interface RemoveWorkspaceRepoDescriptor { - owner: string; - repoName: string; -} - -// Local Workspace Types -export class LocalWorkspace { - readonly type = 'local' satisfies WorkspaceType; - - private _localPath: string | undefined; - private _repositoriesByName: WorkspaceRepositoriesByName | undefined; - private _disposable: Disposable; - - constructor( - public readonly container: Container, - public readonly id: string, - public readonly name: string, - private readonly repositoryDescriptors: LocalWorkspaceRepositoryDescriptor[], - public readonly current: boolean, - localPath?: string, - ) { - this._localPath = localPath; - this._disposable = this.container.git.onDidChangeRepositories(this.resetRepositoriesByName, this); - } - - dispose() { - this._disposable.dispose(); - } - - get shared(): boolean { - return false; - } - - get localPath(): string | undefined { - return this._localPath; - } - - resetRepositoriesByName() { - this._repositoriesByName = undefined; - } - - async getRepositoriesByName(options?: { force?: boolean }): Promise { - if (this._repositoriesByName == null || options?.force) { - this._repositoriesByName = await this.container.workspaces.resolveWorkspaceRepositoriesByName(this.id, { - resolveFromPath: true, - usePathMapping: true, - }); - } - - return this._repositoriesByName; - } - - getRepositoryDescriptors(): Promise { - return Promise.resolve(this.repositoryDescriptors); - } - - getRepositoryDescriptor(name: string): Promise { - return Promise.resolve(this.repositoryDescriptors.find(r => r.name === name)); - } - - setLocalPath(localPath: string | undefined): void { - this._localPath = localPath; - } -} - -export interface LocalWorkspaceFileData { - workspaces: LocalWorkspaceData; -} - -export type LocalWorkspaceData = Record; - -export interface LocalWorkspaceDescriptor { - localId: string; - profileId: string; - name: string; - description: string; - repositories: LocalWorkspaceRepositoryPath[]; - version: number; -} - -export interface LocalWorkspaceRepositoryPath { - localPath: string; -} - -export interface LocalWorkspaceRepositoryDescriptor extends LocalWorkspaceRepositoryPath { - id?: undefined; - name: string; - workspaceId: string; -} - -export interface CloudWorkspaceFileData { - workspaces: CloudWorkspacesPathMap; -} - -export type CloudWorkspacesPathMap = Record; - -export interface CloudWorkspacePaths { - repoPaths: CloudWorkspaceRepoPathMap; - externalLinks: CloudWorkspaceExternalLinkMap; -} - -export type CloudWorkspaceRepoPathMap = Record; - -export type CloudWorkspaceExternalLinkMap = Record; diff --git a/src/plus/workspaces/models/cloudWorkspace.ts b/src/plus/workspaces/models/cloudWorkspace.ts new file mode 100644 index 0000000000000..b2148cfcd1a1c --- /dev/null +++ b/src/plus/workspaces/models/cloudWorkspace.ts @@ -0,0 +1,220 @@ +import type { Disposable } from 'vscode'; +import type { Container } from '../../../container'; +import type { + GKOrgVelocitySettings, + ProjectGoalsSettings, + ProviderCloudWorkspaceData, + UserCloudWorkspaceSettings, + WorkspaceRepositoriesByName, + WorkspaceRepositoryRelation, + WorkspaceType, +} from './workspaces'; + +export class CloudWorkspace { + readonly type = 'cloud' satisfies WorkspaceType; + + private _repositoryDescriptors: CloudWorkspaceRepositoryDescriptor[] | undefined; + private _repositoriesByName: WorkspaceRepositoriesByName | undefined; + private _localPath: string | undefined; + private _disposable: Disposable; + + constructor( + private readonly container: Container, + public readonly id: string, + public readonly name: string, + public readonly organizationId: string | undefined, + public readonly provider: CloudWorkspaceProviderType, + public readonly repoRelation: WorkspaceRepositoryRelation, + public readonly current: boolean, + public readonly azureInfo?: { + organizationId?: string; + project?: string; + }, + repositories?: CloudWorkspaceRepositoryDescriptor[], + localPath?: string, + ) { + this._repositoryDescriptors = repositories; + this._localPath = localPath; + this._disposable = this.container.git.onDidChangeRepositories(this.resetRepositoriesByName, this); + } + + dispose() { + this._disposable.dispose(); + } + + get shared(): boolean { + return this.organizationId != null; + } + + get localPath(): string | undefined { + return this._localPath; + } + + resetRepositoriesByName() { + this._repositoriesByName = undefined; + } + + async getRepositoriesByName(options?: { force?: boolean }): Promise { + if (this._repositoriesByName == null || options?.force) { + this._repositoriesByName = await this.container.workspaces.resolveWorkspaceRepositoriesByName(this.id, { + resolveFromPath: true, + usePathMapping: true, + }); + } + + return this._repositoriesByName; + } + + async getRepositoryDescriptors(options?: { force?: boolean }): Promise { + if (this._repositoryDescriptors == null || options?.force) { + this._repositoryDescriptors = await this.container.workspaces.getCloudWorkspaceRepositories(this.id); + this.resetRepositoriesByName(); + } + + return this._repositoryDescriptors; + } + + async getRepositoryDescriptor(name: string): Promise { + return (await this.getRepositoryDescriptors()).find(r => r.name === name); + } + + // TODO@axosoft-ramint this should be the entry point, not a backdoor to update the cache + addRepositories(repositories: CloudWorkspaceRepositoryDescriptor[]): void { + if (this._repositoryDescriptors == null) { + this._repositoryDescriptors = repositories; + } else { + this._repositoryDescriptors = this._repositoryDescriptors.concat(repositories); + } + + this.resetRepositoriesByName(); + } + + // TODO@axosoft-ramint this should be the entry point, not a backdoor to update the cache + removeRepositories(repoNames: string[]): void { + if (this._repositoryDescriptors == null) return; + + this._repositoryDescriptors = this._repositoryDescriptors.filter(r => !repoNames.includes(r.name)); + this.resetRepositoriesByName(); + } + + setLocalPath(localPath: string | undefined): void { + this._localPath = localPath; + } +} + +export interface CloudWorkspaceRepositoryDescriptor { + id: string; + name: string; + description: string; + repository_id: string; + provider: CloudWorkspaceProviderType | null; + provider_project_name: string | null; + provider_organization_id: string; + provider_organization_name: string | null; + url: string | null; + workspaceId: string; +} + +export interface CloudWorkspaceData { + id: string; + name: string; + description: string; + type: CloudWorkspaceType; + icon_url: string | null; + host_url: string; + status: string; + provider: string; + repo_relation: string; + azure_organization_id: string | null; + azure_project: string | null; + created_date: Date; + updated_date: Date; + created_by: string; + updated_by: string; + members: CloudWorkspaceMember[]; + organization: CloudWorkspaceOrganization; + issue_tracker: CloudWorkspaceIssueTracker; + settings: CloudWorkspaceSettings; + current_user: UserCloudWorkspaceSettings; + errors: string[]; + provider_data: ProviderCloudWorkspaceData; +} +export type CloudWorkspaceType = 'GK_PROJECT' | 'GK_ORG_VELOCITY' | 'GK_CLI'; + +export interface CloudWorkspaceMember { + id: string; + role: string; + name: string; + username: string; + avatar_url: string; +} + +export interface CloudWorkspaceOrganization { + id: string; + team_ids: string[]; +} + +export interface CloudWorkspaceIssueTracker { + provider: string; + settings: CloudWorkspaceIssueTrackerSettings; +} + +interface CloudWorkspaceIssueTrackerSettings { + resource_id: string; +} + +export interface CloudWorkspaceSettings { + gkOrgVelocity: GKOrgVelocitySettings; + goals: ProjectGoalsSettings; +} + +export interface CloudWorkspaceFileData { + workspaces: CloudWorkspacesPathMap; +} + +export enum CloudWorkspaceProviderType { + GitHub = 'github', + GitHubEnterprise = 'github_enterprise', + GitLab = 'gitlab', + GitLabSelfHosted = 'gitlab_self_hosted', + Bitbucket = 'bitbucket', + Azure = 'azure', +} + +export const cloudWorkspaceProviderTypeToRemoteProviderId = { + [CloudWorkspaceProviderType.Azure]: 'azure-devops', + [CloudWorkspaceProviderType.Bitbucket]: 'bitbucket', + [CloudWorkspaceProviderType.GitHub]: 'github', + [CloudWorkspaceProviderType.GitHubEnterprise]: 'github', + [CloudWorkspaceProviderType.GitLab]: 'gitlab', + [CloudWorkspaceProviderType.GitLabSelfHosted]: 'gitlab', +}; + +export enum CloudWorkspaceProviderInputType { + GitHub = 'GITHUB', + GitHubEnterprise = 'GITHUB_ENTERPRISE', + GitLab = 'GITLAB', + GitLabSelfHosted = 'GITLAB_SELF_HOSTED', + Bitbucket = 'BITBUCKET', + Azure = 'AZURE', +} + +export const cloudWorkspaceProviderInputTypeToRemoteProviderId = { + [CloudWorkspaceProviderInputType.Azure]: 'azure-devops', + [CloudWorkspaceProviderInputType.Bitbucket]: 'bitbucket', + [CloudWorkspaceProviderInputType.GitHub]: 'github', + [CloudWorkspaceProviderInputType.GitHubEnterprise]: 'github', + [CloudWorkspaceProviderInputType.GitLab]: 'gitlab', + [CloudWorkspaceProviderInputType.GitLabSelfHosted]: 'gitlab', +}; + +export type CloudWorkspacesPathMap = Record; + +export interface CloudWorkspacePaths { + repoPaths: CloudWorkspaceRepoPathMap; + externalLinks: CloudWorkspaceExternalLinkMap; +} + +export type CloudWorkspaceRepoPathMap = Record; + +export type CloudWorkspaceExternalLinkMap = Record; diff --git a/src/plus/workspaces/models/localWorkspace.ts b/src/plus/workspaces/models/localWorkspace.ts new file mode 100644 index 0000000000000..b9e73629b7314 --- /dev/null +++ b/src/plus/workspaces/models/localWorkspace.ts @@ -0,0 +1,87 @@ +import type { Disposable } from 'vscode'; +import type { Container } from '../../../container'; +import type { WorkspaceRepositoriesByName, WorkspaceType } from './workspaces'; + +export class LocalWorkspace { + readonly type = 'local' satisfies WorkspaceType; + + private _localPath: string | undefined; + private _repositoriesByName: WorkspaceRepositoriesByName | undefined; + private _disposable: Disposable; + + constructor( + public readonly container: Container, + public readonly id: string, + public readonly name: string, + private readonly repositoryDescriptors: LocalWorkspaceRepositoryDescriptor[], + public readonly current: boolean, + localPath?: string, + ) { + this._localPath = localPath; + this._disposable = this.container.git.onDidChangeRepositories(this.resetRepositoriesByName, this); + } + + dispose() { + this._disposable.dispose(); + } + + get shared(): boolean { + return false; + } + + get localPath(): string | undefined { + return this._localPath; + } + + resetRepositoriesByName() { + this._repositoriesByName = undefined; + } + + async getRepositoriesByName(options?: { force?: boolean }): Promise { + if (this._repositoriesByName == null || options?.force) { + this._repositoriesByName = await this.container.workspaces.resolveWorkspaceRepositoriesByName(this.id, { + resolveFromPath: true, + usePathMapping: true, + }); + } + + return this._repositoriesByName; + } + + getRepositoryDescriptors(): Promise { + return Promise.resolve(this.repositoryDescriptors); + } + + getRepositoryDescriptor(name: string): Promise { + return Promise.resolve(this.repositoryDescriptors.find(r => r.name === name)); + } + + setLocalPath(localPath: string | undefined): void { + this._localPath = localPath; + } +} + +export interface LocalWorkspaceDescriptor { + localId: string; + profileId: string; + name: string; + description: string; + repositories: LocalWorkspaceRepositoryPath[]; + version: number; +} + +export interface LocalWorkspaceRepositoryDescriptor extends LocalWorkspaceRepositoryPath { + id?: undefined; + name: string; + workspaceId: string; +} + +interface LocalWorkspaceRepositoryPath { + localPath: string; +} + +export type LocalWorkspaceData = Record; + +export interface LocalWorkspaceFileData { + workspaces: LocalWorkspaceData; +} diff --git a/src/plus/workspaces/models/workspaces.ts b/src/plus/workspaces/models/workspaces.ts new file mode 100644 index 0000000000000..66a839f5910cb --- /dev/null +++ b/src/plus/workspaces/models/workspaces.ts @@ -0,0 +1,333 @@ +import type { Repository } from '../../../git/models/repository'; +import type { + CloudWorkspace, + CloudWorkspaceData, + CloudWorkspaceIssueTracker, + CloudWorkspaceProviderType, + CloudWorkspaceRepositoryDescriptor, +} from './cloudWorkspace'; +import type { LocalWorkspace, LocalWorkspaceRepositoryDescriptor } from './localWorkspace'; + +export type WorkspaceType = 'cloud' | 'local'; +export type WorkspaceAutoAddSetting = 'disabled' | 'enabled' | 'prompt'; + +export enum WorkspaceRepositoryRelation { + Direct = 'DIRECT', + ProviderProject = 'PROVIDER_PROJECT', +} + +export type CodeWorkspaceFileContents = { + folders: { path: string }[]; + settings: Record; +}; + +export type WorkspaceRepositoriesByName = Map; + +export interface RepositoryMatch { + repository: Repository; + descriptor: CloudWorkspaceRepositoryDescriptor | LocalWorkspaceRepositoryDescriptor; +} + +export interface RemoteDescriptor { + provider: string; + owner: string; + repoName: string; + url?: string; +} + +export interface GetWorkspacesResponse { + cloudWorkspaces: CloudWorkspace[]; + localWorkspaces: LocalWorkspace[]; + cloudWorkspaceInfo: string | undefined; + localWorkspaceInfo: string | undefined; +} + +export interface LoadCloudWorkspacesResponse { + cloudWorkspaces: CloudWorkspace[] | undefined; + cloudWorkspaceInfo: string | undefined; +} + +export interface LoadLocalWorkspacesResponse { + localWorkspaces: LocalWorkspace[] | undefined; + localWorkspaceInfo: string | undefined; +} + +export interface GetCloudWorkspaceRepositoriesResponse { + repositories: CloudWorkspaceRepositoryDescriptor[] | undefined; + repositoriesInfo: string | undefined; +} + +export enum WorkspaceAddRepositoriesChoice { + CurrentWindow = 'Current Window', + ParentFolder = 'Parent Folder', +} + +export const defaultWorkspaceCount = 100; +export const defaultWorkspaceRepoCount = 100; + +export type GKOrgVelocitySettings = Record; +export type ProjectGoalsSettings = Record; + +export interface UserCloudWorkspaceSettings { + project_id: string; + user_id: string; + tab_settings: UserCloudWorkspaceTabSettings; +} + +interface UserCloudWorkspaceTabSettings { + issue_tracker: CloudWorkspaceIssueTracker; +} + +export interface ProviderCloudWorkspaceData { + id: string; + provider_organization_id: string; + repository: CloudWorkspaceRepositoryData; + repositories: CloudWorkspaceConnection; + pull_requests: CloudWorkspacePullRequestData[]; + issues: CloudWorkspaceIssue[]; + repository_members: CloudWorkspaceRepositoryMemberData[]; + milestones: CloudWorkspaceMilestone[]; + labels: CloudWorkspaceLabel[]; + issue_types: CloudWorkspaceIssueType[]; + provider_identity: ProviderCloudWorkspaceIdentity; + metrics: ProviderCloudWorkspaceMetrics; +} + +type ProviderCloudWorkspaceMetrics = Record; + +interface ProviderCloudWorkspaceIdentity { + avatar_url: string; + id: string; + name: string; + username: string; + pat_organization: string; + is_using_pat: boolean; + scopes: string; +} + +export interface Branch { + id: string; + node_id: string; + name: string; + commit: BranchCommit; +} + +interface BranchCommit { + id: string; + url: string; + build_status: { + context: string; + state: string; + description: string; + }; +} + +export interface CloudWorkspaceRepositoryData { + id: string; + name: string; + description: string; + repository_id: string; + provider: CloudWorkspaceProviderType | null; + provider_project_name: string | null; + provider_organization_id: string; + provider_organization_name: string | null; + url: string | null; + default_branch: string; + branches: Branch[]; + pull_requests: CloudWorkspacePullRequestData[]; + issues: CloudWorkspaceIssue[]; + members: CloudWorkspaceRepositoryMemberData[]; + milestones: CloudWorkspaceMilestone[]; + labels: CloudWorkspaceLabel[]; + issue_types: CloudWorkspaceIssueType[]; + possibly_deleted: boolean; + has_webhook: boolean; +} + +interface CloudWorkspaceRepositoryMemberData { + avatar_url: string; + name: string; + node_id: string; + username: string; +} + +type CloudWorkspaceMilestone = Record; +type CloudWorkspaceLabel = Record; +type CloudWorkspaceIssueType = Record; + +export interface CloudWorkspacePullRequestData { + id: string; + node_id: string; + number: string; + title: string; + description: string; + url: string; + milestone_id: string; + labels: CloudWorkspaceLabel[]; + author_id: string; + author_username: string; + created_date: Date; + updated_date: Date; + closed_date: Date; + merged_date: Date; + first_commit_date: Date; + first_response_date: Date; + comment_count: number; + repository: CloudWorkspaceRepositoryData; + head_commit: { + id: string; + url: string; + build_status: { + context: string; + state: string; + description: string; + }; + }; + lifecycle_stages: { + stage: string; + start_date: Date; + end_date: Date; + }[]; + reviews: CloudWorkspacePullRequestReviews[]; + head: { + name: string; + }; +} + +interface CloudWorkspacePullRequestReviews { + user_id: string; + avatar_url: string; + state: string; +} + +export interface CloudWorkspaceIssue { + id: string; + node_id: string; + title: string; + author_id: string; + assignee_ids: string[]; + milestone_id: string; + label_ids: string[]; + issue_type: string; + url: string; + created_date: Date; + updated_date: Date; + comment_count: number; + repository: CloudWorkspaceRepositoryData; +} + +export interface CloudWorkspaceConnection { + total_count: number; + page_info: { + start_cursor: string; + end_cursor: string; + has_next_page: boolean; + }; + nodes: i[]; +} + +interface CloudWorkspaceFetchedConnection extends CloudWorkspaceConnection { + is_fetching: boolean; +} + +export interface WorkspaceResponse { + data: { + project: CloudWorkspaceData; + }; +} + +export interface WorkspacesResponse { + data: { + projects: CloudWorkspaceConnection; + }; +} + +export interface WorkspaceRepositoriesResponse { + data: { + project: { + provider_data: { + repositories: CloudWorkspaceConnection; + }; + }; + }; +} + +export interface WorkspacePullRequestsResponse { + data: { + project: { + provider_data: { + pull_requests: CloudWorkspaceFetchedConnection; + }; + }; + }; +} + +export interface WorkspacesWithPullRequestsResponse { + data: { + projects: { + nodes: { + provider_data: { + pull_requests: CloudWorkspaceFetchedConnection; + }; + }[]; + }; + }; + errors?: { + message: string; + path: unknown[]; + statusCode: number; + }[]; +} + +export interface WorkspaceIssuesResponse { + data: { + project: { + provider_data: { + issues: CloudWorkspaceFetchedConnection; + }; + }; + }; +} + +export interface CreateWorkspaceResponse { + data: { + create_project: CloudWorkspaceData | null; + }; +} + +export interface DeleteWorkspaceResponse { + data: { + delete_project: CloudWorkspaceData | null; + }; + errors?: { code: number; message: string }[]; +} + +export type AddRepositoriesToWorkspaceResponse = { + data: { + add_repositories_to_project: { + id: string; + provider_data: Record; + } | null; + }; + errors?: { code: number; message: string }[]; +}; + +export interface RemoveRepositoriesFromWorkspaceResponse { + data: { + remove_repositories_from_project: { + id: string; + } | null; + }; + errors?: { code: number; message: string }[]; +} + +export interface AddWorkspaceRepoDescriptor { + owner: string; + repoName: string; +} + +// TODO@ramint Switch to using repo id once that is no longer bugged +export interface RemoveWorkspaceRepoDescriptor { + owner: string; + repoName: string; +} diff --git a/src/plus/workspaces/workspacesApi.ts b/src/plus/workspaces/workspacesApi.ts index dc91b3d5f4f04..948b3506d6fba 100644 --- a/src/plus/workspaces/workspacesApi.ts +++ b/src/plus/workspaces/workspacesApi.ts @@ -3,11 +3,12 @@ import type { Container } from '../../container'; import { log } from '../../system/decorators/log'; import { Logger } from '../../system/logger'; import type { GraphQLRequest, ServerConnection } from '../gk/serverConnection'; +import type { CloudWorkspaceData } from './models/cloudWorkspace'; +import { CloudWorkspaceProviderInputType } from './models/cloudWorkspace'; import type { AddRepositoriesToWorkspaceResponse, AddWorkspaceRepoDescriptor, CloudWorkspaceConnection, - CloudWorkspaceData, CreateWorkspaceResponse, DeleteWorkspaceResponse, RemoveRepositoriesFromWorkspaceResponse, @@ -15,8 +16,8 @@ import type { WorkspaceRepositoriesResponse, WorkspaceResponse, WorkspacesResponse, -} from './models'; -import { CloudWorkspaceProviderInputType, defaultWorkspaceCount, defaultWorkspaceRepoCount } from './models'; +} from './models/workspaces'; +import { defaultWorkspaceCount, defaultWorkspaceRepoCount } from './models/workspaces'; export class WorkspacesApi { constructor( diff --git a/src/plus/workspaces/workspacesPathMappingProvider.ts b/src/plus/workspaces/workspacesPathMappingProvider.ts index b7c185f95f5a5..00a1a965ff762 100644 --- a/src/plus/workspaces/workspacesPathMappingProvider.ts +++ b/src/plus/workspaces/workspacesPathMappingProvider.ts @@ -1,5 +1,6 @@ import type { Uri } from 'vscode'; -import type { LocalWorkspaceFileData, WorkspaceAutoAddSetting } from './models'; +import type { LocalWorkspaceFileData } from './models/localWorkspace'; +import type { WorkspaceAutoAddSetting } from './models/workspaces'; export interface WorkspacesPathMappingProvider { getCloudWorkspaceRepoPath(cloudWorkspaceId: string, repoId: string): Promise; diff --git a/src/plus/workspaces/workspacesService.ts b/src/plus/workspaces/workspacesService.ts index 363a94540fad3..a1fa2b8a91ca4 100644 --- a/src/plus/workspaces/workspacesService.ts +++ b/src/plus/workspaces/workspacesService.ts @@ -6,37 +6,35 @@ import type { GitRemote } from '../../git/models/remote'; import { RemoteResourceType } from '../../git/models/remoteResource'; import { Repository } from '../../git/models/repository'; import { showRepositoriesPicker } from '../../quickpicks/repositoryPicker'; +import type { OpenWorkspaceLocation } from '../../system/-webview/utils'; +import { openWorkspace } from '../../system/-webview/utils'; import { log } from '../../system/decorators/log'; import { normalizePath } from '../../system/path'; -import type { OpenWorkspaceLocation } from '../../system/vscode/utils'; -import { openWorkspace } from '../../system/vscode/utils'; -import { isSubscriptionStatePaidOrTrial } from '../gk/account/subscription'; -import type { SubscriptionChangeEvent } from '../gk/account/subscriptionService'; import type { ServerConnection } from '../gk/serverConnection'; +import type { SubscriptionChangeEvent } from '../gk/subscriptionService'; +import { isSubscriptionStatePaidOrTrial } from '../gk/utils/subscription.utils'; +import type { CloudWorkspaceData, CloudWorkspaceRepositoryDescriptor } from './models/cloudWorkspace'; +import { + CloudWorkspace, + CloudWorkspaceProviderInputType, + CloudWorkspaceProviderType, + cloudWorkspaceProviderTypeToRemoteProviderId, +} from './models/cloudWorkspace'; +import type { LocalWorkspaceData, LocalWorkspaceRepositoryDescriptor } from './models/localWorkspace'; +import { LocalWorkspace } from './models/localWorkspace'; import type { AddWorkspaceRepoDescriptor, - CloudWorkspaceData, - CloudWorkspaceRepositoryDescriptor, GetWorkspacesResponse, LoadCloudWorkspacesResponse, LoadLocalWorkspacesResponse, - LocalWorkspaceData, - LocalWorkspaceRepositoryDescriptor, RemoteDescriptor, RepositoryMatch, WorkspaceAutoAddSetting, WorkspaceRepositoriesByName, WorkspaceRepositoryRelation, WorkspacesResponse, -} from './models'; -import { - CloudWorkspace, - CloudWorkspaceProviderInputType, - CloudWorkspaceProviderType, - cloudWorkspaceProviderTypeToRemoteProviderId, - LocalWorkspace, - WorkspaceAddRepositoriesChoice, -} from './models'; +} from './models/workspaces'; +import { WorkspaceAddRepositoriesChoice } from './models/workspaces'; import { WorkspacesApi } from './workspacesApi'; import type { WorkspacesPathMappingProvider } from './workspacesPathMappingProvider'; diff --git a/src/quickpicks/aiModelPicker.ts b/src/quickpicks/aiModelPicker.ts index 21a2292fc960f..0025d8d99b1ac 100644 --- a/src/quickpicks/aiModelPicker.ts +++ b/src/quickpicks/aiModelPicker.ts @@ -4,8 +4,8 @@ import type { AIModel } from '../ai/aiProviderService'; import type { AIModels, AIProviders } from '../constants.ai'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { executeCommand } from '../system/vscode/command'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; +import { executeCommand } from '../system/-webview/command'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; export interface ModelQuickPickItem extends QuickPickItem { model: AIModel; diff --git a/src/quickpicks/branchPicker.ts b/src/quickpicks/branchPicker.ts index 945cf7f8daad9..ca09991e8f667 100644 --- a/src/quickpicks/branchPicker.ts +++ b/src/quickpicks/branchPicker.ts @@ -3,7 +3,7 @@ import { window } from 'vscode'; import { getBranches } from '../commands/quickCommand.steps'; import type { GitBranch } from '../git/models/branch'; import type { Repository } from '../git/models/repository'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import type { BranchQuickPickItem } from './items/gitWizard'; export async function showBranchPicker( diff --git a/src/quickpicks/commitPicker.ts b/src/quickpicks/commitPicker.ts index 0eadd46cae241..b6ba54490955b 100644 --- a/src/quickpicks/commitPicker.ts +++ b/src/quickpicks/commitPicker.ts @@ -5,12 +5,12 @@ import { Container } from '../container'; import type { GitCommit, GitStashCommit } from '../git/models/commit'; import type { GitLog } from '../git/models/log'; import type { GitStash } from '../git/models/stash'; +import { configuration } from '../system/-webview/configuration'; +import type { KeyboardScope } from '../system/-webview/keyboard'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { filterMap } from '../system/array'; import { filter, map } from '../system/iterable'; import { isPromise } from '../system/promise'; -import { configuration } from '../system/vscode/configuration'; -import type { KeyboardScope } from '../system/vscode/keyboard'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; import { CommandQuickPickItem } from './items/common'; import type { DirectiveQuickPickItem } from './items/directive'; import { createDirectiveQuickPickItem, Directive, isDirectiveQuickPickItem } from './items/directive'; diff --git a/src/quickpicks/contributorsPicker.ts b/src/quickpicks/contributorsPicker.ts index 8c37552c5e39a..6678192ee9ea1 100644 --- a/src/quickpicks/contributorsPicker.ts +++ b/src/quickpicks/contributorsPicker.ts @@ -4,14 +4,14 @@ import { ClearQuickInputButton } from '../commands/quickCommand.buttons'; import { GlyphChars, quickPickTitleMaxChars } from '../constants'; import type { Container } from '../container'; import type { GitContributor } from '../git/models/contributor'; -import type { ContributorQuickPickItem } from '../git/models/contributor.quickpick'; -import { createContributorQuickPickItem } from '../git/models/contributor.quickpick'; import type { Repository } from '../git/models/repository'; -import { sortContributors } from '../git/utils/vscode/sorting'; +import type { ContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick'; +import { createContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick'; +import { sortContributors } from '../git/utils/-webview/sorting'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { debounce } from '../system/function'; import { defer } from '../system/promise'; import { pad, truncate } from '../system/string'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; export async function showContributorsPicker( container: Container, diff --git a/src/quickpicks/items/commits.ts b/src/quickpicks/items/commits.ts index 9d42b472f62f5..3303b8e0d9d0e 100644 --- a/src/quickpicks/items/commits.ts +++ b/src/quickpicks/items/commits.ts @@ -10,9 +10,11 @@ import { browseAtRevision } from '../../git/actions'; import * as CommitActions from '../../git/actions/commit'; import { CommitFormatter } from '../../git/formatters/commitFormatter'; import type { GitCommit } from '../../git/models/commit'; -import type { GitFile, GitFileChange } from '../../git/models/file'; -import { getGitFileFormattedDirectory, getGitFileStatusThemeIcon } from '../../git/models/file'; -import type { GitStatusFile } from '../../git/models/status'; +import type { GitFile } from '../../git/models/file'; +import type { GitFileChange } from '../../git/models/fileChange'; +import type { GitStatusFile } from '../../git/models/statusFile'; +import { getGitFileFormattedDirectory } from '../../git/utils/-webview/file.utils'; +import { getGitFileStatusThemeIcon } from '../../git/utils/-webview/icons'; import { basename } from '../../system/path'; import { pad } from '../../system/string'; import type { CompareResultsNode } from '../../views/nodes/compareResultsNode'; diff --git a/src/quickpicks/items/gitWizard.ts b/src/quickpicks/items/gitWizard.ts index 455ecb38a997d..8a9ecb5a76260 100644 --- a/src/quickpicks/items/gitWizard.ts +++ b/src/quickpicks/items/gitWizard.ts @@ -10,16 +10,16 @@ import type { GitBranch } from '../../git/models/branch'; import type { GitCommit, GitStashCommit } from '../../git/models/commit'; import { isStash } from '../../git/models/commit'; import type { GitReference } from '../../git/models/reference'; -import { createReference } from '../../git/models/reference.utils'; import type { GitRemote } from '../../git/models/remote'; -import { getRemoteUpstreamDescription } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; -import { isRevisionRange, shortenRevision } from '../../git/models/revision.utils'; import type { GitTag } from '../../git/models/tag'; -import { getBranchIconPath, getWorktreeBranchIconPath } from '../../git/utils/vscode/icons'; +import { getBranchIconPath, getWorktreeBranchIconPath } from '../../git/utils/-webview/icons'; +import { createReference } from '../../git/utils/reference.utils'; +import { getRemoteUpstreamDescription } from '../../git/utils/remote.utils'; +import { isRevisionRange, shortenRevision } from '../../git/utils/revision.utils'; +import { configuration } from '../../system/-webview/configuration'; import { fromNow } from '../../system/date'; import { pad } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; import type { QuickPickItemOfT } from './common'; import { CommandQuickPickItem } from './common'; diff --git a/src/quickpicks/modePicker.ts b/src/quickpicks/modePicker.ts index 129eaa3aa18d2..9603dbb61d918 100644 --- a/src/quickpicks/modePicker.ts +++ b/src/quickpicks/modePicker.ts @@ -1,7 +1,7 @@ import type { QuickPickItem } from 'vscode'; import { window } from 'vscode'; import { GlyphChars } from '../constants'; -import { configuration } from '../system/vscode/configuration'; +import { configuration } from '../system/-webview/configuration'; export interface ModesQuickPickItem extends QuickPickItem { key: string | undefined; diff --git a/src/quickpicks/organizationMembersPicker.ts b/src/quickpicks/organizationMembersPicker.ts index dfe6a938110e8..dc7376fc0f471 100644 --- a/src/quickpicks/organizationMembersPicker.ts +++ b/src/quickpicks/organizationMembersPicker.ts @@ -2,7 +2,7 @@ import type { Disposable } from 'vscode'; import { window } from 'vscode'; import { getAvatarUri } from '../avatars'; import { ClearQuickInputButton } from '../commands/quickCommand.buttons'; -import type { OrganizationMember } from '../plus/gk/account/organization'; +import type { OrganizationMember } from '../plus/gk/models/organization'; import { debounce } from '../system/function'; import { defer } from '../system/promise'; import { sortCompare } from '../system/string'; diff --git a/src/quickpicks/referencePicker.ts b/src/quickpicks/referencePicker.ts index 751822c3b2350..b576d1de30363 100644 --- a/src/quickpicks/referencePicker.ts +++ b/src/quickpicks/referencePicker.ts @@ -9,11 +9,11 @@ import { showDetailsView } from '../git/actions/commit'; import { reveal as revealTag } from '../git/actions/tag'; import type { GitBranch } from '../git/models/branch'; import type { GitReference } from '../git/models/reference'; -import { isBranchReference, isRevisionReference, isTagReference } from '../git/models/reference.utils'; import type { GitTag } from '../git/models/tag'; -import type { BranchSortOptions, TagSortOptions } from '../git/utils/vscode/sorting'; -import type { KeyboardScope } from '../system/vscode/keyboard'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; +import type { BranchSortOptions, TagSortOptions } from '../git/utils/-webview/sorting'; +import { isBranchReference, isRevisionReference, isTagReference } from '../git/utils/reference.utils'; +import type { KeyboardScope } from '../system/-webview/keyboard'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import type { BranchQuickPickItem, RefQuickPickItem, TagQuickPickItem } from './items/gitWizard'; import { createRefQuickPickItem } from './items/gitWizard'; diff --git a/src/quickpicks/remotePicker.ts b/src/quickpicks/remotePicker.ts index e4c7adc916576..c8a2c7342a9b8 100644 --- a/src/quickpicks/remotePicker.ts +++ b/src/quickpicks/remotePicker.ts @@ -2,7 +2,7 @@ import type { Disposable } from 'vscode'; import { window } from 'vscode'; import { SetRemoteAsDefaultQuickInputButton } from '../commands/quickCommand.buttons'; import type { GitRemote } from '../git/models/remote'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import type { RemoteQuickPickItem } from './items/gitWizard'; import { createRemoteQuickPickItem } from './items/gitWizard'; diff --git a/src/quickpicks/remoteProviderPicker.ts b/src/quickpicks/remoteProviderPicker.ts index 58d0296699c90..5891885bd9e36 100644 --- a/src/quickpicks/remoteProviderPicker.ts +++ b/src/quickpicks/remoteProviderPicker.ts @@ -6,19 +6,17 @@ import type { Keys } from '../constants'; import { GlyphChars } from '../constants'; import { GlCommand } from '../constants.commands'; import { Container } from '../container'; -import { - getBranchNameWithoutRemote, - getDefaultBranchName, - getRemoteNameFromBranchName, -} from '../git/models/branch.utils'; import type { GitRemote } from '../git/models/remote'; -import { getHighlanderProviders } from '../git/models/remote'; import type { RemoteResource } from '../git/models/remoteResource'; -import { getNameFromRemoteResource, RemoteResourceType } from '../git/models/remoteResource'; +import { RemoteResourceType } from '../git/models/remoteResource'; import type { RemoteProvider } from '../git/remotes/remoteProvider'; +import { getDefaultBranchName } from '../git/utils/-webview/branch.utils'; +import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '../git/utils/branch.utils'; +import { getHighlanderProviders } from '../git/utils/remote.utils'; +import { getNameFromRemoteResource } from '../git/utils/remoteResource.utils'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { filterMap } from '../system/array'; import { getSettledValue } from '../system/promise'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; import { CommandQuickPickItem } from './items/common'; export class ConfigureCustomRemoteProviderCommandQuickPickItem extends CommandQuickPickItem { diff --git a/src/quickpicks/repositoryPicker.ts b/src/quickpicks/repositoryPicker.ts index f957f94e7494a..5541639fa3c9b 100644 --- a/src/quickpicks/repositoryPicker.ts +++ b/src/quickpicks/repositoryPicker.ts @@ -2,9 +2,9 @@ import type { Disposable, TextEditor, Uri } from 'vscode'; import { window } from 'vscode'; import { Container } from '../container'; import type { Repository } from '../git/models/repository'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { filterMap } from '../system/array'; import { map } from '../system/iterable'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; import { CommandQuickPickItem } from './items/common'; import type { RepositoryQuickPickItem } from './items/gitWizard'; import { createRepositoryQuickPickItem } from './items/gitWizard'; diff --git a/src/quickpicks/revisionFilesPicker.ts b/src/quickpicks/revisionFilesPicker.ts index c13e086332a18..a8e4206b6d29f 100644 --- a/src/quickpicks/revisionFilesPicker.ts +++ b/src/quickpicks/revisionFilesPicker.ts @@ -4,10 +4,10 @@ import type { Keys } from '../constants'; import type { Container } from '../container'; import type { GitRevisionReference } from '../git/models/reference'; import type { GitTreeEntry } from '../git/models/tree'; +import type { KeyboardScope } from '../system/-webview/keyboard'; +import { splitPath } from '../system/-webview/path'; +import { getQuickPickIgnoreFocusOut } from '../system/-webview/utils'; import { filterMap } from '../system/iterable'; -import type { KeyboardScope } from '../system/vscode/keyboard'; -import { splitPath } from '../system/vscode/path'; -import { getQuickPickIgnoreFocusOut } from '../system/vscode/utils'; import type { QuickPickItemOfT } from './items/common'; export type RevisionQuickPickItem = QuickPickItemOfT; diff --git a/src/repositories.ts b/src/repositories.ts index 797d366419001..ae30bd253723b 100644 --- a/src/repositories.ts +++ b/src/repositories.ts @@ -4,9 +4,9 @@ import { Schemes } from './constants'; import type { RevisionUriData } from './git/gitProvider'; import { decodeGitLensRevisionUriAuthority } from './git/gitUri.authority'; import type { Repository } from './git/models/repository'; +import { addVslsPrefixIfNeeded } from './system/-webview/path'; import { normalizePath } from './system/path'; import { UriTrie } from './system/trie'; -import { addVslsPrefixIfNeeded } from './system/vscode/path'; const slash = 47; //CharCode.Slash; diff --git a/src/statusbar/statusBarController.ts b/src/statusbar/statusBarController.ts index 888ea91d7af06..e52220eebb58e 100644 --- a/src/statusbar/statusBarController.ts +++ b/src/statusbar/statusBarController.ts @@ -8,6 +8,9 @@ import type { Container } from '../container'; import { CommitFormatter } from '../git/formatters/commitFormatter'; import type { PullRequest } from '../git/models/pullRequest'; import { detailsMessage } from '../hovers/hovers'; +import { createCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { isTrackableTextEditor } from '../system/-webview/utils'; import { createMarkdownCommandLink } from '../system/commands'; import { debug } from '../system/decorators/log'; import { once } from '../system/event'; @@ -15,9 +18,6 @@ import { Logger } from '../system/logger'; import { getLogScope, setLogScopeExit } from '../system/logger.scope'; import type { MaybePausedResult } from '../system/promise'; import { getSettledValue, pauseOnCancelOrTimeout } from '../system/promise'; -import { createCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { isTrackableTextEditor } from '../system/vscode/utils'; import type { LinesChangeEvent, LineState } from '../trackers/lineTracker'; export class StatusBarController implements Disposable { diff --git a/src/system/vscode/asyncDebouncer.ts b/src/system/-webview/asyncDebouncer.ts similarity index 100% rename from src/system/vscode/asyncDebouncer.ts rename to src/system/-webview/asyncDebouncer.ts diff --git a/src/system/vscode/cancellation.ts b/src/system/-webview/cancellation.ts similarity index 100% rename from src/system/vscode/cancellation.ts rename to src/system/-webview/cancellation.ts diff --git a/src/system/vscode/command.ts b/src/system/-webview/command.ts similarity index 98% rename from src/system/vscode/command.ts rename to src/system/-webview/command.ts index 9cda48d0c652e..999152017ea8f 100644 --- a/src/system/vscode/command.ts +++ b/src/system/-webview/command.ts @@ -1,7 +1,7 @@ import type { Command, Disposable, Uri } from 'vscode'; import { commands } from 'vscode'; import type { Action, ActionContext } from '../../api/gitlens'; -import type { GlCommandBase } from '../../commands/base'; +import type { GlCommandBase } from '../../commands/commandBase'; import type { CodeLensCommand } from '../../config'; import type { Commands, CoreCommands, CoreGitCommands, GlCommands } from '../../constants.commands'; import { actionCommandPrefix, GlCommand } from '../../constants.commands'; diff --git a/src/system/vscode/configuration.ts b/src/system/-webview/configuration.ts similarity index 100% rename from src/system/vscode/configuration.ts rename to src/system/-webview/configuration.ts diff --git a/src/system/vscode/context.ts b/src/system/-webview/context.ts similarity index 100% rename from src/system/vscode/context.ts rename to src/system/-webview/context.ts diff --git a/src/system/vscode/formatPath.ts b/src/system/-webview/formatPath.ts similarity index 100% rename from src/system/vscode/formatPath.ts rename to src/system/-webview/formatPath.ts diff --git a/src/system/vscode/keyboard.ts b/src/system/-webview/keyboard.ts similarity index 100% rename from src/system/vscode/keyboard.ts rename to src/system/-webview/keyboard.ts diff --git a/src/system/vscode/path.ts b/src/system/-webview/path.ts similarity index 100% rename from src/system/vscode/path.ts rename to src/system/-webview/path.ts diff --git a/src/system/vscode/scm.ts b/src/system/-webview/scm.ts similarity index 100% rename from src/system/vscode/scm.ts rename to src/system/-webview/scm.ts diff --git a/src/system/vscode/serialize.ts b/src/system/-webview/serialize.ts similarity index 93% rename from src/system/vscode/serialize.ts rename to src/system/-webview/serialize.ts index ba9558de03912..f9029f39c1531 100644 --- a/src/system/vscode/serialize.ts +++ b/src/system/-webview/serialize.ts @@ -1,4 +1,5 @@ import { Uri } from 'vscode'; +import { Container } from '../../container'; import type { Branded } from '../brand'; // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type @@ -30,6 +31,7 @@ export function serialize(obj: T | undefined): Serialized | if (value instanceof Function || value instanceof Error) return undefined; if (value instanceof RegExp) return value.toString(); if (value instanceof Uri) return value.toString(); + if (value instanceof Container) return undefined; const original = this[key]; return original instanceof Date diff --git a/src/system/vscode/storage.ts b/src/system/-webview/storage.ts similarity index 100% rename from src/system/vscode/storage.ts rename to src/system/-webview/storage.ts diff --git a/src/system/-webview/timeline.ts b/src/system/-webview/timeline.ts new file mode 100644 index 0000000000000..9868d24362658 --- /dev/null +++ b/src/system/-webview/timeline.ts @@ -0,0 +1,18 @@ +import type { GitTimelineItem, TimelineItem } from 'vscode'; + +function isTimelineItem(item: any): item is TimelineItem { + if (item == null) return false; + + return (item as TimelineItem).timestamp != null && (item as TimelineItem).label != null; +} + +export function isGitTimelineItem(item: any): item is GitTimelineItem { + if (item == null) return false; + + return ( + isTimelineItem(item) && + (item as GitTimelineItem).ref != null && + (item as GitTimelineItem).previousRef != null && + (item as GitTimelineItem).message != null + ); +} diff --git a/src/system/vscode/uriMap.ts b/src/system/-webview/uriMap.ts similarity index 100% rename from src/system/vscode/uriMap.ts rename to src/system/-webview/uriMap.ts diff --git a/src/system/vscode/utils.ts b/src/system/-webview/utils.ts similarity index 100% rename from src/system/vscode/utils.ts rename to src/system/-webview/utils.ts diff --git a/src/system/vscode/vscode.ts b/src/system/-webview/vscode.ts similarity index 100% rename from src/system/vscode/vscode.ts rename to src/system/-webview/vscode.ts diff --git a/src/system/__tests__/path.test.ts b/src/system/__tests__/path.test.ts index a0022aa452a85..a57f5fd34b632 100644 --- a/src/system/__tests__/path.test.ts +++ b/src/system/__tests__/path.test.ts @@ -1,6 +1,6 @@ import * as assert from 'assert'; import { suite, test } from 'mocha'; -import { splitPath } from '../vscode/path'; +import { splitPath } from '../-webview/path'; const smallDiskNameRegex = /^[a-z]:\//gm; function capitalizeDiskName(path: string) { diff --git a/src/system/decorators/gate.ts b/src/system/decorators/-webview/gate.ts similarity index 96% rename from src/system/decorators/gate.ts rename to src/system/decorators/-webview/gate.ts index 680a21a18a6e5..e5bd165d96249 100644 --- a/src/system/decorators/gate.ts +++ b/src/system/decorators/-webview/gate.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import { isPromise } from '../promise'; +import { isPromise } from '../../promise'; import { resolveProp } from './resolver'; export function gate any>(resolver?: (...args: Parameters) => string) { diff --git a/src/system/decorators/memoize.ts b/src/system/decorators/-webview/memoize.ts similarity index 100% rename from src/system/decorators/memoize.ts rename to src/system/decorators/-webview/memoize.ts diff --git a/src/system/decorators/resolver.ts b/src/system/decorators/-webview/resolver.ts similarity index 87% rename from src/system/decorators/resolver.ts rename to src/system/decorators/-webview/resolver.ts index fcf2a95794d56..27131c6646034 100644 --- a/src/system/decorators/resolver.ts +++ b/src/system/decorators/-webview/resolver.ts @@ -1,9 +1,9 @@ import { Uri } from 'vscode'; -import { isContainer } from '../../container'; -import { isBranch } from '../../git/models/branch'; -import { isCommit } from '../../git/models/commit'; -import { isTag } from '../../git/models/tag'; -import { isViewNode } from '../../views/nodes/abstract/viewNode'; +import { isContainer } from '../../../container'; +import { isBranch } from '../../../git/models/branch'; +import { isCommit } from '../../../git/models/commit'; +import { isTag } from '../../../git/models/tag'; +import { isViewNode } from '../../../views/nodes/abstract/viewNode'; function replacer(key: string, value: any): any { if (key === '' || value == null || typeof value !== 'object') return value; diff --git a/src/telemetry/telemetry.ts b/src/telemetry/telemetry.ts index 3f90442179b0b..a1ba5915023de 100644 --- a/src/telemetry/telemetry.ts +++ b/src/telemetry/telemetry.ts @@ -5,7 +5,7 @@ import { getProxyAgent } from '@env/fetch'; import { getPlatform } from '@env/platform'; import type { Source, TelemetryEventData, TelemetryEvents, TelemetryGlobalContext } from '../constants.telemetry'; import type { Container } from '../container'; -import { configuration } from '../system/vscode/configuration'; +import { configuration } from '../system/-webview/configuration'; export interface TelemetryContext { env: string; diff --git a/src/telemetry/usageTracker.ts b/src/telemetry/usageTracker.ts index ff4b81fa3469e..18e9142a357ab 100644 --- a/src/telemetry/usageTracker.ts +++ b/src/telemetry/usageTracker.ts @@ -2,8 +2,8 @@ import type { Disposable, Event } from 'vscode'; import { EventEmitter } from 'vscode'; import type { TrackedUsage, TrackedUsageKeys } from '../constants.telemetry'; import type { Container } from '../container'; +import type { Storage } from '../system/-webview/storage'; import { updateRecordValue } from '../system/object'; -import type { Storage } from '../system/vscode/storage'; export type UsageChangeEvent = { /** diff --git a/src/telemetry/walkthroughStateProvider.ts b/src/telemetry/walkthroughStateProvider.ts index 138c79de7559e..f426ca53683f8 100644 --- a/src/telemetry/walkthroughStateProvider.ts +++ b/src/telemetry/walkthroughStateProvider.ts @@ -4,9 +4,9 @@ import { GlCommand } from '../constants.commands'; import { SubscriptionState } from '../constants.subscription'; import type { TrackedUsageKeys } from '../constants.telemetry'; import type { Container } from '../container'; -import type { SubscriptionChangeEvent } from '../plus/gk/account/subscriptionService'; +import type { SubscriptionChangeEvent } from '../plus/gk/subscriptionService'; +import { setContext } from '../system/-webview/context'; import { wait } from '../system/promise'; -import { setContext } from '../system/vscode/context'; import type { UsageChangeEvent } from './usageTracker'; export enum WalkthroughContextKeys { diff --git a/src/terminal/linkProvider.ts b/src/terminal/linkProvider.ts index 0df73b992db7d..af4e2c78b1a1d 100644 --- a/src/terminal/linkProvider.ts +++ b/src/terminal/linkProvider.ts @@ -9,10 +9,10 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import type { PagedResult } from '../git/gitProvider'; import type { GitBranch } from '../git/models/branch'; -import { getBranchNameWithoutRemote } from '../git/models/branch.utils'; -import { createReference } from '../git/models/reference.utils'; import type { GitTag } from '../git/models/tag'; -import { configuration } from '../system/vscode/configuration'; +import { getBranchNameWithoutRemote } from '../git/utils/branch.utils'; +import { createReference } from '../git/utils/reference.utils'; +import { configuration } from '../system/-webview/configuration'; const commandsRegexShared = /\b(g(?:it)?\b\s*)\b(branch|checkout|cherry-pick|fetch|grep|log|merge|pull|push|rebase|reset|revert|show|stash|status|tag)\b/gi; diff --git a/src/trackers/documentTracker.ts b/src/trackers/documentTracker.ts index eac0ce1924ba4..c6368a694b695 100644 --- a/src/trackers/documentTracker.ts +++ b/src/trackers/documentTracker.ts @@ -16,14 +16,14 @@ import type { GitUri } from '../git/gitUri'; import { isGitUri } from '../git/gitUri'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { UriSet } from '../system/-webview/uriMap'; +import { findTextDocument, isVisibleDocument } from '../system/-webview/utils'; import { debug } from '../system/decorators/log'; import { once } from '../system/event'; import type { Deferrable } from '../system/function'; import { debounce } from '../system/function'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; -import { UriSet } from '../system/vscode/uriMap'; -import { findTextDocument, isVisibleDocument } from '../system/vscode/utils'; import type { TrackedGitDocument } from './trackedDocument'; import { createTrackedGitDocument } from './trackedDocument'; diff --git a/src/trackers/lineTracker.ts b/src/trackers/lineTracker.ts index 0b832b24ff1e5..eb2dfc5216030 100644 --- a/src/trackers/lineTracker.ts +++ b/src/trackers/lineTracker.ts @@ -2,11 +2,11 @@ import type { Event, Selection, TextEditor, TextEditorSelectionChangeEvent } fro import { Disposable, EventEmitter, window } from 'vscode'; import type { Container } from '../container'; import type { GitCommit } from '../git/models/commit'; +import { isTrackableTextEditor } from '../system/-webview/utils'; import { debug } from '../system/decorators/log'; import type { Deferrable } from '../system/function'; import { debounce } from '../system/function'; import { getLogScope, setLogScopeExit } from '../system/logger.scope'; -import { isTrackableTextEditor } from '../system/vscode/utils'; import type { DocumentBlameStateChangeEvent, DocumentContentChangeEvent, diff --git a/src/trackers/trackedDocument.ts b/src/trackers/trackedDocument.ts index b9b1103aec202..908a9c2d657af 100644 --- a/src/trackers/trackedDocument.ts +++ b/src/trackers/trackedDocument.ts @@ -4,13 +4,13 @@ import { GitUri } from '../git/gitUri'; import type { GitBlame } from '../git/models/blame'; import type { GitDiffFile } from '../git/models/diff'; import type { GitLog } from '../git/models/log'; +import { configuration } from '../system/-webview/configuration'; +import { getEditorIfVisible, isActiveDocument, isVisibleDocument } from '../system/-webview/utils'; import { debug, logName } from '../system/decorators/log'; import type { Deferrable } from '../system/function'; import { debounce } from '../system/function'; import { Logger } from '../system/logger'; import { getLogScope } from '../system/logger.scope'; -import { configuration } from '../system/vscode/configuration'; -import { getEditorIfVisible, isActiveDocument, isVisibleDocument } from '../system/vscode/utils'; import type { DocumentBlameStateChangeEvent, GitDocumentTracker } from './documentTracker'; interface CachedItem { diff --git a/src/uris/deepLinks/deepLink.ts b/src/uris/deepLinks/deepLink.ts index 4b8e1ac0f3e1c..dad2b2d5bb4e9 100644 --- a/src/uris/deepLinks/deepLink.ts +++ b/src/uris/deepLinks/deepLink.ts @@ -4,7 +4,7 @@ import { GlCommand } from '../../constants.commands'; import type { GitReference } from '../../git/models/reference'; import type { GitRemote } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; -import type { OpenWorkspaceLocation } from '../../system/vscode/utils'; +import type { OpenWorkspaceLocation } from '../../system/-webview/utils'; export type UriTypes = 'link'; diff --git a/src/uris/deepLinks/deepLinkService.ts b/src/uris/deepLinks/deepLinkService.ts index d2b7a9da89949..db0da1194a4ee 100644 --- a/src/uris/deepLinks/deepLinkService.ts +++ b/src/uris/deepLinks/deepLinkService.ts @@ -6,28 +6,29 @@ import type { Container } from '../../container'; import { executeGitCommand } from '../../git/actions'; import { openComparisonChanges, openFileAtRevision } from '../../git/actions/commit'; import type { GitBranch } from '../../git/models/branch'; -import { getBranchNameWithoutRemote } from '../../git/models/branch.utils'; import type { GitCommit } from '../../git/models/commit'; import type { GitReference } from '../../git/models/reference'; -import { createReference } from '../../git/models/reference.utils'; import type { Repository, RepositoryChangeEvent } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; -import { isSha } from '../../git/models/revision.utils'; +import type { RepositoryIdentity } from '../../git/models/repositoryIdentities'; +import { missingRepositoryId } from '../../git/models/repositoryIdentities'; import type { GitTag } from '../../git/models/tag'; import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; -import type { RepositoryIdentity } from '../../gk/models/repositoryIdentities'; -import { missingRepositoryId } from '../../gk/models/repositoryIdentities'; -import { ensureAccount, ensurePaidPlan } from '../../plus/utils'; +import { getBranchNameWithoutRemote } from '../../git/utils/branch.utils'; +import { createReference } from '../../git/utils/reference.utils'; +import { isSha } from '../../git/utils/revision.utils'; +import { ensureAccount } from '../../plus/gk/utils/-webview/acount.utils'; +import { ensurePaidPlan } from '../../plus/gk/utils/-webview/plus.utils'; import { createQuickPickSeparator } from '../../quickpicks/items/common'; +import { executeCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import type { OpenWorkspaceLocation } from '../../system/-webview/utils'; +import { findOrOpenEditor, openWorkspace } from '../../system/-webview/utils'; import { debug } from '../../system/decorators/log'; import { once } from '../../system/event'; import { Logger } from '../../system/logger'; import { maybeUri, normalizePath } from '../../system/path'; import { fromBase64 } from '../../system/string'; -import { executeCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import type { OpenWorkspaceLocation } from '../../system/vscode/utils'; -import { findOrOpenEditor, openWorkspace } from '../../system/vscode/utils'; import { showInspectView } from '../../webviews/commitDetails/actions'; import type { ShowWipArgs } from '../../webviews/commitDetails/protocol'; import type { ShowInCommitGraphCommandArgs } from '../../webviews/plus/graph/protocol'; diff --git a/src/uris/uriService.ts b/src/uris/uriService.ts index e43d2c92f784c..dc775255a1398 100644 --- a/src/uris/uriService.ts +++ b/src/uris/uriService.ts @@ -1,8 +1,8 @@ import type { Disposable, Event, Uri, UriHandler } from 'vscode'; import { EventEmitter, window } from 'vscode'; import type { Container } from '../container'; -import { AuthenticationUriPathPrefix, LoginUriPathPrefix } from '../plus/gk/account/authenticationConnection'; -import { SubscriptionUpdatedUriPathPrefix } from '../plus/gk/account/subscription'; +import { AuthenticationUriPathPrefix, LoginUriPathPrefix } from '../plus/gk/authenticationConnection'; +import { SubscriptionUpdatedUriPathPrefix } from '../plus/gk/utils/subscription.utils'; import { CloudIntegrationAuthenticationUriPathPrefix } from '../plus/integrations/authentication/models'; import { log } from '../system/decorators/log'; diff --git a/src/views/branchesView.ts b/src/views/branchesView.ts index 1e2621291456c..667010e84e0e7 100644 --- a/src/views/branchesView.ts +++ b/src/views/branchesView.ts @@ -7,14 +7,14 @@ import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; import type { GitBranchReference, GitRevisionReference } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; -import { getWorktreesByBranch } from '../git/models/worktree.utils'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { getWorktreesByBranch } from '../git/utils/-webview/worktree.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/views/commitsView.ts b/src/views/commitsView.ts index d7b5a5a7cd11c..87ad8142aef73 100644 --- a/src/views/commitsView.ts +++ b/src/views/commitsView.ts @@ -7,21 +7,21 @@ import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import type { GitCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; -import { matchContributor } from '../git/models/contributor'; import type { GitRevisionReference } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { getLastFetchedUpdateInterval } from '../git/models/repository.utils'; import type { GitUser } from '../git/models/user'; +import { matchContributor } from '../git/utils/contributor.utils'; +import { getLastFetchedUpdateInterval } from '../git/utils/fetch.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; import { showContributorsPicker } from '../quickpicks/contributorsPicker'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; -import { gate } from '../system/decorators/gate'; +import { createCommand, executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { gate } from '../system/decorators/-webview/gate'; import { debug } from '../system/decorators/log'; import { disposableInterval } from '../system/function'; -import { createCommand, executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; import type { UsageChangeEvent } from '../telemetry/usageTracker'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; diff --git a/src/views/contributorsView.ts b/src/views/contributorsView.ts index fd929b4918439..97dfc50b30e6a 100644 --- a/src/views/contributorsView.ts +++ b/src/views/contributorsView.ts @@ -8,12 +8,12 @@ import { GitUri } from '../git/gitUri'; import type { GitContributor } from '../git/models/contributor'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; -import { gate } from '../system/decorators/gate'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { gate } from '../system/decorators/-webview/gate'; import { debug } from '../system/decorators/log'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/views/draftsView.ts b/src/views/draftsView.ts index e740ad642a700..264d5cd7ff000 100644 --- a/src/views/draftsView.ts +++ b/src/views/draftsView.ts @@ -7,12 +7,12 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { AuthenticationRequiredError } from '../errors'; import { unknownGitUri } from '../git/gitUri'; -import type { Draft } from '../gk/models/drafts'; -import { ensurePlusFeaturesEnabled } from '../plus/gk/utils'; -import { gate } from '../system/decorators/gate'; +import type { Draft } from '../plus/drafts/models/drafts'; +import { ensurePlusFeaturesEnabled } from '../plus/gk/utils/-webview/plus.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { groupByFilterMap } from '../system/iterable'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; import { CacheableChildrenViewNode } from './nodes/abstract/cacheableChildrenViewNode'; import { DraftNode } from './nodes/draftNode'; import { GroupingNode } from './nodes/groupingNode'; diff --git a/src/views/fileHistoryView.ts b/src/views/fileHistoryView.ts index 396edd6a3029b..b41cc954c2c7e 100644 --- a/src/views/fileHistoryView.ts +++ b/src/views/fileHistoryView.ts @@ -3,9 +3,9 @@ import type { FileHistoryViewConfig } from '../config'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import type { GitUri } from '../git/gitUri'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { FileHistoryTrackerNode } from './nodes/fileHistoryTrackerNode'; import { LineHistoryTrackerNode } from './nodes/lineHistoryTrackerNode'; import { ViewBase } from './viewBase'; diff --git a/src/views/launchpadView.ts b/src/views/launchpadView.ts index 7a22d34ebd0e7..d344e28f814e5 100644 --- a/src/views/launchpadView.ts +++ b/src/views/launchpadView.ts @@ -8,15 +8,15 @@ import type { Container } from '../container'; import { AuthenticationRequiredError } from '../errors'; import { PlusFeatures } from '../features'; import { GitUri, unknownGitUri } from '../git/gitUri'; -import type { SubscriptionChangeEvent } from '../plus/gk/account/subscriptionService'; -import { ensurePlusFeaturesEnabled } from '../plus/gk/utils'; +import type { SubscriptionChangeEvent } from '../plus/gk/subscriptionService'; +import { ensurePlusFeaturesEnabled } from '../plus/gk/utils/-webview/plus.utils'; import type { LaunchpadCommandArgs } from '../plus/launchpad/launchpad'; import type { LaunchpadItem } from '../plus/launchpad/launchpadProvider'; import { groupAndSortLaunchpadItems } from '../plus/launchpad/launchpadProvider'; -import type { LaunchpadGroup } from '../plus/launchpad/models'; -import { launchpadGroupIconMap, launchpadGroupLabelMap } from '../plus/launchpad/models'; -import { createCommand, executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import type { LaunchpadGroup } from '../plus/launchpad/models/launchpad'; +import { launchpadGroupIconMap, launchpadGroupLabelMap } from '../plus/launchpad/models/launchpad'; +import { createCommand, executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { CacheableChildrenViewNode } from './nodes/abstract/cacheableChildrenViewNode'; import type { ClipboardType, ViewNode } from './nodes/abstract/viewNode'; import { ContextValues, getViewNodeId } from './nodes/abstract/viewNode'; diff --git a/src/views/lineHistoryView.ts b/src/views/lineHistoryView.ts index c7152af343320..dfb8fad527657 100644 --- a/src/views/lineHistoryView.ts +++ b/src/views/lineHistoryView.ts @@ -2,9 +2,9 @@ import type { ConfigurationChangeEvent, Disposable } from 'vscode'; import type { LineHistoryViewConfig } from '../config'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { LineHistoryTrackerNode } from './nodes/lineHistoryTrackerNode'; import { ViewBase } from './viewBase'; import { registerViewCommand } from './viewCommands'; diff --git a/src/views/nodes/UncommittedFileNode.ts b/src/views/nodes/UncommittedFileNode.ts index e1eed6906aff7..c0f81d38ac6a8 100644 --- a/src/views/nodes/UncommittedFileNode.ts +++ b/src/views/nodes/UncommittedFileNode.ts @@ -5,7 +5,7 @@ import { GlCommand } from '../../constants.commands'; import { StatusFileFormatter } from '../../git/formatters/statusFormatter'; import { GitUri } from '../../git/gitUri'; import type { GitFile } from '../../git/models/file'; -import { getGitFileStatusIcon } from '../../git/models/file'; +import { getGitFileStatusIcon } from '../../git/utils/fileStatus.utils'; import { dirname, joinPaths } from '../../system/path'; import type { ViewsWithCommits } from '../viewBase'; import { getFileTooltipMarkdown, ViewFileNode } from './abstract/viewFileNode'; diff --git a/src/views/nodes/UncommittedFilesNode.ts b/src/views/nodes/UncommittedFilesNode.ts index b660e5a412224..6341b90055775 100644 --- a/src/views/nodes/UncommittedFilesNode.ts +++ b/src/views/nodes/UncommittedFilesNode.ts @@ -2,7 +2,8 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitUri } from '../../git/gitUri'; import type { GitTrackingState } from '../../git/models/branch'; import type { GitFileWithCommit } from '../../git/models/file'; -import type { GitStatus, GitStatusFile } from '../../git/models/status'; +import type { GitStatus } from '../../git/models/status'; +import type { GitStatusFile } from '../../git/models/statusFile'; import { makeHierarchical } from '../../system/array'; import { flatMap, groupBy } from '../../system/iterable'; import { joinPaths, normalizePath } from '../../system/path'; diff --git a/src/views/nodes/abstract/repositoriesSubscribeableNode.ts b/src/views/nodes/abstract/repositoriesSubscribeableNode.ts index eaa9164670a93..7fbb17386ba04 100644 --- a/src/views/nodes/abstract/repositoriesSubscribeableNode.ts +++ b/src/views/nodes/abstract/repositoriesSubscribeableNode.ts @@ -1,7 +1,7 @@ import { Disposable } from 'vscode'; import type { RepositoriesChangeEvent } from '../../../git/gitProviderService'; import { unknownGitUri } from '../../../git/gitUri'; -import type { SubscriptionChangeEvent } from '../../../plus/gk/account/subscriptionService'; +import type { SubscriptionChangeEvent } from '../../../plus/gk/subscriptionService'; import { debug } from '../../../system/decorators/log'; import { weakEvent } from '../../../system/event'; import { szudzikPairing } from '../../../system/function'; diff --git a/src/views/nodes/abstract/repositoryFolderNode.ts b/src/views/nodes/abstract/repositoryFolderNode.ts index 5de74b78388a9..6aa2865676242 100644 --- a/src/views/nodes/abstract/repositoryFolderNode.ts +++ b/src/views/nodes/abstract/repositoryFolderNode.ts @@ -2,11 +2,11 @@ import type { Disposable } from 'vscode'; import { MarkdownString, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GlyphChars } from '../../../constants'; import type { GitUri } from '../../../git/gitUri'; -import { getHighlanderProviders } from '../../../git/models/remote'; import type { Repository, RepositoryChangeEvent } from '../../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../../git/models/repository'; -import { formatLastFetched } from '../../../git/models/repository.utils'; -import { gate } from '../../../system/decorators/gate'; +import { formatLastFetched } from '../../../git/utils/-webview/repository.utils'; +import { getHighlanderProviders } from '../../../git/utils/remote.utils'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug, log } from '../../../system/decorators/log'; import { weakEvent } from '../../../system/event'; import { basename } from '../../../system/path'; diff --git a/src/views/nodes/abstract/subscribeableViewNode.ts b/src/views/nodes/abstract/subscribeableViewNode.ts index 1f5d388fea58e..e93258486b3f7 100644 --- a/src/views/nodes/abstract/subscribeableViewNode.ts +++ b/src/views/nodes/abstract/subscribeableViewNode.ts @@ -2,7 +2,7 @@ import type { TreeViewVisibilityChangeEvent } from 'vscode'; import { Disposable } from 'vscode'; import type { TreeViewSubscribableNodeTypes } from '../../../constants.views'; import type { GitUri } from '../../../git/gitUri'; -import { gate } from '../../../system/decorators/gate'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug } from '../../../system/decorators/log'; import { weakEvent } from '../../../system/event'; import type { View } from '../../viewBase'; diff --git a/src/views/nodes/abstract/viewFileNode.ts b/src/views/nodes/abstract/viewFileNode.ts index 3e975df5b503e..2d6553161357f 100644 --- a/src/views/nodes/abstract/viewFileNode.ts +++ b/src/views/nodes/abstract/viewFileNode.ts @@ -3,7 +3,7 @@ import type { TreeViewFileNodeTypes } from '../../../constants.views'; import { StatusFileFormatter } from '../../../git/formatters/statusFormatter'; import type { GitUri } from '../../../git/gitUri'; import type { GitFile } from '../../../git/models/file'; -import type { GitStatusFile } from '../../../git/models/status'; +import type { GitStatusFile } from '../../../git/models/statusFile'; import type { View } from '../../viewBase'; import { ViewNode } from './viewNode'; diff --git a/src/views/nodes/abstract/viewNode.ts b/src/views/nodes/abstract/viewNode.ts index 0b983406f15dd..5664818bd6908 100644 --- a/src/views/nodes/abstract/viewNode.ts +++ b/src/views/nodes/abstract/viewNode.ts @@ -12,20 +12,22 @@ import type { GitRemote } from '../../../git/models/remote'; import type { Repository } from '../../../git/models/repository'; import type { GitTag } from '../../../git/models/tag'; import type { GitWorktree } from '../../../git/models/worktree'; -import type { Draft } from '../../../gk/models/drafts'; +import type { Draft } from '../../../plus/drafts/models/drafts'; import type { LaunchpadItem } from '../../../plus/launchpad/launchpadProvider'; -import type { LaunchpadGroup } from '../../../plus/launchpad/models'; +import type { LaunchpadGroup } from '../../../plus/launchpad/models/launchpad'; import { launchpadCategoryToGroupMap, sharedCategoryToLaunchpadActionCategoryMap, -} from '../../../plus/launchpad/models'; +} from '../../../plus/launchpad/models/launchpad'; import type { CloudWorkspace, CloudWorkspaceRepositoryDescriptor, +} from '../../../plus/workspaces/models/cloudWorkspace'; +import type { LocalWorkspace, LocalWorkspaceRepositoryDescriptor, -} from '../../../plus/workspaces/models'; -import { gate } from '../../../system/decorators/gate'; +} from '../../../plus/workspaces/models/localWorkspace'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug, logName } from '../../../system/decorators/log'; import { is as isA } from '../../../system/function'; import { getLoggableName } from '../../../system/logger'; diff --git a/src/views/nodes/abstract/viewRefNode.ts b/src/views/nodes/abstract/viewRefNode.ts index 2735956525f53..5d81d069e33bb 100644 --- a/src/views/nodes/abstract/viewRefNode.ts +++ b/src/views/nodes/abstract/viewRefNode.ts @@ -1,7 +1,7 @@ import type { TreeViewRefFileNodeTypes, TreeViewRefNodeTypes } from '../../../constants.views'; import type { GitUri } from '../../../git/gitUri'; import type { GitReference, GitRevisionReference } from '../../../git/models/reference'; -import { getReferenceLabel } from '../../../git/models/reference.utils'; +import { getReferenceLabel } from '../../../git/utils/reference.utils'; import type { View } from '../../viewBase'; import { ViewFileNode } from './viewFileNode'; import { ViewNode } from './viewNode'; diff --git a/src/views/nodes/autolinkedItemNode.ts b/src/views/nodes/autolinkedItemNode.ts index f80211d244fed..f2e97488c12d3 100644 --- a/src/views/nodes/autolinkedItemNode.ts +++ b/src/views/nodes/autolinkedItemNode.ts @@ -1,8 +1,8 @@ import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import type { Autolink } from '../../autolinks'; import { GitUri } from '../../git/gitUri'; -import type { IssueOrPullRequest } from '../../git/models/issue'; -import { getIssueOrPullRequestMarkdownIcon, getIssueOrPullRequestThemeIcon } from '../../git/utils/vscode/icons'; +import type { IssueOrPullRequest } from '../../git/models/issueOrPullRequest'; +import { getIssueOrPullRequestMarkdownIcon, getIssueOrPullRequestThemeIcon } from '../../git/utils/-webview/icons'; import { fromNow } from '../../system/date'; import { isPromise } from '../../system/promise'; import type { ViewsWithCommits } from '../viewBase'; diff --git a/src/views/nodes/branchNode.ts b/src/views/nodes/branchNode.ts index 6b9faa3766e0f..3060a4b91107c 100644 --- a/src/views/nodes/branchNode.ts +++ b/src/views/nodes/branchNode.ts @@ -8,28 +8,28 @@ import type { Container } from '../../container'; import type { GitUri } from '../../git/gitUri'; import { unknownGitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; -import { getTargetBranchName } from '../../git/models/branch.utils'; import { isStash } from '../../git/models/commit'; import type { GitLog } from '../../git/models/log'; import type { PullRequest, PullRequestState } from '../../git/models/pullRequest'; import type { GitBranchReference } from '../../git/models/reference'; -import { getHighlanderProviders } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; -import { getLastFetchedUpdateInterval } from '../../git/models/repository.utils'; import type { GitUser } from '../../git/models/user'; import type { GitWorktree } from '../../git/models/worktree'; -import { getBranchIconPath, getRemoteIconPath, getWorktreeBranchIconPath } from '../../git/utils/vscode/icons'; +import { getTargetBranchName } from '../../git/utils/-webview/branch.utils'; +import { getBranchIconPath, getRemoteIconPath, getWorktreeBranchIconPath } from '../../git/utils/-webview/icons'; +import { getLastFetchedUpdateInterval } from '../../git/utils/fetch.utils'; +import { getHighlanderProviders } from '../../git/utils/remote.utils'; +import { getContext } from '../../system/-webview/context'; import { fromNow } from '../../system/date'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { log } from '../../system/decorators/log'; -import { memoize } from '../../system/decorators/memoize'; import { weakEvent } from '../../system/event'; import { disposableInterval } from '../../system/function'; import { map } from '../../system/iterable'; import type { Deferred } from '../../system/promise'; import { defer, getSettledValue } from '../../system/promise'; import { pad } from '../../system/string'; -import { getContext } from '../../system/vscode/context'; import type { View, ViewsWithBranches } from '../viewBase'; import { disposeChildren } from '../viewBase'; import { createViewDecorationUri } from '../viewDecorationProvider'; diff --git a/src/views/nodes/branchTrackingStatusFilesNode.ts b/src/views/nodes/branchTrackingStatusFilesNode.ts index acd52c7b3956c..448a56dfc5c77 100644 --- a/src/views/nodes/branchTrackingStatusFilesNode.ts +++ b/src/views/nodes/branchTrackingStatusFilesNode.ts @@ -3,7 +3,7 @@ import type { FilesComparison } from '../../git/actions/commit'; import { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; import type { GitFileWithCommit } from '../../git/models/file'; -import { createRevisionRange } from '../../git/models/revision.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; import { makeHierarchical } from '../../system/array'; import { filter, flatMap, groupByMap, map } from '../../system/iterable'; import { joinPaths, normalizePath } from '../../system/path'; diff --git a/src/views/nodes/branchTrackingStatusNode.ts b/src/views/nodes/branchTrackingStatusNode.ts index abb7e1649f13e..64395bee8fa1a 100644 --- a/src/views/nodes/branchTrackingStatusNode.ts +++ b/src/views/nodes/branchTrackingStatusNode.ts @@ -3,14 +3,14 @@ import type { Colors } from '../../constants.colors'; import type { FilesComparison } from '../../git/actions/commit'; import { GitUri } from '../../git/gitUri'; import type { GitBranch, GitTrackingState } from '../../git/models/branch'; -import { getRemoteNameFromBranchName } from '../../git/models/branch.utils'; import type { GitLog } from '../../git/models/log'; import type { GitRemote } from '../../git/models/remote'; -import { getHighlanderProviders } from '../../git/models/remote'; -import { createRevisionRange } from '../../git/models/revision.utils'; -import { getUpstreamStatus } from '../../git/models/status'; +import { getRemoteNameFromBranchName } from '../../git/utils/branch.utils'; +import { getHighlanderProviders } from '../../git/utils/remote.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; +import { getUpstreamStatus } from '../../git/utils/status.utils'; import { fromNow } from '../../system/date'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { first, last, map } from '../../system/iterable'; import { pluralize } from '../../system/string'; diff --git a/src/views/nodes/branchesNode.ts b/src/views/nodes/branchesNode.ts index d8c34f45ca39d..1c1451f24b59e 100644 --- a/src/views/nodes/branchesNode.ts +++ b/src/views/nodes/branchesNode.ts @@ -1,9 +1,9 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; -import { getLocalBranchUpstreamNames } from '../../git/models/branch.utils'; import type { Repository } from '../../git/models/repository'; -import { getOpenedWorktreesByBranch } from '../../git/models/worktree.utils'; +import { getOpenedWorktreesByBranch } from '../../git/utils/-webview/worktree.utils'; +import { getLocalBranchUpstreamNames } from '../../git/utils/branch.utils'; import { makeHierarchical } from '../../system/array'; import { debug } from '../../system/decorators/log'; import { PageableResult } from '../../system/paging'; diff --git a/src/views/nodes/commitFileNode.ts b/src/views/nodes/commitFileNode.ts index a1c69f38660aa..d06b304830d05 100644 --- a/src/views/nodes/commitFileNode.ts +++ b/src/views/nodes/commitFileNode.ts @@ -9,10 +9,10 @@ import { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; import type { GitCommit } from '../../git/models/commit'; import type { GitFile } from '../../git/models/file'; -import { getGitFileStatusIcon } from '../../git/models/file'; import type { GitRevisionReference } from '../../git/models/reference'; +import { getGitFileStatusIcon } from '../../git/utils/fileStatus.utils'; +import { relativeDir } from '../../system/-webview/path'; import { joinPaths } from '../../system/path'; -import { relativeDir } from '../../system/vscode/path'; import type { ViewsWithCommits, ViewsWithStashes } from '../viewBase'; import { createViewDecorationUri } from '../viewDecorationProvider'; import { getFileTooltipMarkdown } from './abstract/viewFileNode'; diff --git a/src/views/nodes/commitNode.ts b/src/views/nodes/commitNode.ts index 4cbd0f721fa41..222973b449e2d 100644 --- a/src/views/nodes/commitNode.ts +++ b/src/views/nodes/commitNode.ts @@ -10,13 +10,13 @@ import type { PullRequest } from '../../git/models/pullRequest'; import type { GitRevisionReference } from '../../git/models/reference'; import type { GitRemote } from '../../git/models/remote'; import type { RemoteProvider } from '../../git/remotes/remoteProvider'; +import { configuration } from '../../system/-webview/configuration'; +import { getContext } from '../../system/-webview/context'; import { makeHierarchical } from '../../system/array'; import { joinPaths, normalizePath } from '../../system/path'; import type { Deferred } from '../../system/promise'; import { defer, getSettledValue, pauseOnCancelOrTimeoutMapTuplePromise } from '../../system/promise'; import { sortCompare } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext } from '../../system/vscode/context'; import type { FileHistoryView } from '../fileHistoryView'; import type { ViewsWithCommits } from '../viewBase'; import { disposeChildren } from '../viewBase'; diff --git a/src/views/nodes/common.ts b/src/views/nodes/common.ts index cd913fad44f5d..f13857f38866b 100644 --- a/src/views/nodes/common.ts +++ b/src/views/nodes/common.ts @@ -2,7 +2,7 @@ import type { Command, Uri } from 'vscode'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GlyphChars } from '../../constants'; import { unknownGitUri } from '../../git/gitUri'; -import { configuration } from '../../system/vscode/configuration'; +import { configuration } from '../../system/-webview/configuration'; import type { View } from '../viewBase'; import type { PageableViewNode } from './abstract/viewNode'; import { ContextValues, ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/compareBranchNode.ts b/src/views/nodes/compareBranchNode.ts index ab7734b5631c5..fba6d769f38b0 100644 --- a/src/views/nodes/compareBranchNode.ts +++ b/src/views/nodes/compareBranchNode.ts @@ -5,10 +5,10 @@ import { GlyphChars } from '../../constants'; import type { StoredBranchComparison, StoredBranchComparisons, StoredNamedRef } from '../../constants.storage'; import type { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; -import { createRevisionRange, shortenRevision } from '../../git/models/revision.utils'; import type { GitUser } from '../../git/models/user'; import type { CommitsQueryResults, FilesQueryResults } from '../../git/queryResults'; import { getCommitsQuery, getFilesQuery } from '../../git/queryResults'; +import { createRevisionRange, shortenRevision } from '../../git/utils/revision.utils'; import { CommandQuickPickItem } from '../../quickpicks/items/common'; import { showReferencePicker } from '../../quickpicks/referencePicker'; import { debug, log } from '../../system/decorators/log'; diff --git a/src/views/nodes/compareResultsNode.ts b/src/views/nodes/compareResultsNode.ts index 8b2f350f2294a..84c54e557ef3b 100644 --- a/src/views/nodes/compareResultsNode.ts +++ b/src/views/nodes/compareResultsNode.ts @@ -4,11 +4,11 @@ import { md5 } from '@env/crypto'; import type { StoredNamedRef } from '../../constants.storage'; import type { FilesComparison } from '../../git/actions/commit'; import { GitUri } from '../../git/gitUri'; -import { createRevisionRange, shortenRevision } from '../../git/models/revision.utils'; import type { GitUser } from '../../git/models/user'; import type { CommitsQueryResults, FilesQueryResults } from '../../git/queryResults'; import { getAheadBehindFilesQuery, getCommitsQuery, getFilesQuery } from '../../git/queryResults'; -import { gate } from '../../system/decorators/gate'; +import { createRevisionRange, shortenRevision } from '../../git/utils/revision.utils'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; import { pluralize } from '../../system/string'; diff --git a/src/views/nodes/contributorNode.ts b/src/views/nodes/contributorNode.ts index fcfcc3e70bbb2..bb6fa416f467d 100644 --- a/src/views/nodes/contributorNode.ts +++ b/src/views/nodes/contributorNode.ts @@ -4,12 +4,12 @@ import { GlyphChars } from '../../constants'; import type { GitUri } from '../../git/gitUri'; import type { GitContributor } from '../../git/models/contributor'; import type { GitLog } from '../../git/models/log'; +import { configuration } from '../../system/-webview/configuration'; import { formatNumeric } from '../../system/date'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import { pluralize } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; import type { ContactPresence } from '../../vsls/vsls'; import type { ViewsWithContributors } from '../viewBase'; import type { ClipboardType, PageableViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/contributorsNode.ts b/src/views/nodes/contributorsNode.ts index d545343c2441f..73028af53707a 100644 --- a/src/views/nodes/contributorsNode.ts +++ b/src/views/nodes/contributorsNode.ts @@ -2,9 +2,9 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import type { GitUri } from '../../git/gitUri'; import type { GitContributor } from '../../git/models/contributor'; import type { Repository } from '../../git/models/repository'; -import { sortContributors } from '../../git/utils/vscode/sorting'; +import { sortContributors } from '../../git/utils/-webview/sorting'; +import { configuration } from '../../system/-webview/configuration'; import { debug } from '../../system/decorators/log'; -import { configuration } from '../../system/vscode/configuration'; import type { ViewsWithContributorsNode } from '../viewBase'; import { CacheableChildrenViewNode } from './abstract/cacheableChildrenViewNode'; import type { ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/draftNode.ts b/src/views/nodes/draftNode.ts index 4461660542366..d7983357341f1 100644 --- a/src/views/nodes/draftNode.ts +++ b/src/views/nodes/draftNode.ts @@ -2,9 +2,9 @@ import type { Uri } from 'vscode'; import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { getAvatarUri } from '../../avatars'; import type { GitUri } from '../../git/gitUri'; -import type { Draft } from '../../gk/models/drafts'; +import type { Draft } from '../../plus/drafts/models/drafts'; +import { configuration } from '../../system/-webview/configuration'; import { formatDate, fromNow } from '../../system/date'; -import { configuration } from '../../system/vscode/configuration'; import type { DraftsView } from '../draftsView'; import type { ViewsWithCommits } from '../viewBase'; import { ContextValues, getViewNodeId, ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/fileHistoryNode.ts b/src/views/nodes/fileHistoryNode.ts index 1f5c10402858c..015aee17389ad 100644 --- a/src/views/nodes/fileHistoryNode.ts +++ b/src/views/nodes/fileHistoryNode.ts @@ -5,14 +5,14 @@ import type { GitLog } from '../../git/models/log'; import type { RepositoryChangeEvent, RepositoryFileSystemChangeEvent } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; import { deletedOrMissing } from '../../git/models/revision'; -import { gate } from '../../system/decorators/gate'; +import { configuration } from '../../system/-webview/configuration'; +import { gate } from '../../system/decorators/-webview/gate'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { debug } from '../../system/decorators/log'; -import { memoize } from '../../system/decorators/memoize'; import { weakEvent } from '../../system/event'; import { filterMap, flatMap, map, uniqueBy } from '../../system/iterable'; import { Logger } from '../../system/logger'; import { basename } from '../../system/path'; -import { configuration } from '../../system/vscode/configuration'; import type { FileHistoryView } from '../fileHistoryView'; import { SubscribeableViewNode } from './abstract/subscribeableViewNode'; import type { PageableViewNode, ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/fileHistoryTrackerNode.ts b/src/views/nodes/fileHistoryTrackerNode.ts index 0e6be924d309e..0713bc9dd299f 100644 --- a/src/views/nodes/fileHistoryTrackerNode.ts +++ b/src/views/nodes/fileHistoryTrackerNode.ts @@ -2,19 +2,19 @@ import type { TextEditor } from 'vscode'; import { Disposable, TreeItem, TreeItemCollapsibleState, window } from 'vscode'; import type { GitCommitish } from '../../git/gitUri'; import { GitUri, unknownGitUri } from '../../git/gitUri'; -import { isBranchReference } from '../../git/models/reference.utils'; -import { isSha } from '../../git/models/revision.utils'; +import { isBranchReference } from '../../git/utils/reference.utils'; +import { isSha } from '../../git/utils/revision.utils'; import { showReferencePicker } from '../../quickpicks/referencePicker'; +import { setContext } from '../../system/-webview/context'; +import { isFolderUri, isVirtualUri } from '../../system/-webview/utils'; import { UriComparer } from '../../system/comparers'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; import type { Deferrable } from '../../system/function'; import { debounce } from '../../system/function'; import { Logger } from '../../system/logger'; import { getLogScope, setLogScopeExit } from '../../system/logger.scope'; -import { setContext } from '../../system/vscode/context'; -import { isFolderUri, isVirtualUri } from '../../system/vscode/utils'; import type { FileHistoryView } from '../fileHistoryView'; import { SubscribeableViewNode } from './abstract/subscribeableViewNode'; import type { ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/fileRevisionAsCommitNode.ts b/src/views/nodes/fileRevisionAsCommitNode.ts index 7f2b5962f3e1c..7e323fab7cfd7 100644 --- a/src/views/nodes/fileRevisionAsCommitNode.ts +++ b/src/views/nodes/fileRevisionAsCommitNode.ts @@ -10,11 +10,11 @@ import { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; import type { GitCommit } from '../../git/models/commit'; import type { GitFile } from '../../git/models/file'; -import { getGitFileStatusIcon } from '../../git/models/file'; import type { GitRevisionReference } from '../../git/models/reference'; +import { getGitFileStatusIcon } from '../../git/utils/fileStatus.utils'; +import { configuration } from '../../system/-webview/configuration'; import { joinPaths } from '../../system/path'; import { getSettledValue, pauseOnCancelOrTimeoutMapTuplePromise } from '../../system/promise'; -import { configuration } from '../../system/vscode/configuration'; import type { FileHistoryView } from '../fileHistoryView'; import type { LineHistoryView } from '../lineHistoryView'; import type { ViewsWithCommits } from '../viewBase'; diff --git a/src/views/nodes/launchpadViewGroupingNode.ts b/src/views/nodes/launchpadViewGroupingNode.ts index 0d9d14aacceb6..553f6f1c6988d 100644 --- a/src/views/nodes/launchpadViewGroupingNode.ts +++ b/src/views/nodes/launchpadViewGroupingNode.ts @@ -1,6 +1,6 @@ import type { TreeItem } from 'vscode'; import { Disposable, TreeItemCollapsibleState } from 'vscode'; -import type { LaunchpadGroup } from '../../plus/launchpad/models'; +import type { LaunchpadGroup } from '../../plus/launchpad/models/launchpad'; import type { TreeViewNodeCollapsibleStateChangeEvent, View } from '../viewBase'; import type { ViewNode } from './abstract/viewNode'; import { GroupingNode } from './groupingNode'; diff --git a/src/views/nodes/lineHistoryNode.ts b/src/views/nodes/lineHistoryNode.ts index db04f19b217d9..04429cdcca7b4 100644 --- a/src/views/nodes/lineHistoryNode.ts +++ b/src/views/nodes/lineHistoryNode.ts @@ -2,15 +2,15 @@ import { Disposable, Selection, TreeItem, TreeItemCollapsibleState, window } fro import type { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; import type { GitFile } from '../../git/models/file'; -import { GitFileIndexStatus } from '../../git/models/file'; +import { GitFileIndexStatus } from '../../git/models/fileStatus'; import type { GitLog } from '../../git/models/log'; import type { RepositoryChangeEvent, RepositoryFileSystemChangeEvent } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; import { deletedOrMissing } from '../../git/models/revision'; -import { isUncommitted } from '../../git/models/revision.utils'; -import { gate } from '../../system/decorators/gate'; +import { isUncommitted } from '../../git/utils/revision.utils'; +import { gate } from '../../system/decorators/-webview/gate'; +import { memoize } from '../../system/decorators/-webview/memoize'; import { debug } from '../../system/decorators/log'; -import { memoize } from '../../system/decorators/memoize'; import { weakEvent } from '../../system/event'; import { filterMap } from '../../system/iterable'; import { Logger } from '../../system/logger'; diff --git a/src/views/nodes/lineHistoryTrackerNode.ts b/src/views/nodes/lineHistoryTrackerNode.ts index 01a0f388d4fbc..521c9dc0e3771 100644 --- a/src/views/nodes/lineHistoryTrackerNode.ts +++ b/src/views/nodes/lineHistoryTrackerNode.ts @@ -2,18 +2,18 @@ import type { Selection } from 'vscode'; import { TreeItem, TreeItemCollapsibleState, window } from 'vscode'; import type { GitCommitish } from '../../git/gitUri'; import { GitUri, unknownGitUri } from '../../git/gitUri'; -import { isBranchReference } from '../../git/models/reference.utils'; import { deletedOrMissing } from '../../git/models/revision'; -import { isSha } from '../../git/models/revision.utils'; +import { isBranchReference } from '../../git/utils/reference.utils'; +import { isSha } from '../../git/utils/revision.utils'; import { showReferencePicker } from '../../quickpicks/referencePicker'; +import { setContext } from '../../system/-webview/context'; import { UriComparer } from '../../system/comparers'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; import { debounce } from '../../system/function'; import { Logger } from '../../system/logger'; import { getLogScope, setLogScopeExit } from '../../system/logger.scope'; -import { setContext } from '../../system/vscode/context'; import type { LinesChangeEvent } from '../../trackers/lineTracker'; import type { FileHistoryView } from '../fileHistoryView'; import type { LineHistoryView } from '../lineHistoryView'; diff --git a/src/views/nodes/mergeConflictCurrentChangesNode.ts b/src/views/nodes/mergeConflictCurrentChangesNode.ts index 4bc5a33b5ff73..4a8ca5bd0ff29 100644 --- a/src/views/nodes/mergeConflictCurrentChangesNode.ts +++ b/src/views/nodes/mergeConflictCurrentChangesNode.ts @@ -7,9 +7,9 @@ import { GitUri } from '../../git/gitUri'; import type { GitCommit } from '../../git/models/commit'; import type { GitFile } from '../../git/models/file'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; -import { getReferenceLabel } from '../../git/models/reference.utils'; -import { createCommand, createCoreCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; +import { createCommand, createCoreCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; import type { FileHistoryView } from '../fileHistoryView'; import type { LineHistoryView } from '../lineHistoryView'; import type { ViewsWithCommits } from '../viewBase'; diff --git a/src/views/nodes/mergeConflictFileNode.ts b/src/views/nodes/mergeConflictFileNode.ts index a818a86c13dd3..6f6605e450572 100644 --- a/src/views/nodes/mergeConflictFileNode.ts +++ b/src/views/nodes/mergeConflictFileNode.ts @@ -4,8 +4,8 @@ import { StatusFileFormatter } from '../../git/formatters/statusFormatter'; import { GitUri } from '../../git/gitUri'; import type { GitFile } from '../../git/models/file'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; -import { createCoreCommand } from '../../system/vscode/command'; -import { relativeDir } from '../../system/vscode/path'; +import { createCoreCommand } from '../../system/-webview/command'; +import { relativeDir } from '../../system/-webview/path'; import type { ViewsWithCommits } from '../viewBase'; import { getFileTooltipMarkdown, ViewFileNode } from './abstract/viewFileNode'; import type { ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/mergeConflictFilesNode.ts b/src/views/nodes/mergeConflictFilesNode.ts index 480712f342470..42c6e8af2b1c3 100644 --- a/src/views/nodes/mergeConflictFilesNode.ts +++ b/src/views/nodes/mergeConflictFilesNode.ts @@ -1,7 +1,7 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitUri } from '../../git/gitUri'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; -import type { GitStatusFile } from '../../git/models/status'; +import type { GitStatusFile } from '../../git/models/statusFile'; import { makeHierarchical } from '../../system/array'; import { joinPaths, normalizePath } from '../../system/path'; import { pluralize, sortCompare } from '../../system/string'; diff --git a/src/views/nodes/mergeConflictIncomingChangesNode.ts b/src/views/nodes/mergeConflictIncomingChangesNode.ts index 8f9c4d7cc2d06..065ec0ae85305 100644 --- a/src/views/nodes/mergeConflictIncomingChangesNode.ts +++ b/src/views/nodes/mergeConflictIncomingChangesNode.ts @@ -7,9 +7,9 @@ import { GitUri } from '../../git/gitUri'; import type { GitCommit } from '../../git/models/commit'; import type { GitFile } from '../../git/models/file'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; -import { getReferenceLabel } from '../../git/models/reference.utils'; -import { createCommand, createCoreCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; +import { createCommand, createCoreCommand } from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; import type { FileHistoryView } from '../fileHistoryView'; import type { LineHistoryView } from '../lineHistoryView'; import type { ViewsWithCommits } from '../viewBase'; diff --git a/src/views/nodes/pausedOperationStatusNode.ts b/src/views/nodes/pausedOperationStatusNode.ts index 100a5d0b3102a..48d309bac337f 100644 --- a/src/views/nodes/pausedOperationStatusNode.ts +++ b/src/views/nodes/pausedOperationStatusNode.ts @@ -3,9 +3,9 @@ import type { Colors } from '../../constants.colors'; import { GitUri } from '../../git/gitUri'; import type { GitBranch } from '../../git/models/branch'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; -import { getReferenceLabel } from '../../git/models/reference.utils'; import type { GitStatus } from '../../git/models/status'; import { pausedOperationStatusStringsByType } from '../../git/utils/pausedOperationStatus.utils'; +import { getReferenceLabel } from '../../git/utils/reference.utils'; import { pluralize } from '../../system/string'; import type { ViewsWithCommits } from '../viewBase'; import { createViewDecorationUri } from '../viewDecorationProvider'; diff --git a/src/views/nodes/pullRequestNode.ts b/src/views/nodes/pullRequestNode.ts index 6954bae681d94..2fc72edec8b78 100644 --- a/src/views/nodes/pullRequestNode.ts +++ b/src/views/nodes/pullRequestNode.ts @@ -3,16 +3,13 @@ import { GitUri } from '../../git/gitUri'; import { GitBranch } from '../../git/models/branch'; import type { GitCommit } from '../../git/models/commit'; import type { PullRequest } from '../../git/models/pullRequest'; -import { - ensurePullRequestRefs, - getComparisonRefsForPullRequest, - getOrOpenPullRequestRepository, -} from '../../git/models/pullRequest'; import type { GitBranchReference } from '../../git/models/reference'; import type { Repository } from '../../git/models/repository'; -import { createRevisionRange } from '../../git/models/revision.utils'; import { getAheadBehindFilesQuery, getCommitsQuery } from '../../git/queryResults'; -import { getIssueOrPullRequestMarkdownIcon, getIssueOrPullRequestThemeIcon } from '../../git/utils/vscode/icons'; +import { getIssueOrPullRequestMarkdownIcon, getIssueOrPullRequestThemeIcon } from '../../git/utils/-webview/icons'; +import { ensurePullRequestRefs, getOrOpenPullRequestRepository } from '../../git/utils/-webview/pullRequest.utils'; +import { getComparisonRefsForPullRequest } from '../../git/utils/pullRequest.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; import { pluralize } from '../../system/string'; import type { ViewsWithCommits } from '../viewBase'; import { CacheableChildrenViewNode } from './abstract/cacheableChildrenViewNode'; diff --git a/src/views/nodes/reflogRecordNode.ts b/src/views/nodes/reflogRecordNode.ts index 7774d9878db08..c7a2998f34125 100644 --- a/src/views/nodes/reflogRecordNode.ts +++ b/src/views/nodes/reflogRecordNode.ts @@ -3,7 +3,7 @@ import { GlyphChars } from '../../constants'; import { GitUri } from '../../git/gitUri'; import type { GitLog } from '../../git/models/log'; import type { GitReflogRecord } from '../../git/models/reflog'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import type { ViewsWithCommits } from '../viewBase'; diff --git a/src/views/nodes/remoteNode.ts b/src/views/nodes/remoteNode.ts index c991fead31f5b..49bd37975bb55 100644 --- a/src/views/nodes/remoteNode.ts +++ b/src/views/nodes/remoteNode.ts @@ -2,8 +2,8 @@ import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'v import { GlyphChars } from '../../constants'; import { GitUri } from '../../git/gitUri'; import type { GitRemote } from '../../git/models/remote'; -import { getRemoteUpstreamDescription } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; +import { getRemoteUpstreamDescription } from '../../git/utils/remote.utils'; import { makeHierarchical } from '../../system/array'; import { log } from '../../system/decorators/log'; import type { ViewsWithRemotes } from '../viewBase'; diff --git a/src/views/nodes/repositoriesNode.ts b/src/views/nodes/repositoriesNode.ts index bc6f0c1ac01d1..c76b2adef9250 100644 --- a/src/views/nodes/repositoriesNode.ts +++ b/src/views/nodes/repositoriesNode.ts @@ -2,7 +2,7 @@ import type { TextEditor } from 'vscode'; import { Disposable, TreeItem, TreeItemCollapsibleState, window, workspace } from 'vscode'; import type { RepositoriesChangeEvent } from '../../git/gitProviderService'; import { GitUri, unknownGitUri } from '../../git/gitUri'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; import { debounce, szudzikPairing } from '../../system/function'; diff --git a/src/views/nodes/repositoryNode.ts b/src/views/nodes/repositoryNode.ts index 77c1dd141c44a..e6e801e894020 100644 --- a/src/views/nodes/repositoryNode.ts +++ b/src/views/nodes/repositoryNode.ts @@ -3,20 +3,17 @@ import { GlyphChars } from '../../constants'; import { Features } from '../../features'; import type { GitUri } from '../../git/gitUri'; import { GitBranch } from '../../git/models/branch'; -import { getHighlanderProviders } from '../../git/models/remote'; import type { Repository, RepositoryChangeEvent, RepositoryFileSystemChangeEvent } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; -import { formatLastFetched, getLastFetchedUpdateInterval } from '../../git/models/repository.utils'; import type { GitStatus } from '../../git/models/status'; -import { getRepositoryStatusIconPath } from '../../git/utils/vscode/icons'; -import type { - CloudWorkspace, - CloudWorkspaceRepositoryDescriptor, - LocalWorkspace, - LocalWorkspaceRepositoryDescriptor, -} from '../../plus/workspaces/models'; +import { getRepositoryStatusIconPath } from '../../git/utils/-webview/icons'; +import { formatLastFetched } from '../../git/utils/-webview/repository.utils'; +import { getLastFetchedUpdateInterval } from '../../git/utils/fetch.utils'; +import { getHighlanderProviders } from '../../git/utils/remote.utils'; +import type { CloudWorkspace, CloudWorkspaceRepositoryDescriptor } from '../../plus/workspaces/models/cloudWorkspace'; +import type { LocalWorkspace, LocalWorkspaceRepositoryDescriptor } from '../../plus/workspaces/models/localWorkspace'; import { findLastIndex } from '../../system/array'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug, log } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; import { disposableInterval } from '../../system/function'; diff --git a/src/views/nodes/resultsCommitsNode.ts b/src/views/nodes/resultsCommitsNode.ts index 464c51a91bfbb..07e35bf8c2e83 100644 --- a/src/views/nodes/resultsCommitsNode.ts +++ b/src/views/nodes/resultsCommitsNode.ts @@ -3,12 +3,12 @@ import { GitUri } from '../../git/gitUri'; import { isStash } from '../../git/models/commit'; import type { GitRevisionRange } from '../../git/models/revision'; import type { CommitsQueryResults, FilesQueryResults } from '../../git/queryResults'; -import { gate } from '../../system/decorators/gate'; +import { configuration } from '../../system/-webview/configuration'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import type { Deferred } from '../../system/promise'; import { defer, pauseOnCancelOrTimeout } from '../../system/promise'; -import { configuration } from '../../system/vscode/configuration'; import type { ViewsWithCommits } from '../viewBase'; import type { PageableViewNode } from './abstract/viewNode'; import { ContextValues, getViewNodeId, ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/resultsFileNode.ts b/src/views/nodes/resultsFileNode.ts index 019013a628242..672b45271828c 100644 --- a/src/views/nodes/resultsFileNode.ts +++ b/src/views/nodes/resultsFileNode.ts @@ -5,11 +5,11 @@ import { GlCommand } from '../../constants.commands'; import { StatusFileFormatter } from '../../git/formatters/statusFormatter'; import { GitUri } from '../../git/gitUri'; import type { GitFile } from '../../git/models/file'; -import { getGitFileStatusIcon } from '../../git/models/file'; import type { GitRevisionReference } from '../../git/models/reference'; -import { createReference } from '../../git/models/reference.utils'; +import { getGitFileStatusIcon } from '../../git/utils/fileStatus.utils'; +import { createReference } from '../../git/utils/reference.utils'; +import { relativeDir } from '../../system/-webview/path'; import { joinPaths } from '../../system/path'; -import { relativeDir } from '../../system/vscode/path'; import type { View } from '../viewBase'; import { getFileTooltipMarkdown } from './abstract/viewFileNode'; import type { ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/resultsFilesNode.ts b/src/views/nodes/resultsFilesNode.ts index a45fc4085a7dd..445c85b62aa3a 100644 --- a/src/views/nodes/resultsFilesNode.ts +++ b/src/views/nodes/resultsFilesNode.ts @@ -4,7 +4,7 @@ import { GitUri } from '../../git/gitUri'; import type { GitFile } from '../../git/models/file'; import type { FilesQueryResults } from '../../git/queryResults'; import { makeHierarchical } from '../../system/array'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import { joinPaths, normalizePath } from '../../system/path'; diff --git a/src/views/nodes/searchResultsNode.ts b/src/views/nodes/searchResultsNode.ts index f39550ddf2bc8..2988b48c82f3f 100644 --- a/src/views/nodes/searchResultsNode.ts +++ b/src/views/nodes/searchResultsNode.ts @@ -7,7 +7,7 @@ import { GitUri } from '../../git/gitUri'; import type { GitLog } from '../../git/models/log'; import type { CommitsQueryResults } from '../../git/queryResults'; import { getSearchQueryComparisonKey, getStoredSearchQuery } from '../../git/search'; -import { gate } from '../../system/decorators/gate'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { pluralize } from '../../system/string'; import type { SearchAndCompareView } from '../searchAndCompareView'; diff --git a/src/views/nodes/stashNode.ts b/src/views/nodes/stashNode.ts index 882b654e637af..aa4574f8bbf96 100644 --- a/src/views/nodes/stashNode.ts +++ b/src/views/nodes/stashNode.ts @@ -3,11 +3,11 @@ import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'v import { CommitFormatter } from '../../git/formatters/commitFormatter'; import type { GitStashCommit } from '../../git/models/commit'; import type { GitStashReference } from '../../git/models/reference'; +import { configuration } from '../../system/-webview/configuration'; import { makeHierarchical } from '../../system/array'; import { joinPaths, normalizePath } from '../../system/path'; import { getSettledValue, pauseOnCancelOrTimeoutMapTuplePromise } from '../../system/promise'; import { sortCompare } from '../../system/string'; -import { configuration } from '../../system/vscode/configuration'; import type { ViewsWithStashes } from '../viewBase'; import type { ViewNode } from './abstract/viewNode'; import { ContextValues, getViewNodeId } from './abstract/viewNode'; diff --git a/src/views/nodes/statusFileNode.ts b/src/views/nodes/statusFileNode.ts index 9ec3a859de76d..695d238a5cc77 100644 --- a/src/views/nodes/statusFileNode.ts +++ b/src/views/nodes/statusFileNode.ts @@ -6,10 +6,11 @@ import { GlCommand } from '../../constants.commands'; import { StatusFileFormatter } from '../../git/formatters/statusFormatter'; import { GitUri } from '../../git/gitUri'; import type { GitFileWithCommit } from '../../git/models/file'; -import { getGitFileStatusIcon, isGitFileChange } from '../../git/models/file'; -import { shortenRevision } from '../../git/models/revision.utils'; +import { isGitFileChange } from '../../git/models/fileChange'; +import { getGitFileStatusIcon } from '../../git/utils/fileStatus.utils'; +import { shortenRevision } from '../../git/utils/revision.utils'; +import { relativeDir } from '../../system/-webview/path'; import { joinPaths } from '../../system/path'; -import { relativeDir } from '../../system/vscode/path'; import type { ViewsWithCommits } from '../viewBase'; import { getFileTooltip, ViewFileNode } from './abstract/viewFileNode'; import type { ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/statusFilesNode.ts b/src/views/nodes/statusFilesNode.ts index add25202863a3..e076c225e1512 100644 --- a/src/views/nodes/statusFilesNode.ts +++ b/src/views/nodes/statusFilesNode.ts @@ -3,7 +3,8 @@ import { GitUri } from '../../git/gitUri'; import type { GitCommit } from '../../git/models/commit'; import type { GitFileWithCommit } from '../../git/models/file'; import type { GitLog } from '../../git/models/log'; -import type { GitStatus, GitStatusFile } from '../../git/models/status'; +import type { GitStatus } from '../../git/models/status'; +import type { GitStatusFile } from '../../git/models/statusFile'; import { makeHierarchical } from '../../system/array'; import { filter, flatMap, groupBy, map } from '../../system/iterable'; import { joinPaths, normalizePath } from '../../system/path'; diff --git a/src/views/nodes/tagNode.ts b/src/views/nodes/tagNode.ts index 7f8485780805e..04ee27e303155 100644 --- a/src/views/nodes/tagNode.ts +++ b/src/views/nodes/tagNode.ts @@ -4,9 +4,9 @@ import { emojify } from '../../emojis'; import type { GitUri } from '../../git/gitUri'; import type { GitLog } from '../../git/models/log'; import type { GitTagReference } from '../../git/models/reference'; -import { shortenRevision } from '../../git/models/revision.utils'; import type { GitTag } from '../../git/models/tag'; -import { gate } from '../../system/decorators/gate'; +import { shortenRevision } from '../../git/utils/revision.utils'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import { pad } from '../../system/string'; diff --git a/src/views/nodes/workspaceMissingRepositoryNode.ts b/src/views/nodes/workspaceMissingRepositoryNode.ts index ebac55b05344f..3ba9183798c6f 100644 --- a/src/views/nodes/workspaceMissingRepositoryNode.ts +++ b/src/views/nodes/workspaceMissingRepositoryNode.ts @@ -1,12 +1,8 @@ import { MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import type { Colors } from '../../constants.colors'; import { unknownGitUri } from '../../git/gitUri'; -import type { - CloudWorkspace, - CloudWorkspaceRepositoryDescriptor, - LocalWorkspace, - LocalWorkspaceRepositoryDescriptor, -} from '../../plus/workspaces/models'; +import type { CloudWorkspace, CloudWorkspaceRepositoryDescriptor } from '../../plus/workspaces/models/cloudWorkspace'; +import type { LocalWorkspace, LocalWorkspaceRepositoryDescriptor } from '../../plus/workspaces/models/localWorkspace'; import { createViewDecorationUri } from '../viewDecorationProvider'; import type { WorkspacesView } from '../workspacesView'; import { ContextValues, getViewNodeId, ViewNode } from './abstract/viewNode'; diff --git a/src/views/nodes/workspaceNode.ts b/src/views/nodes/workspaceNode.ts index 2ea5452636474..927c9a68a8b70 100644 --- a/src/views/nodes/workspaceNode.ts +++ b/src/views/nodes/workspaceNode.ts @@ -1,10 +1,11 @@ import { Disposable, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import type { RepositoriesChangeEvent } from '../../git/gitProviderService'; import { GitUri } from '../../git/gitUri'; -import type { CloudWorkspace, LocalWorkspace } from '../../plus/workspaces/models'; +import type { CloudWorkspace } from '../../plus/workspaces/models/cloudWorkspace'; +import type { LocalWorkspace } from '../../plus/workspaces/models/localWorkspace'; +import { createCommand } from '../../system/-webview/command'; import { debug } from '../../system/decorators/log'; import { weakEvent } from '../../system/event'; -import { createCommand } from '../../system/vscode/command'; import { createViewDecorationUri } from '../viewDecorationProvider'; import type { WorkspacesView } from '../workspacesView'; import { SubscribeableViewNode } from './abstract/subscribeableViewNode'; diff --git a/src/views/nodes/worktreeNode.ts b/src/views/nodes/worktreeNode.ts index bce2d5798e54b..07a55a6b4cfeb 100644 --- a/src/views/nodes/worktreeNode.ts +++ b/src/views/nodes/worktreeNode.ts @@ -6,18 +6,18 @@ import type { GitBranch } from '../../git/models/branch'; import { isStash } from '../../git/models/commit'; import type { GitLog } from '../../git/models/log'; import type { PullRequest, PullRequestState } from '../../git/models/pullRequest'; -import { getHighlanderProviderName } from '../../git/models/remote'; -import { shortenRevision } from '../../git/models/revision.utils'; import type { GitStatus } from '../../git/models/status'; import type { GitWorktree } from '../../git/models/worktree'; -import { getBranchIconPath } from '../../git/utils/vscode/icons'; -import { gate } from '../../system/decorators/gate'; +import { getBranchIconPath } from '../../git/utils/-webview/icons'; +import { getHighlanderProviderName } from '../../git/utils/remote.utils'; +import { shortenRevision } from '../../git/utils/revision.utils'; +import { getContext } from '../../system/-webview/context'; +import { gate } from '../../system/decorators/-webview/gate'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; import type { Deferred } from '../../system/promise'; import { defer, getSettledValue } from '../../system/promise'; import { pad } from '../../system/string'; -import { getContext } from '../../system/vscode/context'; import type { ViewsWithWorktrees } from '../viewBase'; import { createViewDecorationUri } from '../viewDecorationProvider'; import { CacheableChildrenViewNode } from './abstract/cacheableChildrenViewNode'; diff --git a/src/views/nodes/worktreesNode.ts b/src/views/nodes/worktreesNode.ts index 070890099bc0b..549fdadb7e787 100644 --- a/src/views/nodes/worktreesNode.ts +++ b/src/views/nodes/worktreesNode.ts @@ -3,7 +3,7 @@ import { GlyphChars } from '../../constants'; import { PlusFeatures } from '../../features'; import type { GitUri } from '../../git/gitUri'; import type { Repository } from '../../git/models/repository'; -import { sortWorktrees } from '../../git/utils/vscode/sorting'; +import { sortWorktrees } from '../../git/utils/-webview/sorting'; import { filterMap } from '../../system/array'; import { debug } from '../../system/decorators/log'; import { map } from '../../system/iterable'; diff --git a/src/views/pullRequestView.ts b/src/views/pullRequestView.ts index 577966a90b4f2..fae1d67cacda4 100644 --- a/src/views/pullRequestView.ts +++ b/src/views/pullRequestView.ts @@ -7,9 +7,9 @@ import { unknownGitUri } from '../git/gitUri'; import type { GitBranch } from '../git/models/branch'; import type { GitCommit } from '../git/models/commit'; import type { PullRequest } from '../git/models/pullRequest'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { ViewNode } from './nodes/abstract/viewNode'; import { PullRequestNode } from './nodes/pullRequestNode'; import { ViewBase } from './viewBase'; diff --git a/src/views/remotesView.ts b/src/views/remotesView.ts index 5513f79c2617e..ab932663ba982 100644 --- a/src/views/remotesView.ts +++ b/src/views/remotesView.ts @@ -4,18 +4,18 @@ import type { RemotesViewConfig, ViewBranchesLayout, ViewFilesLayout } from '../ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; -import { getRemoteNameFromBranchName } from '../git/models/branch.utils'; import type { GitCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; import type { GitBranchReference, GitRevisionReference } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { GitRemote } from '../git/models/remote'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { getRemoteNameFromBranchName } from '../git/utils/branch.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/views/repositoriesView.ts b/src/views/repositoriesView.ts index c3b132b517f2b..d863a5ab8c5cf 100644 --- a/src/views/repositoriesView.ts +++ b/src/views/repositoriesView.ts @@ -3,7 +3,6 @@ import { EventEmitter, ProgressLocation, window } from 'vscode'; import type { RepositoriesViewConfig, ViewBranchesLayout, ViewFilesLayout } from '../config'; import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; -import { getRemoteNameFromBranchName } from '../git/models/branch.utils'; import type { GitCommit } from '../git/models/commit'; import { isCommit } from '../git/models/commit'; import type { GitContributor } from '../git/models/contributor'; @@ -13,13 +12,14 @@ import type { GitStashReference, GitTagReference, } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { GitRemote } from '../git/models/remote'; import type { GitWorktree } from '../git/models/worktree'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; +import { getRemoteNameFromBranchName } from '../git/utils/branch.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import { gate } from '../system/decorators/-webview/gate'; import { BranchesNode } from './nodes/branchesNode'; import { BranchNode } from './nodes/branchNode'; import { BranchOrTagFolderNode } from './nodes/branchOrTagFolderNode'; diff --git a/src/views/searchAndCompareView.ts b/src/views/searchAndCompareView.ts index 87a174b70189e..32bef39b6246b 100644 --- a/src/views/searchAndCompareView.ts +++ b/src/views/searchAndCompareView.ts @@ -7,18 +7,18 @@ import type { StoredNamedRef, StoredSearchAndCompareItem } from '../constants.st import type { Container } from '../container'; import { unknownGitUri } from '../git/gitUri'; import type { GitLog } from '../git/models/log'; -import { getRevisionRangeParts, isRevisionRange, shortenRevision } from '../git/models/revision.utils'; import { getSearchQuery } from '../git/search'; +import { getRevisionRangeParts, isRevisionRange, shortenRevision } from '../git/utils/revision.utils'; import { ReferencesQuickPickIncludes, showReferencePicker } from '../quickpicks/referencePicker'; import { getRepositoryOrShowPicker } from '../quickpicks/repositoryPicker'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { filterMap } from '../system/array'; -import { gate } from '../system/decorators/gate'; +import { gate } from '../system/decorators/-webview/gate'; import { debug, log } from '../system/decorators/log'; import { updateRecordValue } from '../system/object'; import { isPromise } from '../system/promise'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import { ContextValues, ViewNode } from './nodes/abstract/viewNode'; import { ComparePickerNode } from './nodes/comparePickerNode'; diff --git a/src/views/stashesView.ts b/src/views/stashesView.ts index 0b985464d0c19..0d0199157d533 100644 --- a/src/views/stashesView.ts +++ b/src/views/stashesView.ts @@ -5,13 +5,13 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import type { GitStashReference } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/views/tagsView.ts b/src/views/tagsView.ts index cdae63c453472..dc32fd59e1261 100644 --- a/src/views/tagsView.ts +++ b/src/views/tagsView.ts @@ -5,13 +5,13 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { GitUri } from '../git/gitUri'; import type { GitTagReference } from '../git/models/reference'; -import { getReferenceLabel } from '../git/models/reference.utils'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { getReferenceLabel } from '../git/utils/reference.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/views/viewBase.ts b/src/views/viewBase.ts index 3864c4207ed17..06f427e1d3213 100644 --- a/src/views/viewBase.ts +++ b/src/views/viewBase.ts @@ -35,14 +35,14 @@ import type { TreeViewCommandSuffixesByViewType } from '../constants.commands'; import type { TrackedUsageFeatures } from '../constants.telemetry'; import type { TreeViewIds, TreeViewTypes, WebviewViewTypes } from '../constants.views'; import type { Container } from '../container'; +import { executeCoreCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; import { debug, log } from '../system/decorators/log'; import { once } from '../system/event'; import { debounce } from '../system/function'; import { Logger } from '../system/logger'; import { getLogScope } from '../system/logger.scope'; import { cancellable, isPromise } from '../system/promise'; -import { executeCoreCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; import type { BranchesView } from './branchesView'; import type { CommitsView } from './commitsView'; import type { ContributorsView } from './contributorsView'; diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 27c4a86796435..238e858400a2f 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -22,26 +22,21 @@ import * as StashActions from '../git/actions/stash'; import * as TagActions from '../git/actions/tag'; import * as WorktreeActions from '../git/actions/worktree'; import { GitUri } from '../git/gitUri'; -import { matchContributor } from '../git/models/contributor'; +import { RemoteResourceType } from '../git/models/remoteResource'; +import { deletedOrMissing } from '../git/models/revision'; import { ensurePullRequestRefs, - getComparisonRefsForPullRequest, getOpenedPullRequestRepo, getOrOpenPullRequestRepository, - getRepositoryIdentityForPullRequest, -} from '../git/models/pullRequest'; -import { createReference } from '../git/models/reference.utils'; -import { RemoteResourceType } from '../git/models/remoteResource'; -import { deletedOrMissing } from '../git/models/revision'; -import { shortenRevision } from '../git/models/revision.utils'; +} from '../git/utils/-webview/pullRequest.utils'; +import { matchContributor } from '../git/utils/contributor.utils'; +import { getComparisonRefsForPullRequest, getRepositoryIdentityForPullRequest } from '../git/utils/pullRequest.utils'; +import { createReference } from '../git/utils/reference.utils'; +import { shortenRevision } from '../git/utils/revision.utils'; import { showPatchesView } from '../plus/drafts/actions'; import { getPullRequestBranchDeepLink } from '../plus/launchpad/launchpadProvider'; import type { AssociateIssueWithBranchCommandArgs } from '../plus/startWork/startWork'; import { showContributorsPicker } from '../quickpicks/contributorsPicker'; -import { filterMap } from '../system/array'; -import { log } from '../system/decorators/log'; -import { partial, sequentialize } from '../system/function'; -import { join, map } from '../system/iterable'; import { executeActionCommand, executeCommand, @@ -49,11 +44,15 @@ import { executeCoreGitCommand, executeEditorCommand, registerCommand, -} from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; -import type { OpenWorkspaceLocation } from '../system/vscode/utils'; -import { openUrl, openWorkspace, revealInFileExplorer } from '../system/vscode/utils'; +} from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; +import type { OpenWorkspaceLocation } from '../system/-webview/utils'; +import { openUrl, openWorkspace, revealInFileExplorer } from '../system/-webview/utils'; +import { filterMap } from '../system/array'; +import { log } from '../system/decorators/log'; +import { partial, sequentialize } from '../system/function'; +import { join, map } from '../system/iterable'; import { DeepLinkActionType } from '../uris/deepLinks/deepLink'; import type { LaunchpadItemNode } from './launchpadView'; import type { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; @@ -1612,11 +1611,11 @@ export class ViewCommands implements Disposable { const comparison = await node.getFilesComparison(); if (!comparison?.files.length) return undefined; - return CommitActions.openOnlyChangedFiles(comparison.files); + return CommitActions.openOnlyChangedFiles(node.view.container, comparison.files); } if (!node.isAny('commit', 'stash')) return undefined; - return CommitActions.openOnlyChangedFiles(node.commit); + return CommitActions.openOnlyChangedFiles(node.view.container, node.commit); } @log() diff --git a/src/views/viewDecorationProvider.ts b/src/views/viewDecorationProvider.ts index 06c5cf847d229..2fe30e796b922 100644 --- a/src/views/viewDecorationProvider.ts +++ b/src/views/viewDecorationProvider.ts @@ -4,7 +4,7 @@ import { getQueryDataFromScmGitUri } from '../@types/vscode.git.uri'; import { GlyphChars, Schemes } from '../constants'; import type { Colors } from '../constants.colors'; import type { GitBranchStatus } from '../git/models/branch'; -import type { GitFileStatus } from '../git/models/file'; +import type { GitFileStatus } from '../git/models/fileStatus'; import type { GitPausedOperation } from '../git/models/pausedOperationStatus'; export class ViewFileDecorationProvider implements FileDecorationProvider, Disposable { diff --git a/src/views/views.ts b/src/views/views.ts index d1dcc82807ad4..6ff50f6e513a9 100644 --- a/src/views/views.ts +++ b/src/views/views.ts @@ -11,12 +11,12 @@ import type { } from '../git/models/reference'; import type { GitRemote } from '../git/models/remote'; import type { GitWorktree } from '../git/models/worktree'; +import { executeCommand, executeCoreCommand, registerCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { getContext, setContext } from '../system/-webview/context'; import { once } from '../system/function'; import { first } from '../system/iterable'; import { compare } from '../system/version'; -import { executeCommand, executeCoreCommand, registerCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { getContext, setContext } from '../system/vscode/context'; import { registerCommitDetailsWebviewView, registerGraphDetailsWebviewView, diff --git a/src/views/workspacesView.ts b/src/views/workspacesView.ts index b34b16247fc3f..8110090ff7919 100644 --- a/src/views/workspacesView.ts +++ b/src/views/workspacesView.ts @@ -6,12 +6,12 @@ import { GlCommand } from '../constants.commands'; import type { Container } from '../container'; import { unknownGitUri } from '../git/gitUri'; import type { Repository } from '../git/models/repository'; -import { ensurePlusFeaturesEnabled } from '../plus/gk/utils'; -import { gate } from '../system/decorators/gate'; +import { ensurePlusFeaturesEnabled } from '../plus/gk/utils/-webview/plus.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { openUrl, openWorkspace } from '../system/-webview/utils'; +import { gate } from '../system/decorators/-webview/gate'; import { debug } from '../system/decorators/log'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; -import { openUrl, openWorkspace } from '../system/vscode/utils'; import { ViewNode } from './nodes/abstract/viewNode'; import { MessageNode } from './nodes/common'; import { RepositoriesNode } from './nodes/repositoriesNode'; diff --git a/src/views/worktreesView.ts b/src/views/worktreesView.ts index 8d52ea4b63ea9..bddaae3d2eb2f 100644 --- a/src/views/worktreesView.ts +++ b/src/views/worktreesView.ts @@ -8,12 +8,12 @@ import { PlusFeatures } from '../features'; import { GitUri } from '../git/gitUri'; import type { RepositoryChangeEvent } from '../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository'; -import { groupRepositories } from '../git/models/repository.utils'; import type { GitWorktree } from '../git/models/worktree'; -import { ensurePlusFeaturesEnabled } from '../plus/gk/utils'; -import { gate } from '../system/decorators/gate'; -import { executeCommand } from '../system/vscode/command'; -import { configuration } from '../system/vscode/configuration'; +import { groupRepositories } from '../git/utils/-webview/repository.utils'; +import { ensurePlusFeaturesEnabled } from '../plus/gk/utils/-webview/plus.utils'; +import { executeCommand } from '../system/-webview/command'; +import { configuration } from '../system/-webview/configuration'; +import { gate } from '../system/decorators/-webview/gate'; import { RepositoriesSubscribeableNode } from './nodes/abstract/repositoriesSubscribeableNode'; import { RepositoryFolderNode } from './nodes/abstract/repositoryFolderNode'; import type { ViewNode } from './nodes/abstract/viewNode'; diff --git a/src/vsls/host.ts b/src/vsls/host.ts index 2c18954d2beb5..a5111920f185d 100644 --- a/src/vsls/host.ts +++ b/src/vsls/host.ts @@ -3,12 +3,12 @@ import { Disposable, Uri, workspace } from 'vscode'; import { git, gitLogStreamTo } from '@env/providers'; import type { LiveShare, SharedService } from '../@types/vsls'; import type { Container } from '../container'; +import { isVslsRoot } from '../system/-webview/path'; import { debug, log } from '../system/decorators/log'; import { join } from '../system/iterable'; import { Logger } from '../system/logger'; import { getLogScope } from '../system/logger.scope'; import { normalizePath } from '../system/path'; -import { isVslsRoot } from '../system/vscode/path'; import type { GetRepositoriesForUriRequest, GetRepositoriesForUriResponse, diff --git a/src/vsls/vsls.ts b/src/vsls/vsls.ts index 3fed0c156dee8..ca7272487ec47 100644 --- a/src/vsls/vsls.ts +++ b/src/vsls/vsls.ts @@ -3,13 +3,13 @@ import { Disposable, extensions, workspace } from 'vscode'; import type { LiveShare, LiveShareExtension, SessionChangeEvent } from '../@types/vsls'; import { Schemes } from '../constants'; import type { Container } from '../container'; +import { configuration } from '../system/-webview/configuration'; +import { setContext } from '../system/-webview/context'; import { debug } from '../system/decorators/log'; import { once } from '../system/event'; import { Logger } from '../system/logger'; import type { Deferred } from '../system/promise'; import { defer } from '../system/promise'; -import { configuration } from '../system/vscode/configuration'; -import { setContext } from '../system/vscode/context'; import { VslsGuestService } from './guest'; import { VslsHostService } from './host'; diff --git a/src/webviews/apps/commitDetails/commitDetails.ts b/src/webviews/apps/commitDetails/commitDetails.ts index 6d3ecd0b39d95..a75e3a008fb02 100644 --- a/src/webviews/apps/commitDetails/commitDetails.ts +++ b/src/webviews/apps/commitDetails/commitDetails.ts @@ -1,5 +1,5 @@ /*global*/ -import type { Serialized } from '../../../system/vscode/serialize'; +import type { Serialized } from '../../../system/-webview/serialize'; import type { State } from '../../commitDetails/protocol'; import { App } from '../shared/appBase'; import { DOM } from '../shared/dom'; diff --git a/src/webviews/apps/commitDetails/components/commit-details-app.ts b/src/webviews/apps/commitDetails/components/commit-details-app.ts index c380f6caf8f8d..f17635d1df81a 100644 --- a/src/webviews/apps/commitDetails/components/commit-details-app.ts +++ b/src/webviews/apps/commitDetails/components/commit-details-app.ts @@ -4,8 +4,8 @@ import { customElement, property, state } from 'lit/decorators.js'; import { when } from 'lit/directives/when.js'; import type { ViewFilesLayout } from '../../../../config'; import type { Commands } from '../../../../constants.commands'; +import type { Serialized } from '../../../../system/-webview/serialize'; import { pluralize } from '../../../../system/string'; -import type { Serialized } from '../../../../system/vscode/serialize'; import type { DraftState, ExecuteCommitActionsParams, Mode, State } from '../../../commitDetails/protocol'; import { ChangeReviewModeCommand, diff --git a/src/webviews/apps/commitDetails/components/gl-commit-details.ts b/src/webviews/apps/commitDetails/components/gl-commit-details.ts index 55c491ef2a037..b8e9795eae4f1 100644 --- a/src/webviews/apps/commitDetails/components/gl-commit-details.ts +++ b/src/webviews/apps/commitDetails/components/gl-commit-details.ts @@ -8,9 +8,9 @@ import type { ManageCloudIntegrationsCommandArgs, } from '../../../../commands/cloudIntegrations'; import type { IssueIntegrationId, SupportedCloudIntegrationIds } from '../../../../constants.integrations'; -import type { IssueOrPullRequest } from '../../../../git/models/issue'; +import type { IssueOrPullRequest } from '../../../../git/models/issueOrPullRequest'; import type { PullRequestShape } from '../../../../git/models/pullRequest'; -import type { Serialized } from '../../../../system/vscode/serialize'; +import type { Serialized } from '../../../../system/-webview/serialize'; import type { State } from '../../../commitDetails/protocol'; import { messageHeadlineSplitterToken } from '../../../commitDetails/protocol'; import type { TreeItemAction, TreeItemBase } from '../../shared/components/tree/base'; diff --git a/src/webviews/apps/commitDetails/components/gl-inspect-patch.ts b/src/webviews/apps/commitDetails/components/gl-inspect-patch.ts index db63608bb6c12..4174ed44896c6 100644 --- a/src/webviews/apps/commitDetails/components/gl-inspect-patch.ts +++ b/src/webviews/apps/commitDetails/components/gl-inspect-patch.ts @@ -1,6 +1,6 @@ import { css, html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import type { DraftVisibility } from '../../../../gk/models/drafts'; +import type { DraftVisibility } from '../../../../plus/drafts/models/drafts'; import type { Preferences, State } from '../../../commitDetails/protocol'; import type { Change, DraftUserSelection } from '../../../plus/patchDetails/protocol'; import { GlElement } from '../../shared/components/element'; diff --git a/src/webviews/apps/home/components/promo-banner.ts b/src/webviews/apps/home/components/promo-banner.ts index 9a9353d778fc5..7dd3908d13672 100644 --- a/src/webviews/apps/home/components/promo-banner.ts +++ b/src/webviews/apps/home/components/promo-banner.ts @@ -1,7 +1,7 @@ import { consume } from '@lit/context'; import { css, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { getApplicablePromo } from '../../../../plus/gk/account/promos'; +import { getApplicablePromo } from '../../../../plus/gk/utils/promo.utils'; import type { State } from '../../../home/protocol'; import { stateContext } from '../context'; import '../../shared/components/promo'; diff --git a/src/webviews/apps/plus/graph/GraphWrapper.tsx b/src/webviews/apps/plus/graph/GraphWrapper.tsx index b9b25c881bdc0..4b5a2d7101caa 100644 --- a/src/webviews/apps/plus/graph/GraphWrapper.tsx +++ b/src/webviews/apps/plus/graph/GraphWrapper.tsx @@ -24,8 +24,8 @@ import type { BranchGitCommandArgs } from '../../../../commands/git/branch'; import type { DateStyle, GraphBranchesVisibility } from '../../../../config'; import { GlCommand } from '../../../../constants.commands'; import type { SearchQuery } from '../../../../constants.search'; -import type { Subscription } from '../../../../plus/gk/account/subscription'; -import { isSubscriptionPaid } from '../../../../plus/gk/account/subscription'; +import type { Subscription } from '../../../../plus/gk/models/subscription'; +import { isSubscriptionPaid } from '../../../../plus/gk/utils/subscription.utils'; import type { LaunchpadCommandArgs } from '../../../../plus/launchpad/launchpad'; import { createCommandLink } from '../../../../system/commands'; import { filterMap, first, groupByFilterMap, join } from '../../../../system/iterable'; diff --git a/src/webviews/apps/plus/home/components/branch-card.ts b/src/webviews/apps/plus/home/components/branch-card.ts index 28c2e68319eec..bc7f7025ea107 100644 --- a/src/webviews/apps/plus/home/components/branch-card.ts +++ b/src/webviews/apps/plus/home/components/branch-card.ts @@ -10,7 +10,7 @@ import { launchpadCategoryToGroupMap, launchpadGroupIconMap, launchpadGroupLabelMap, -} from '../../../../../plus/launchpad/models'; +} from '../../../../../plus/launchpad/models/launchpad'; import type { AssociateIssueWithBranchCommandArgs } from '../../../../../plus/startWork/startWork'; import { createCommandLink } from '../../../../../system/commands'; import { fromNow } from '../../../../../system/date'; diff --git a/src/webviews/apps/plus/patchDetails/components/gl-draft-details.ts b/src/webviews/apps/plus/patchDetails/components/gl-draft-details.ts index 3b79b535f6a25..05b00edbabdc5 100644 --- a/src/webviews/apps/plus/patchDetails/components/gl-draft-details.ts +++ b/src/webviews/apps/plus/patchDetails/components/gl-draft-details.ts @@ -12,7 +12,7 @@ import type { DraftPatchFileChange, DraftRole, DraftVisibility, -} from '../../../../../gk/models/drafts'; +} from '../../../../../plus/drafts/models/drafts'; import { makeHierarchical } from '../../../../../system/array'; import { flatCount } from '../../../../../system/iterable'; import type { diff --git a/src/webviews/apps/plus/patchDetails/components/gl-patch-create.ts b/src/webviews/apps/plus/patchDetails/components/gl-patch-create.ts index 2a8e92598bfbc..ab4f5b583fcfe 100644 --- a/src/webviews/apps/plus/patchDetails/components/gl-patch-create.ts +++ b/src/webviews/apps/plus/patchDetails/components/gl-patch-create.ts @@ -5,11 +5,11 @@ import { map } from 'lit/directives/map.js'; import { repeat } from 'lit/directives/repeat.js'; import { when } from 'lit/directives/when.js'; import { urls } from '../../../../../constants'; -import type { GitFileChangeShape } from '../../../../../git/models/file'; -import type { DraftRole, DraftVisibility } from '../../../../../gk/models/drafts'; +import type { GitFileChangeShape } from '../../../../../git/models/fileChange'; +import type { DraftRole, DraftVisibility } from '../../../../../plus/drafts/models/drafts'; +import type { Serialized } from '../../../../../system/-webview/serialize'; import { debounce } from '../../../../../system/function'; import { flatCount } from '../../../../../system/iterable'; -import type { Serialized } from '../../../../../system/vscode/serialize'; import type { Change, DraftUserSelection, diff --git a/src/webviews/apps/plus/patchDetails/components/gl-tree-base.ts b/src/webviews/apps/plus/patchDetails/components/gl-tree-base.ts index 29cfc5f476349..0781b009c4e30 100644 --- a/src/webviews/apps/plus/patchDetails/components/gl-tree-base.ts +++ b/src/webviews/apps/plus/patchDetails/components/gl-tree-base.ts @@ -1,5 +1,5 @@ import { html, nothing } from 'lit'; -import type { GitFileChangeShape } from '../../../../../git/models/file'; +import type { GitFileChangeShape } from '../../../../../git/models/fileChange'; import type { HierarchicalItem } from '../../../../../system/array'; import { makeHierarchical } from '../../../../../system/array'; import { GlElement } from '../../../shared/components/element'; diff --git a/src/webviews/apps/plus/patchDetails/patchDetails.ts b/src/webviews/apps/plus/patchDetails/patchDetails.ts index cd0088a228a71..84a27d38a1ee2 100644 --- a/src/webviews/apps/plus/patchDetails/patchDetails.ts +++ b/src/webviews/apps/plus/patchDetails/patchDetails.ts @@ -2,9 +2,9 @@ import type { TextDocumentShowOptions } from 'vscode'; import type { ViewFilesLayout } from '../../../../config'; import type { Commands } from '../../../../constants.commands'; -import type { DraftPatchFileChange, DraftVisibility } from '../../../../gk/models/drafts'; +import type { DraftPatchFileChange, DraftVisibility } from '../../../../plus/drafts/models/drafts'; +import type { Serialized } from '../../../../system/-webview/serialize'; import { debounce } from '../../../../system/function'; -import type { Serialized } from '../../../../system/vscode/serialize'; import type { State, SwitchModeParams } from '../../../plus/patchDetails/protocol'; import { ApplyPatchCommand, diff --git a/src/webviews/apps/plus/shared/components/account-chip.ts b/src/webviews/apps/plus/shared/components/account-chip.ts index f1d50506451e4..453f6e39fd2a3 100644 --- a/src/webviews/apps/plus/shared/components/account-chip.ts +++ b/src/webviews/apps/plus/shared/components/account-chip.ts @@ -5,14 +5,14 @@ import { when } from 'lit/directives/when.js'; import { urls } from '../../../../../constants'; import { proTrialLengthInDays, SubscriptionPlanId, SubscriptionState } from '../../../../../constants.subscription'; import type { Source } from '../../../../../constants.telemetry'; -import type { Promo } from '../../../../../plus/gk/account/promos'; -import { getApplicablePromo } from '../../../../../plus/gk/account/promos'; +import type { Promo } from '../../../../../plus/gk/models/promo'; +import { getApplicablePromo } from '../../../../../plus/gk/utils/promo.utils'; import { getSubscriptionPlanTier, getSubscriptionStateName, getSubscriptionTimeRemaining, hasAccountFromSubscriptionState, -} from '../../../../../plus/gk/account/subscription'; +} from '../../../../../plus/gk/utils/subscription.utils'; import { createCommandLink } from '../../../../../system/commands'; import { pluralize } from '../../../../../system/string'; import type { State } from '../../../../home/protocol'; diff --git a/src/webviews/apps/plus/shared/components/feature-gate-plus-state.ts b/src/webviews/apps/plus/shared/components/feature-gate-plus-state.ts index 2b7c4028f3628..9a48868396314 100644 --- a/src/webviews/apps/plus/shared/components/feature-gate-plus-state.ts +++ b/src/webviews/apps/plus/shared/components/feature-gate-plus-state.ts @@ -11,8 +11,8 @@ import { import type { Source } from '../../../../../constants.telemetry'; import type { FeaturePreview } from '../../../../../features'; import { getFeaturePreviewStatus } from '../../../../../features'; -import type { Promo } from '../../../../../plus/gk/account/promos'; -import { getApplicablePromo } from '../../../../../plus/gk/account/promos'; +import type { Promo } from '../../../../../plus/gk/models/promo'; +import { getApplicablePromo } from '../../../../../plus/gk/utils/promo.utils'; import { pluralize } from '../../../../../system/string'; import type { GlButton } from '../../../shared/components/button'; import { linkStyles } from './vscode.css'; diff --git a/src/webviews/apps/plus/shared/components/integrations-chip.ts b/src/webviews/apps/plus/shared/components/integrations-chip.ts index 42d3e334cf47c..9d7aa3afc503e 100644 --- a/src/webviews/apps/plus/shared/components/integrations-chip.ts +++ b/src/webviews/apps/plus/shared/components/integrations-chip.ts @@ -7,7 +7,7 @@ import type { } from '../../../../../commands/cloudIntegrations'; import type { IntegrationFeatures } from '../../../../../constants.integrations'; import type { Source } from '../../../../../constants.telemetry'; -import { hasAccountFromSubscriptionState } from '../../../../../plus/gk/account/subscription'; +import { hasAccountFromSubscriptionState } from '../../../../../plus/gk/utils/subscription.utils'; import { createCommandLink } from '../../../../../system/commands'; import type { IntegrationState, State } from '../../../../home/protocol'; import { stateContext } from '../../../home/context'; diff --git a/src/webviews/apps/plus/timeline/timeline.ts b/src/webviews/apps/plus/timeline/timeline.ts index 14d2fb29bdf35..2edae98a95f4a 100644 --- a/src/webviews/apps/plus/timeline/timeline.ts +++ b/src/webviews/apps/plus/timeline/timeline.ts @@ -2,7 +2,7 @@ import './timeline.scss'; import type { PropertyValues } from 'lit'; import { html, LitElement, nothing } from 'lit'; import { customElement, query, state } from 'lit/decorators.js'; -import { isSubscriptionPaid } from '../../../../plus/gk/account/subscription'; +import { isSubscriptionPaid } from '../../../../plus/gk/utils/subscription.utils'; import type { Period, State } from '../../../plus/timeline/protocol'; import { OpenDataPointCommand, UpdatePeriodCommand } from '../../../plus/timeline/protocol'; import { GlApp } from '../../shared/app'; diff --git a/src/webviews/apps/shared/components/feature-badge.ts b/src/webviews/apps/shared/components/feature-badge.ts index 8369918c5cfee..40005f6db047a 100644 --- a/src/webviews/apps/shared/components/feature-badge.ts +++ b/src/webviews/apps/shared/components/feature-badge.ts @@ -5,15 +5,15 @@ import type { GlCommands } from '../../../../constants.commands'; import { GlCommand } from '../../../../constants.commands'; import { proTrialLengthInDays, SubscriptionPlanId, SubscriptionState } from '../../../../constants.subscription'; import type { Source } from '../../../../constants.telemetry'; -import type { Promo } from '../../../../plus/gk/account/promos'; -import { getApplicablePromo } from '../../../../plus/gk/account/promos'; -import type { Subscription } from '../../../../plus/gk/account/subscription'; +import type { Promo } from '../../../../plus/gk/models/promo'; +import type { Subscription } from '../../../../plus/gk/models/subscription'; +import { getApplicablePromo } from '../../../../plus/gk/utils/promo.utils'; import { getSubscriptionPlanName, getSubscriptionTimeRemaining, isSubscriptionPaid, isSubscriptionStateTrial, -} from '../../../../plus/gk/account/subscription'; +} from '../../../../plus/gk/utils/subscription.utils'; import { pluralize } from '../../../../system/string'; import type { GlPopover } from './overlays/popover'; import { focusOutline } from './styles/lit/a11y.css'; diff --git a/src/webviews/apps/shared/components/feature-gate.ts b/src/webviews/apps/shared/components/feature-gate.ts index 8dbc31bc4f3ad..0d8d2b704d398 100644 --- a/src/webviews/apps/shared/components/feature-gate.ts +++ b/src/webviews/apps/shared/components/feature-gate.ts @@ -3,7 +3,7 @@ import { customElement, property } from 'lit/decorators.js'; import type { SubscriptionState } from '../../../../constants.subscription'; import type { Source } from '../../../../constants.telemetry'; import type { FeaturePreview } from '../../../../features'; -import { isSubscriptionStatePaidOrTrial } from '../../../../plus/gk/account/subscription'; +import { isSubscriptionStatePaidOrTrial } from '../../../../plus/gk/utils/subscription.utils'; import '../../plus/shared/components/feature-gate-plus-state'; import { linkStyles } from '../../plus/shared/components/vscode.css'; diff --git a/src/webviews/apps/shared/components/promo.ts b/src/webviews/apps/shared/components/promo.ts index c4fdb519dab64..b0414a09c7bd2 100644 --- a/src/webviews/apps/shared/components/promo.ts +++ b/src/webviews/apps/shared/components/promo.ts @@ -1,7 +1,7 @@ import { css, html, LitElement, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import type { Promo } from '../../../../plus/gk/account/promos'; +import type { Promo } from '../../../../plus/gk/models/promo'; import { typeCheck } from '../../../../system/function'; @customElement('gl-promo') diff --git a/src/webviews/apps/shared/components/status/git-status.ts b/src/webviews/apps/shared/components/status/git-status.ts index 315b3da4b0cdb..1ae6577d1c395 100644 --- a/src/webviews/apps/shared/components/status/git-status.ts +++ b/src/webviews/apps/shared/components/status/git-status.ts @@ -1,28 +1,8 @@ import type { PropertyValueMap } from 'lit'; import { css, html, LitElement } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import type { GitFileStatus } from '../../../../../git/models/file'; - -// TODO: use the model version -const statusTextMap: Record = { - '.': 'Unchanged', - '!': 'Ignored', - '?': 'Untracked', - A: 'Added', - D: 'Deleted', - M: 'Modified', - R: 'Renamed', - C: 'Copied', - AA: 'Conflict', - AU: 'Conflict', - UA: 'Conflict', - DD: 'Conflict', - DU: 'Conflict', - UD: 'Conflict', - UU: 'Conflict', - T: 'Modified', - U: 'Updated but Unmerged', -}; +import type { GitFileStatus } from '../../../../../git/models/fileStatus'; +import { getGitFileStatusText } from '../../../../../git/utils/fileStatus.utils'; @customElement('gl-git-status') export class GlGitStatus extends LitElement { @@ -73,7 +53,7 @@ export class GlGitStatus extends LitElement { @state() get statusName() { if (!this.status) return ''; - return statusTextMap[this.status]; + return getGitFileStatusText(this.status); } override updated(changedProperties: PropertyValueMap | Map): void { diff --git a/src/webviews/apps/shared/components/tree/base.ts b/src/webviews/apps/shared/components/tree/base.ts index b1a455c054b6a..9d7fda24a3ea2 100644 --- a/src/webviews/apps/shared/components/tree/base.ts +++ b/src/webviews/apps/shared/components/tree/base.ts @@ -1,5 +1,5 @@ -import type { GitFileStatus } from '../../../../../git/models/file'; -import type { DraftPatchFileChange } from '../../../../../gk/models/drafts'; +import type { GitFileStatus } from '../../../../../git/models/fileStatus'; +import type { DraftPatchFileChange } from '../../../../../plus/drafts/models/drafts'; export interface TreeItemBase { // node properties diff --git a/src/webviews/apps/shared/ipc.ts b/src/webviews/apps/shared/ipc.ts index f0b7d9d56a840..24cc695307297 100644 --- a/src/webviews/apps/shared/ipc.ts +++ b/src/webviews/apps/shared/ipc.ts @@ -1,10 +1,10 @@ /*global window */ +import type { Serialized } from '../../../system/-webview/serialize'; import { getScopedCounter } from '../../../system/counter'; import { debug, logName } from '../../../system/decorators/log'; import { Logger } from '../../../system/logger'; import { getLogScope, getNewLogScope } from '../../../system/logger.scope'; import { maybeStopWatch } from '../../../system/stopwatch'; -import type { Serialized } from '../../../system/vscode/serialize'; import type { IpcCallParamsType, IpcCallResponseParamsType, IpcCommand, IpcMessage, IpcRequest } from '../../protocol'; import { ipcPromiseSettled, isIpcPromise } from '../../protocol'; import { DOM } from './dom'; diff --git a/src/webviews/apps/tsconfig.json b/src/webviews/apps/tsconfig.json index 7020338ae45df..f491e28c23fb8 100644 --- a/src/webviews/apps/tsconfig.json +++ b/src/webviews/apps/tsconfig.json @@ -9,23 +9,20 @@ }, "useDefineForClassFields": false // Needed for lit decorators https://github.com/lit/lit/issues/3278 https://lit.dev/docs/tools/publishing/#publishing-modern-javascript }, - // Keep in sync with `eslint.config.mjs` + // Keep in sync with `src/eslint.config.mjs` "include": [ "**/*", - "../../@types/**/*", - "../../env/browser/**/*", - "../../plus/gk/account/promos.ts", - "../../plus/gk/account/subscription.ts", - "../../plus/launchpad/models.ts", "../**/protocol.ts", + "../../**/models/**/*.ts", + "../../**/utils/**/*.ts", + "../../@types/**/*", "../../config.ts", "../../constants.ts", "../../constants.*.ts", + "../../env/browser/**/*", "../../features.ts", - "../../git/utils/*.ts", - "../../subscription.ts", - "../../system/*.ts", - "../../system/decorators/log.ts" + "../../system/**/*.ts", + "../../**/webview/**/*" ], - "exclude": ["**/vscode/**/*"] + "exclude": ["**/-webview/**/*"] } diff --git a/src/webviews/commitDetails/commitDetailsWebview.ts b/src/webviews/commitDetails/commitDetailsWebview.ts index 8aad0e25c6413..1e064af75264b 100644 --- a/src/webviews/commitDetails/commitDetailsWebview.ts +++ b/src/webviews/commitDetails/commitDetailsWebview.ts @@ -27,25 +27,37 @@ import { CommitFormatter } from '../../git/formatters/commitFormatter'; import type { GitBranch } from '../../git/models/branch'; import type { GitCommit } from '../../git/models/commit'; import { isCommit, isStash } from '../../git/models/commit'; -import type { GitFileChange, GitFileChangeShape } from '../../git/models/file'; -import type { IssueOrPullRequest } from '../../git/models/issue'; -import { serializeIssueOrPullRequest } from '../../git/models/issue'; +import type { GitFileChange, GitFileChangeShape } from '../../git/models/fileChange'; +import type { IssueOrPullRequest } from '../../git/models/issueOrPullRequest'; import type { PullRequest } from '../../git/models/pullRequest'; -import { getComparisonRefsForPullRequest, serializePullRequest } from '../../git/models/pullRequest'; import type { GitRevisionReference } from '../../git/models/reference'; -import { createReference, getReferenceFromRevision } from '../../git/models/reference.utils'; import type { GitRemote } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; import { uncommitted, uncommittedStaged } from '../../git/models/revision'; -import { shortenRevision } from '../../git/models/revision.utils'; -import type { CreateDraftChange, Draft, DraftVisibility } from '../../gk/models/drafts'; +import { getReferenceFromRevision } from '../../git/utils/-webview/reference.utils'; +import { serializeIssueOrPullRequest } from '../../git/utils/issueOrPullRequest.utils'; +import { getComparisonRefsForPullRequest, serializePullRequest } from '../../git/utils/pullRequest.utils'; +import { createReference } from '../../git/utils/reference.utils'; +import { shortenRevision } from '../../git/utils/revision.utils'; import { showPatchesView } from '../../plus/drafts/actions'; -import type { Subscription } from '../../plus/gk/account/subscription'; -import type { SubscriptionChangeEvent } from '../../plus/gk/account/subscriptionService'; +import type { CreateDraftChange, Draft, DraftVisibility } from '../../plus/drafts/models/drafts'; +import { confirmDraftStorage } from '../../plus/drafts/utils/-webview/drafts.utils'; +import type { Subscription } from '../../plus/gk/models/subscription'; +import type { SubscriptionChangeEvent } from '../../plus/gk/subscriptionService'; +import { ensureAccount } from '../../plus/gk/utils/-webview/acount.utils'; import type { ConnectionStateChangeEvent } from '../../plus/integrations/integrationService'; import { getEntityIdentifierInput } from '../../plus/integrations/providers/utils'; -import { confirmDraftStorage, ensureAccount } from '../../plus/utils'; +import { + executeCommand, + executeCoreCommand, + executeCoreGitCommand, + registerCommand, +} from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { getContext, onDidChangeContext } from '../../system/-webview/context'; +import type { Serialized } from '../../system/-webview/serialize'; +import { serialize } from '../../system/-webview/serialize'; import { debug } from '../../system/decorators/log'; import type { Deferrable } from '../../system/function'; import { debounce } from '../../system/function'; @@ -54,16 +66,6 @@ import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; import { MRU } from '../../system/mru'; import { getSettledValue, pauseOnCancelOrTimeoutMapTuplePromise } from '../../system/promise'; -import { - executeCommand, - executeCoreCommand, - executeCoreGitCommand, - registerCommand, -} from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext, onDidChangeContext } from '../../system/vscode/context'; -import type { Serialized } from '../../system/vscode/serialize'; -import { serialize } from '../../system/vscode/serialize'; import type { LinesChangeEvent } from '../../trackers/lineTracker'; import type { ShowInCommitGraphCommandArgs } from '../plus/graph/protocol'; import type { Change } from '../plus/patchDetails/protocol'; diff --git a/src/webviews/commitDetails/protocol.ts b/src/webviews/commitDetails/protocol.ts index 4c4b64d976040..da67d19617ff5 100644 --- a/src/webviews/commitDetails/protocol.ts +++ b/src/webviews/commitDetails/protocol.ts @@ -3,13 +3,13 @@ import type { Autolink } from '../../autolinks'; import type { Config, DateStyle } from '../../config'; import type { Sources } from '../../constants.telemetry'; import type { GitCommitIdentityShape, GitCommitStats } from '../../git/models/commit'; -import type { GitFileChangeShape } from '../../git/models/file'; -import type { IssueOrPullRequest } from '../../git/models/issue'; +import type { GitFileChangeShape } from '../../git/models/fileChange'; +import type { IssueOrPullRequest } from '../../git/models/issueOrPullRequest'; import type { PullRequestShape } from '../../git/models/pullRequest'; import type { Repository } from '../../git/models/repository'; -import type { Draft, DraftVisibility } from '../../gk/models/drafts'; +import type { Draft, DraftVisibility } from '../../plus/drafts/models/drafts'; +import type { Serialized } from '../../system/-webview/serialize'; import type { DateTimeFormat } from '../../system/date'; -import type { Serialized } from '../../system/vscode/serialize'; import type { Change, DraftUserSelection } from '../plus/patchDetails/protocol'; import type { IpcScope, WebviewState } from '../protocol'; import { IpcCommand, IpcNotification, IpcRequest } from '../protocol'; diff --git a/src/webviews/commitDetails/registration.ts b/src/webviews/commitDetails/registration.ts index 57b1ae88dca0f..121b2bd955154 100644 --- a/src/webviews/commitDetails/registration.ts +++ b/src/webviews/commitDetails/registration.ts @@ -1,5 +1,5 @@ import type { CommitSelectedEvent } from '../../eventBus'; -import type { Serialized } from '../../system/vscode/serialize'; +import type { Serialized } from '../../system/-webview/serialize'; import type { WebviewsController } from '../webviewsController'; import type { ShowWipArgs, State } from './protocol'; diff --git a/src/webviews/home/homeWebview.ts b/src/webviews/home/homeWebview.ts index efaa40a5f4c5c..f66c31f9de1d4 100644 --- a/src/webviews/home/homeWebview.ts +++ b/src/webviews/home/homeWebview.ts @@ -20,40 +20,46 @@ import { openComparisonChanges } from '../../git/actions/commit'; import * as RepoActions from '../../git/actions/repository'; import type { BranchContributionsOverview } from '../../git/gitProvider'; import type { GitBranch } from '../../git/models/branch'; -import { getAssociatedIssuesForBranch, getBranchTargetInfo } from '../../git/models/branch.utils'; -import type { GitFileChangeShape } from '../../git/models/file'; +import type { GitFileChangeShape } from '../../git/models/fileChange'; import type { Issue } from '../../git/models/issue'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; import type { PullRequest } from '../../git/models/pullRequest'; -import { getComparisonRefsForPullRequest } from '../../git/models/pullRequest'; -import { getReferenceFromBranch } from '../../git/models/reference.utils'; import { RemoteResourceType } from '../../git/models/remoteResource'; import type { Repository } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; import { uncommitted } from '../../git/models/revision'; -import { createRevisionRange } from '../../git/models/revision.utils'; import type { GitStatus } from '../../git/models/status'; import type { GitWorktree } from '../../git/models/worktree'; -import { getOpenedWorktreesByBranch, groupWorktreesByBranch } from '../../git/models/worktree.utils'; -import { sortBranches } from '../../git/utils/vscode/sorting'; +import { getAssociatedIssuesForBranch } from '../../git/utils/-webview/branch.issue.utils'; +import { getBranchTargetInfo } from '../../git/utils/-webview/branch.utils'; +import { getReferenceFromBranch } from '../../git/utils/-webview/reference.utils'; +import { sortBranches } from '../../git/utils/-webview/sorting'; +import { getOpenedWorktreesByBranch, groupWorktreesByBranch } from '../../git/utils/-webview/worktree.utils'; +import { getComparisonRefsForPullRequest } from '../../git/utils/pullRequest.utils'; +import { createRevisionRange } from '../../git/utils/revision.utils'; import { showPatchesView } from '../../plus/drafts/actions'; -import type { Subscription } from '../../plus/gk/account/subscription'; -import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/account/subscription'; -import type { SubscriptionChangeEvent } from '../../plus/gk/account/subscriptionService'; +import type { Subscription } from '../../plus/gk/models/subscription'; +import type { SubscriptionChangeEvent } from '../../plus/gk/subscriptionService'; +import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/utils/subscription.utils'; import type { LaunchpadCategorizedResult } from '../../plus/launchpad/launchpadProvider'; import { getLaunchpadItemGroups } from '../../plus/launchpad/launchpadProvider'; -import { getLaunchpadSummary } from '../../plus/launchpad/utils'; +import { getLaunchpadSummary } from '../../plus/launchpad/utils/-webview/launchpad.utils'; import type { StartWorkCommandArgs } from '../../plus/startWork/startWork'; import { showRepositoryPicker } from '../../quickpicks/repositoryPicker'; +import { + executeActionCommand, + executeCommand, + executeCoreCommand, + registerCommand, +} from '../../system/-webview/command'; +import { configuration } from '../../system/-webview/configuration'; +import { getContext, onDidChangeContext } from '../../system/-webview/context'; +import { openUrl, openWorkspace } from '../../system/-webview/utils'; import { debug } from '../../system/decorators/log'; import type { Deferrable } from '../../system/function'; import { debounce } from '../../system/function'; import { filterMap } from '../../system/iterable'; import { getSettledValue } from '../../system/promise'; -import { executeActionCommand, executeCommand, executeCoreCommand, registerCommand } from '../../system/vscode/command'; -import { configuration } from '../../system/vscode/configuration'; -import { getContext, onDidChangeContext } from '../../system/vscode/context'; -import { openUrl, openWorkspace } from '../../system/vscode/utils'; import type { ShowInCommitGraphCommandArgs } from '../plus/graph/protocol'; import type { Change } from '../plus/patchDetails/protocol'; import type { IpcMessage } from '../protocol'; diff --git a/src/webviews/home/protocol.ts b/src/webviews/home/protocol.ts index 54b08d3e6f107..17c7f1b440719 100644 --- a/src/webviews/home/protocol.ts +++ b/src/webviews/home/protocol.ts @@ -5,10 +5,10 @@ import type { Issue } from '../../git/models/issue'; import type { MergeConflict } from '../../git/models/mergeConflict'; import type { GitPausedOperationStatus } from '../../git/models/pausedOperationStatus'; import type { GitBranchReference } from '../../git/models/reference'; -import type { Subscription } from '../../plus/gk/account/subscription'; +import type { Subscription } from '../../plus/gk/models/subscription'; import type { LaunchpadSummaryResult } from '../../plus/launchpad/launchpadIndicator'; import type { LaunchpadItem } from '../../plus/launchpad/launchpadProvider'; -import type { LaunchpadGroup } from '../../plus/launchpad/models'; +import type { LaunchpadGroup } from '../../plus/launchpad/models/launchpad'; import type { IpcScope, WebviewState } from '../protocol'; import { IpcCommand, IpcNotification, IpcRequest } from '../protocol'; diff --git a/src/webviews/plus/graph/graphWebview.ts b/src/webviews/plus/graph/graphWebview.ts index 8b5d944173054..088561951a5af 100644 --- a/src/webviews/plus/graph/graphWebview.ts +++ b/src/webviews/plus/graph/graphWebview.ts @@ -2,7 +2,7 @@ import type { CancellationToken, ColorTheme, ConfigurationChangeEvent } from 'vs import { CancellationTokenSource, Disposable, env, Uri, window } from 'vscode'; import type { CreatePullRequestActionContext, OpenPullRequestActionContext } from '../../../api/gitlens'; import { getAvatarUri } from '../../../avatars'; -import { parseCommandContext } from '../../../commands/base'; +import { parseCommandContext } from '../../../commands/commandContext.utils'; import type { CopyDeepLinkCommandArgs } from '../../../commands/copyDeepLink'; import type { CopyMessageToClipboardCommandArgs } from '../../../commands/copyMessageToClipboard'; import type { CopyShaToClipboardCommandArgs } from '../../../commands/copyShaToClipboard'; @@ -50,27 +50,12 @@ import * as WorktreeActions from '../../../git/actions/worktree'; import { GitSearchError } from '../../../git/errors'; import { CommitFormatter } from '../../../git/formatters/commitFormatter'; import type { GitBranch } from '../../../git/models/branch'; -import { - getAssociatedIssuesForBranch, - getBranchId, - getBranchNameWithoutRemote, - getDefaultBranchName, - getLocalBranchByUpstream, - getRemoteNameFromBranchName, - getTargetBranchName, -} from '../../../git/models/branch.utils'; import type { GitCommit } from '../../../git/models/commit'; import { isStash } from '../../../git/models/commit'; -import { splitCommitMessage } from '../../../git/models/commit.utils'; import { GitContributor } from '../../../git/models/contributor'; import type { GitGraph, GitGraphRowType } from '../../../git/models/graph'; import type { IssueShape } from '../../../git/models/issue'; import type { PullRequest } from '../../../git/models/pullRequest'; -import { - getComparisonRefsForPullRequest, - getRepositoryIdentityForPullRequest, - serializePullRequest, -} from '../../../git/models/pullRequest'; import type { GitBranchReference, GitReference, @@ -78,7 +63,6 @@ import type { GitStashReference, GitTagReference, } from '../../../git/models/reference'; -import { createReference, getReferenceFromBranch, isGitReference } from '../../../git/models/reference.utils'; import { RemoteResourceType } from '../../../git/models/remoteResource'; import type { Repository, @@ -86,21 +70,47 @@ import type { RepositoryFileSystemChangeEvent, } from '../../../git/models/repository'; import { isRepository, RepositoryChange, RepositoryChangeComparisonMode } from '../../../git/models/repository'; -import { getLastFetchedUpdateInterval } from '../../../git/models/repository.utils'; import { uncommitted } from '../../../git/models/revision'; -import { isSha, shortenRevision } from '../../../git/models/revision.utils'; -import { getWorktreesByBranch } from '../../../git/models/worktree.utils'; import type { GitSearch } from '../../../git/search'; import { getSearchQueryComparisonKey, parseSearchQuery } from '../../../git/search'; -import { getRemoteIconUri } from '../../../git/utils/vscode/icons'; -import type { FeaturePreviewChangeEvent, SubscriptionChangeEvent } from '../../../plus/gk/account/subscriptionService'; +import { getAssociatedIssuesForBranch } from '../../../git/utils/-webview/branch.issue.utils'; +import { getDefaultBranchName, getTargetBranchName } from '../../../git/utils/-webview/branch.utils'; +import { getRemoteIconUri } from '../../../git/utils/-webview/icons'; +import { getReferenceFromBranch } from '../../../git/utils/-webview/reference.utils'; +import { getWorktreesByBranch } from '../../../git/utils/-webview/worktree.utils'; +import { + getBranchId, + getBranchNameWithoutRemote, + getLocalBranchByUpstream, + getRemoteNameFromBranchName, +} from '../../../git/utils/branch.utils'; +import { splitCommitMessage } from '../../../git/utils/commit.utils'; +import { getLastFetchedUpdateInterval } from '../../../git/utils/fetch.utils'; +import { + getComparisonRefsForPullRequest, + getRepositoryIdentityForPullRequest, + serializePullRequest, +} from '../../../git/utils/pullRequest.utils'; +import { createReference, isGitReference } from '../../../git/utils/reference.utils'; +import { isSha, shortenRevision } from '../../../git/utils/revision.utils'; +import type { FeaturePreviewChangeEvent, SubscriptionChangeEvent } from '../../../plus/gk/subscriptionService'; import type { ConnectionStateChangeEvent } from '../../../plus/integrations/integrationService'; import { remoteProviderIdToIntegrationId } from '../../../plus/integrations/integrationService'; import { getPullRequestBranchDeepLink } from '../../../plus/launchpad/launchpadProvider'; import type { AssociateIssueWithBranchCommandArgs } from '../../../plus/startWork/startWork'; import { ReferencesQuickPickIncludes, showReferencePicker } from '../../../quickpicks/referencePicker'; import { showRepositoryPicker } from '../../../quickpicks/repositoryPicker'; -import { gate } from '../../../system/decorators/gate'; +import { + executeActionCommand, + executeCommand, + executeCoreCommand, + registerCommand, +} from '../../../system/-webview/command'; +import { configuration } from '../../../system/-webview/configuration'; +import { getContext, onDidChangeContext } from '../../../system/-webview/context'; +import type { OpenWorkspaceLocation } from '../../../system/-webview/utils'; +import { isDarkTheme, isLightTheme, openUrl, openWorkspace } from '../../../system/-webview/utils'; +import { gate } from '../../../system/decorators/-webview/gate'; import { debug, log } from '../../../system/decorators/log'; import type { Deferrable } from '../../../system/function'; import { debounce, disposableInterval } from '../../../system/function'; @@ -112,16 +122,6 @@ import { pauseOnCancelOrTimeoutMapTuplePromise, } from '../../../system/promise'; import { Stopwatch } from '../../../system/stopwatch'; -import { - executeActionCommand, - executeCommand, - executeCoreCommand, - registerCommand, -} from '../../../system/vscode/command'; -import { configuration } from '../../../system/vscode/configuration'; -import { getContext, onDidChangeContext } from '../../../system/vscode/context'; -import type { OpenWorkspaceLocation } from '../../../system/vscode/utils'; -import { isDarkTheme, isLightTheme, openUrl, openWorkspace } from '../../../system/vscode/utils'; import { isWebviewItemContext, isWebviewItemGroupContext, serializeWebviewItemContext } from '../../../system/webview'; import { DeepLinkActionType } from '../../../uris/deepLinks/deepLink'; import { RepositoryFolderNode } from '../../../views/nodes/abstract/repositoryFolderNode'; @@ -3877,7 +3877,7 @@ export class GraphWebviewProvider implements WebviewProvider