Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add `rad-edit` command
xphoniex committed 3 years ago
commit 72ec0775c7fab75a5fe8d634e20ae11a73b5d309
parent 4feb224b1aa2ca4ebd07ba45e900a407f0404e1f
4 files changed +110 -0
modified radicle-cli/src/commands.rs
@@ -4,6 +4,8 @@ pub mod rad_auth;
pub mod rad_checkout;
#[path = "commands/clone.rs"]
pub mod rad_clone;
+
#[path = "commands/edit.rs"]
+
pub mod rad_edit;
#[path = "commands/help.rs"]
pub mod rad_help;
#[path = "commands/init.rs"]
added radicle-cli/src/commands/edit.rs
@@ -0,0 +1,99 @@
+
use std::ffi::OsString;
+
use std::str::FromStr;
+

+
use anyhow::{anyhow, Context as _};
+

+
use radicle::identity::Id;
+
use radicle::storage::{ReadStorage, WriteStorage};
+

+
use crate::terminal as term;
+
use crate::terminal::args::{Args, Error, Help};
+

+
pub const HELP: Help = Help {
+
    name: "edit",
+
    description: "Edit a radicle identity doc",
+
    version: env!("CARGO_PKG_VERSION"),
+
    usage: r#"
+
Usage
+

+
    rad edit [<id>] [<option>...]
+

+
    Edits the identity document pointed to by the ID. If it isn't specified,
+
    the current project is edited.
+

+
Options
+

+
    --help              Print help
+
"#,
+
};
+

+
#[derive(Default, Debug, Eq, PartialEq)]
+
pub struct Options {
+
    pub id: Option<Id>,
+
}
+

+
impl Args for Options {
+
    fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
+
        use lexopt::prelude::*;
+

+
        let mut parser = lexopt::Parser::from_args(args);
+
        let mut id: Option<Id> = None;
+

+
        while let Some(arg) = parser.next()? {
+
            match arg {
+
                Long("help") => {
+
                    return Err(Error::Help.into());
+
                }
+
                Value(val) if id.is_none() => {
+
                    let val = val.to_string_lossy();
+

+
                    if let Ok(val) = Id::from_str(&val) {
+
                        id = Some(val);
+
                    } else {
+
                        return Err(anyhow!("invalid ID '{}'", val));
+
                    }
+
                }
+
                _ => return Err(anyhow::anyhow!(arg.unexpected())),
+
            }
+
        }
+

+
        Ok((Options { id }, vec![]))
+
    }
+
}
+

+
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
+
    let profile = ctx.profile()?;
+
    let signer = term::signer(&profile)?;
+
    let storage = &profile.storage;
+

+
    let id = options
+
        .id
+
        .or_else(|| radicle::rad::cwd().ok().map(|(_, id)| id))
+
        .context("Couldn't get ID from either command line or cwd")?;
+

+
    let mut project = storage
+
        .get(signer.public_key(), id)?
+
        .context("No project with such ID exists")?;
+

+
    let repo = storage.repository(id)?;
+

+
    let payload = serde_json::to_string_pretty(&project.payload)?;
+
    match term::Editor::new().edit(&payload)? {
+
        Some(updated_payload) => {
+
            project.payload = serde_json::from_str(&updated_payload)?;
+
            project.sign(&signer).and_then(|(_, sig)| {
+
                project.update(
+
                    signer.public_key(),
+
                    "Updated payload",
+
                    &[(signer.public_key(), sig)],
+
                    &repo,
+
                )
+
            })?;
+
        }
+
        None => return Err(anyhow!("Operation aborted!")),
+
    }
+

+
    term::success!("Update successful!");
+

+
    Ok(())
+
}
modified radicle-cli/src/commands/help.rs
@@ -20,6 +20,7 @@ const COMMANDS: &[Help] = &[
    rad_track::HELP,
    rad_untrack::HELP,
    rad_ls::HELP,
+
    rad_edit::HELP,
    HELP,
];

modified radicle-cli/src/main.rs
@@ -166,6 +166,14 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyhow::Error>>
                args.to_vec(),
            );
        }
+
        "edit" => {
+
            term::run_command_args::<rad_edit::Options, _>(
+
                rad_edit::HELP,
+
                "Edit",
+
                rad_edit::run,
+
                args.to_vec(),
+
            );
+
        }
        _ => {
            let exe = format!("{}-{}", NAME, exe);
            let status = process::Command::new(exe.clone()).args(args).status();