Skip to content

Commit 279b181

Browse files
committed
feature: show commit gpg sign status (#614)
Signed-off-by: leo <[email protected]>
1 parent 5c92fbd commit 279b181

File tree

7 files changed

+131
-1
lines changed

7 files changed

+131
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
namespace SourceGit.Commands
2+
{
3+
public class QueryCommitSignInfo : Command
4+
{
5+
public QueryCommitSignInfo(string repo, string sha)
6+
{
7+
WorkingDirectory = repo;
8+
Context = repo;
9+
10+
var allowedSignersFile = new Config(repo).Get("gpg.ssh.allowedSignersFile");
11+
if (string.IsNullOrEmpty(allowedSignersFile))
12+
Args = $"-c gpg.ssh.allowedSignersFile=/dev/null show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}";
13+
else
14+
Args = $"show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}";
15+
}
16+
17+
public Models.CommitSignInfo Result()
18+
{
19+
var rs = ReadToEnd();
20+
if (!rs.IsSuccess)
21+
return null;
22+
23+
var raw = rs.StdOut.Trim();
24+
if (raw.Length > 1)
25+
return new Models.CommitSignInfo() { VerifyResult = raw[0], Key = raw.Substring(2) };
26+
27+
return null;
28+
}
29+
}
30+
}

src/Models/CommitSignInfo.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using Avalonia.Media;
2+
3+
namespace SourceGit.Models
4+
{
5+
public class CommitSignInfo
6+
{
7+
public string Key { get; set; } = string.Empty;
8+
public char VerifyResult { get; set; } = 'N';
9+
10+
public IBrush Brush
11+
{
12+
get
13+
{
14+
switch (VerifyResult)
15+
{
16+
case 'G':
17+
case 'U':
18+
return Brushes.Green;
19+
case 'X':
20+
case 'Y':
21+
case 'R':
22+
return Brushes.DarkOrange;
23+
case 'B':
24+
case 'E':
25+
return Brushes.Red;
26+
default:
27+
return Brushes.Transparent;
28+
}
29+
}
30+
}
31+
32+
public string ToolTip
33+
{
34+
get
35+
{
36+
switch (VerifyResult)
37+
{
38+
case 'G':
39+
return $"Good Signature.\n\nKey: {Key}";
40+
case 'B':
41+
return $"Bad Signature.\n\nKey: {Key}";
42+
case 'U':
43+
return $"Good Signature with unknown validity.\n\nKey: {Key}";
44+
case 'X':
45+
return $"Good Signature but has expired.\n\nKey: {Key}";
46+
case 'Y':
47+
return $"Good Signature made by expired key.\n\nKey: {Key}";
48+
case 'R':
49+
return $"Good signature made by a revoked key.\n\nKey: {Key}";
50+
case 'E':
51+
return $"Signature cannot be checked.\n\nKey: {Key}";
52+
default:
53+
return "No signature.";
54+
}
55+
}
56+
}
57+
}
58+
}

src/Resources/Icons.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
<StreamGeometry x:Key="Icons.Undo">M762 1024C876 818 895 504 448 514V768L64 384l384-384v248c535-14 595 472 314 776z</StreamGeometry>
122122
<StreamGeometry x:Key="Icons.Unlock">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</StreamGeometry>
123123
<StreamGeometry x:Key="Icons.Up">M170 831l343-342L855 831l105-105-448-448L64 726 170 831z</StreamGeometry>
124+
<StreamGeometry x:Key="Icons.Verified">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</StreamGeometry>
124125
<StreamGeometry x:Key="Icons.Waiting">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</StreamGeometry>
125126
<StreamGeometry x:Key="Icons.Whitespace">M0 512M1024 512M512 0M512 1024M762 412v100h-500v-100h-150v200h800v-200h-150z</StreamGeometry>
126127
<StreamGeometry x:Key="Icons.Window.Close">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</StreamGeometry>

src/ViewModels/CommitDetail.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public string FullMessage
4545
private set => SetProperty(ref _fullMessage, value);
4646
}
4747

48+
public Models.CommitSignInfo SignInfo
49+
{
50+
get => _signInfo;
51+
private set => SetProperty(ref _signInfo, value);
52+
}
53+
4854
public List<Models.Change> Changes
4955
{
5056
get => _changes;
@@ -131,6 +137,7 @@ public void Cleanup()
131137
_visibleChanges.Clear();
132138
if (_selectedChanges != null)
133139
_selectedChanges.Clear();
140+
_signInfo = null;
134141
_searchChangeFilter = null;
135142
_diffContext = null;
136143
_viewRevisionFileContent = null;
@@ -474,6 +481,7 @@ private void Refresh()
474481
{
475482
_changes = null;
476483
FullMessage = string.Empty;
484+
SignInfo = null;
477485
Changes = [];
478486
VisibleChanges = null;
479487
SelectedChanges = null;
@@ -488,6 +496,12 @@ private void Refresh()
488496
Dispatcher.UIThread.Invoke(() => FullMessage = fullMessage);
489497
});
490498

499+
Task.Run(() =>
500+
{
501+
var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA).Result();
502+
Dispatcher.UIThread.Invoke(() => SignInfo = signInfo);
503+
});
504+
491505
if (_cancelToken != null)
492506
_cancelToken.Requested = true;
493507

@@ -637,6 +651,7 @@ private void TryToAddContextMenuItemsForGitLFS(ContextMenu menu, string path)
637651
private int _activePageIndex = 0;
638652
private Models.Commit _commit = null;
639653
private string _fullMessage = string.Empty;
654+
private Models.CommitSignInfo _signInfo = null;
640655
private List<Models.Change> _changes = null;
641656
private List<Models.Change> _visibleChanges = null;
642657
private List<Models.Change> _selectedChanges = null;

src/Views/CommitBaseInfo.axaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@
6060
Margin="12,0,4,0"
6161
VerticalAlignment="Center"/>
6262

63+
<ContentControl Content="{Binding #ThisControl.SignInfo}">
64+
<ContentControl.Styles>
65+
<Style Selector="ToolTip">
66+
<Setter Property="MaxWidth" Value="800"/>
67+
</Style>
68+
</ContentControl.Styles>
69+
70+
<ContentControl.DataTemplates>
71+
<DataTemplate DataType="m:CommitSignInfo">
72+
<Border Width="24" Background="Transparent" ToolTip.Tip="{Binding ToolTip}">
73+
<Path Width="14" Height="14" Data="{StaticResource Icons.Verified}" Fill="{Binding Brush}"/>
74+
</Border>
75+
</DataTemplate>
76+
</ContentControl.DataTemplates>
77+
</ContentControl>
78+
6379
<Button Classes="icon_button" Width="24" Cursor="Hand" Click="OnCopyCommitSHA" ToolTip.Tip="{DynamicResource Text.Copy}">
6480
<Path Width="12" Height="12" Data="{StaticResource Icons.Copy}"/>
6581
</Button>
@@ -105,7 +121,7 @@
105121
VerticalAlignment="Center"
106122
UseGraphColor="False"/>
107123
</Border>
108-
124+
109125
<!-- Messages -->
110126
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
111127
<v:CommitMessagePresenter Grid.Row="3" Grid.Column="1"

src/Views/CommitBaseInfo.axaml.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ public string Message
1717
set => SetValue(MessageProperty, value);
1818
}
1919

20+
public static readonly StyledProperty<Models.CommitSignInfo> SignInfoProperty =
21+
AvaloniaProperty.Register<CommitBaseInfo, Models.CommitSignInfo>(nameof(SignInfo));
22+
23+
public Models.CommitSignInfo SignInfo
24+
{
25+
get => GetValue(SignInfoProperty);
26+
set => SetValue(SignInfoProperty, value);
27+
}
28+
2029
public static readonly StyledProperty<bool> SupportsContainsInProperty =
2130
AvaloniaProperty.Register<CommitBaseInfo, bool>(nameof(SupportsContainsIn));
2231

src/Views/CommitDetail.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<!-- Base Information -->
2222
<v:CommitBaseInfo Content="{Binding Commit}"
2323
Message="{Binding FullMessage}"
24+
SignInfo="{Binding SignInfo}"
2425
SupportsContainsIn="True"
2526
WebLinks="{Binding WebLinks}"
2627
IssueTrackerRules="{Binding IssueTrackerRules}"/>

0 commit comments

Comments
 (0)