diff --git a/.gitignore b/.gitignore index 01c86a307e510..ced5e09ef008d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ images/settings gitlens-*.vsix product.json tsconfig*.tsbuildinfo +localdev*.instructions.md diff --git a/docs/links.md b/docs/links.md index f128d35218fc3..ef5b4644d92ee 100644 --- a/docs/links.md +++ b/docs/links.md @@ -320,7 +320,7 @@ _{prefix}/integrations/connect(&integration={integration})_ - _github_ - Connects the GitHub integration. - _gitlab_ - Connects the GitLab integration. - _bitbucket_ - Connects the Bitbucket integration. - - _azuredevOps_ - Connects the Azure DevOps integration. + - _azureDevOps_ - Connects the Azure DevOps integration. - _jira_ - Connects the Jira integration. - _linear_ - Connects the Linear integration. - _trello_ - Connects the Trello integration. diff --git a/src/autolinks/autolinksProvider.ts b/src/autolinks/autolinksProvider.ts index 455cf1523482c..547a03bb5c84d 100644 --- a/src/autolinks/autolinksProvider.ts +++ b/src/autolinks/autolinksProvider.ts @@ -2,7 +2,6 @@ import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable } from 'vscode'; import { GlyphChars } from '../constants'; import type { IntegrationIds } from '../constants.integrations'; -import { IssuesCloudHostIntegrationId } from '../constants.integrations'; import type { Container } from '../container'; import type { GitRemote } from '../git/models/remote'; import type { RemoteProvider, RemoteProviderId } from '../git/remotes/remoteProvider'; @@ -177,16 +176,11 @@ export class AutolinksProvider implements Disposable { return getAutolinks(message, refsets); } - getAutolinkEnrichableId(autolink: Autolink): string { - // TODO: this should return linking key for all types of providers: such as TST-123 or #89 or PR 89 (or a pair: key+id). - // Each provider should form whatever ID they need in their specific getIssueOrPullRequest() method. - switch (autolink.provider?.id) { - case IssuesCloudHostIntegrationId.Jira: - case IssuesCloudHostIntegrationId.Linear: - return `${autolink.prefix}${autolink.id}`; - default: - return autolink.id; - } + getAutolinkEnrichableId(autolink: Autolink): { id: string; key: string } { + return { + id: autolink.id, + key: `${autolink.prefix}${autolink.id}`, + }; } async getEnrichedAutolinks( @@ -258,15 +252,19 @@ export class AutolinksProvider implements Disposable { integration != null && integrationId === integration.id && link.provider?.domain === integration.domain - ? integration.getIssueOrPullRequest( + ? integration.getLinkedIssueOrPullRequest( link.descriptor ?? remote.provider.repoDesc, this.getAutolinkEnrichableId(link), { type: link.type }, ) : link.descriptor != null - ? linkIntegration?.getIssueOrPullRequest(link.descriptor, this.getAutolinkEnrichableId(link), { - type: link.type, - }) + ? linkIntegration?.getLinkedIssueOrPullRequest( + link.descriptor, + this.getAutolinkEnrichableId(link), + { + type: link.type, + }, + ) : undefined; enrichedAutolinks.set(id, [issueOrPullRequestPromise, link]); } diff --git a/src/commands/toggleFileAnnotations.ts b/src/commands/toggleFileAnnotations.ts index a9537a71edb45..85294da4481c8 100644 --- a/src/commands/toggleFileAnnotations.ts +++ b/src/commands/toggleFileAnnotations.ts @@ -29,6 +29,7 @@ export class ClearFileAnnotationsCommand extends EditorCommand { // Clear split editors as though they were linked, because we can't handle the command states effectively await Promise.allSettled( + // eslint-disable-next-line @typescript-eslint/await-thenable [editor, ...getOtherVisibleTextEditors(editor)].map(e => this.container.fileAnnotations.clear(e)), ); } catch (ex) { diff --git a/src/git/remotes/remoteProvider.ts b/src/git/remotes/remoteProvider.ts index 4215e802f2163..323f489953c8b 100644 --- a/src/git/remotes/remoteProvider.ts +++ b/src/git/remotes/remoteProvider.ts @@ -234,6 +234,7 @@ export abstract class RemoteProvider getSettledValue(r)) .filter(r => r != null); diff --git a/src/plus/ai/aiProviderService.ts b/src/plus/ai/aiProviderService.ts index 3ff30b0865772..3dbded6eabda1 100644 --- a/src/plus/ai/aiProviderService.ts +++ b/src/plus/ai/aiProviderService.ts @@ -1708,7 +1708,6 @@ export class AIProviderService implements Disposable { setLogScopeExit( scope, `model: ${model.provider.id}/${model.id}`, - // eslint-disable-next-line @typescript-eslint/no-base-to-string `failed: ${String(ex)} (${String(ex.original)})`, ); @@ -1718,7 +1717,6 @@ export class AIProviderService implements Disposable { ...telementry.data, duration: Date.now() - start, failed: true, - // eslint-disable-next-line @typescript-eslint/no-base-to-string 'failed.error': String(ex), 'failed.error.detail': String(ex.original), }, diff --git a/src/plus/integrations/models/integration.ts b/src/plus/integrations/models/integration.ts index 249a3cd25ac1c..fc7294407158b 100644 --- a/src/plus/integrations/models/integration.ts +++ b/src/plus/integrations/models/integration.ts @@ -499,9 +499,9 @@ export abstract class IntegrationBase< ): Promise; @debug() - async getIssueOrPullRequest( + async getLinkedIssueOrPullRequest( resource: T, - id: string, + link: { id: string; key: string }, options?: { expiryOverride?: boolean | number; type?: IssueOrPullRequestType }, ): Promise { const scope = getLogScope(); @@ -512,17 +512,17 @@ export abstract class IntegrationBase< await this.refreshSessionIfExpired(scope); const issueOrPR = this.container.cache.getIssueOrPullRequest( - id, + link.key, options?.type, resource, this, () => ({ value: (async () => { try { - const result = await this.getProviderIssueOrPullRequest( + const result = await this.getProviderLinkedIssueOrPullRequest( this._session!, resource, - id, + link, options?.type, ); this.resetRequestExceptionCount('getIssueOrPullRequest'); @@ -538,10 +538,10 @@ export abstract class IntegrationBase< return issueOrPR; } - protected abstract getProviderIssueOrPullRequest( + protected abstract getProviderLinkedIssueOrPullRequest( session: ProviderAuthenticationSession, resource: T, - id: string, + link: { id: string; key: string }, type: undefined | IssueOrPullRequestType, ): Promise; diff --git a/src/plus/integrations/providers/azureDevOps.ts b/src/plus/integrations/providers/azureDevOps.ts index abd8dee6bdb1d..60f08efe7d2f5 100644 --- a/src/plus/integrations/providers/azureDevOps.ts +++ b/src/plus/integrations/providers/azureDevOps.ts @@ -259,10 +259,10 @@ export abstract class AzureDevOpsIntegrationBase< return Promise.resolve(undefined); } - protected override async getProviderIssueOrPullRequest( + protected override async getProviderLinkedIssueOrPullRequest( { accessToken }: AuthenticationSession, repo: AzureRepositoryDescriptor, - id: string, + { id }: { id: string; key: string }, type: undefined | IssueOrPullRequestType, ): Promise { return (await this.container.azure)?.getIssueOrPullRequest(this, accessToken, repo.owner, repo.name, id, { diff --git a/src/plus/integrations/providers/bitbucket-server.ts b/src/plus/integrations/providers/bitbucket-server.ts index fc142fc9c3c4f..6d6b4f7ef1215 100644 --- a/src/plus/integrations/providers/bitbucket-server.ts +++ b/src/plus/integrations/providers/bitbucket-server.ts @@ -105,10 +105,10 @@ export class BitbucketServerIntegration extends GitHostIntegration< return Promise.resolve(undefined); } - protected override async getProviderIssueOrPullRequest( + protected override async getProviderLinkedIssueOrPullRequest( { accessToken }: AuthenticationSession, repo: BitbucketRepositoryDescriptor, - id: string, + { id }: { id: string; key: string }, type: undefined | IssueOrPullRequestType, ): Promise { if (type === 'issue') { diff --git a/src/plus/integrations/providers/bitbucket.ts b/src/plus/integrations/providers/bitbucket.ts index 809a7779acab2..cf4255968f2e3 100644 --- a/src/plus/integrations/providers/bitbucket.ts +++ b/src/plus/integrations/providers/bitbucket.ts @@ -87,10 +87,10 @@ export class BitbucketIntegration extends GitHostIntegration< return Promise.resolve(undefined); } - protected override async getProviderIssueOrPullRequest( + protected override async getProviderLinkedIssueOrPullRequest( { accessToken }: AuthenticationSession, repo: BitbucketRepositoryDescriptor, - id: string, + { id }: { id: string; key: string }, type: undefined | IssueOrPullRequestType, ): Promise { return (await this.container.bitbucket)?.getIssueOrPullRequest( diff --git a/src/plus/integrations/providers/github.ts b/src/plus/integrations/providers/github.ts index b83e9738a4597..24ba41d9e8dda 100644 --- a/src/plus/integrations/providers/github.ts +++ b/src/plus/integrations/providers/github.ts @@ -83,10 +83,10 @@ abstract class GitHubIntegrationBase extends Gi }); } - protected override async getProviderIssueOrPullRequest( + protected override async getProviderLinkedIssueOrPullRequest( { accessToken }: AuthenticationSession, repo: GitHubRepositoryDescriptor, - id: string, + { id }: { id: string; key: string }, ): Promise { return (await this.container.github)?.getIssueOrPullRequest( this, diff --git a/src/plus/integrations/providers/gitlab.ts b/src/plus/integrations/providers/gitlab.ts index ca226ef815278..bb4ff22e8bab6 100644 --- a/src/plus/integrations/providers/gitlab.ts +++ b/src/plus/integrations/providers/gitlab.ts @@ -87,10 +87,10 @@ abstract class GitLabIntegrationBase extends Gi }); } - protected override async getProviderIssueOrPullRequest( + protected override async getProviderLinkedIssueOrPullRequest( { accessToken }: AuthenticationSession, repo: GitLabRepositoryDescriptor, - id: string, + { id }: { id: string; key: string }, ): Promise { return (await this.container.gitlab)?.getIssueOrPullRequest( this, diff --git a/src/plus/integrations/providers/jira.ts b/src/plus/integrations/providers/jira.ts index b2373d05ec735..d81c3ca8f7dc8 100644 --- a/src/plus/integrations/providers/jira.ts +++ b/src/plus/integrations/providers/jira.ts @@ -272,15 +272,15 @@ export class JiraIntegration extends IssuesIntegration { const api = await this.getProvidersApi(); const issue = await api.getIssue( this.id, - { resourceId: resource.id, number: id }, + { resourceId: resource.id, number: key }, { accessToken: session.accessToken }, ); return issue != null ? toIssueShape(issue, this) : undefined; diff --git a/src/plus/integrations/providers/linear.ts b/src/plus/integrations/providers/linear.ts index 5e33f25a24a1b..a4d8559d72ec2 100644 --- a/src/plus/integrations/providers/linear.ts +++ b/src/plus/integrations/providers/linear.ts @@ -210,10 +210,10 @@ export class LinearIntegration extends IssuesIntegration { const issue = await this.getRawProviderIssue(session, resource, id); diff --git a/src/system/promise.ts b/src/system/promise.ts index 7737a3018e2a3..7aa3da84941eb 100644 --- a/src/system/promise.ts +++ b/src/system/promise.ts @@ -200,6 +200,7 @@ export function getDeferredPromiseIfPending(deferred: Deferred | undefined export type MaybePromiseArr = (Promise | T | undefined)[]; export async function nonnullSettled(arr: MaybePromiseArr): Promise { + // eslint-disable-next-line @typescript-eslint/await-thenable const all = await Promise.allSettled(arr); return all.map(r => getSettledValue(r)).filter(v => v != null); } @@ -450,6 +451,7 @@ export async function pauseOnCancelOrTimeoutMapTuple } const results = await Promise.all( + // eslint-disable-next-line @typescript-eslint/await-thenable map(source, ([id, [promise, ...rest]]) => promise == null ? ([id, [undefined, ...rest]] as const) diff --git a/src/views/nodes/lineHistoryNode.ts b/src/views/nodes/lineHistoryNode.ts index 68dab8c7470e0..6ec5142854cf9 100644 --- a/src/views/nodes/lineHistoryNode.ts +++ b/src/views/nodes/lineHistoryNode.ts @@ -81,8 +81,8 @@ export class LineHistoryNode this.getLog(selection), sha == null || isUncommitted(sha) ? this.editorContents - ? await this.view.container.git.getBlameForRangeContents(this.uri, selection, this.editorContents) - : await this.view.container.git.getBlameForRange(this.uri, selection) + ? this.view.container.git.getBlameForRangeContents(this.uri, selection, this.editorContents) + : this.view.container.git.getBlameForRange(this.uri, selection) : undefined, svc.getBranchesAndTagsTipsLookup(this.branch?.name), range ? svc.commits.getLogShas(range, { limit: 0 }) : undefined, diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 79d95b1e96eb0..3b22433668920 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -144,6 +144,7 @@ export class ViewCommands implements Disposable { if (selection.length === 0) return; const data = join( + // eslint-disable-next-line @typescript-eslint/await-thenable filterMap(await Promise.allSettled(map(selection, n => n.toClipboard?.(type))), r => r.status === 'fulfilled' && r.value?.trim() ? r.value : undefined, ), @@ -167,6 +168,7 @@ export class ViewCommands implements Disposable { if (!selection.length) return; const urls = [ + // eslint-disable-next-line @typescript-eslint/await-thenable ...filterMap(await Promise.allSettled(map(selection, n => n.getUrl?.())), r => r.status === 'fulfilled' && r.value?.trim() ? r.value : undefined, ), diff --git a/src/webviews/home/homeWebview.ts b/src/webviews/home/homeWebview.ts index cf85fb4d16c02..45d68f831dd96 100644 --- a/src/webviews/home/homeWebview.ts +++ b/src/webviews/home/homeWebview.ts @@ -1208,6 +1208,7 @@ export class HomeWebviewProvider implements WebviewProvider getSettledValue(r))]; diff --git a/tests/docker/run-unit-tests.sh b/tests/docker/run-unit-tests.sh index 642698950de40..3b174b35ada07 100755 --- a/tests/docker/run-unit-tests.sh +++ b/tests/docker/run-unit-tests.sh @@ -1,6 +1,7 @@ ( set -e pnpm run pretty:check + pnpm run lint pnpm run test ); EXIT_CODE=$?;

AltStyle によって変換されたページ (->オリジナル) /