Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions git-branchless-lib/src/core/node_descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,79 @@ impl NodeDescriptor for RelativeTimeDescriptor {
}
}

/// Display the GPG signature status for a commit.
#[derive(Debug)]
pub struct SignatureStatusDescriptor {
is_enabled: bool,
repo_path: String,
}

impl SignatureStatusDescriptor {
/// Constructor.
pub fn new(repo: &Repo, is_enabled: bool) -> eyre::Result<Self> {
let repo_path = repo.get_path().to_string_lossy().to_string();
Ok(Self {
is_enabled,
repo_path,
})
}
}

impl NodeDescriptor for SignatureStatusDescriptor {
#[instrument]
fn describe_node(
&mut self,
_glyphs: &Glyphs,
object: &NodeObject,
) -> eyre::Result<Option<StyledString>> {
if !self.is_enabled {
return Ok(None);
}

let oid = object.get_oid().to_string();

// Use git command-line to get signature information as git2 doesn't
// expose GPG signature verification directly
let output = std::process::Command::new("git")
.args(["-C", &self.repo_path, "verify-commit", &oid, "--raw"])
.output();

match output {
Ok(output) => {
if output.status.success() {
// Good signature
let mut result = StyledString::new();
result.append_styled("[G]", BaseColor::Green.light());
Ok(Some(result))
Comment on lines +560 to +562
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick (maybe change)] It looks like other uses of StyledString in this file seem to use let result = StyledString::styled("[G]", BaseColor::Green.light());. To be consistent, can you update these uses of ::new() to match. Or is there a reason that won't work in this context?

} else {
// Bad signature
let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("BAD signature") {
let mut result = StyledString::new();
result.append_styled("[B]", BaseColor::Red.light());
Ok(Some(result))
} else if stderr.contains("No signature") {
let mut result = StyledString::new();
result.append_styled("[N]", BaseColor::Yellow.light());
Ok(Some(result))
} else {
// Unknown error
let mut result = StyledString::new();
result.append_styled("[?]", BaseColor::Magenta.light());
Ok(Some(result))
}
}
}
Err(_) => {
// Error running command
let mut result = StyledString::new();
result.append_styled("[E]", BaseColor::Red.light());
Ok(Some(result))
}
}
}
}

#[cfg(test)]
mod tests {
use std::ops::{Add, Sub};
Expand Down
4 changes: 4 additions & 0 deletions git-branchless-opts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,10 @@ pub struct SmartlogArgs {
/// Options for resolving revset expressions.
#[clap(flatten)]
pub resolve_revset_options: ResolveRevsetOptions,

/// Show GPG signature status for each commit.
#[clap(action, long = "show-signature")]
pub show_signature: bool,
}

/// The Git hosting provider to use, called a "forge".
Expand Down
9 changes: 8 additions & 1 deletion git-branchless-smartlog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use lib::core::formatting::Pluralize;
use lib::core::node_descriptors::{
BranchesDescriptor, CommitMessageDescriptor, CommitOidDescriptor,
DifferentialRevisionDescriptor, ObsolescenceExplanationDescriptor, Redactor,
RelativeTimeDescriptor,
RelativeTimeDescriptor, SignatureStatusDescriptor,
};
use lib::git::{GitRunInfo, Repo};

Expand Down Expand Up @@ -753,6 +753,9 @@ mod render {

/// Normally HEAD and the main branch are included. Set this to exclude them.
pub exact: bool,

/// Show GPG signature status for each commit.
pub show_signature: bool,
}
}

Expand All @@ -769,6 +772,7 @@ pub fn smartlog(
resolve_revset_options,
reverse,
exact,
show_signature,
} = options;

let repo = Repo::from_dir(&git_run_info.working_directory)?;
Expand Down Expand Up @@ -845,6 +849,7 @@ pub fn smartlog(
&Redactor::Disabled,
)?,
&mut DifferentialRevisionDescriptor::new(&repo, &Redactor::Disabled)?,
&mut SignatureStatusDescriptor::new(&repo, show_signature)?,
&mut CommitMessageDescriptor::new(&Redactor::Disabled)?,
],
)?
Expand Down Expand Up @@ -916,6 +921,7 @@ pub fn command_main(ctx: CommandContext, args: SmartlogArgs) -> EyreExitOr<()> {
resolve_revset_options,
reverse,
exact,
show_signature,
} = args;

smartlog(
Expand All @@ -927,6 +933,7 @@ pub fn command_main(ctx: CommandContext, args: SmartlogArgs) -> EyreExitOr<()> {
resolve_revset_options,
reverse,
exact,
show_signature,
},
)
}