Skip to content

Commit

Permalink
Parse url for base branch and pr bases
Browse files Browse the repository at this point in the history
- will help us compare pr base against target
  • Loading branch information
mtsgrd committed Nov 19, 2024
1 parent a045cfd commit 4c212cd
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 57 deletions.
27 changes: 24 additions & 3 deletions apps/desktop/src/lib/baseBranch/baseBranchService.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
import { BaseBranch, NoDefaultTarget } from './baseBranch';
import { Code, invoke } from '$lib/backend/ipc';
import { showError } from '$lib/notifications/toasts';
import { uniqueDerived } from '$lib/stores/uniqueStore';
import { parseRemoteUrl } from '$lib/url/gitUrl';
import { plainToInstance } from 'class-transformer';
import { writable } from 'svelte/store';
import { derived, writable } from 'svelte/store';

export interface RemoteBranchInfo {
name: string;
}

export class BaseBranchService {
readonly base = writable<BaseBranch | null | undefined>(undefined, () => {
// Primary private writable that this class emits to.
private readonly _base = writable<BaseBranch | null | undefined>(undefined, () => {
this.refresh();
});

// Deduplciated since updates are frequent.
readonly base = uniqueDerived(this._base);

// Deduplicated repo information.
readonly repo = uniqueDerived(
derived(this.base, (base) => {
return base ? parseRemoteUrl(base.remoteUrl) : undefined;
})
);

// Deduplicated push repo information.
readonly pushRepo = uniqueDerived(
derived(this.base, (base) => {
return base ? parseRemoteUrl(base.pushRemoteUrl) : undefined;
})
);

readonly loading = writable(false);
readonly error = writable();

Expand All @@ -25,7 +46,7 @@ export class BaseBranchService {
await invoke<any>('get_base_branch_data', { projectId: this.projectId })
);
if (!baseBranch) this.error.set(new NoDefaultTarget());
this.base.set(baseBranch);
this._base.set(baseBranch);
} catch (err: any) {
this.error.set(err);
throw err;
Expand Down
9 changes: 4 additions & 5 deletions apps/desktop/src/lib/components/PullRequestPreview.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import { showError } from '$lib/notifications/toasts';
import { RemotesService } from '$lib/remotes/service';
import Link from '$lib/shared/Link.svelte';
import { remoteUrlIsHttp } from '$lib/utils/url';
import { BranchController } from '$lib/vbranches/branchController';
import { VirtualBranchService } from '$lib/vbranches/virtualBranch';
import { getContext } from '@gitbutler/shared/context';
Expand All @@ -23,7 +22,7 @@
const remotesService = getContext(RemotesService);
const baseBranchService = getContext(BaseBranchService);
const virtualBranchService = getContext(VirtualBranchService);
const baseBranch = $derived(baseBranchService.base);
const baseRepo = $derived(baseBranchService.repo);
let inputRemoteName = $state<string>(pr.repoOwner || '');
Expand All @@ -36,10 +35,10 @@
}
function getRemoteUrl() {
const baseRemoteUrl = $baseBranch?.remoteUrl;
if (!baseRemoteUrl) return;
const repo = $baseRepo;
if (!repo) return;
if (remoteUrlIsHttp(baseRemoteUrl)) {
if ($baseRepo?.protocol?.startsWith('http')) {
return pr.repositoryHttpsUrl;
} else {
return pr.repositorySshUrl;
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/lib/forge/github/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parseRemoteUrl } from '$lib/url/gitUrl';
import type { CheckSuite, DetailedPullRequest, Label, PullRequest } from '../interface/types';
import type { RestEndpointMethodTypes } from '@octokit/rest';

Expand All @@ -11,6 +12,8 @@ export function parseGitHubDetailedPullRequest(
number: data.number,
title: data.title,
body: data.body ?? undefined,
baseRepo: parseRemoteUrl(data.base?.repo.git_url),
baseBranch: data.base?.ref,
sourceBranch: data.head?.ref,
draft: data.draft,
htmlUrl: data.html_url,
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/lib/forge/interface/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface DetailedPullRequest {
rebaseable: boolean;
squashable: boolean;
state: 'open' | 'closed';
baseRepo: RepoInfo | undefined;
baseBranch: string;
}

export type ChecksStatus = {
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/lib/url/gitUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type RepoInfo = {
export function parseRemoteUrl(url: string): RepoInfo | undefined {
try {
const { protocol, name, owner, organization, resource } = gitUrlParse(url);
const hash = hashCode(name + '|' + owner + '|' + name + '|' + organization);
const hash = hashCode(name + '|' + owner + '|' + organization);

return {
protocol,
Expand Down
18 changes: 1 addition & 17 deletions apps/desktop/src/lib/utils/url.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { remoteUrlIsHttp, convertRemoteToWebUrl, getEditorUri } from '$lib/utils/url';
import { convertRemoteToWebUrl, getEditorUri } from '$lib/utils/url';
import { describe, expect, test } from 'vitest';

describe.concurrent('cleanUrl', () => {
Expand All @@ -25,22 +25,6 @@ describe.concurrent('cleanUrl', () => {
'https://github.com/user/repo'
);
});

const httpRemoteUrls = ['https://github.com/user/repo.git', 'http://192.168.1.1/user/repo.git'];

test.each(httpRemoteUrls)('HTTP Remote - %s', (remoteUrl) => {
expect(remoteUrlIsHttp(remoteUrl)).toBe(true);
});

const nonHttpRemoteUrls = [
'git@github.com:user/repo.git',
'ssh://git@github.com:22/user/repo.git',
'git://github.com/user/repo.git'
];

test.each(nonHttpRemoteUrls)('Non HTTP Remote - %s', (remoteUrl) => {
expect(remoteUrlIsHttp(remoteUrl)).toBe(false);
});
});

describe.concurrent('getEditorUri', () => {
Expand Down
7 changes: 0 additions & 7 deletions apps/desktop/src/lib/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ export function convertRemoteToWebUrl(url: string): string {
return `${protocol}://${gitRemote.resource}/${gitRemote.owner}/${gitRemote.name}`;
}

export function remoteUrlIsHttp(url: string): boolean {
const httpProtocols = ['http', 'https'];
const gitRemote = GitUrlParse(url);

return httpProtocols.includes(gitRemote.protocol);
}

export interface EditorUriParams {
schemeId: string;
path: string[];
Expand Down
13 changes: 5 additions & 8 deletions apps/desktop/src/routes/[projectId]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import { ModeService } from '$lib/modes/service';
import Navigation from '$lib/navigation/Navigation.svelte';
import { UncommitedFilesWatcher } from '$lib/uncommitedFiles/watcher';
import { parseRemoteUrl } from '$lib/url/gitUrl';
import { debounce } from '$lib/utils/debounce';
import { BranchController } from '$lib/vbranches/branchController';
import { UpstreamIntegrationService } from '$lib/vbranches/upstreamIntegrationService';
Expand Down Expand Up @@ -57,8 +56,8 @@
const branchesError = $derived(vbranchService.branchesError);
const baseBranch = $derived(baseBranchService.base);
const remoteUrl = $derived($baseBranch?.remoteUrl);
const forkUrl = $derived($baseBranch?.pushRemoteUrl);
const repoInfo = $derived(baseBranchService.repo);
const forkInfo = $derived(baseBranchService.pushRepo);
const user = $derived(userService.user);
const accessToken = $derived($user?.github_access_token);
const baseError = $derived(baseBranchService.error);
Expand Down Expand Up @@ -100,8 +99,6 @@
const octokit = $derived(accessToken ? octokitFromAccessToken(accessToken) : undefined);
const forgeFactory = $derived(new DefaultForgeFactory(octokit));
const repoInfo = $derived(remoteUrl ? parseRemoteUrl(remoteUrl) : undefined);
const forkInfo = $derived(forkUrl && forkUrl !== remoteUrl ? parseRemoteUrl(forkUrl) : undefined);
const baseBranchName = $derived($baseBranch?.shortName);
const listServiceStore = createForgeListingServiceStore(undefined);
Expand Down Expand Up @@ -140,14 +137,14 @@
$effect(() => {
const forge =
repoInfo && baseBranchName
? forgeFactory.build(repoInfo, baseBranchName, forkInfo)
$repoInfo && baseBranchName
? forgeFactory.build($repoInfo, baseBranchName, $forkInfo)
: undefined;
const ghListService = forge?.listService();
listServiceStore.set(ghListService);
forgeStore.set(forge);
prService.set(forge ? forge.prService() : undefined);
setPostHogRepo(repoInfo);
setPostHogRepo($repoInfo);
return () => {
setPostHogRepo(undefined);
};
Expand Down
36 changes: 20 additions & 16 deletions apps/desktop/src/routes/[projectId]/board/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,29 @@
const project = getContext(Project);
const forge = getForge();
const baseBranchService = getContext(BaseBranchService);
const baseBranch = baseBranchService.base;
const baseRepo = $derived(baseBranchService.repo);
let viewport: HTMLDivElement;
let contents: HTMLDivElement;
let viewport: HTMLDivElement | undefined = $state();
let contents: HTMLDivElement | undefined = $state();
const httpsWarningBannerDismissed = projectHttpsWarningBannerDismissed(project.id);
function shouldShowHttpsWarning() {
if (httpsWarningBannerDismissed) return false;
if (!$baseBranch?.remoteUrl.startsWith('https')) return false;
if ($baseBranch?.remoteUrl.includes('github.com') && !!$forge) return false;
if (!$baseRepo?.protocol?.startsWith('https')) return false;
if ($forge?.name === 'github') return false;
return true;
}
$: if (shouldShowHttpsWarning()) {
showToast({
title: 'HTTPS remote detected',
message: 'In order to push & fetch, you may need to set up an SSH key.',
style: 'neutral'
});
}
$effect(() => {
if (shouldShowHttpsWarning()) {
showToast({
title: 'HTTPS remote detected',
message: 'In order to push & fetch, you may need to set up an SSH key.',
style: 'neutral'
});
}
});
const modeService = getContext(ModeService);
const mode = modeService.mode;
Expand All @@ -42,10 +44,12 @@
goto(`/${project.id}/edit`);
}
$: if ($mode?.type === 'Edit') {
// That was causing an incorrect linting error when project.id was accessed inside the reactive block
gotoEdit();
}
$effect(() => {
if ($mode?.type === 'Edit') {
// That was causing an incorrect linting error when project.id was accessed inside the reactive block
gotoEdit();
}
});
</script>

<div class="board-wrapper">
Expand Down

0 comments on commit 4c212cd

Please sign in to comment.