/ radicle-cli / src / commands / fork.rs
fork.rs
 1  use std::ffi::OsString;
 2  use std::path::Path;
 3  
 4  use anyhow::Context as _;
 5  
 6  use radicle::prelude::Id;
 7  use radicle::rad;
 8  
 9  use crate::terminal as term;
10  use crate::terminal::args;
11  use crate::terminal::args::{Args, Error, Help};
12  
13  pub const HELP: Help = Help {
14      name: "fork",
15      description: "Create a fork of a project",
16      version: env!("CARGO_PKG_VERSION"),
17      usage: r#"
18  Usage
19  
20      rad fork [<rid>] [<option>...]
21  
22  Options
23  
24      --help          Print help
25  "#,
26  };
27  
28  pub struct Options {
29      rid: Option<Id>,
30  }
31  
32  impl Args for Options {
33      fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
34          use lexopt::prelude::*;
35  
36          let mut parser = lexopt::Parser::from_args(args);
37          let mut rid = None;
38  
39          if let Some(arg) = parser.next()? {
40              match arg {
41                  Long("help") | Short('h') => {
42                      return Err(Error::Help.into());
43                  }
44                  Value(val) if rid.is_none() => {
45                      rid = Some(args::rid(&val)?);
46                  }
47                  _ => return Err(anyhow::anyhow!(arg.unexpected())),
48              }
49          }
50  
51          Ok((Options { rid }, vec![]))
52      }
53  }
54  
55  pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
56      let profile = ctx.profile()?;
57      let signer = profile.signer()?;
58      let storage = &profile.storage;
59  
60      let rid = match options.rid {
61          Some(rid) => rid,
62          None => {
63              let (_, rid) = radicle::rad::repo(Path::new("."))
64                  .context("Current directory is not a radicle project")?;
65  
66              rid
67          }
68      };
69  
70      rad::fork(rid, &signer, &storage)?;
71      term::success!("Forked project {rid} for {}", profile.id());
72  
73      Ok(())
74  }