mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 13:11:49 +00:00
[Svelte]: UI Updates for Perforce Depots and Git Repos (#64014)
Introduces basic (and incomplete) UI support for perforce, including displaying changelist ids, listing changelists, and removing references to commits and branches.
This commit is contained in:
parent
4caad25380
commit
b0702f3c3c
@ -20,4 +20,8 @@ fragment Commit on GitCommit {
|
||||
...Avatar_Person
|
||||
}
|
||||
}
|
||||
perforceChangelist {
|
||||
cid
|
||||
canonicalURL
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="title">
|
||||
<a class="subject" href={commit.canonicalURL}>{commit.subject}</a>
|
||||
<a class="subject" href={commit.perforceChangelist?.canonicalURL ?? commit.canonicalURL}>{commit.subject}</a>
|
||||
{#if !alwaysExpanded && commit.body && !$isViewportMobile}
|
||||
<Button
|
||||
variant="secondary"
|
||||
@ -59,7 +59,7 @@
|
||||
</div>
|
||||
<div class="author">
|
||||
{#if !committerIsAuthor}authored by <strong>{author.person.name}</strong> and{/if}
|
||||
committed by <strong>{committer.person.name}</strong>
|
||||
{commit.perforceChangelist ? 'submitted' : 'committed'} by <strong>{committer.person.name}</strong>
|
||||
<Timestamp date={commitDate} />
|
||||
</div>
|
||||
{#if commit.body}
|
||||
|
||||
@ -28,6 +28,10 @@ fragment RevPickerGitCommit on GitCommit {
|
||||
oid
|
||||
subject
|
||||
abbreviatedOID
|
||||
perforceChangelist {
|
||||
cid
|
||||
canonicalURL
|
||||
}
|
||||
...RepositoryGitRevAuthor
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import type { Placement } from '@floating-ui/dom'
|
||||
import type { ComponentProps } from 'svelte'
|
||||
import type { HTMLButtonAttributes } from 'svelte/elements'
|
||||
|
||||
import { goto } from '$app/navigation'
|
||||
@ -44,7 +45,6 @@
|
||||
|
||||
import Picker from './Picker.svelte'
|
||||
import RepositoryRevPickerItem from './RepositoryRevPickerItem.svelte'
|
||||
import type { ComponentProps } from 'svelte'
|
||||
|
||||
type $$Props = HTMLButtonAttributes & {
|
||||
repoURL: string
|
||||
@ -53,6 +53,7 @@
|
||||
defaultBranch: string
|
||||
display?: ComponentProps<ButtonGroup>['display']
|
||||
placement?: Placement
|
||||
isPerforceDepot: boolean
|
||||
onSelect?: (revision: string) => void
|
||||
getRepositoryTags: (query: string) => PromiseLike<RepositoryTags>
|
||||
getRepositoryCommits: (query: string) => PromiseLike<RepositoryCommits>
|
||||
@ -65,6 +66,8 @@
|
||||
export let defaultBranch: $$Props['defaultBranch']
|
||||
export let placement: $$Props['placement'] = 'right-start'
|
||||
export let display: $$Props['display'] = undefined
|
||||
export let isPerforceDepot: $$Props['isPerforceDepot']
|
||||
|
||||
/**
|
||||
* Optional handler for revision selection.
|
||||
* If not provided, the default handler will replace the revision in the current URL.
|
||||
@ -121,68 +124,83 @@
|
||||
|
||||
<div slot="content" class="content" let:toggle>
|
||||
<Tabs>
|
||||
<TabPanel title="Branches" shortcut={branchesHotkey}>
|
||||
<Picker
|
||||
name="branches"
|
||||
seeAllItemsURL={`${repoURL}/-/branches`}
|
||||
getData={getRepositoryBranches}
|
||||
toOption={branch => ({ value: branch.id, label: branch.displayName })}
|
||||
onSelect={branch => {
|
||||
toggle(false)
|
||||
onSelect(branch.abbrevName)
|
||||
}}
|
||||
let:value
|
||||
>
|
||||
<RepositoryRevPickerItem
|
||||
icon={ILucideGitBranch}
|
||||
label={value.displayName}
|
||||
author={value.target.commit?.author}
|
||||
{#if !isPerforceDepot}
|
||||
<TabPanel title="Branches" shortcut={branchesHotkey}>
|
||||
<Picker
|
||||
name="branches"
|
||||
seeAllItemsURL={`${repoURL}/-/branches`}
|
||||
getData={getRepositoryBranches}
|
||||
toOption={branch => ({ value: branch.id, label: branch.displayName })}
|
||||
onSelect={branch => {
|
||||
toggle(false)
|
||||
onSelect(branch.abbrevName)
|
||||
}}
|
||||
let:value
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
<Icon icon={ILucideGitBranch} inline aria-hidden="true" />
|
||||
<Badge variant="link">{value.displayName}</Badge>
|
||||
{#if value.displayName === defaultBranch}
|
||||
<Badge variant="secondary" small>DEFAULT</Badge>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</RepositoryRevPickerItem>
|
||||
</Picker>
|
||||
</TabPanel>
|
||||
<TabPanel title="Tags" shortcut={tagsHotkey}>
|
||||
<RepositoryRevPickerItem
|
||||
icon={ILucideGitBranch}
|
||||
label={value.displayName}
|
||||
author={value.target.commit?.author}
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
<Icon icon={ILucideGitBranch} inline aria-hidden="true" />
|
||||
<Badge variant="link">{value.displayName}</Badge>
|
||||
{#if value.displayName === defaultBranch}
|
||||
<Badge variant="secondary" small>DEFAULT</Badge>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</RepositoryRevPickerItem>
|
||||
</Picker>
|
||||
</TabPanel>
|
||||
<TabPanel title="Tags" shortcut={tagsHotkey}>
|
||||
<Picker
|
||||
name="tags"
|
||||
seeAllItemsURL={`${repoURL}/-/tags`}
|
||||
getData={getRepositoryTags}
|
||||
toOption={tag => ({ value: tag.id, label: tag.displayName })}
|
||||
onSelect={tag => {
|
||||
toggle(false)
|
||||
onSelect(tag.abbrevName)
|
||||
}}
|
||||
let:value
|
||||
>
|
||||
<RepositoryRevPickerItem
|
||||
icon={ILucideTag}
|
||||
label={value.displayName}
|
||||
author={value.target.commit?.author}
|
||||
/>
|
||||
</Picker>
|
||||
</TabPanel>
|
||||
{/if}
|
||||
<TabPanel title={isPerforceDepot ? 'Changelists' : 'Commits'} shortcut={commitsHotkey}>
|
||||
<!-- TODO: seeAllItemsURL should point to /-/changelists for perforce, but that doesn't exist yet -->
|
||||
<Picker
|
||||
name="tags"
|
||||
seeAllItemsURL={`${repoURL}/-/tags`}
|
||||
getData={getRepositoryTags}
|
||||
toOption={tag => ({ value: tag.id, label: tag.displayName })}
|
||||
onSelect={tag => {
|
||||
toggle(false)
|
||||
onSelect(tag.abbrevName)
|
||||
}}
|
||||
let:value
|
||||
>
|
||||
<RepositoryRevPickerItem
|
||||
icon={ILucideTag}
|
||||
label={value.displayName}
|
||||
author={value.target.commit?.author}
|
||||
/>
|
||||
</Picker>
|
||||
</TabPanel>
|
||||
<TabPanel title="Commits" shortcut={commitsHotkey}>
|
||||
<Picker
|
||||
name="commits"
|
||||
name={isPerforceDepot ? 'changelists' : 'commits'}
|
||||
seeAllItemsURL={`${repoURL}/-/commits`}
|
||||
getData={getRepositoryCommits}
|
||||
toOption={commit => ({ value: commit.id, label: commit.oid })}
|
||||
toOption={commit => {
|
||||
return isPerforceDepot && commit.perforceChangelist
|
||||
? { value: commit.id, label: commit.perforceChangelist.cid }
|
||||
: { value: commit.id, label: commit.oid }
|
||||
}}
|
||||
onSelect={commit => {
|
||||
toggle(false)
|
||||
onSelect(commit.oid)
|
||||
if (isPerforceDepot && commit.perforceChangelist) {
|
||||
onSelect(`changelist/${commit?.perforceChangelist?.cid}`)
|
||||
} else {
|
||||
onSelect(commit.oid)
|
||||
}
|
||||
}}
|
||||
let:value
|
||||
>
|
||||
<RepositoryRevPickerItem label="" author={value.author}>
|
||||
<svelte:fragment slot="title">
|
||||
<Icon icon={ILucideGitCommitVertical} inline aria-hidden="true" />
|
||||
<Badge variant="link">{value.abbreviatedOID}</Badge>
|
||||
<span class="rev-badge"
|
||||
><Badge variant="link">
|
||||
{value.perforceChangelist?.cid ?? value.abbreviatedOID}
|
||||
</Badge></span
|
||||
>
|
||||
<span class="commit-subject">{value.subject}</span>
|
||||
</svelte:fragment>
|
||||
</RepositoryRevPickerItem>
|
||||
@ -200,6 +218,14 @@
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.rev-badge {
|
||||
display: contents;
|
||||
:global([data-badge]) {
|
||||
// Always show the full (abbreviated) changelist ID or commit hash
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.close-button {
|
||||
border-left: 1px solid var(--secondary);
|
||||
}
|
||||
|
||||
@ -31,6 +31,11 @@ export const svelteKitRoutes: SvelteKitRoute[] = [
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commits(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/[path=commit_or_changelist]/[...revspec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/(?:commit|changelist)(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/branches',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/?$'),
|
||||
@ -41,11 +46,6 @@ export const svelteKitRoutes: SvelteKitRoute[] = [
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/all/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/commit/[...revspec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commit(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/compare/[...rangeSpec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/compare(?:/.*)?/?$'),
|
||||
|
||||
5
client/web-sveltekit/src/params/commit_or_changelist.ts
Normal file
5
client/web-sveltekit/src/params/commit_or_changelist.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import type { ParamMatcher } from '@sveltejs/kit'
|
||||
|
||||
export const match: ParamMatcher = param => {
|
||||
return param === 'commit' || param === 'changelist'
|
||||
}
|
||||
@ -215,6 +215,7 @@
|
||||
revision={data.revision}
|
||||
commitID={data.resolvedRevision.commitID}
|
||||
defaultBranch={data.defaultBranch}
|
||||
isPerforceDepot={data.isPerforceDepot}
|
||||
getRepositoryBranches={data.getRepoBranches}
|
||||
getRepositoryCommits={data.getRepoCommits}
|
||||
getRepositoryTags={data.getRepoTags}
|
||||
|
||||
@ -5,13 +5,12 @@
|
||||
import { navigating } from '$app/stores'
|
||||
import Commit from '$lib/Commit.svelte'
|
||||
import LoadingSpinner from '$lib/LoadingSpinner.svelte'
|
||||
import RepositoryRevPicker from '$lib/repo/RepositoryRevPicker.svelte'
|
||||
import { getHumanNameForCodeHost } from '$lib/repo/shared/codehost'
|
||||
import Scroller, { type Capture as ScrollerCapture } from '$lib/Scroller.svelte'
|
||||
import CodeHostIcon from '$lib/search/CodeHostIcon.svelte'
|
||||
import { Alert, Badge } from '$lib/wildcard'
|
||||
|
||||
import RepositoryRevPicker from '$lib/repo/RepositoryRevPicker.svelte'
|
||||
|
||||
import type { PageData, Snapshot } from './$types'
|
||||
|
||||
export let data: PageData
|
||||
@ -61,9 +60,13 @@
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
Commit History
|
||||
{#if data.path}
|
||||
in <code>{data.path}</code>
|
||||
{#if commits && commits[0]?.perforceChangelist !== null}
|
||||
Changelists
|
||||
{:else}
|
||||
Commit History
|
||||
{#if data.path}
|
||||
in <code>{data.path}</code>
|
||||
{/if}
|
||||
{/if}
|
||||
</h2>
|
||||
<div>
|
||||
@ -73,6 +76,7 @@
|
||||
commitID={data.resolvedRevision.commitID}
|
||||
defaultBranch={data.defaultBranch}
|
||||
placement="bottom-start"
|
||||
isPerforceDepot={data.isPerforceDepot}
|
||||
getRepositoryBranches={data.getRepoBranches}
|
||||
getRepositoryCommits={data.getRepoCommits}
|
||||
getRepositoryTags={data.getRepoTags}
|
||||
@ -90,11 +94,27 @@
|
||||
</div>
|
||||
<ul class="actions">
|
||||
<li>
|
||||
{#if commit.perforceChangelist}
|
||||
Changelist ID:
|
||||
{/if}
|
||||
<Badge variant="link">
|
||||
<a href={commit.canonicalURL} title="View commit">{commit.abbreviatedOID}</a>
|
||||
{#if commit.perforceChangelist}
|
||||
<a href={commit.perforceChangelist?.canonicalURL} title="View changelist"
|
||||
>{commit.perforceChangelist?.cid}</a
|
||||
>
|
||||
{:else}
|
||||
<a href={commit.canonicalURL} title="View commit">{commit.abbreviatedOID}</a>
|
||||
{/if}
|
||||
</Badge>
|
||||
</li>
|
||||
<li><a href="/{data.repoName}@{commit.oid}">Browse files</a></li>
|
||||
|
||||
<li>
|
||||
<a
|
||||
href={commit.perforceChangelist
|
||||
? `/${data.repoName}@changelist/${commit.perforceChangelist.cid}`
|
||||
: `/${data.repoName}@${commit.oid}`}>Browse files</a
|
||||
>
|
||||
</li>
|
||||
{#each commit.externalURLs as { url, serviceKind }}
|
||||
<li>
|
||||
<a href={url}>
|
||||
|
||||
@ -30,6 +30,10 @@ query CommitsPage_CommitsQuery(
|
||||
ancestors(first: $first, afterCursor: $afterCursor, path: $path) {
|
||||
...CommitsPage_GitCommitConnection
|
||||
}
|
||||
perforceChangelist {
|
||||
cid
|
||||
canonicalURL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
export let data: LayoutData
|
||||
|
||||
const menuOpen = writable(false)
|
||||
|
||||
const navEntries: MenuEntry[] = [
|
||||
{ path: '', icon: ILucideCode, label: 'Code', visibility: 'user', preserveRevision: true },
|
||||
{
|
||||
@ -61,6 +62,21 @@
|
||||
{ path: '/-/tags', icon: ILucideTag, label: 'Tags', visibility: 'user' },
|
||||
{ path: '/-/stats/contributors', icon: ILucideUsers, label: 'Contributors', visibility: 'user' },
|
||||
]
|
||||
const perforceNavEntries: MenuEntry[] = navEntries
|
||||
.map(entry => {
|
||||
// Replace commits with changelists
|
||||
if (entry.label === 'Commits') {
|
||||
return {
|
||||
// TODO: this should direct the user to a "changelists" page
|
||||
path: '/-/commits',
|
||||
icon: ILucideGitCommitVertical,
|
||||
label: 'Changelists',
|
||||
visibility: 'user',
|
||||
} satisfies MenuEntry
|
||||
}
|
||||
return entry
|
||||
})
|
||||
.filter(entry => entry.label !== 'Branches')
|
||||
const menuEntries: MenuEntry[] = [
|
||||
{ path: '/-/compare', icon: ILucideGitCompare, label: 'Compare', visibility: 'user' },
|
||||
{ path: '/-/own', icon: ILucideUsers, label: 'Ownership', visibility: 'admin' },
|
||||
@ -85,7 +101,7 @@
|
||||
|
||||
setRepositoryPageContext(repositoryContext)
|
||||
|
||||
$: viewableNavEntries = navEntries.filter(
|
||||
$: viewableNavEntries = (data.isPerforceDepot ? perforceNavEntries : navEntries).filter(
|
||||
entry => entry.visibility === 'user' || (entry.visibility === 'admin' && data.user?.siteAdmin)
|
||||
)
|
||||
$: visibleNavEntryCount = viewableNavEntries.length
|
||||
@ -118,6 +134,7 @@
|
||||
function isActive(href: string, url: URL): boolean {
|
||||
return href === data.repoURL ? isCodePage(data.repoURL, $page.url.pathname) : url.pathname.startsWith(href)
|
||||
}
|
||||
|
||||
$: tabs = navEntriesToShow.map(entry => ({
|
||||
id: entry.label,
|
||||
title: entry.label,
|
||||
@ -129,6 +146,7 @@
|
||||
$: ({ repoName, revision } = data)
|
||||
$: query = `repo:${repositoryInsertText({ repository: repoName })}${revision ? `@${revision}` : ''} `
|
||||
$: queryState = queryStateStore({ query }, $settings)
|
||||
|
||||
function handleSearchSubmit(): void {
|
||||
TELEMETRY_RECORDER.recordEvent('search', 'submit', {
|
||||
metadata: { source: TELEMETRY_SEARCH_SOURCE_TYPE['repo'] },
|
||||
|
||||
@ -52,6 +52,7 @@ export const load: LayoutLoad = async ({ params, url, depends }) => {
|
||||
displayRevision: displayRevision(revision, resolvedRepository),
|
||||
defaultBranch: resolvedRepository.defaultBranch?.abbrevName || 'HEAD',
|
||||
resolvedRepository: resolvedRepository,
|
||||
isPerforceDepot: resolvedRepository.externalRepository.serviceType === 'perforce',
|
||||
|
||||
// Repository pickers queries (branch, tags and commits)
|
||||
getRepoBranches: (searchTerm: string) =>
|
||||
|
||||
@ -60,6 +60,8 @@
|
||||
|
||||
repositoryContext.set({})
|
||||
})
|
||||
|
||||
$: changelistId = data.commit.perforceChangelist?.cid
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -70,26 +72,38 @@
|
||||
{#if data.commit}
|
||||
<Scroller bind:this={scroller} margin={600} on:more={diffQuery?.fetchMore}>
|
||||
<div class="header">
|
||||
<div class="info"><Commit commit={data.commit} alwaysExpanded={!$isViewportMobile} /></div>
|
||||
<div class="info">
|
||||
<Commit commit={data.commit} alwaysExpanded={!$isViewportMobile} />
|
||||
</div>
|
||||
<ul class="actions">
|
||||
<li>
|
||||
<span>Commit:</span>
|
||||
<Badge variant="secondary"><code>{data.commit.abbreviatedOID}</code></Badge> <CopyButton
|
||||
value={data.commit.abbreviatedOID}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span>{pluralize('Parent', data.commit.parents.length)}:</span>
|
||||
{#each data.commit.parents as parent}
|
||||
<Badge variant="link"><a href={parent.canonicalURL}>{parent.abbreviatedOID}</a></Badge
|
||||
> <CopyButton value={parent.abbreviatedOID} />{' '}
|
||||
{/each}
|
||||
</li>
|
||||
<li>
|
||||
<a href="/{data.repoName}@{data.commit.oid}"
|
||||
>Browse files at <Badge variant="link">{data.commit.abbreviatedOID}</Badge></a
|
||||
>
|
||||
<span>{data.isPerforceDepot ? 'Changelist ID:' : 'Commit:'}</span>
|
||||
<Badge variant="secondary"
|
||||
><code>{data.isPerforceDepot ? changelistId : data.commit.abbreviatedOID}</code></Badge
|
||||
> <CopyButton value={data.commit.abbreviatedOID} />
|
||||
</li>
|
||||
{#if !data.isPerforceDepot}
|
||||
<li>
|
||||
<span>{pluralize('Parent', data.commit.parents.length)}:</span>
|
||||
{#each data.commit.parents as parent}
|
||||
<Badge variant="link">
|
||||
<a href={parent.canonicalURL}>{parent.abbreviatedOID}</a>
|
||||
</Badge> <CopyButton value={parent.abbreviatedOID} />{' '}
|
||||
{/each}
|
||||
</li>
|
||||
<li>
|
||||
<a href="/{data.repoName}@{data.commit.oid}">
|
||||
Browse files at
|
||||
<Badge variant="link">{data.commit.abbreviatedOID}</Badge>
|
||||
</a>
|
||||
</li>
|
||||
{:else}
|
||||
<li>
|
||||
<a href={`/${data.repoName}@changelist/${data.commit.perforceChangelist?.cid}`}
|
||||
>Browse files
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{#each data.commit.externalURLs as { url, serviceKind }}
|
||||
<li>
|
||||
<a href={url}>
|
||||
@ -4,22 +4,30 @@ import { IncrementalRestoreStrategy, getGraphQLClient, infinityQuery } from '$li
|
||||
import { parseRepoRevision } from '$lib/shared'
|
||||
|
||||
import type { PageLoad } from './$types'
|
||||
import { CommitPage_CommitQuery, CommitPage_DiffQuery } from './page.gql'
|
||||
import { CommitPage_CommitQuery, CommitPage_DiffQuery, CommitPage_Changelist, CommitPage_Commit } from './page.gql'
|
||||
|
||||
const PAGE_SIZE = 20
|
||||
|
||||
export const load: PageLoad = async ({ params }) => {
|
||||
const client = getGraphQLClient()
|
||||
const { repoName } = parseRepoRevision(params.repo)
|
||||
|
||||
const result = await client.query(CommitPage_CommitQuery, { repoName, revspec: params.revspec })
|
||||
|
||||
if (result.error) {
|
||||
error(500, `Unable to load commit data: ${result.error}`)
|
||||
async function getCommit(): Promise<CommitPage_Commit | null> {
|
||||
if (params.path === 'changelist') {
|
||||
const result = await client.query(CommitPage_Changelist, { repoName, changelistId: params.revspec })
|
||||
if (result.error) {
|
||||
error(500, `Unable to load changelist data: ${result.error}`)
|
||||
}
|
||||
return result.data?.repository?.changelist?.commit ?? null
|
||||
} else {
|
||||
const result = await client.query(CommitPage_CommitQuery, { repoName, revspec: params.revspec })
|
||||
if (result.error) {
|
||||
error(500, `Unable to load commit data: ${result.error}`)
|
||||
}
|
||||
return result.data?.repository?.commit ?? null
|
||||
}
|
||||
}
|
||||
|
||||
const commit = result.data?.repository?.commit
|
||||
|
||||
const commit = await getCommit()
|
||||
if (!commit) {
|
||||
error(404, 'Commit not found')
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
query CommitPage_CommitQuery($repoName: String!, $revspec: String!) {
|
||||
repository(name: $repoName) {
|
||||
id
|
||||
commit(rev: $revspec) {
|
||||
...CommitPage_Commit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query CommitPage_Changelist($repoName: String!, $changelistId: String!) {
|
||||
repository(name: $repoName) {
|
||||
sourceType
|
||||
changelist(cid: $changelistId) {
|
||||
__typename
|
||||
...PerforceChangelistFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment PerforceChangelistFields on PerforceChangelist {
|
||||
cid
|
||||
canonicalURL
|
||||
commit {
|
||||
...CommitPage_Commit
|
||||
}
|
||||
}
|
||||
|
||||
fragment CommitPage_Commit on GitCommit {
|
||||
id
|
||||
oid
|
||||
perforceChangelist {
|
||||
cid
|
||||
canonicalURL
|
||||
}
|
||||
parents {
|
||||
id
|
||||
oid
|
||||
abbreviatedOID
|
||||
canonicalURL
|
||||
}
|
||||
externalURLs {
|
||||
url
|
||||
serviceKind
|
||||
}
|
||||
...Commit
|
||||
__typename
|
||||
}
|
||||
|
||||
query CommitPage_DiffQuery($repoName: String!, $base: String, $head: String, $first: Int, $after: String) {
|
||||
repository(name: $repoName) {
|
||||
id
|
||||
comparison(base: $base, head: $head) {
|
||||
fileDiffs(first: $first, after: $after) {
|
||||
...CommitPage_DiffConnection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment CommitPage_DiffConnection on FileDiffConnection {
|
||||
nodes {
|
||||
...FileDiff_Diff
|
||||
}
|
||||
pageInfo {
|
||||
endCursor
|
||||
hasNextPage
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
query CommitPage_CommitQuery($repoName: String!, $revspec: String!) {
|
||||
repository(name: $repoName) {
|
||||
id
|
||||
commit(rev: $revspec) {
|
||||
id
|
||||
oid
|
||||
parents {
|
||||
id
|
||||
oid
|
||||
abbreviatedOID
|
||||
canonicalURL
|
||||
}
|
||||
externalURLs {
|
||||
url
|
||||
serviceKind
|
||||
}
|
||||
...Commit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query CommitPage_DiffQuery($repoName: String!, $base: String, $head: String, $first: Int, $after: String) {
|
||||
repository(name: $repoName) {
|
||||
id
|
||||
comparison(base: $base, head: $head) {
|
||||
fileDiffs(first: $first, after: $after) {
|
||||
...CommitPage_DiffConnection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment CommitPage_DiffConnection on FileDiffConnection {
|
||||
nodes {
|
||||
...FileDiff_Diff
|
||||
}
|
||||
pageInfo {
|
||||
endCursor
|
||||
hasNextPage
|
||||
}
|
||||
}
|
||||
@ -109,6 +109,7 @@
|
||||
commitID={data.base?.commitID || ''}
|
||||
defaultBranch={data.defaultBranch}
|
||||
placement="bottom-start"
|
||||
isPerforceDepot={data.isPerforceDepot}
|
||||
onSelect={revision => handleSelect(revision, data.head?.revision || '')}
|
||||
getRepositoryBranches={data.getRepoBranches}
|
||||
getRepositoryCommits={data.getRepoCommits}
|
||||
@ -125,6 +126,7 @@
|
||||
commitID={data.head?.commitID || ''}
|
||||
defaultBranch={data.defaultBranch}
|
||||
placement="bottom-start"
|
||||
isPerforceDepot={data.isPerforceDepot}
|
||||
onSelect={revision => handleSelect(data.base?.revision || '', revision)}
|
||||
getRepositoryBranches={data.getRepoBranches}
|
||||
getRepositoryCommits={data.getRepoCommits}
|
||||
|
||||
@ -31,6 +31,11 @@ export const svelteKitRoutes: SvelteKitRoute[] = [
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commits(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/[path=commit_or_changelist]/[...revspec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/(?:commit|changelist)(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/branches',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/?$'),
|
||||
@ -41,11 +46,6 @@ export const svelteKitRoutes: SvelteKitRoute[] = [
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/all/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/commit/[...revspec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commit(?:/.*)?/?$'),
|
||||
isRepoRoot: false,
|
||||
},
|
||||
{
|
||||
id: '/[...repo=reporev]/-/compare/[...rangeSpec]',
|
||||
pattern: new RegExp('^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/compare(?:/.*)?/?$'),
|
||||
|
||||
@ -263,9 +263,15 @@ func patternForRouteId(routeId string) (string, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// We don't use params within a segement, e.g.
|
||||
// foo-[bar]-[[baz]], so for simplicity we don't support that.
|
||||
if strings.Contains(segment, "[") {
|
||||
if segment == "[path=commit_or_changelist]" {
|
||||
// TODO(camdencheek): clean this up.
|
||||
// We don't generally support arbitrary matchers,
|
||||
// but for the one case we use this right now this just hard-codes it.
|
||||
b.WriteString(`/(?:commit|changelist)`)
|
||||
continue
|
||||
} else if strings.Contains(segment, "[") {
|
||||
// We don't use params within a segement, e.g.
|
||||
// foo-[bar]-[[baz]], so for simplicity we don't support that.
|
||||
return "", errors.New("params within a segment are not supported")
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,11 @@ var svelteKitRoutes = []svelteKitRoute{
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commits(?:/.*)?/?$"),
|
||||
Tag: tags.EnableOptIn | tags.EnableRollout,
|
||||
},
|
||||
{
|
||||
Id: "/[...repo=reporev]/-/[path=commit_or_changelist]/[...revspec]",
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/(?:commit|changelist)(?:/.*)?/?$"),
|
||||
Tag: tags.EnableOptIn | tags.EnableRollout,
|
||||
},
|
||||
{
|
||||
Id: "/[...repo=reporev]/-/branches",
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/?$"),
|
||||
@ -48,11 +53,6 @@ var svelteKitRoutes = []svelteKitRoute{
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/branches/all/?$"),
|
||||
Tag: tags.EnableOptIn | tags.EnableRollout,
|
||||
},
|
||||
{
|
||||
Id: "/[...repo=reporev]/-/commit/[...revspec]",
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/commit(?:/.*)?/?$"),
|
||||
Tag: tags.EnableOptIn | tags.EnableRollout,
|
||||
},
|
||||
{
|
||||
Id: "/[...repo=reporev]/-/compare/[...rangeSpec]",
|
||||
Pattern: regexp.MustCompile("^/(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,})))(?:@(?:(?:(?:[^@/-]|(?:[^/@]{2,}))/)*(?:[^@/-]|(?:[^/@]{2,}))))?/-/compare(?:/.*)?/?$"),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user