radicle_cli/commands/seed/
args.rs1use std::time;
2
3use clap::Parser;
4
5use nonempty::NonEmpty;
6use radicle::node::policy::Scope;
7use radicle::prelude::*;
8
9use crate::node::SyncSettings;
10use crate::terminal;
11
12const ABOUT: &str = "Manage repository seeding policies";
13
14const LONG_ABOUT: &str = r#"
15The `seed` command, when no Repository ID is provided, will list the
16repositories being seeded.
17
18When a Repository ID is provided it updates or creates the seeding policy for
19that repository. To delete a seeding policy, use the `rad unseed` command.
20
21When seeding a repository, a scope can be specified: this can be either `all` or
22`followed`. When using `all`, all remote nodes will be followed for that repository.
23On the other hand, with `followed`, only the repository delegates will be followed,
24plus any remote that is explicitly followed via `rad follow <nid>`.
25"#;
26
27#[derive(Parser, Debug)]
28#[command(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
29pub struct Args {
30 #[arg(value_name = "RID", num_args = 1..)]
31 pub(super) rids: Option<Vec<RepoId>>,
32
33 #[arg(long, overrides_with("no_fetch"), hide(true))]
35 fetch: bool,
36
37 #[arg(long, overrides_with("fetch"))]
39 no_fetch: bool,
40
41 #[arg(long, value_name = "NID", action = clap::ArgAction::Append)]
43 pub(super) from: Vec<NodeId>,
44
45 #[arg(long, short, value_name = "SECS", default_value_t = 9)]
47 timeout: u64,
48
49 #[arg(
51 long,
52 default_value_t = Scope::Followed,
53 value_parser = terminal::args::ScopeParser
54 )]
55 pub(super) scope: Scope,
56
57 #[arg(long, short)]
59 pub(super) verbose: bool,
60}
61
62pub(super) enum Operation {
63 List,
64 Seed {
65 rids: NonEmpty<RepoId>,
66 should_fetch: bool,
67 settings: SyncSettings,
68 scope: Scope,
69 },
70}
71
72impl From<Args> for Operation {
73 fn from(args: Args) -> Self {
74 let should_fetch = args.should_fetch();
75 let timeout = args.timeout();
76 let Args {
77 rids, from, scope, ..
78 } = args;
79 match rids.and_then(NonEmpty::from_vec) {
80 Some(rids) => Operation::Seed {
81 rids,
82 should_fetch,
83 settings: SyncSettings::default().seeds(from).timeout(timeout),
84 scope,
85 },
86 None => Self::List,
87 }
88 }
89}
90
91impl Args {
92 fn timeout(&self) -> time::Duration {
93 time::Duration::from_secs(self.timeout)
94 }
95
96 fn should_fetch(&self) -> bool {
97 match (self.fetch, self.no_fetch) {
98 (true, false) => true,
99 (false, true) => false,
100 (_, _) => true,
102 }
103 }
104}