History

feat(pull-requests): link multiple pull requests to threads (#10839)

Julius Marminge committed 2 months ago

Commit afb84891 parent 383cc40172 files · +12057 −908Browse files

Showing the changes to packages/shared/src/sourceControl.ts (1 of 172 files). Show all

Unified · Split

packages/shared/src/sourceControl.ts+45−1
@@ -1,4 +1,8 @@
1import type { SourceControlProviderInfo, SourceControlProviderKind } from "@t3tools/contracts";1import type {
2 RepositoryIdentity,
3 SourceControlProviderInfo,
4 SourceControlProviderKind,
5} from "@t3tools/contracts";
2 6
3export interface ChangeRequestPresentation {7export interface ChangeRequestPresentation {
4 readonly icon: "github" | "gitlab" | "azure-devops" | "bitbucket" | "change-request";8 readonly icon: "github" | "gitlab" | "azure-devops" | "bitbucket" | "change-request";
@@ -234,3 +238,43 @@ export function detectSourceControlProviderFromRemoteUrl( · 229 unmodified lines
234 baseUrl: toBaseUrl(host),238 baseUrl: toBaseUrl(host),
235 };239 };
236}240}
241
242/**
243 * The provider-native repository selector. `displayName` is the full path below the host, which
244 * is what nested GitLab groups need; owner/name is the two-segment fallback for identities
245 * recorded before that field existed.
246 *
247 * Azure DevOps is the exception: `az repos pr list --repository` takes a repository name, and
248 * takes the organisation and project from the checkout it detects — so the recorded
249 * `org/project/_git/repo` path is refused outright and the whole repository reads as
250 * unavailable. Its name is the last segment, which is what this hands over.
251 *
252 * One function because everything downstream is keyed by what it answers: the rows' own
253 * `repository`, the per-repository cursors, and the detail and diff reads a row leads to.
254 */
255export function sourceControlRepositorySelector(
256 identity:
257 | Pick<RepositoryIdentity, "provider" | "displayName" | "owner" | "name">
258 | null
259 | undefined,
260): string | null {
261 if (!identity) return null;
262 if (identity.provider === "azure-devops") {
263 const segments = (identity.displayName ?? "").split("/").filter((part) => part !== "_git");
264 return identity.name || segments.at(-1) || null;
265 }
266 if (identity.displayName) return identity.displayName;
267 return identity.owner && identity.name ? `${identity.owner}/${identity.name}` : null;
268}
269
270export function canonicalRepositoryKey(key: string): string {
271 return key
272 .replace(
273 /^(?:ssh\.dev\.azure\.com|vs-ssh\.visualstudio\.com)\/v3\/([^/]+)\/([^/]+)\/([^/]+)$/u,
274 "dev.azure.com/$1/$2/_git/$3",
275 )
276 .replace(
277 /^([^.]+)\.visualstudio\.com\/(?:defaultcollection\/)?([^/]+)\/_git\/([^/]+)$/u,
278 "dev.azure.com/$1/$2/_git/$3",
279 );
280}