cli: rad id update --edit

Introduce an `--edit` option to `rad id update` to allow a user to open up their
text editor for changing the document's contents.
This commit is contained in:
Fintan Halpenny 2024-11-06 16:18:03 +00:00 committed by cloudhead
parent c6d975799a
commit 43e08a8e70
No known key found for this signature in database
1 changed files with 31 additions and 7 deletions

View File

@ -5,7 +5,7 @@ use std::{ffi::OsString, io};
use anyhow::{anyhow, Context};
use radicle::cob::identity::{self, IdentityMut, Revision, RevisionId};
use radicle::identity::{doc, Doc, Identity, RawDoc, Visibility};
use radicle::identity::{doc, Doc, Identity, PayloadError, RawDoc, Visibility};
use radicle::prelude::{Did, RepoId, Signer};
use radicle::storage::refs;
use radicle::storage::{ReadRepository, ReadStorage as _, WriteRepository};
@ -33,8 +33,7 @@ Usage
[--delegate <did>] [--rescind <did>]
[--threshold <num>] [--visibility <private | public>]
[--allow <did>] [--disallow <did>]
[--no-confirm] [--payload <id> <key> <val>...]
[<option>...]
[--no-confirm] [--payload <id> <key> <val>...] [--edit] [<option>...]
rad id edit <revision-id> [--title <string>] [--description <string>] [<option>...]
rad id show <revision-id> [<option>...]
rad id <accept | reject | redact> <revision-id> [<option>...]
@ -64,6 +63,7 @@ pub enum Operation {
allow: BTreeSet<Did>,
disallow: BTreeSet<Did>,
payload: Vec<(doc::PayloadId, String, json::Value)>,
edit: bool,
},
AcceptRevision {
revision: Rev,
@ -146,6 +146,7 @@ impl Args for Options {
let mut threshold: Option<usize> = None;
let mut interactive = Interactive::new(io::stdout());
let mut payload = Vec::new();
let mut edit = false;
let mut quiet = false;
while let Some(arg) = parser.next()? {
@ -237,6 +238,9 @@ impl Args for Options {
payload.push((id, key, val));
}
Long("edit") => {
edit = true;
}
Value(val) => {
let val = term::args::rev(&val)?;
revision = Some(val);
@ -276,6 +280,7 @@ impl Args for Options {
allow,
disallow,
payload,
edit,
},
};
Ok((
@ -385,6 +390,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
allow,
disallow,
payload,
edit,
} => {
let proposal = {
let mut proposal = current.doc.clone().edit();
@ -416,8 +422,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
}
}
(Visibility::Public, Some(EditVisibility::Private)) => {
// We ignore disallow since only allowing matters and
// the sets are disjoint
// We ignore disallow since only allowing matters and the sets are disjoint.
proposal.visibility = Visibility::Private { allow };
}
(Visibility::Private { .. }, Some(EditVisibility::Public)) if !allow.is_empty() || !disallow.is_empty() => {
@ -462,8 +467,27 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
}
proposal
};
// Verify that the project payload can still be parsed into the
// `Project` type.
// If `--edit` is specified, the document can also be edited via a text edit.
let proposal = if edit {
match term::editor::Editor::comment()
.extension("json")
.initial(serde_json::to_string_pretty(&current.doc)?)?
.edit()?
{
Some(proposal) => serde_json::from_str::<RawDoc>(&proposal)?,
None => {
term::print(term::format::italic(
"Nothing to do. The document is up to date. See `rad inspect --identity`.",
));
return Ok(());
}
}
} else {
proposal
};
// Verify that the project payload can still be parsed into the `Project` type.
if let Err(PayloadError::Json(e)) = proposal.project() {
anyhow::bail!("failed to verify `xyz.radicle.project`, {e}");
}