summaryrefslogtreecommitdiffstats
path: root/src/repo.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/repo.rs')
-rw-r--r--src/repo.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/repo.rs b/src/repo.rs
index 59cf8fb..0e12f01 100644
--- a/src/repo.rs
+++ b/src/repo.rs
@@ -298,6 +298,13 @@ pub enum RepoCommand {
#[clap(long, short)]
push: bool,
},
+ Fork {
+ repo: RepoArg,
+ #[clap(long)]
+ name: Option<String>,
+ #[clap(long, short = 'R')]
+ remote: Option<String>,
+ },
View {
name: Option<RepoArg>,
#[clap(long, short = 'R')]
@@ -394,6 +401,45 @@ impl RepoCommand {
}
}
}
+ RepoCommand::Fork { repo, name, remote } => {
+ match (repo.host.as_deref(), host_name) {
+ (Some(a), Some(b)) => {
+ fn strip(s: &str) -> &str {
+ let no_scheme = s
+ .strip_prefix("https://")
+ .or_else(|| s.strip_prefix("http://"))
+ .unwrap_or(s);
+ let no_trailing_slash =
+ no_scheme.strip_suffix("/").unwrap_or(no_scheme);
+ no_trailing_slash
+ }
+ if strip(a) != strip(b) {
+ eyre::bail!("conflicting hosts {a} and {b}. please only specify one");
+ }
+ }
+ _ => (),
+ }
+ let repo_info = RepoInfo::get_current(host_name, Some(&repo), remote.as_deref())?;
+ let api = keys.get_api(&repo_info.host_url()).await?;
+ let repo = repo_info
+ .name()
+ .ok_or_eyre("couldn't get repo name, please specify")?;
+ let opt = forgejo_api::structs::CreateForkOption {
+ name,
+ organization: None,
+ };
+ let new_fork = api.create_fork(repo.owner(), repo.name(), opt).await?;
+ let fork_full_name = new_fork
+ .full_name
+ .as_deref()
+ .ok_or_eyre("fork does not have name")?;
+ println!(
+ "Forked {}/{} into {}",
+ repo.owner(),
+ repo.name(),
+ fork_full_name
+ );
+ }
RepoCommand::View { name, remote } => {
let repo = RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref())?;
let api = keys.get_api(&repo.host_url()).await?;