Harness the power of signify(1) to sign arbitrary git objects
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add list signatures cmd

+85
+75
src/list_signatures.rs
··· 1 + //! List signatures stored in this repository. 2 + 3 + use std::collections::BTreeMap; 4 + 5 + use anyhow::{Context, Result}; 6 + use git2::{Oid, Repository}; 7 + 8 + use super::utils; 9 + 10 + /// List signatures stored in this repository. 11 + pub fn command() -> Result<()> { 12 + let repo = utils::open_repository()?; 13 + 14 + for (oid, signers) in find_signers(&repo)? { 15 + let object = repo 16 + .find_object(oid, None) 17 + .context("Failed to find signed object")?; 18 + 19 + let signed_rev = { 20 + let opts = { 21 + let mut opts = git2::DescribeOptions::new(); 22 + opts.describe_all(); 23 + opts.show_commit_oid_as_fallback(true); 24 + opts 25 + }; 26 + object 27 + .describe(&opts) 28 + .with_context(|| format!("Failed to describe oid={oid}"))? 29 + .format(None) 30 + .with_context(|| format!("Failed to format description of oid={oid}"))? 31 + }; 32 + 33 + println!("Signers of {signed_rev}:"); 34 + 35 + for (signer, revname) in &signers { 36 + println!(" - {signer}"); 37 + println!(" {revname}"); 38 + } 39 + } 40 + 41 + Ok(()) 42 + } 43 + 44 + fn find_signers(repo: &Repository) -> Result<BTreeMap<Oid, Vec<(Oid, String)>>> { 45 + let mut signers: BTreeMap<_, Vec<_>> = BTreeMap::new(); 46 + 47 + for maybe_rev in repo 48 + .references_glob(utils::ALL_SIGNIFY_SIGNATURE_REFS) 49 + .context("Failed to look-up all git-signify signature refs")? 50 + { 51 + let rev = maybe_rev.context("Failed to parse git revision")?; 52 + let revname = rev.name().context("Invalid revision name")?; 53 + 54 + let Some(("", signer_and_oid)) = 55 + revname.split_once(utils::ALL_SIGNIFY_SIGNATURE_REFS_PREFIX) 56 + else { 57 + continue; 58 + }; 59 + let Some((signer, oid)) = signer_and_oid.split_once('/') else { 60 + continue; 61 + }; 62 + 63 + let oid = Oid::from_str(oid) 64 + .with_context(|| format!("Failed to parse git oid={oid} of signed obj"))?; 65 + let signer = Oid::from_str(signer) 66 + .with_context(|| format!("Failed to parse git signer with oid={oid}"))?; 67 + 68 + signers 69 + .entry(oid) 70 + .or_default() 71 + .push((signer, revname.to_string())); 72 + } 73 + 74 + Ok(signers) 75 + }
+4
src/main.rs
··· 1 1 mod fingerprint; 2 + mod list_signatures; 2 3 mod pull; 3 4 mod push; 4 5 mod raw; ··· 60 61 /// The name of the remote repository 61 62 remote: Option<Cow<'static, str>>, 62 63 }, 64 + /// List signatures stored in this repository 65 + ListSignatures, 63 66 } 64 67 65 68 #[derive(Subcommand)] ··· 112 115 } => verify::command(public_key, rev), 113 116 Action::Push { remote } => push::command(&remote.unwrap_or(Cow::Borrowed("origin"))), 114 117 Action::Pull { remote } => pull::command(&remote.unwrap_or(Cow::Borrowed("origin"))), 118 + Action::ListSignatures => list_signatures::command(), 115 119 } 116 120 }
+6
src/utils.rs
··· 511 511 512 512 /// Git refspec describing all signify references. 513 513 pub const ALL_SIGNIFY_REFS: &str = "refs/signify/*"; 514 + 515 + /// Git refspec describing all signify signature references. 516 + pub const ALL_SIGNIFY_SIGNATURE_REFS: &str = "refs/signify/signatures/*"; 517 + 518 + /// Git refspec prefix describing all signify signature references. 519 + pub const ALL_SIGNIFY_SIGNATURE_REFS_PREFIX: &str = "refs/signify/signatures/";