radicle_cli/commands/
unblock.rs1use std::ffi::OsString;
2
3use radicle::prelude::{NodeId, RepoId};
4
5use crate::terminal as term;
6use crate::terminal::args;
7use crate::terminal::args::{Args, Error, Help};
8
9pub const HELP: Help = Help {
10 name: "unblock",
11 description: "Unblock repositories or nodes to allow them to be seeded or followed",
12 version: env!("RADICLE_VERSION"),
13 usage: r#"
14Usage
15
16 rad unblock <rid> [<option>...]
17 rad unblock <nid> [<option>...]
18
19 Unblock a repository or remote to allow it to be seeded or followed.
20
21Options
22
23 --help Print help
24"#,
25};
26
27enum Target {
28 Node(NodeId),
29 Repo(RepoId),
30}
31
32impl std::fmt::Display for Target {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 match self {
35 Self::Node(nid) => nid.fmt(f),
36 Self::Repo(rid) => rid.fmt(f),
37 }
38 }
39}
40
41pub struct Options {
42 target: Target,
43}
44
45impl Args for Options {
46 fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
47 use lexopt::prelude::*;
48
49 let mut parser = lexopt::Parser::from_args(args);
50 let mut target = None;
51
52 while let Some(arg) = parser.next()? {
53 match arg {
54 Long("help") | Short('h') => {
55 return Err(Error::Help.into());
56 }
57 Value(val) if target.is_none() => {
58 if let Ok(rid) = args::rid(&val) {
59 target = Some(Target::Repo(rid));
60 } else if let Ok(nid) = args::nid(&val) {
61 target = Some(Target::Node(nid));
62 } else {
63 anyhow::bail!(
64 "invalid repository or remote specified, see `rad unblock --help`"
65 )
66 }
67 }
68 _ => anyhow::bail!(arg.unexpected()),
69 }
70 }
71
72 Ok((
73 Options {
74 target: target.ok_or(anyhow::anyhow!(
75 "a repository or remote to unblock must be specified, see `rad unblock --help`"
76 ))?,
77 },
78 vec![],
79 ))
80 }
81}
82
83pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
84 let profile = ctx.profile()?;
85 let mut policies = profile.policies_mut()?;
86
87 let updated = match options.target {
88 Target::Node(nid) => policies.unblock_nid(&nid)?,
89 Target::Repo(rid) => policies.unblock_rid(&rid)?,
90 };
91
92 if updated {
93 term::success!("The 'block' policy for {} is removed", options.target);
94 } else {
95 term::info!("No 'block' policy exists for {}", options.target)
96 }
97 Ok(())
98}