radicle_cli/commands/
clean.rs1use std::ffi::OsString;
2
3use anyhow::anyhow;
4
5use radicle::identity::RepoId;
6use radicle::storage;
7use radicle::storage::WriteStorage;
8
9use crate::terminal as term;
10use crate::terminal::args::{Args, Error, Help};
11
12pub const HELP: Help = Help {
13 name: "clean",
14 description: "Remove all remotes from a repository",
15 version: env!("RADICLE_VERSION"),
16 usage: r#"
17Usage
18
19 rad clean <rid> [<option>...]
20
21 Removes all remotes from a repository, as long as they are not the
22 local operator or a delegate of the repository.
23
24 Note that remotes will still be fetched as long as they are
25 followed and/or the follow scope is "all".
26
27Options
28
29 --no-confirm Do not ask for confirmation before removal (default: false)
30 --help Print help
31"#,
32};
33
34pub struct Options {
35 rid: RepoId,
36 confirm: bool,
37}
38
39impl Args for Options {
40 fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
41 use lexopt::prelude::*;
42
43 let mut parser = lexopt::Parser::from_args(args);
44 let mut id: Option<RepoId> = None;
45 let mut confirm = true;
46
47 while let Some(arg) = parser.next()? {
48 match arg {
49 Long("no-confirm") => {
50 confirm = false;
51 }
52 Long("help") | Short('h') => {
53 return Err(Error::Help.into());
54 }
55 Value(val) if id.is_none() => {
56 id = Some(term::args::rid(&val)?);
57 }
58 _ => anyhow::bail!(arg.unexpected()),
59 }
60 }
61
62 Ok((
63 Options {
64 rid: id
65 .ok_or_else(|| anyhow!("an RID must be provided; see `rad clean --help`"))?,
66 confirm,
67 },
68 vec![],
69 ))
70 }
71}
72
73pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
74 let profile = ctx.profile()?;
75 let storage = &profile.storage;
76 let rid = options.rid;
77 let path = storage::git::paths::repository(storage, &rid);
78
79 if !path.exists() {
80 anyhow::bail!("repository {rid} was not found");
81 }
82
83 if !options.confirm || term::confirm(format!("Clean {rid}?")) {
84 let cleaned = storage.clean(rid)?;
85 for remote in cleaned {
86 term::info!("Removed {remote}");
87 }
88 term::success!("Successfully cleaned {rid}");
89 }
90
91 Ok(())
92}