mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-18 06:22:28 +03:00
Merge pull request #3978 from gitbutlerapp/add-git-config-module
support setting signCommits git config
This commit is contained in:
commit
0b57a44d63
@ -29,6 +29,12 @@ const defaultGitConfig = Object.freeze({
|
||||
|
||||
class DummyGitConfigService implements GitConfigService {
|
||||
constructor(private config: { [index: string]: string | undefined }) {}
|
||||
async getSignCommitsConfig(_projectId: string): Promise<boolean | undefined> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
async setSignCommitsConfig(_projectId: string, _value: boolean): Promise<unknown> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
async get<T extends string>(key: string): Promise<T | undefined> {
|
||||
return (this.config[key] || undefined) as T | undefined;
|
||||
|
@ -13,4 +13,15 @@ export class GitConfigService {
|
||||
async set<T extends string>(key: string, value: T) {
|
||||
return await invoke<T | undefined>('git_set_global_config', { key, value });
|
||||
}
|
||||
|
||||
// Gets the value of `gitbutler.signCommits`
|
||||
// Determines if the app should attempt to sign commits using per the git configuration.
|
||||
async getSignCommitsConfig(projectId: string): Promise<boolean | undefined> {
|
||||
return await invoke<boolean | undefined>('get_sign_commits_config', { projectId });
|
||||
}
|
||||
|
||||
// Sets the value of `gitbutler.signCommits`
|
||||
async setSignCommitsConfig(projectId: string, value: boolean) {
|
||||
return await invoke('set_sign_commits_config', { projectId, value });
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
import SectionCard from './SectionCard.svelte';
|
||||
import Spacer from './Spacer.svelte';
|
||||
import TextBox from './TextBox.svelte';
|
||||
import { GitConfigService } from '$lib/backend/gitConfigService';
|
||||
import { Project, ProjectService } from '$lib/backend/projects';
|
||||
import Toggle from '$lib/components/Toggle.svelte';
|
||||
import { projectRunCommitHooks } from '$lib/config/config';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const projectService = getContext(ProjectService);
|
||||
const project = getContext(Project);
|
||||
@ -14,6 +16,7 @@
|
||||
let allowForcePushing = project?.ok_with_force_push;
|
||||
let omitCertificateCheck = project?.omit_certificate_check;
|
||||
|
||||
const gitConfig = getContext(GitConfigService);
|
||||
const runCommitHooks = projectRunCommitHooks(project.id);
|
||||
|
||||
async function setWithForcePush(value: boolean) {
|
||||
@ -30,6 +33,16 @@
|
||||
project.snapshot_lines_threshold = value;
|
||||
await projectService.updateProject(project);
|
||||
}
|
||||
|
||||
let signCommits = false;
|
||||
async function setSignCommits(value: boolean) {
|
||||
signCommits = value;
|
||||
await gitConfig.setSignCommitsConfig(project.id, value);
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
signCommits = (await gitConfig.getSignCommitsConfig(project.id)) || false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="wrapper">
|
||||
@ -48,6 +61,20 @@
|
||||
</svelte:fragment>
|
||||
</SectionCard>
|
||||
|
||||
<SectionCard orientation="row" labelFor="allowForcePush">
|
||||
<svelte:fragment slot="title">Sign commits</svelte:fragment>
|
||||
<svelte:fragment slot="caption">
|
||||
GitButler will sign commits as per your git configuration.
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="actions">
|
||||
<Toggle
|
||||
id="signCommits"
|
||||
bind:checked={signCommits}
|
||||
on:change={async () => await setSignCommits(signCommits)}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</SectionCard>
|
||||
|
||||
<SectionCard orientation="row" labelFor="omitCertificateCheck">
|
||||
<svelte:fragment slot="title">Ignore host certificate checks</svelte:fragment>
|
||||
<svelte:fragment slot="caption">
|
||||
|
35
crates/gitbutler-core/src/config/git.rs
Normal file
35
crates/gitbutler-core/src/config/git.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::projects::Project;
|
||||
use anyhow::Result;
|
||||
use git2::ConfigLevel;
|
||||
|
||||
const CFG_SIGN_COMMITS: &str = "gitbutler.signCommits";
|
||||
|
||||
impl Project {
|
||||
pub fn set_sign_commits(&self, val: bool) -> Result<()> {
|
||||
self.set_local_bool(CFG_SIGN_COMMITS, val)
|
||||
}
|
||||
pub fn sign_commits(&self) -> Result<Option<bool>> {
|
||||
self.get_bool(CFG_SIGN_COMMITS)
|
||||
}
|
||||
|
||||
fn set_local_bool(&self, key: &str, val: bool) -> Result<()> {
|
||||
let repo = git2::Repository::open(&self.path)?;
|
||||
let config = repo.config()?;
|
||||
match config.open_level(ConfigLevel::Local) {
|
||||
Ok(mut local) => local.set_bool(key, val).map_err(Into::into),
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_bool(&self, key: &str) -> Result<Option<bool>> {
|
||||
let repo = git2::Repository::open(&self.path)?;
|
||||
let config = repo.config()?;
|
||||
match config.get_bool(key) {
|
||||
Ok(value) => Ok(Some(value)),
|
||||
Err(err) => match err.code() {
|
||||
git2::ErrorCode::NotFound => Ok(None),
|
||||
_ => Err(err.into()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
1
crates/gitbutler-core/src/config/mod.rs
Normal file
1
crates/gitbutler-core/src/config/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod git;
|
@ -15,6 +15,7 @@
|
||||
|
||||
pub mod askpass;
|
||||
pub mod assets;
|
||||
pub mod config;
|
||||
pub mod dedup;
|
||||
pub mod error;
|
||||
pub mod fs;
|
||||
|
34
crates/gitbutler-tauri/src/config.rs
Normal file
34
crates/gitbutler-tauri/src/config.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::error::Error;
|
||||
use anyhow::Context;
|
||||
use gitbutler_core::projects::{self, ProjectId};
|
||||
use tauri::Manager;
|
||||
use tracing::instrument;
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(handle), err(Debug))]
|
||||
pub async fn get_sign_commits_config(
|
||||
handle: tauri::AppHandle,
|
||||
project_id: ProjectId,
|
||||
) -> Result<Option<bool>, Error> {
|
||||
handle
|
||||
.state::<projects::Controller>()
|
||||
.get(project_id)
|
||||
.context("failed to get project")?
|
||||
.sign_commits()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(handle), err(Debug))]
|
||||
pub async fn set_sign_commits_config(
|
||||
handle: tauri::AppHandle,
|
||||
project_id: ProjectId,
|
||||
value: bool,
|
||||
) -> Result<(), Error> {
|
||||
handle
|
||||
.state::<projects::Controller>()
|
||||
.get(project_id)
|
||||
.context("failed to get project")?
|
||||
.set_sign_commits(value)
|
||||
.map_err(Into::into)
|
||||
}
|
@ -21,6 +21,7 @@ pub mod menu;
|
||||
pub mod watcher;
|
||||
|
||||
pub mod askpass;
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod github;
|
||||
pub mod keys;
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
use gitbutler_core::{assets, git, storage};
|
||||
use gitbutler_tauri::{
|
||||
app, askpass, commands, github, keys, logs, menu, projects, remotes, undo, users,
|
||||
app, askpass, commands, config, github, keys, logs, menu, projects, remotes, undo, users,
|
||||
virtual_branches, watcher, zip,
|
||||
};
|
||||
use tauri::{generate_context, Manager};
|
||||
@ -209,6 +209,8 @@ fn main() {
|
||||
undo::list_snapshots,
|
||||
undo::restore_snapshot,
|
||||
undo::snapshot_diff,
|
||||
config::get_sign_commits_config,
|
||||
config::set_sign_commits_config,
|
||||
menu::menu_item_set_enabled,
|
||||
keys::commands::get_public_key,
|
||||
github::commands::init_device_oauth,
|
||||
|
Loading…
Reference in New Issue
Block a user