Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: interactive `rad publish`
◌ CI pending Fintan Halpenny committed 2 months ago
commit 9bd46869e60913e5aa38bfa7c90f78797c63769d
parent 423cf604e1178d62c6952f866b4b5d0b9667aca8
1 pending (1 total) View logs
2 files changed +54 -19
modified crates/radicle-cli/src/commands/publish.rs
@@ -6,6 +6,7 @@ use radicle::cob;
use radicle::identity::{Identity, Visibility};
use radicle::node::Handle as _;
use radicle::storage::{SignRepository, ValidateRepository, WriteRepository, WriteStorage};
+
use radicle_term::PREFIX_WARNING;

use crate::terminal as term;

@@ -44,29 +45,43 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
    let signer = profile.signer()?;

    // Update identity document.
-
    let doc = doc.clone().with_edits(|doc| {
+
    let proposal = doc.clone().with_edits(|doc| {
        doc.visibility = Visibility::Public;
    })?;

-
    // SAFETY: the `Title` here is guaranteed to be nonempty and does not
-
    // contain `\n` or `\r`.
-
    #[allow(clippy::unwrap_used)]
-
    identity.update(
-
        cob::Title::new("Publish repository").unwrap(),
-
        "",
-
        &doc,
-
        &signer,
-
    )?;
-
    repo.sign_refs(&signer)?;
-
    repo.set_identity_head()?;
-
    let validations = repo.validate()?;
+
    let confirmation = format!(
+
        r#"
+
{PREFIX_WARNING} {rid} is about to be made public which makes it available to the Radicle network.
+
{PREFIX_WARNING} Are you sure you want to make {rid} public?"#
+
    );
+
    if args.interactive().confirm(confirmation) {
+
        // SAFETY: the `Title` here is guaranteed to be nonempty and does not
+
        // contain `\n` or `\r`.
+
        #[allow(clippy::unwrap_used)]
+
        identity.update(
+
            cob::Title::new("Publish repository").unwrap(),
+
            "",
+
            &proposal,
+
            &signer,
+
        )?;
+
        repo.sign_refs(&signer)?;
+
        repo.set_identity_head()?;
+
        let validations = repo.validate()?;

-
    if !validations.is_empty() {
-
        for err in validations {
-
            term::error(format!("validation error: {err}"));
+
        if !validations.is_empty() {
+
            for err in validations {
+
                term::error(format!("validation error: {err}"));
+
            }
+
            anyhow::bail!("fatal: repository storage is corrupt");
        }
-
        anyhow::bail!("fatal: repository storage is corrupt");
+
    } else {
+
        term::success!(
+
            "Repository will remain {}",
+
            term::format::visibility(doc.visibility())
+
        );
+
        return Ok(());
    }
+

    let mut node = radicle::Node::new(profile.socket());
    let spinner = term::spinner("Updating inventory..");

@@ -76,7 +91,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {

    term::success!(
        "Repository is now {}",
-
        term::format::visibility(doc.visibility())
+
        term::format::visibility(proposal.visibility())
    );

    if !node.is_running() {
modified crates/radicle-cli/src/commands/publish/args.rs
@@ -1,4 +1,9 @@
+
use std::io;
+

+
use clap::Parser;
+

use radicle::identity::RepoId;
+
use radicle_term::Interactive;

const ABOUT: &str = "Publish a repository to the network";

@@ -14,7 +19,7 @@ single delegate. The delegate must be the currently authenticated
user. For repositories with more than one delegate, the `rad id`
command must be used."#;

-
#[derive(Debug, clap::Parser)]
+
#[derive(Debug, Parser)]
#[command(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
pub struct Args {
    /// The Repository ID of the repository to publish
@@ -22,6 +27,21 @@ pub struct Args {
    /// [example values: rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH, z3Tr6bC7ctEg2EHmLvknUr29mEDLH]
    #[arg(value_name = "RID")]
    pub(super) rid: Option<RepoId>,
+

+
    /// Do not ask for confirmation to publish the repository.
+
    #[arg(long)]
+
    #[arg(global = true)]
+
    no_confirm: bool,
+
}
+

+
impl Args {
+
    pub(super) fn interactive(&self) -> Interactive {
+
        if self.no_confirm {
+
            Interactive::No
+
        } else {
+
            Interactive::new(io::stdout())
+
        }
+
    }
}

#[cfg(test)]