From 279b1819a3e4dac731e1b782b8d7a991c9181e84 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 29 Oct 2024 21:03:45 +0800 Subject: [PATCH] feature: show commit gpg sign status (#614) Signed-off-by: leo --- src/Commands/QueryCommitSignInfo.cs | 30 +++++++++++++++ src/Models/CommitSignInfo.cs | 58 +++++++++++++++++++++++++++++ src/Resources/Icons.axaml | 1 + src/ViewModels/CommitDetail.cs | 15 ++++++++ src/Views/CommitBaseInfo.axaml | 18 ++++++++- src/Views/CommitBaseInfo.axaml.cs | 9 +++++ src/Views/CommitDetail.axaml | 1 + 7 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/Commands/QueryCommitSignInfo.cs create mode 100644 src/Models/CommitSignInfo.cs diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs new file mode 100644 index 00000000..5ce18319 --- /dev/null +++ b/src/Commands/QueryCommitSignInfo.cs @@ -0,0 +1,30 @@ +namespace SourceGit.Commands +{ + public class QueryCommitSignInfo : Command + { + public QueryCommitSignInfo(string repo, string sha) + { + WorkingDirectory = repo; + Context = repo; + + var allowedSignersFile = new Config(repo).Get("gpg.ssh.allowedSignersFile"); + if (string.IsNullOrEmpty(allowedSignersFile)) + Args = $"-c gpg.ssh.allowedSignersFile=/dev/null show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; + else + Args = $"show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; + } + + public Models.CommitSignInfo Result() + { + var rs = ReadToEnd(); + if (!rs.IsSuccess) + return null; + + var raw = rs.StdOut.Trim(); + if (raw.Length > 1) + return new Models.CommitSignInfo() { VerifyResult = raw[0], Key = raw.Substring(2) }; + + return null; + } + } +} diff --git a/src/Models/CommitSignInfo.cs b/src/Models/CommitSignInfo.cs new file mode 100644 index 00000000..143cb347 --- /dev/null +++ b/src/Models/CommitSignInfo.cs @@ -0,0 +1,58 @@ +using Avalonia.Media; + +namespace SourceGit.Models +{ + public class CommitSignInfo + { + public string Key { get; set; } = string.Empty; + public char VerifyResult { get; set; } = 'N'; + + public IBrush Brush + { + get + { + switch (VerifyResult) + { + case 'G': + case 'U': + return Brushes.Green; + case 'X': + case 'Y': + case 'R': + return Brushes.DarkOrange; + case 'B': + case 'E': + return Brushes.Red; + default: + return Brushes.Transparent; + } + } + } + + public string ToolTip + { + get + { + switch (VerifyResult) + { + case 'G': + return $"Good Signature.\n\nKey: {Key}"; + case 'B': + return $"Bad Signature.\n\nKey: {Key}"; + case 'U': + return $"Good Signature with unknown validity.\n\nKey: {Key}"; + case 'X': + return $"Good Signature but has expired.\n\nKey: {Key}"; + case 'Y': + return $"Good Signature made by expired key.\n\nKey: {Key}"; + case 'R': + return $"Good signature made by a revoked key.\n\nKey: {Key}"; + case 'E': + return $"Signature cannot be checked.\n\nKey: {Key}"; + default: + return "No signature."; + } + } + } + } +} diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 1a84597e..cc56d33d 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -121,6 +121,7 @@ M762 1024C876 818 895 504 448 514V768L64 384l384-384v248c535-14 595 472 314 776z M832 464H332V240c0-31 25-56 56-56h248c31 0 56 25 56 56v68c0 4 4 8 8 8h56c4 0 8-4 8-8v-68c0-71-57-128-128-128H388c-71 0-128 57-128 128v224h-68c-18 0-32 14-32 32v384c0 18 14 32 32 32h640c18 0 32-14 32-32V496c0-18-14-32-32-32zM540 701v53c0 4-4 8-8 8h-40c-4 0-8-4-8-8v-53c-12-9-20-23-20-39 0-27 22-48 48-48s48 22 48 48c0 16-8 30-20 39z M170 831l343-342L855 831l105-105-448-448L64 726 170 831z + M880 128A722 722 0 01555 13a77 77 0 00-85 0 719 719 0 01-325 115c-40 4-71 38-71 80v369c0 246 329 446 439 446 110 0 439-200 439-446V207c0-41-31-76-71-80zM465 692a36 36 0 01-53 0L305 579a42 42 0 010-57 36 36 0 0153 0l80 85L678 353a36 36 0 0153 0 42 42 0 01-0 57L465 692z M812 864h-29V654c0-21-11-40-28-52l-133-88 134-89c18-12 28-31 28-52V164h28c18 0 32-14 32-32s-14-32-32-32H212c-18 0-32 14-32 32s14 32 32 32h30v210c0 21 11 40 28 52l133 88-134 89c-18 12-28 31-28 52V864H212c-18 0-32 14-32 32s14 32 32 32h600c18 0 32-14 32-32s-14-32-32-32zM441 566c18-12 28-31 28-52s-11-40-28-52L306 373V164h414v209l-136 90c-18 12-28 31-28 52 0 21 11 40 28 52l135 89V695c-9-7-20-13-32-19-30-15-93-41-176-41-63 0-125 14-175 38-12 6-22 12-31 18v-36l136-90z M0 512M1024 512M512 0M512 1024M762 412v100h-500v-100h-150v200h800v-200h-150z M519 459 222 162a37 37 0 10-52 52l297 297L169 809a37 37 0 1052 52l297-297 297 297a37 37 0 1052-52l-297-297 297-297a37 37 0 10-52-52L519 459z diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 3692be10..b533b24a 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -45,6 +45,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _fullMessage, value); } + public Models.CommitSignInfo SignInfo + { + get => _signInfo; + private set => SetProperty(ref _signInfo, value); + } + public List Changes { get => _changes; @@ -131,6 +137,7 @@ namespace SourceGit.ViewModels _visibleChanges.Clear(); if (_selectedChanges != null) _selectedChanges.Clear(); + _signInfo = null; _searchChangeFilter = null; _diffContext = null; _viewRevisionFileContent = null; @@ -474,6 +481,7 @@ namespace SourceGit.ViewModels { _changes = null; FullMessage = string.Empty; + SignInfo = null; Changes = []; VisibleChanges = null; SelectedChanges = null; @@ -488,6 +496,12 @@ namespace SourceGit.ViewModels Dispatcher.UIThread.Invoke(() => FullMessage = fullMessage); }); + Task.Run(() => + { + var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA).Result(); + Dispatcher.UIThread.Invoke(() => SignInfo = signInfo); + }); + if (_cancelToken != null) _cancelToken.Requested = true; @@ -637,6 +651,7 @@ namespace SourceGit.ViewModels private int _activePageIndex = 0; private Models.Commit _commit = null; private string _fullMessage = string.Empty; + private Models.CommitSignInfo _signInfo = null; private List _changes = null; private List _visibleChanges = null; private List _selectedChanges = null; diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index 623332c4..d45b5a86 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -60,6 +60,22 @@ Margin="12,0,4,0" VerticalAlignment="Center"/> + + + + + + + + + + + + + + @@ -105,7 +121,7 @@ VerticalAlignment="Center" UseGraphColor="False"/> - + SetValue(MessageProperty, value); } + public static readonly StyledProperty SignInfoProperty = + AvaloniaProperty.Register(nameof(SignInfo)); + + public Models.CommitSignInfo SignInfo + { + get => GetValue(SignInfoProperty); + set => SetValue(SignInfoProperty, value); + } + public static readonly StyledProperty SupportsContainsInProperty = AvaloniaProperty.Register(nameof(SupportsContainsIn)); diff --git a/src/Views/CommitDetail.axaml b/src/Views/CommitDetail.axaml index 8307d650..cb99b3d9 100644 --- a/src/Views/CommitDetail.axaml +++ b/src/Views/CommitDetail.axaml @@ -21,6 +21,7 @@