|
1 | | -import { ColorThemeKind, ThemeColor, ThemeIcon, window } from 'vscode'; |
| 1 | +import { ColorThemeKind, ThemeColor, ThemeIcon, Uri, window } from 'vscode'; |
| 2 | +import { Schemes } from '../../constants'; |
2 | 3 | import type { Colors } from '../../constants.colors'; |
| 4 | +import type { Container } from '../../container'; |
| 5 | +import type { RepositoryIdentityDescriptor } from '../../gk/models/repositoryIdentities'; |
3 | 6 | import type { ProviderReference } from './remoteProvider'; |
| 7 | +import type { Repository } from './repository'; |
4 | 8 |
|
5 | 9 | export type IssueOrPullRequestType = 'issue' | 'pullrequest'; |
6 | 10 | export type IssueOrPullRequestState = 'opened' | 'closed' | 'merged'; |
@@ -45,6 +49,7 @@ export interface IssueRepository { |
45 | 49 | owner: string; |
46 | 50 | repo: string; |
47 | 51 | accessLevel?: RepositoryAccessLevel; |
| 52 | + url?: string; |
48 | 53 | } |
49 | 54 |
|
50 | 55 | export interface IssueShape extends IssueOrPullRequest { |
@@ -217,6 +222,7 @@ export function serializeIssue(value: IssueShape): IssueShape { |
217 | 222 | : { |
218 | 223 | owner: value.repository.owner, |
219 | 224 | repo: value.repository.repo, |
| 225 | + url: value.repository.url, |
220 | 226 | }, |
221 | 227 | assignees: value.assignees.map(assignee => ({ |
222 | 228 | id: assignee.id, |
@@ -261,3 +267,67 @@ export class Issue implements IssueShape { |
261 | 267 | public readonly body?: string, |
262 | 268 | ) {} |
263 | 269 | } |
| 270 | + |
| 271 | +export type IssueRepositoryIdentityDescriptor = RequireSomeWithProps< |
| 272 | + RequireSome<RepositoryIdentityDescriptor<string>, 'provider'>, |
| 273 | + 'provider', |
| 274 | + 'id' | 'domain' | 'repoDomain' | 'repoName' |
| 275 | +> & |
| 276 | + RequireSomeWithProps<RequireSome<RepositoryIdentityDescriptor<string>, 'remote'>, 'remote', 'domain'>; |
| 277 | + |
| 278 | +export function getRepositoryIdentityForIssue(issue: IssueShape | Issue): IssueRepositoryIdentityDescriptor { |
| 279 | + if (issue.repository == null) throw new Error('Missing repository'); |
| 280 | + |
| 281 | + return { |
| 282 | + remote: { |
| 283 | + url: issue.repository.url, |
| 284 | + domain: issue.provider.domain, |
| 285 | + }, |
| 286 | + name: `${issue.repository.owner}/${issue.repository.repo}`, |
| 287 | + provider: { |
| 288 | + id: issue.provider.id, |
| 289 | + domain: issue.provider.domain, |
| 290 | + repoDomain: issue.repository.owner, |
| 291 | + repoName: issue.repository.repo, |
| 292 | + repoOwnerDomain: issue.repository.owner, |
| 293 | + }, |
| 294 | + }; |
| 295 | +} |
| 296 | + |
| 297 | +export function getVirtualUriForIssue(issue: IssueShape | Issue): Uri | undefined { |
| 298 | + if (issue.repository == null) throw new Error('Missing repository'); |
| 299 | + if (issue.provider.id !== 'github') return undefined; |
| 300 | + |
| 301 | + const uri = Uri.parse(issue.repository.url ?? issue.url); |
| 302 | + return uri.with({ scheme: Schemes.Virtual, authority: 'github', path: uri.path }); |
| 303 | +} |
| 304 | + |
| 305 | +export async function getOrOpenIssueRepository( |
| 306 | + container: Container, |
| 307 | + issue: IssueShape | Issue, |
| 308 | + options?: { promptIfNeeded?: boolean; skipVirtual?: boolean }, |
| 309 | +): Promise<Repository | undefined> { |
| 310 | + const identity = getRepositoryIdentityForIssue(issue); |
| 311 | + let repo = await container.repositoryIdentity.getRepository(identity, { |
| 312 | + openIfNeeded: true, |
| 313 | + keepOpen: false, |
| 314 | + prompt: false, |
| 315 | + }); |
| 316 | + |
| 317 | + if (repo == null && !options?.skipVirtual) { |
| 318 | + const virtualUri = getVirtualUriForIssue(issue); |
| 319 | + if (virtualUri != null) { |
| 320 | + repo = await container.git.getOrOpenRepository(virtualUri, { closeOnOpen: true, detectNested: false }); |
| 321 | + } |
| 322 | + } |
| 323 | + |
| 324 | + if (repo == null && options?.promptIfNeeded) { |
| 325 | + repo = await container.repositoryIdentity.getRepository(identity, { |
| 326 | + openIfNeeded: true, |
| 327 | + keepOpen: false, |
| 328 | + prompt: true, |
| 329 | + }); |
| 330 | + } |
| 331 | + |
| 332 | + return repo; |
| 333 | +} |
0 commit comments