This commit is contained in:
Cyborus 2024-04-17 15:58:45 -04:00
parent 46cd32ebd8
commit c272e9f6da
No known key found for this signature in database
4 changed files with 65 additions and 31 deletions

View file

@ -100,7 +100,9 @@ impl IssueCommand {
use IssueSubcommand::*; use IssueSubcommand::*;
let repo = RepoInfo::get_current(host_name, self.repo.as_deref(), self.remote.as_deref())?; let repo = RepoInfo::get_current(host_name, self.repo.as_deref(), self.remote.as_deref())?;
let api = keys.get_api(repo.host_url())?; let api = keys.get_api(repo.host_url())?;
let repo = repo.name().ok_or_eyre("couldn't get repo name, try specifying with --repo")?; let repo = repo
.name()
.ok_or_eyre("couldn't get repo name, try specifying with --repo")?;
match self.command { match self.command {
Create { title, body } => create_issue(&repo, &api, title, body).await?, Create { title, body } => create_issue(&repo, &api, title, body).await?,
View { id, command } => match command.unwrap_or(ViewCommand::Body) { View { id, command } => match command.unwrap_or(ViewCommand::Body) {

View file

@ -43,7 +43,10 @@ async fn main() -> eyre::Result<()> {
Command::Repo(subcommand) => subcommand.run(&keys, host_name).await?, Command::Repo(subcommand) => subcommand.run(&keys, host_name).await?,
Command::Issue(subcommand) => subcommand.run(&keys, host_name).await?, Command::Issue(subcommand) => subcommand.run(&keys, host_name).await?,
Command::User { remote } => { Command::User { remote } => {
let url = repo::RepoInfo::get_current(host_name, None, remote.as_deref()).wrap_err("could not find host, try specifying with --host")?.host_url().clone(); let url = repo::RepoInfo::get_current(host_name, None, remote.as_deref())
.wrap_err("could not find host, try specifying with --host")?
.host_url()
.clone();
let name = keys.get_login(&url)?.username(); let name = keys.get_login(&url)?.username();
eprintln!("currently signed in to {name}@{url}"); eprintln!("currently signed in to {name}@{url}");
} }

View file

@ -1,4 +1,4 @@
use clap::{Subcommand, Args}; use clap::{Args, Subcommand};
use eyre::{bail, eyre, OptionExt}; use eyre::{bail, eyre, OptionExt};
use forgejo_api::{ use forgejo_api::{
structs::{RepoCreateReleaseAttachmentQuery, RepoListReleasesQuery}, structs::{RepoCreateReleaseAttachmentQuery, RepoListReleasesQuery},
@ -6,7 +6,10 @@ use forgejo_api::{
}; };
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use crate::{keys::KeyInfo, repo::{RepoInfo, RepoName}}; use crate::{
keys::KeyInfo,
repo::{RepoInfo, RepoName},
};
#[derive(Args, Clone, Debug)] #[derive(Args, Clone, Debug)]
pub struct ReleaseCommand { pub struct ReleaseCommand {
@ -113,9 +116,12 @@ pub enum AssetCommand {
impl ReleaseCommand { impl ReleaseCommand {
pub async fn run(self, keys: &KeyInfo, remote_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &KeyInfo, remote_name: Option<&str>) -> eyre::Result<()> {
let repo = RepoInfo::get_current(remote_name, self.repo.as_deref(), self.remote.as_deref())?; let repo =
RepoInfo::get_current(remote_name, self.repo.as_deref(), self.remote.as_deref())?;
let api = keys.get_api(&repo.host_url())?; let api = keys.get_api(&repo.host_url())?;
let repo = repo.name().ok_or_eyre("couldn't get repo name, try specifying with --repo")?; let repo = repo
.name()
.ok_or_eyre("couldn't get repo name, try specifying with --repo")?;
match self.command { match self.command {
ReleaseSubcommand::Create { ReleaseSubcommand::Create {
name, name,
@ -140,12 +146,16 @@ impl ReleaseCommand {
draft, draft,
prerelease, prerelease,
} => edit_release(&repo, &api, name, rename, tag, body, draft, prerelease).await?, } => edit_release(&repo, &api, name, rename, tag, body, draft, prerelease).await?,
ReleaseSubcommand::Delete { name, by_tag } => delete_release(&repo, &api, name, by_tag).await?, ReleaseSubcommand::Delete { name, by_tag } => {
delete_release(&repo, &api, name, by_tag).await?
}
ReleaseSubcommand::List { ReleaseSubcommand::List {
include_prerelease, include_prerelease,
include_draft, include_draft,
} => list_releases(&repo, &api, include_prerelease, include_draft).await?, } => list_releases(&repo, &api, include_prerelease, include_draft).await?,
ReleaseSubcommand::View { name, by_tag } => view_release(&repo, &api, name, by_tag).await?, ReleaseSubcommand::View { name, by_tag } => {
view_release(&repo, &api, name, by_tag).await?
}
ReleaseSubcommand::Browse { name } => browse_release(&repo, &api, name).await?, ReleaseSubcommand::Browse { name } => browse_release(&repo, &api, name).await?,
ReleaseSubcommand::Asset(subcommand) => match subcommand { ReleaseSubcommand::Asset(subcommand) => match subcommand {
AssetCommand::Create { AssetCommand::Create {

View file

@ -9,7 +9,11 @@ pub struct RepoInfo {
} }
impl RepoInfo { impl RepoInfo {
pub fn get_current(host: Option<&str>, repo: Option<&str>, remote: Option<&str>) -> eyre::Result<Self> { pub fn get_current(
host: Option<&str>,
repo: Option<&str>,
remote: Option<&str>,
) -> eyre::Result<Self> {
// l = domain/owner/name // l = domain/owner/name
// s = owner/name // s = owner/name
// x = is present // x = is present
@ -56,18 +60,20 @@ impl RepoInfo {
// let repo_url; // let repo_url;
// let remote; // let remote;
// let host; // let host;
// //
// let url = if repo_url { repo_url } // let url = if repo_url { repo_url }
// else if repo_name { host.or(remote) } // else if repo_name { host.or(remote) }
// else { remote.or_host() } // else { remote.or_host() }
// //
// let name = repo_name.or(remote) // let name = repo_name.or(remote)
let mut repo_url: Option<Url> = None; let mut repo_url: Option<Url> = None;
let mut repo_name: Option<RepoName> = None; let mut repo_name: Option<RepoName> = None;
if let Some(repo) = repo { if let Some(repo) = repo {
let (head, name) = repo.rsplit_once("/").ok_or_eyre("repo name must contain owner and name")?; let (head, name) = repo
.rsplit_once("/")
.ok_or_eyre("repo name must contain owner and name")?;
let name = name.strip_suffix(".git").unwrap_or(name); let name = name.strip_suffix(".git").unwrap_or(name);
match head.rsplit_once("/") { match head.rsplit_once("/") {
Some((url, owner)) => { Some((url, owner)) => {
@ -80,20 +86,24 @@ impl RepoInfo {
owner: owner.to_owned(), owner: owner.to_owned(),
name: name.to_owned(), name: name.to_owned(),
}); });
}, }
None => { None => {
repo_name = Some(RepoName { repo_name = Some(RepoName {
owner: head.to_owned(), owner: head.to_owned(),
name: name.to_owned(), name: name.to_owned(),
}); });
}, }
} }
} }
let repo_url = repo_url; let repo_url = repo_url;
let repo_name = repo_name; let repo_name = repo_name;
let host_url = host.and_then(|host| Url::parse(host).ok().or_else(|| Url::parse(&format!("https://{host}/")).ok())); let host_url = host.and_then(|host| {
Url::parse(host)
.ok()
.or_else(|| Url::parse(&format!("https://{host}/")).ok())
});
let (remote_url, remote_repo_name) = { let (remote_url, remote_repo_name) = {
let mut out = (None, None); let mut out = (None, None);
@ -113,17 +123,21 @@ impl RepoInfo {
} }
// if there's a remote whose host url matches the one // if there's a remote whose host url matches the one
// specified with `--host`, use that // specified with `--host`, use that
// //
// This is different than using `--host` itself, since this // This is different than using `--host` itself, since this
// will include the repo name, which `--host` can't do. // will include the repo name, which `--host` can't do.
} else if let Some(host_url) = &host_url { } else if let Some(host_url) = &host_url {
for remote_name in all_remotes.iter() { for remote_name in all_remotes.iter() {
let Some(remote_name) = remote_name else { continue }; let Some(remote_name) = remote_name else {
continue;
};
let remote = local_repo.find_remote(remote_name)?; let remote = local_repo.find_remote(remote_name)?;
if let Some(url) = remote.url() { if let Some(url) = remote.url() {
let (url, _) = url_strip_repo_name(Url::parse(url)?)?; let (url, _) = url_strip_repo_name(Url::parse(url)?)?;
if url.host_str() == host_url.host_str() && url.path() == host_url.path() { if url.host_str() == host_url.host_str()
&& url.path() == host_url.path()
{
tmp2 = Some(remote_name.to_owned()); tmp2 = Some(remote_name.to_owned());
name = tmp2.as_deref(); name = tmp2.as_deref();
} }
@ -138,11 +152,14 @@ impl RepoInfo {
let head = local_repo.head()?; let head = local_repo.head()?;
let branch_name = head.name().ok_or_else(|| eyre!("branch name not UTF-8"))?; let branch_name = head.name().ok_or_else(|| eyre!("branch name not UTF-8"))?;
tmp = local_repo.branch_upstream_remote(branch_name).ok(); tmp = local_repo.branch_upstream_remote(branch_name).ok();
name = tmp.as_ref().map(|remote| { name = tmp
remote .as_ref()
.as_str() .map(|remote| {
.ok_or_else(|| eyre!("remote name not UTF-8")) remote
}).transpose()?; .as_str()
.ok_or_else(|| eyre!("remote name not UTF-8"))
})
.transpose()?;
} }
if let Some(name) = name { if let Some(name) = name {
@ -152,7 +169,6 @@ impl RepoInfo {
let (url, name) = url_strip_repo_name(url)?; let (url, name) = url_strip_repo_name(url)?;
out = (Some(url), Some(name)) out = (Some(url), Some(name))
} }
} }
} else { } else {
@ -176,10 +192,7 @@ impl RepoInfo {
}; };
let info = match (url, name) { let info = match (url, name) {
(Some(url), name) => RepoInfo { (Some(url), name) => RepoInfo { url, name },
url,
name,
},
(None, Some(_)) => eyre::bail!("cannot find repo, no host specified"), (None, Some(_)) => eyre::bail!("cannot find repo, no host specified"),
(None, None) => eyre::bail!("no repo info specified"), (None, None) => eyre::bail!("no repo info specified"),
}; };
@ -327,7 +340,9 @@ impl RepoCommand {
RepoCommand::Info { name, remote } => { RepoCommand::Info { name, remote } => {
let repo = RepoInfo::get_current(host_name, name.as_deref(), remote.as_deref())?; let repo = RepoInfo::get_current(host_name, name.as_deref(), remote.as_deref())?;
let api = keys.get_api(&repo.host_url())?; let api = keys.get_api(&repo.host_url())?;
let repo = repo.name().ok_or_eyre("couldn't get repo name, please specify")?; let repo = repo
.name()
.ok_or_eyre("couldn't get repo name, please specify")?;
let repo = api.repo_get(repo.owner(), repo.name()).await?; let repo = api.repo_get(repo.owner(), repo.name()).await?;
dbg!(repo); dbg!(repo);
@ -335,8 +350,12 @@ impl RepoCommand {
RepoCommand::Browse { name, remote } => { RepoCommand::Browse { name, remote } => {
let repo = RepoInfo::get_current(host_name, name.as_deref(), remote.as_deref())?; let repo = RepoInfo::get_current(host_name, name.as_deref(), remote.as_deref())?;
let mut url = repo.host_url().clone(); let mut url = repo.host_url().clone();
let repo = repo.name().ok_or_eyre("couldn't get repo name, please specify")?; let repo = repo
url.path_segments_mut().map_err(|_| eyre!("url invalid"))?.extend([repo.owner(), repo.name()]); .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())?; open::that(url.as_str())?;
} }