Harness the power of signify(1) to sign arbitrary git objects
1//! Create signatures with [`libsignify`] and store references
2//! to them in git.
3
4use std::path::PathBuf;
5
6use anyhow::{Context, Result};
7
8use crate::raw::sign::sign;
9use crate::utils;
10
11/// Execute the `sign` command.
12pub fn command(key_path: PathBuf, rev: String) -> Result<()> {
13 let repo = utils::open_repository()?;
14 for (path, secret_key) in utils::get_secret_keys(key_path)? {
15 let signed_object = repo
16 .revparse_single(&rev)
17 .context("Failed to look-up object to sign")?
18 .id();
19 let key_fingerprint = secret_key.public_key()?.fingerprint()?;
20 let reference = utils::craft_signature_reference(key_fingerprint, signed_object);
21 if utils::revparse_single_ok_or_else(&repo, &reference, |_| Ok(true), || Ok(false))? {
22 println!("Signature already exists with key:");
23 println!(" - {}", path.display());
24 println!("Signature stored under:");
25 println!(" - {reference}");
26 continue;
27 }
28 let tree_oid = sign(&repo, &secret_key, &rev)?;
29 repo.reference(
30 &reference, tree_oid,
31 // references to signatures are non-deterministic,
32 // so we should fail if we attempt to overwrite a
33 // signature in our local git repository
34 false, "",
35 )
36 .context("Failed to store reference to signature")?;
37 println!("Signed with key:");
38 println!(" - {}", path.display());
39 println!("Signature stored under:");
40 println!(" - {reference}");
41 }
42 Ok(())
43}