Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
REVIEW: move args to module
✗ CI failure Erik Kundt committed 7 months ago
commit 838fef8ff2600aada7bdc72d142b790f80214271
parent 96d2e720f8a9780463c25ad70d45609cc363db3b
1 failed 1 pending (2 total) View logs
2 files changed +104 -91
modified crates/radicle-cli/src/commands/clone.rs
@@ -1,14 +1,14 @@
+
pub mod args;
+

use std::path::{Path, PathBuf};
-
use std::time;

-
use clap::Parser;
use radicle::issue::cache::Issues as _;
use radicle::patch::cache::Patches as _;
use thiserror::Error;

use radicle::git::raw;
+
use radicle::identity::doc;
use radicle::identity::doc::RepoId;
-
use radicle::identity::{doc, IdError};
use radicle::node;
use radicle::node::policy::Scope;
use radicle::node::{Handle as _, Node};
@@ -25,94 +25,8 @@ use crate::project;
use crate::terminal as term;
use crate::terminal::Element as _;

-
pub(crate) const ABOUT: &str = "Clone a Radicle repository";
-

-
const LONG_ABOUT: &str = r#"
-
The `clone` command will use your local node's routing table to find seeds from
-
which it can clone the repository.
-

-
For private repositories, use the `--seed` options, to clone directly
-
from known seeds in the privacy set."#;
-

-
/// Parse an RID, optionally stripping "rad://" prefix.
-
fn parse_rid(value: &str) -> Result<RepoId, IdError> {
-
    use std::str::FromStr as _;
-
    RepoId::from_str(value.strip_prefix("rad://").unwrap_or(value))
-
}
-

-
#[derive(Debug, Parser)]
-
pub struct SyncArgs {
-
    /// Clone from this seed (may be specified multiple times).
-
    #[arg(short, long = "seed", value_name = "NID", action = clap::ArgAction::Append)]
-
    pub seeds: Vec<NodeId>,
-

-
    /// Timeout for fetching repository in seconds.
-
    #[arg(long, default_value_t = 9, value_name = "SECS")]
-
    pub timeout: usize,
-
}
-

-
impl From<SyncArgs> for SyncSettings {
-
    fn from(args: SyncArgs) -> Self {
-
        SyncSettings {
-
            timeout: time::Duration::from_secs(args.timeout as u64),
-
            seeds: args.seeds.into_iter().collect(),
-
            ..SyncSettings::default()
-
        }
-
    }
-
}
-

-
#[derive(Clone, Debug)]
-
struct ScopeParser;
-

-
impl clap::builder::TypedValueParser for ScopeParser {
-
    type Value = Scope;
-

-
    fn parse_ref(
-
        &self,
-
        cmd: &clap::Command,
-
        arg: Option<&clap::Arg>,
-
        value: &std::ffi::OsStr,
-
    ) -> Result<Self::Value, clap::Error> {
-
        <Scope as std::str::FromStr>::from_str.parse_ref(cmd, arg, value)
-
    }
-

-
    fn possible_values(
-
        &self,
-
    ) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
-
        use clap::builder::PossibleValue;
-
        Some(Box::new(
-
            [PossibleValue::new("all"), PossibleValue::new("followed")].into_iter(),
-
        ))
-
    }
-
}
-

-
#[derive(Debug, Parser)]
-
#[clap(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
-
pub struct Args {
-
    /// ID of the repository to clone
-
    #[arg(value_name = "RID", value_parser = parse_rid)]
-
    pub(crate) repo: RepoId,
-

-
    /// The target directory for the repository to be cloned into.
-
    #[arg(value_name = "PATH")]
-
    directory: Option<PathBuf>,
-

-
    /// Follow scope
-
    #[arg(long, default_value_t = Scope::All, value_name = "SCOPE", value_parser = ScopeParser)]
-
    scope: Scope,
-

-
    #[clap(flatten)]
-
    sync: SyncArgs,
-

-
    /// Make a bare repository.
-
    #[arg(long)]
-
    bare: bool,
-

-
    // We keep this flag here for consistency though it doesn't have any effect,
-
    // since the command is fully non-interactive.
-
    #[arg(long, hide = true)]
-
    no_confirm: bool,
-
}
+
pub use args::Args;
+
pub(crate) use args::ABOUT;

pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
    let profile = ctx.profile()?;
added crates/radicle-cli/src/commands/clone/args.rs
@@ -0,0 +1,99 @@
+
use std::path::PathBuf;
+
use std::time;
+

+
use clap::Parser;
+

+
use crate::node::SyncSettings;
+
use radicle::identity::doc::RepoId;
+
use radicle::identity::IdError;
+
use radicle::node::policy::Scope;
+
use radicle::prelude::*;
+

+
pub(crate) const ABOUT: &str = "Clone a Radicle repository";
+

+
const LONG_ABOUT: &str = r#"
+
The `clone` command will use your local node's routing table to find seeds from
+
which it can clone the repository.
+

+
For private repositories, use the `--seed` options, to clone directly
+
from known seeds in the privacy set."#;
+

+
/// Parse an RID, optionally stripping "rad://" prefix.
+
fn parse_rid(value: &str) -> Result<RepoId, IdError> {
+
    use std::str::FromStr as _;
+
    RepoId::from_str(value.strip_prefix("rad://").unwrap_or(value))
+
}
+

+
#[derive(Debug, Parser)]
+
pub struct SyncArgs {
+
    /// Clone from this seed (may be specified multiple times).
+
    #[arg(short, long = "seed", value_name = "NID", action = clap::ArgAction::Append)]
+
    pub(crate) seeds: Vec<NodeId>,
+

+
    /// Timeout for fetching repository in seconds.
+
    #[arg(long, default_value_t = 9, value_name = "SECS")]
+
    pub(crate) timeout: usize,
+
}
+

+
impl From<SyncArgs> for SyncSettings {
+
    fn from(args: SyncArgs) -> Self {
+
        SyncSettings {
+
            timeout: time::Duration::from_secs(args.timeout as u64),
+
            seeds: args.seeds.into_iter().collect(),
+
            ..SyncSettings::default()
+
        }
+
    }
+
}
+

+
#[derive(Clone, Debug)]
+
struct ScopeParser;
+

+
impl clap::builder::TypedValueParser for ScopeParser {
+
    type Value = Scope;
+

+
    fn parse_ref(
+
        &self,
+
        cmd: &clap::Command,
+
        arg: Option<&clap::Arg>,
+
        value: &std::ffi::OsStr,
+
    ) -> Result<Self::Value, clap::Error> {
+
        <Scope as std::str::FromStr>::from_str.parse_ref(cmd, arg, value)
+
    }
+

+
    fn possible_values(
+
        &self,
+
    ) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
+
        use clap::builder::PossibleValue;
+
        Some(Box::new(
+
            [PossibleValue::new("all"), PossibleValue::new("followed")].into_iter(),
+
        ))
+
    }
+
}
+

+
#[derive(Debug, Parser)]
+
#[clap(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
+
pub struct Args {
+
    /// ID of the repository to clone
+
    #[arg(value_name = "RID", value_parser = parse_rid)]
+
    pub(crate) repo: RepoId,
+

+
    /// The target directory for the repository to be cloned into.
+
    #[arg(value_name = "PATH")]
+
    pub(crate) directory: Option<PathBuf>,
+

+
    /// Follow scope
+
    #[arg(long, default_value_t = Scope::All, value_name = "SCOPE", value_parser = ScopeParser)]
+
    pub(crate) scope: Scope,
+

+
    #[clap(flatten)]
+
    pub(crate) sync: SyncArgs,
+

+
    /// Make a bare repository.
+
    #[arg(long)]
+
    pub(crate) bare: bool,
+

+
    // We keep this flag here for consistency though it doesn't have any effect,
+
    // since the command is fully non-interactive.
+
    #[arg(long, hide = true)]
+
    pub(crate) no_confirm: bool,
+
}