Skip to content

Commit

Permalink
Better flows around setting up FS sync and Git
Browse files Browse the repository at this point in the history
  • Loading branch information
gschier committed Feb 7, 2025
1 parent eca51cc commit c17c3fc
Show file tree
Hide file tree
Showing 20 changed files with 499 additions and 299 deletions.
9 changes: 4 additions & 5 deletions src-tauri/yaak-git/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ export function useGit(dir: string) {
mutationFn: () => invoke('plugin:yaak-git|pull', { dir }),
onSuccess,
}),
init: useMutation<void, string, void>({
mutationKey: ['git', 'initialize', dir],
mutationFn: () => invoke('plugin:yaak-git|initialize', { dir }),
onSuccess,
}),
unstage: useMutation<void, string, { relaPaths: string[] }>({
mutationKey: ['git', 'unstage', dir],
mutationFn: (args) => invoke('plugin:yaak-git|unstage', { dir, ...args }),
Expand All @@ -74,3 +69,7 @@ export function useGit(dir: string) {
},
] as const;
}

export async function gitInit(dir: string) {
await invoke('plugin:yaak-git|initialize', { dir });
}
10 changes: 9 additions & 1 deletion src-tauri/yaak-git/src/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,15 @@ pub(crate) fn git_checkout_branch(dir: &Path, branch: &str, force: bool) -> Resu

pub(crate) fn git_create_branch(dir: &Path, name: &str) -> Result<()> {
let repo = open_repo(dir)?;
let head = repo.head()?.peel_to_commit()?;
let head = match repo.head() {
Ok(h) => h,
Err(e) if e.code() == git2::ErrorCode::UnbornBranch => {
let msg = "Cannot create branch when there are no commits";
return Err(GenericError(msg.into()));
}
Err(e) => return Err(e.into()),
};
let head = head.peel_to_commit()?;

repo.branch(name, &head, false)?;

Expand Down
7 changes: 6 additions & 1 deletion src-tauri/yaak-git/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pub struct GitAuthor {

pub fn git_init(dir: &Path) -> Result<()> {
git2::Repository::init(dir)?;
let repo = open_repo(dir)?;
// Default to main instead of master, to align with
// the official Git and GitHub behavior
repo.set_head("refs/heads/main")?;
info!("Initialized {dir:?}");
Ok(())
}
Expand Down Expand Up @@ -134,7 +138,8 @@ pub fn git_commit(dir: &Path, message: &str) -> Result<()> {
pub fn git_log(dir: &Path) -> Result<Vec<GitCommit>> {
let repo = open_repo(dir)?;

if repo.is_empty()? {
// Return empty if empty repo or no head (new repo)
if repo.is_empty()? || repo.head().is_err() {
return Ok(vec![]);
}

Expand Down
6 changes: 2 additions & 4 deletions src-tauri/yaak-git/src/merge.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::error::Error::MergeConflicts;
use crate::util::bytes_to_string;
use git2::{AnnotatedCommit, Branch, IndexEntry, MergeOptions, Reference, Repository};
use git2::{AnnotatedCommit, Branch, IndexEntry, Reference, Repository};
use log::{debug, info};


pub(crate) fn do_merge(
repo: &Repository,
local_branch: &Branch,
Expand Down Expand Up @@ -46,7 +45,6 @@ pub(crate) fn do_merge(
Ok(())
}


pub(crate) fn merge_fast_forward(
repo: &Repository,
local_reference: &mut Reference,
Expand Down Expand Up @@ -79,7 +77,7 @@ pub(crate) fn merge_normal(
let local_tree = repo.find_commit(local.id())?.tree()?;
let remote_tree = repo.find_commit(remote.id())?.tree()?;
let ancestor = repo.find_commit(repo.merge_base(local.id(), remote.id())?)?.tree()?;

let mut idx = repo.merge_trees(&ancestor, &local_tree, &remote_tree, None)?;

if idx.has_conflicts() {
Expand Down
27 changes: 27 additions & 0 deletions src-web/commands/openSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { SettingsTab } from '../components/Settings/SettingsTab';
import { getActiveWorkspaceId } from '../hooks/useActiveWorkspace';
import { createFastMutation } from '../hooks/useFastMutation';
import { trackEvent } from '../lib/analytics';
import { router } from '../lib/router';
import { invokeCmd } from '../lib/tauri';

export const openSettings = createFastMutation<void, string, SettingsTab | null>({
mutationKey: ['open_settings'],
mutationFn: async function (tab) {
const workspaceId = getActiveWorkspaceId();
if (workspaceId == null) return;

trackEvent('dialog', 'show', { id: 'settings', tab: `${tab}` });
const location = router.buildLocation({
to: '/workspaces/$workspaceId/settings',
params: { workspaceId },
search: { tab: tab ?? SettingsTab.General },
});
await invokeCmd('cmd_new_child_window', {
url: location.href,
label: 'settings',
title: 'Yaak Settings',
innerSize: [750, 600],
});
},
});
25 changes: 25 additions & 0 deletions src-web/commands/openWorkspaceSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { WorkspaceSettingsDialog } from '../components/WorkspaceSettingsDialog';
import { getActiveWorkspaceId } from '../hooks/useActiveWorkspace';
import { createFastMutation } from '../hooks/useFastMutation';
import { showDialog } from '../lib/dialog';

export const openWorkspaceSettings = createFastMutation<void, string, { openSyncMenu?: boolean }>({
mutationKey: ['open_workspace_settings'],
async mutationFn({ openSyncMenu }) {
const workspaceId = getActiveWorkspaceId();
showDialog({
id: 'workspace-settings',
title: 'Workspace Settings',
size: 'md',
render({ hide }) {
return (
<WorkspaceSettingsDialog
workspaceId={workspaceId}
hide={hide}
openSyncMenu={openSyncMenu}
/>
);
},
});
},
});
6 changes: 2 additions & 4 deletions src-web/components/CommandPaletteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fuzzyFilter } from 'fuzzbunny';
import type { KeyboardEvent, ReactNode } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createFolder } from '../commands/commands';
import { openSettings } from '../commands/openSettings';
import { switchWorkspace } from '../commands/switchWorkspace';
import { useActiveCookieJar } from '../hooks/useActiveCookieJar';
import { useActiveEnvironment } from '../hooks/useActiveEnvironment';
Expand All @@ -17,7 +18,6 @@ import { useEnvironments } from '../hooks/useEnvironments';
import type { HotkeyAction } from '../hooks/useHotKey';
import { useHotKey } from '../hooks/useHotKey';
import { useHttpRequestActions } from '../hooks/useHttpRequestActions';
import { useOpenSettings } from '../hooks/useOpenSettings';
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
import { useRecentRequests } from '../hooks/useRecentRequests';
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
Expand Down Expand Up @@ -71,7 +71,6 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
const [recentRequests] = useRecentRequests();
const [, setSidebarHidden] = useSidebarHidden();
const { baseEnvironment } = useEnvironments();
const { mutate: openSettings } = useOpenSettings();
const { mutate: createHttpRequest } = useCreateHttpRequest();
const { mutate: createGrpcRequest } = useCreateGrpcRequest();
const { mutate: createEnvironment } = useCreateEnvironment();
Expand All @@ -85,7 +84,7 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
key: 'settings.open',
label: 'Open Settings',
action: 'settings.show',
onSelect: openSettings,
onSelect: () => openSettings.mutate(null),
},
{
key: 'app.create',
Expand Down Expand Up @@ -193,7 +192,6 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
createWorkspace,
deleteRequest,
httpRequestActions,
openSettings,
renameRequest,
sendRequest,
setSidebarHidden,
Expand Down
22 changes: 18 additions & 4 deletions src-web/components/CreateWorkspaceDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { gitInit } from '@yaakapp-internal/git';
import type { WorkspaceMeta } from '@yaakapp-internal/models';
import { useState } from 'react';
import { upsertWorkspace } from '../commands/upsertWorkspace';
import { upsertWorkspaceMeta } from '../commands/upsertWorkspaceMeta';
import { router } from '../lib/router';
import { invokeCmd } from '../lib/tauri';
import { showErrorToast } from '../lib/toast';
import { Button } from './core/Button';
import { PlainInput } from './core/PlainInput';
import { VStack } from './core/Stacks';
Expand All @@ -15,7 +17,10 @@ interface Props {

export function CreateWorkspaceDialog({ hide }: Props) {
const [name, setName] = useState<string>('');
const [settingSyncDir, setSettingSyncDir] = useState<string | null>(null);
const [syncConfig, setSyncConfig] = useState<{
filePath: string | null;
initGit?: boolean;
}>({ filePath: null, initGit: true });

return (
<VStack
Expand All @@ -33,7 +38,16 @@ export function CreateWorkspaceDialog({ hide }: Props) {
const workspaceMeta = await invokeCmd<WorkspaceMeta>('cmd_get_workspace_meta', {
workspaceId: workspace.id,
});
upsertWorkspaceMeta.mutate({ ...workspaceMeta, settingSyncDir });
await upsertWorkspaceMeta.mutateAsync({
...workspaceMeta,
settingSyncDir: syncConfig.filePath,
});

if (syncConfig.initGit && syncConfig.filePath) {
gitInit(syncConfig.filePath).catch((err) => {
showErrorToast('git-init-error', String(err));
});
}

// Navigate to workspace
await router.navigate({
Expand All @@ -47,8 +61,8 @@ export function CreateWorkspaceDialog({ hide }: Props) {
<PlainInput required label="Name" defaultValue={name} onChange={setName} />

<SyncToFilesystemSetting
onChange={setSettingSyncDir}
value={settingSyncDir}
onChange={setSyncConfig}
value={syncConfig}
allowNonEmptyDirectory // Will do initial import when the workspace is created
/>
<Button type="submit" color="primary" className="ml-auto mt-3">
Expand Down
Loading

0 comments on commit c17c3fc

Please sign in to comment.