radicle_cli/commands/clone/
args.rs1use std::path::PathBuf;
2
3use clap::Parser;
4
5use crate::node::SyncSettings;
6use radicle::identity::doc::RepoId;
7use radicle::identity::IdError;
8use radicle::node::policy::Scope;
9use radicle::prelude::*;
10
11use crate::terminal;
12
13const ABOUT: &str = "Clone a Radicle repository";
14
15const LONG_ABOUT: &str = r#"
16The `clone` command will use your local node's routing table to find seeds from
17which it can clone the repository.
18
19For private repositories, use the `--seed` options, to clone directly
20from known seeds in the privacy set."#;
21
22fn parse_rid(value: &str) -> Result<RepoId, IdError> {
24 value.strip_prefix("rad://").unwrap_or(value).parse()
25}
26
27#[derive(Debug, Parser)]
28pub(super) struct SyncArgs {
29 #[arg(short, long = "seed", value_name = "NID", action = clap::ArgAction::Append)]
31 seeds: Vec<NodeId>,
32
33 #[arg(long, value_parser = humantime::parse_duration, default_value = "9s")]
37 timeout: std::time::Duration,
38}
39
40impl From<SyncArgs> for SyncSettings {
41 fn from(args: SyncArgs) -> Self {
42 SyncSettings {
43 timeout: args.timeout,
44 seeds: args.seeds.into_iter().collect(),
45 ..SyncSettings::default()
46 }
47 }
48}
49
50#[derive(Debug, Parser)]
51#[clap(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
52pub struct Args {
53 #[arg(value_name = "RID", value_parser = parse_rid)]
57 pub(super) repo: RepoId,
58
59 #[arg(value_name = "PATH")]
61 pub(super) directory: Option<PathBuf>,
62
63 #[arg(
65 long,
66 value_parser = terminal::args::ScopeParser
67 )]
68 pub(super) scope: Option<Scope>,
69
70 #[clap(flatten)]
71 pub(super) sync: SyncArgs,
72
73 #[arg(long)]
75 pub(super) bare: bool,
76
77 #[arg(long, hide = true)]
80 pub(super) no_confirm: bool,
81}
82
83#[cfg(test)]
84mod test {
85 use super::Args;
86 use clap::Parser;
87
88 #[test]
89 fn should_parse_rid_non_urn() {
90 let args = Args::try_parse_from(["clone", "z3Tr6bC7ctEg2EHmLvknUr29mEDLH"]);
91 assert!(args.is_ok())
92 }
93
94 #[test]
95 fn should_parse_rid_urn() {
96 let args = Args::try_parse_from(["clone", "rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH"]);
97 assert!(args.is_ok())
98 }
99
100 #[test]
101 fn should_parse_rid_url() {
102 let args = Args::try_parse_from(["clone", "rad://z3Tr6bC7ctEg2EHmLvknUr29mEDLH"]);
103 assert!(args.is_ok())
104 }
105}