git-ents.gitmain
⌘K
foforge
account.rs94 lines · 2.7 KB · rusthistorycomment on this file
1//! `git ents account create`: link a member to a login identity at the
2//! fixed `refs/meta/account` ref (`model.account`).
3
4use ents_model::{Account, MemberId, namespace};
5use ents_receive::{Identity, propose_entity};
6use gix_ref_store::RefStoreRead;
7
8use super::{actor, signer};
9use crate::error::{Error, Result};
10use crate::mutate::outcome_to_result;
11use crate::root::LocalRoot;
12
13/// `git ents account show`: this repository's account identity.
14///
15/// # Errors
16///
17/// [`Error::NotFound`] if no account has been created yet
18/// (`git ents account create` first).
19pub fn show(root: &LocalRoot) -> Result<Account> {
20 #[expect(
21 clippy::expect_used,
22 clippy::unwrap_in_result,
23 reason = "ACCOUNT_REF is a fixed, compile-time-known-valid refname literal"
24 )]
25 let name: gix::refs::FullName = namespace::ACCOUNT_REF
26 .try_into()
27 .expect("fixed, valid refname");
28 let Some(tip) = root.refs.get(name.as_ref())? else {
29 return Err(Error::NotFound {
30 what: "account".to_owned(),
31 });
32 };
33 let tree = super::commit_tree(&root.objects, tip)?;
34 Ok(facet_git_tree::deserialize::<Account>(
35 &tree,
36 &root.objects,
37 )?)
38}
39
40/// Run `git ents account create`.
41///
42/// # Errors
43///
44/// [`Error::NotFound`] if `member` is given but no such member exists (or,
45/// when omitted, the signer's own key is not enrolled yet — enroll it with
46/// `git ents members add` first); otherwise see
47/// [`crate::mutate::outcome_to_result`].
48pub fn create(
49 root: &LocalRoot,
50 member: Option<String>,
51 login: String,
52 key: Option<std::path::PathBuf>,
53) -> Result<()> {
54 let signer = signer(root, key.clone())?;
55 let member_id = match member {
56 Some(username) => MemberId::new(username),
57 None => {
58 let (username, _) =
59 super::members::check(root, key)?.ok_or_else(|| Error::NotFound {
60 what: "member for the current signing key".to_owned(),
61 })?;
62 MemberId::new(username)
63 }
64 };
65 let account = Account {
66 member: member_id,
67 login,
68 };
69 #[expect(
70 clippy::expect_used,
71 clippy::unwrap_in_result,
72 reason = "ACCOUNT_REF is a fixed, compile-time-known-valid refname literal"
73 )]
74 let name: gix::refs::FullName = namespace::ACCOUNT_REF
75 .try_into()
76 .expect("fixed, valid refname");
77 let identity = Identity {
78 actor: actor(&signer),
79 author: None,
80 sign: &|payload| signer.sign(payload),
81 };
82 let outcome = propose_entity(
83 &root.refs,
84 &root.objects,
85 &root.events,
86 name,
87 &account,
88 &identity,
89 "Create account",
90 root.mode(),
91 )?;
92 outcome_to_result(outcome, None)?;
93 Ok(())
94}