feat: add aliases to keys file

This commit is contained in:
Cyborus 2024-09-05 13:16:05 -04:00
parent f8650ab284
commit 7121e26215
No known key found for this signature in database
9 changed files with 49 additions and 20 deletions

View file

@ -26,7 +26,7 @@ impl AuthCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
match self { match self {
AuthCommand::Login => { AuthCommand::Login => {
let repo_info = crate::repo::RepoInfo::get_current(host_name, None, None)?; let repo_info = crate::repo::RepoInfo::get_current(host_name, None, None, &keys)?;
let host_url = repo_info.host_url(); let host_url = repo_info.host_url();
let client_info = get_client_info_for(host_url); let client_info = get_client_info_for(host_url);
if let Some((client_id, _)) = client_info { if let Some((client_id, _)) = client_info {
@ -52,7 +52,7 @@ impl AuthCommand {
} }
} }
AuthCommand::AddKey { user, key } => { AuthCommand::AddKey { user, key } => {
let repo_info = crate::repo::RepoInfo::get_current(host_name, None, None)?; let repo_info = crate::repo::RepoInfo::get_current(host_name, None, None, &keys)?;
let host_url = repo_info.host_url(); let host_url = repo_info.host_url();
let key = match key { let key = match key {
Some(key) => key, Some(key) => key,

View file

@ -168,7 +168,7 @@ pub enum ViewCommand {
impl IssueCommand { impl IssueCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
use IssueSubcommand::*; use IssueSubcommand::*;
let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref())?; let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref(), &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let repo = repo.name().ok_or_else(|| self.no_repo_error())?; let repo = repo.name().ok_or_else(|| self.no_repo_error())?;
match self.command { match self.command {

View file

@ -6,6 +6,8 @@ use url::Url;
#[derive(serde::Serialize, serde::Deserialize, Clone, Default)] #[derive(serde::Serialize, serde::Deserialize, Clone, Default)]
pub struct KeyInfo { pub struct KeyInfo {
pub hosts: BTreeMap<String, LoginInfo>, pub hosts: BTreeMap<String, LoginInfo>,
#[serde(default)]
pub aliases: BTreeMap<String, String>,
} }
impl KeyInfo { impl KeyInfo {
@ -54,6 +56,21 @@ impl KeyInfo {
pub async fn get_api(&mut self, url: &Url) -> eyre::Result<forgejo_api::Forgejo> { pub async fn get_api(&mut self, url: &Url) -> eyre::Result<forgejo_api::Forgejo> {
self.get_login(url)?.api_for(url).await.map_err(Into::into) self.get_login(url)?.api_for(url).await.map_err(Into::into)
} }
pub fn deref_alias(&self, url: url::Url) -> url::Url {
match self.aliases.get(crate::host_with_port(&url)) {
Some(replacement) => {
let s = format!(
"{}{}{}",
&url[..url::Position::BeforeHost],
replacement,
&url[url::Position::AfterPort..]
);
url::Url::parse(&s).unwrap()
}
None => url,
}
}
} }
#[derive(serde::Serialize, serde::Deserialize, Clone)] #[derive(serde::Serialize, serde::Deserialize, Clone)]

View file

@ -65,7 +65,7 @@ async fn main() -> eyre::Result<()> {
Command::Pr(subcommand) => subcommand.run(&mut keys, host_name).await?, Command::Pr(subcommand) => subcommand.run(&mut keys, host_name).await?,
Command::Wiki(subcommand) => subcommand.run(&mut keys, host_name).await?, Command::Wiki(subcommand) => subcommand.run(&mut keys, host_name).await?,
Command::WhoAmI { remote } => { Command::WhoAmI { remote } => {
let url = repo::RepoInfo::get_current(host_name, None, remote.as_deref()) let url = repo::RepoInfo::get_current(host_name, None, remote.as_deref(), &keys)
.wrap_err("could not find host, try specifying with --host")? .wrap_err("could not find host, try specifying with --host")?
.host_url() .host_url()
.clone(); .clone();

View file

@ -264,7 +264,7 @@ pub enum ViewCommand {
impl PrCommand { impl PrCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
use PrSubcommand::*; use PrSubcommand::*;
let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref())?; let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref(), &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let repo = repo.name().ok_or_else(|| self.no_repo_error())?; let repo = repo.name().ok_or_else(|| self.no_repo_error())?;
match self.command { match self.command {

View file

@ -126,7 +126,12 @@ pub enum AssetCommand {
impl ReleaseCommand { impl ReleaseCommand {
pub async fn run(self, keys: &mut KeyInfo, remote_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut KeyInfo, remote_name: Option<&str>) -> eyre::Result<()> {
let repo = RepoInfo::get_current(remote_name, self.repo.as_ref(), self.remote.as_deref())?; let repo = RepoInfo::get_current(
remote_name,
self.repo.as_ref(),
self.remote.as_deref(),
&keys,
)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let repo = repo let repo = repo
.name() .name()

View file

@ -17,6 +17,7 @@ impl RepoInfo {
host: Option<&str>, host: Option<&str>,
repo: Option<&RepoArg>, repo: Option<&RepoArg>,
remote: Option<&str>, remote: Option<&str>,
keys: &crate::keys::KeyInfo,
) -> eyre::Result<Self> { ) -> eyre::Result<Self> {
// l = domain/owner/name // l = domain/owner/name
// s = owner/name // s = owner/name
@ -53,6 +54,7 @@ impl RepoInfo {
.ok() .ok()
.filter(|x| !x.cannot_be_a_base()) .filter(|x| !x.cannot_be_a_base())
.or_else(|| Url::parse(&format!("https://{host}/")).ok()) .or_else(|| Url::parse(&format!("https://{host}/")).ok())
.map(|url| keys.deref_alias(url))
} }
repo_name = Some(RepoName { repo_name = Some(RepoName {
owner: repo.owner.clone(), owner: repo.owner.clone(),
@ -68,6 +70,7 @@ impl RepoInfo {
.ok() .ok()
.filter(|x| !x.cannot_be_a_base()) .filter(|x| !x.cannot_be_a_base())
.or_else(|| Url::parse(&format!("https://{host}/")).ok()) .or_else(|| Url::parse(&format!("https://{host}/")).ok())
.map(|url| keys.deref_alias(url))
}); });
let (remote_url, remote_repo_name) = { let (remote_url, remote_repo_name) = {
@ -97,7 +100,7 @@ impl RepoInfo {
if let Some(host_url) = &host_url { if let Some(host_url) = &host_url {
let remote = local_repo.find_remote(remote_name_s)?; let remote = local_repo.find_remote(remote_name_s)?;
let url_s = std::str::from_utf8(remote.url_bytes())?; let url_s = std::str::from_utf8(remote.url_bytes())?;
let url = crate::ssh_url_parse(url_s)?; let url = keys.deref_alias(crate::ssh_url_parse(url_s)?);
if crate::host_with_port(&url) == crate::host_with_port(host_url) { if crate::host_with_port(&url) == crate::host_with_port(host_url) {
name = Some(remote_name_s.to_owned()); name = Some(remote_name_s.to_owned());
@ -123,8 +126,9 @@ impl RepoInfo {
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(crate::ssh_url_parse(url)?)?; let url = keys.deref_alias(crate::ssh_url_parse(url)?);
if crate::host_with_port(&url) == crate::host_with_port(host_url) let (url, _) = url_strip_repo_name(url)?;
if crate::host_with_port(&url) == crate::host_with_port(&url)
&& url.path() == host_url.path() && url.path() == host_url.path()
{ {
name = Some(remote_name.to_owned()); name = Some(remote_name.to_owned());
@ -138,7 +142,7 @@ impl RepoInfo {
if let Some(name) = name { if let Some(name) = name {
if let Ok(remote) = local_repo.find_remote(&name) { if let Ok(remote) = local_repo.find_remote(&name) {
let url_s = std::str::from_utf8(remote.url_bytes())?; let url_s = std::str::from_utf8(remote.url_bytes())?;
let url = crate::ssh_url_parse(url_s)?; let url = keys.deref_alias(crate::ssh_url_parse(url_s)?);
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))
@ -362,7 +366,7 @@ impl RepoCommand {
remote, remote,
push, push,
} => { } => {
let host = RepoInfo::get_current(host_name, None, None)?; let host = RepoInfo::get_current(host_name, None, None, &keys)?;
let api = keys.get_api(host.host_url()).await?; let api = keys.get_api(host.host_url()).await?;
create_repo(&api, repo, description, private, remote, push).await?; create_repo(&api, repo, description, private, remote, push).await?;
} }
@ -381,7 +385,8 @@ impl RepoCommand {
} }
} }
let repo_info = RepoInfo::get_current(host_name, Some(&repo), remote.as_deref())?; let repo_info =
RepoInfo::get_current(host_name, Some(&repo), remote.as_deref(), &keys)?;
let api = keys.get_api(repo_info.host_url()).await?; let api = keys.get_api(repo_info.host_url()).await?;
let repo = repo_info let repo = repo_info
.name() .name()
@ -389,7 +394,8 @@ impl RepoCommand {
fork_repo(&api, repo, name).await? fork_repo(&api, repo, name).await?
} }
RepoCommand::View { name, remote } => { RepoCommand::View { name, remote } => {
let repo = RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref())?; let repo =
RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref(), &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let repo = repo let repo = repo
.name() .name()
@ -397,20 +403,20 @@ impl RepoCommand {
view_repo(&api, repo).await? view_repo(&api, repo).await?
} }
RepoCommand::Clone { repo, path } => { RepoCommand::Clone { repo, path } => {
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?; let repo = RepoInfo::get_current(host_name, Some(&repo), None, &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let name = repo.name().unwrap(); let name = repo.name().unwrap();
cmd_clone_repo(&api, name, path).await?; cmd_clone_repo(&api, name, path).await?;
} }
RepoCommand::Star { repo } => { RepoCommand::Star { repo } => {
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?; let repo = RepoInfo::get_current(host_name, Some(&repo), None, &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let name = repo.name().unwrap(); let name = repo.name().unwrap();
api.user_current_put_star(name.owner(), name.name()).await?; api.user_current_put_star(name.owner(), name.name()).await?;
println!("Starred {}/{}!", name.owner(), name.name()); println!("Starred {}/{}!", name.owner(), name.name());
} }
RepoCommand::Unstar { repo } => { RepoCommand::Unstar { repo } => {
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?; let repo = RepoInfo::get_current(host_name, Some(&repo), None, &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let name = repo.name().unwrap(); let name = repo.name().unwrap();
api.user_current_delete_star(name.owner(), name.name()) api.user_current_delete_star(name.owner(), name.name())
@ -418,13 +424,14 @@ impl RepoCommand {
println!("Removed star from {}/{}", name.owner(), name.name()); println!("Removed star from {}/{}", name.owner(), name.name());
} }
RepoCommand::Delete { repo } => { RepoCommand::Delete { repo } => {
let repo = RepoInfo::get_current(host_name, Some(&repo), None)?; let repo = RepoInfo::get_current(host_name, Some(&repo), None, &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let name = repo.name().unwrap(); let name = repo.name().unwrap();
delete_repo(&api, name).await?; delete_repo(&api, name).await?;
} }
RepoCommand::Browse { name, remote } => { RepoCommand::Browse { name, remote } => {
let repo = RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref())?; let repo =
RepoInfo::get_current(host_name, name.as_ref(), remote.as_deref(), &keys)?;
let mut url = repo.host_url().clone(); let mut url = repo.host_url().clone();
let repo = repo let repo = repo
.name() .name()

View file

@ -173,7 +173,7 @@ pub enum VisbilitySetting {
impl UserCommand { impl UserCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
let repo = RepoInfo::get_current(host_name, None, self.remote.as_deref())?; let repo = RepoInfo::get_current(host_name, None, self.remote.as_deref(), &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
match self.command { match self.command {
UserSubcommand::Search { query, page } => user_search(&api, &query, page).await?, UserSubcommand::Search { query, page } => user_search(&api, &query, page).await?,

View file

@ -45,7 +45,7 @@ impl WikiCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> { pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
use WikiSubcommand::*; use WikiSubcommand::*;
let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref())?; let repo = RepoInfo::get_current(host_name, self.repo(), self.remote.as_deref(), &keys)?;
let api = keys.get_api(repo.host_url()).await?; let api = keys.get_api(repo.host_url()).await?;
let repo = repo let repo = repo
.name() .name()