Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
cli: rad id update --edit
Merged fintohaps opened 1 year ago

Introduce an --edit option to rad id update to allow a user to open up their text editor for changing the document’s contents.

2 files changed +35 -6 f9c35231 43e08a8e
modified radicle-cli/examples/rad-id-update-delete-field.md
@@ -74,5 +74,5 @@ Note that we cannot delete mandatory fields:

``` (fails)
$ rad id update --title "Delete default branch" --payload xyz.radicle.project defaultBranch null
-
✗ Error: failed to verify `xyz.radicle.project`, json: missing field `defaultBranch`
+
✗ Error: failed to verify `xyz.radicle.project`, missing field `defaultBranch`
```
modified radicle-cli/src/commands/id.rs
@@ -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};
@@ -34,6 +34,7 @@ Usage
                  [--threshold <num>] [--visibility <private | public>]
                  [--allow <did>] [--disallow <did>]
                  [--no-confirm] [--payload <id> <key> <val>...]
+
                  [--edit]
                  [<option>...]
    rad id edit <revision-id> [--title <string>] [--description <string>] [<option>...]
    rad id show <revision-id> [<option>...]
@@ -64,6 +65,7 @@ pub enum Operation {
        allow: BTreeSet<Did>,
        disallow: BTreeSet<Did>,
        payload: Vec<(doc::PayloadId, String, json::Value)>,
+
        edit: bool,
    },
    AcceptRevision {
        revision: Rev,
@@ -146,6 +148,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 +240,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 +282,7 @@ impl Args for Options {
                allow,
                disallow,
                payload,
+
                edit,
            },
        };
        Ok((
@@ -385,6 +392,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();
@@ -460,13 +468,34 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
                        anyhow::bail!("payload `{id}` not found in identity document");
                    }
                }
-
                // Verify that the project payload can still be parsed into the
-
                // `Project` type.
-
                if let Err(e) = proposal.project() {
-
                    anyhow::bail!("failed to verify `xyz.radicle.project`, {e}");
+
                proposal
+
            };
+

+
            // 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}");
+
            }
            let proposal = proposal.verified()?;
            if proposal == current.doc {
                if !options.quiet {