mirror of
https://codeberg.org/Cyborus/forgejo-cli.git
synced 2024-11-27 12:03:49 +01:00
refactor: move repo commands into individual functions
This commit is contained in:
parent
5f2f3ceb95
commit
ed86e74d1b
1 changed files with 268 additions and 230 deletions
214
src/repo.rs
214
src/repo.rs
|
@ -2,7 +2,7 @@ use std::{io::Write, path::PathBuf, str::FromStr};
|
|||
|
||||
use clap::Subcommand;
|
||||
use eyre::{eyre, OptionExt};
|
||||
use forgejo_api::structs::CreateRepoOption;
|
||||
use forgejo_api::{structs::CreateRepoOption, Forgejo};
|
||||
use url::Url;
|
||||
|
||||
use crate::SpecialRender;
|
||||
|
@ -364,6 +364,95 @@ impl RepoCommand {
|
|||
remote,
|
||||
push,
|
||||
} => {
|
||||
let host = RepoInfo::get_current(host_name, None, None)?;
|
||||
let api = keys.get_api(host.host_url()).await?;
|
||||
create_repo(&api, repo, description, private, remote, push).await?;
|
||||
}
|
||||
RepoCommand::Fork { repo, name, remote } => {
|
||||
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
|
||||
}
|
||||
match (repo.host.as_deref(), host_name) {
|
||||
(Some(a), Some(b)) => {
|
||||
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")?;
|
||||
fork_repo(&api, repo, name).await?
|
||||
}
|
||||
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?;
|
||||
let repo = repo
|
||||
.name()
|
||||
.ok_or_eyre("couldn't get repo name, please specify")?;
|
||||
view_repo(&api, &repo).await?
|
||||
}
|
||||
RepoCommand::Clone { repo, path } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
cmd_clone_repo(&api, &name, path).await?;
|
||||
}
|
||||
RepoCommand::Star { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
api.user_current_put_star(name.owner(), name.name()).await?;
|
||||
println!("Starred {}/{}!", name.owner(), name.name());
|
||||
}
|
||||
RepoCommand::Unstar { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
api.user_current_delete_star(name.owner(), name.name())
|
||||
.await?;
|
||||
println!("Removed star from {}/{}", name.owner(), name.name());
|
||||
}
|
||||
RepoCommand::Delete { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
delete_repo(&api, &name).await?;
|
||||
}
|
||||
RepoCommand::Browse { name, remote } => {
|
||||
let repo = RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref())?;
|
||||
let mut url = repo.host_url().clone();
|
||||
let repo = repo
|
||||
.name()
|
||||
.ok_or_eyre("couldn't get repo name, please specify")?;
|
||||
url.path_segments_mut()
|
||||
.map_err(|_| eyre!("url invalid"))?
|
||||
.extend([repo.owner(), repo.name()]);
|
||||
|
||||
open::that(url.as_str())?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_repo(
|
||||
api: &Forgejo,
|
||||
repo: String,
|
||||
description: Option<String>,
|
||||
private: bool,
|
||||
remote: Option<String>,
|
||||
push: bool,
|
||||
) -> eyre::Result<()> {
|
||||
if remote.is_some() || push {
|
||||
let repo = git2::Repository::open(".")?;
|
||||
|
||||
|
@ -372,8 +461,6 @@ impl RepoCommand {
|
|||
eyre::bail!("A remote named \"{upstream}\" already exists");
|
||||
}
|
||||
}
|
||||
let host = RepoInfo::get_current(host_name, None, None)?;
|
||||
let api = keys.get_api(host.host_url()).await?;
|
||||
let repo_spec = CreateRepoOption {
|
||||
auto_init: Some(false),
|
||||
default_branch: Some("main".into()),
|
||||
|
@ -422,34 +509,14 @@ impl RepoCommand {
|
|||
remote.fetch(&[&branch_shorthand], None, None)?;
|
||||
|
||||
let mut current_branch = git2::Branch::wrap(head);
|
||||
current_branch
|
||||
.set_upstream(Some(&format!("{upstream}/{branch_shorthand}")))?;
|
||||
current_branch.set_upstream(Some(&format!("{upstream}/{branch_shorthand}")))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
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")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fork_repo(api: &Forgejo, repo: &RepoName, name: Option<String>) -> eyre::Result<()> {
|
||||
let opt = forgejo_api::structs::CreateForkOption {
|
||||
name,
|
||||
organization: None,
|
||||
|
@ -465,13 +532,11 @@ impl RepoCommand {
|
|||
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?;
|
||||
let repo = repo
|
||||
.name()
|
||||
.ok_or_eyre("couldn't get repo name, please specify")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn view_repo(api: &Forgejo, repo: &RepoName) -> eyre::Result<()> {
|
||||
let repo = api.repo_get(repo.owner(), repo.name()).await?;
|
||||
|
||||
let SpecialRender {
|
||||
|
@ -577,12 +642,15 @@ impl RepoCommand {
|
|||
println!();
|
||||
println!("View online at {html_url}");
|
||||
}
|
||||
}
|
||||
RepoCommand::Clone { repo, path } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn cmd_clone_repo(
|
||||
api: &Forgejo,
|
||||
name: &RepoName,
|
||||
path: Option<std::path::PathBuf>,
|
||||
) -> eyre::Result<()> {
|
||||
let repo_data = api.repo_get(name.owner(), name.name()).await?;
|
||||
let clone_url = repo_data
|
||||
.clone_url
|
||||
|
@ -609,55 +677,8 @@ impl RepoCommand {
|
|||
.ok_or_eyre("parent repo does not have clone url")?;
|
||||
local_repo.remote("upstream", parent_clone_url.as_str())?;
|
||||
}
|
||||
}
|
||||
RepoCommand::Star { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
api.user_current_put_star(name.owner(), name.name()).await?;
|
||||
println!("Starred {}/{}!", name.owner(), name.name());
|
||||
}
|
||||
RepoCommand::Unstar { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
api.user_current_delete_star(name.owner(), name.name())
|
||||
.await?;
|
||||
println!("Removed star from {}/{}", name.owner(), name.name());
|
||||
}
|
||||
RepoCommand::Delete { repo } => {
|
||||
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?;
|
||||
let api = keys.get_api(&repo.host_url()).await?;
|
||||
let name = repo.name().unwrap();
|
||||
print!(
|
||||
"Are you sure you want to delete {}/{}? (y/N) ",
|
||||
name.owner(),
|
||||
name.name()
|
||||
);
|
||||
let user_response = crate::readline("").await?;
|
||||
let yes = matches!(user_response.trim(), "y" | "Y" | "yes" | "Yes");
|
||||
if yes {
|
||||
api.repo_delete(name.owner(), name.name()).await?;
|
||||
println!("Deleted {}/{}", name.owner(), name.name());
|
||||
} else {
|
||||
println!("Did not delete");
|
||||
}
|
||||
}
|
||||
RepoCommand::Browse { name, remote } => {
|
||||
let repo = RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref())?;
|
||||
let mut url = repo.host_url().clone();
|
||||
let repo = repo
|
||||
.name()
|
||||
.ok_or_eyre("couldn't get repo name, please specify")?;
|
||||
url.path_segments_mut()
|
||||
.map_err(|_| eyre!("url invalid"))?
|
||||
.extend([repo.owner(), repo.name()]);
|
||||
|
||||
open::that(url.as_str())?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_repo(
|
||||
|
@ -726,3 +747,20 @@ pub fn clone_repo(
|
|||
println!("Cloned {} into {}", repo_name, path.display());
|
||||
Ok(local_repo)
|
||||
}
|
||||
|
||||
async fn delete_repo(api: &Forgejo, name: &RepoName) -> eyre::Result<()> {
|
||||
print!(
|
||||
"Are you sure you want to delete {}/{}? (y/N) ",
|
||||
name.owner(),
|
||||
name.name()
|
||||
);
|
||||
let user_response = crate::readline("").await?;
|
||||
let yes = matches!(user_response.trim(), "y" | "Y" | "yes" | "Yes");
|
||||
if yes {
|
||||
api.repo_delete(name.owner(), name.name()).await?;
|
||||
println!("Deleted {}/{}", name.owner(), name.name());
|
||||
} else {
|
||||
println!("Did not delete");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue