summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyborus <cyborus@cyborus.xyz>2023-11-17 20:50:08 +0100
committerCyborus <cyborus@cyborus.xyz>2023-11-17 20:50:08 +0100
commit51b180d4a9dc59901cdd74a2729285b506c4e013 (patch)
treeeca3666f2cfbedc8c887d69feb22ffc290c241ce
parentfmt (diff)
downloadforgejo-cli-51b180d4a9dc59901cdd74a2729285b506c4e013.tar.xz
forgejo-cli-51b180d4a9dc59901cdd74a2729285b506c4e013.zip
decouple repo info from key info
-rw-r--r--src/keys.rs94
-rw-r--r--src/main.rs9
-rw-r--r--src/repo.rs64
3 files changed, 67 insertions, 100 deletions
diff --git a/src/keys.rs b/src/keys.rs
index a0be833..aca310b 100644
--- a/src/keys.rs
+++ b/src/keys.rs
@@ -42,35 +42,6 @@ impl KeyInfo {
Ok(())
}
- pub fn get_current(&self) -> eyre::Result<(HostInfo<'_>, RepoInfo)> {
- let repo = git2::Repository::open(".")?;
- let remote_url = get_remote(&repo)?;
- let login_info = self.get_login(&remote_url)?;
-
- let mut path = remote_url
- .path_segments()
- .ok_or_else(|| eyre!("bad path"))?
- .collect::<Vec<_>>();
- let repo_name = path
- .pop()
- .ok_or_else(|| eyre!("path does not have repo name"))?
- .to_string();
- let owner = path
- .pop()
- .ok_or_else(|| eyre!("path does not have owner name"))?
- .to_string();
- let base_path = path.join("/");
-
- let mut url = remote_url;
- url.set_path(&base_path);
- let host_info = HostInfo { url, login_info };
- let repo_info = RepoInfo {
- owner,
- name: repo_name,
- };
- Ok((host_info, repo_info))
- }
-
pub fn get_login(&self, url: &Url) -> eyre::Result<&LoginInfo> {
let host_str = url
.host_str()
@@ -87,61 +58,12 @@ impl KeyInfo {
.ok_or_else(|| eyre!("not signed in to {domain}"))?;
Ok(login_info)
}
-}
-pub struct HostInfo<'a> {
- url: Url,
- login_info: &'a LoginInfo,
-}
-
-impl<'a> HostInfo<'a> {
- pub fn api(&self) -> Result<forgejo_api::Forgejo, forgejo_api::ForgejoError> {
- self.login_info.api_for(self.url())
- }
-
- pub fn url(&self) -> &Url {
- &self.url
- }
-
- pub fn username(&self) -> &'a str {
- &self.login_info.name
+ pub fn get_api(&self, url: &Url) -> eyre::Result<forgejo_api::Forgejo> {
+ self.get_login(url)?.api_for(url).map_err(Into::into)
}
}
-pub struct RepoInfo {
- owner: String,
- name: String,
-}
-
-impl RepoInfo {
- pub fn owner(&self) -> &str {
- &self.owner
- }
-
- pub fn name(&self) -> &str {
- &self.name
- }
-}
-
-fn repo_from_url(url: &Url) -> eyre::Result<&str> {
- let mut iter = url
- .path_segments()
- .ok_or_else(|| eyre!("failed to get path from url"))?;
- soft_assert::soft_assert!(
- matches!(iter.next(), Some(_)),
- Err(eyre!("path should have 2 segments, has none"))
- );
- let repo = iter
- .next()
- .ok_or_else(|| eyre!("path should have 2 segments, has only 1"))?;
- let repo = repo.strip_suffix(".git").unwrap_or(repo);
- soft_assert::soft_assert!(
- matches!(iter.next(), None),
- Err(eyre!("path should have 2 segments, has more"))
- );
- Ok(repo)
-}
-
#[derive(serde::Serialize, serde::Deserialize, Clone, Default)]
pub struct LoginInfo {
name: String,
@@ -161,15 +83,3 @@ impl LoginInfo {
forgejo_api::Forgejo::new(&self.key, url.clone())
}
}
-
-fn get_remote(repo: &git2::Repository) -> eyre::Result<Url> {
- let head = repo.head()?;
- let branch_name = head.name().ok_or_else(|| eyre!("branch name not UTF-8"))?;
- let remote_name = repo.branch_upstream_remote(branch_name)?;
- let remote_name = remote_name
- .as_str()
- .ok_or_else(|| eyre!("remote name not UTF-8"))?;
- let remote = repo.find_remote(remote_name)?;
- let url = Url::parse(std::str::from_utf8(remote.url_bytes())?)?;
- Ok(url)
-}
diff --git a/src/main.rs b/src/main.rs
index e53b7d1..5008a92 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -39,13 +39,13 @@ async fn main() -> eyre::Result<()> {
Command::Repo(repo_subcommand) => repo_subcommand.run(&keys).await?,
Command::User { host } => {
let host = host.map(|host| Url::parse(&host)).transpose()?;
- let (url, name) = match host {
- Some(url) => (keys.get_login(&url)?.username(), url),
+ let url = match host {
+ Some(url) => url,
None => {
- let (host, _) = keys.get_current()?;
- (host.username(), host.url().clone())
+ repo::RepoInfo::get_current()?.url().clone()
}
};
+ let name = keys.get_login(&url)?.username();
eprintln!("currently signed in to {name}@{url}");
}
Command::Auth(auth_subcommand) => auth_subcommand.run(&mut keys).await?,
@@ -65,3 +65,4 @@ async fn readline(msg: &str) -> eyre::Result<String> {
})
.await?
}
+
diff --git a/src/repo.rs b/src/repo.rs
index f82ee97..9d5fc7a 100644
--- a/src/repo.rs
+++ b/src/repo.rs
@@ -1,6 +1,62 @@
use clap::Subcommand;
use forgejo_api::CreateRepoOption;
use url::Url;
+use eyre::eyre;
+
+pub struct RepoInfo {
+ owner: String,
+ name: String,
+ url: Url,
+}
+
+impl RepoInfo {
+ pub fn get_current() -> eyre::Result<Self> {
+ let repo = git2::Repository::open(".")?;
+ let url = get_remote(&repo)?;
+
+ let mut path = url
+ .path_segments()
+ .ok_or_else(|| eyre!("bad path"))?;
+ let owner = path
+ .next()
+ .ok_or_else(|| eyre!("path does not have owner name"))?
+ .to_string();
+ let name = path
+ .next()
+ .ok_or_else(|| eyre!("path does not have repo name"))?
+ .to_string();
+
+ let repo_info = RepoInfo {
+ owner,
+ name,
+ url,
+ };
+ Ok(repo_info)
+ }
+ pub fn owner(&self) -> &str {
+ &self.owner
+ }
+
+ pub fn name(&self) -> &str {
+ &self.name
+ }
+
+ pub fn url(&self) -> &Url {
+ &self.url
+ }
+}
+
+fn get_remote(repo: &git2::Repository) -> eyre::Result<Url> {
+ let head = repo.head()?;
+ let branch_name = head.name().ok_or_else(|| eyre!("branch name not UTF-8"))?;
+ let remote_name = repo.branch_upstream_remote(branch_name)?;
+ let remote_name = remote_name
+ .as_str()
+ .ok_or_else(|| eyre!("remote name not UTF-8"))?;
+ let remote = repo.find_remote(remote_name)?;
+ let url = Url::parse(std::str::from_utf8(remote.url_bytes())?)?;
+ Ok(url)
+}
#[derive(Subcommand, Clone, Debug)]
pub enum RepoCommand {
@@ -73,8 +129,8 @@ impl RepoCommand {
}
}
RepoCommand::Info => {
- let (host, repo) = keys.get_current()?;
- let api = host.api()?;
+ let repo = RepoInfo::get_current()?;
+ let api = keys.get_api(repo.url())?;
let repo = api.get_repo(repo.owner(), repo.name()).await?;
match repo {
Some(repo) => {
@@ -84,8 +140,8 @@ impl RepoCommand {
}
}
RepoCommand::Browse => {
- let (host, repo) = keys.get_current()?;
- let mut url = host.url().clone();
+ let repo = RepoInfo::get_current()?;
+ let mut url = repo.url().clone();
let new_path = format!(
"{}/{}/{}",
url.path().strip_suffix("/").unwrap_or(url.path()),