Mohammed Naser | 5e52f87 | 2025-02-17 16:02:00 -0500 | [diff] [blame] | 1 | use crate::clients::ClientSet; |
| 2 | use crate::RepositoryClient; |
| 3 | use std::error::Error; |
| 4 | use url::Url; |
| 5 | |
| 6 | pub struct Repository<'a> { |
| 7 | pub owner: String, |
| 8 | pub name: String, |
| 9 | client: &'a dyn RepositoryClient, |
| 10 | } |
| 11 | |
| 12 | impl<'a> Repository<'a> { |
| 13 | pub fn from_url(clientset: &'a ClientSet, url: &str) -> Result<Self, Box<dyn Error>> { |
| 14 | let url = url.trim_end_matches(".git"); |
| 15 | let parsed_url = Url::parse(url)?; |
| 16 | let hostname = parsed_url.host_str().ok_or("Invalid repository URL")?; |
| 17 | let parts: Vec<&str> = parsed_url |
| 18 | .path_segments() |
| 19 | .ok_or("Invalid repository URL")? |
| 20 | .collect(); |
| 21 | if parts.len() < 2 { |
| 22 | return Err("Invalid repository URL".into()); |
| 23 | } |
| 24 | |
| 25 | let client: &dyn RepositoryClient = match hostname { |
| 26 | "opendev.org" => &clientset.opendev, |
| 27 | "github.com" => &clientset.github, |
| 28 | _ => return Err("Unsupported repository host".into()), |
| 29 | }; |
| 30 | |
| 31 | Ok(Repository { |
| 32 | owner: parts[parts.len() - 2].to_string(), |
| 33 | name: parts[parts.len() - 1].to_string(), |
| 34 | client, |
| 35 | }) |
| 36 | } |
| 37 | |
| 38 | pub async fn get_latest_commit(&self, branch: &str) -> Result<String, Box<dyn Error>> { |
| 39 | self.client.get_latest_commit(self, branch).await |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | #[cfg(test)] |
| 44 | mod tests { |
| 45 | use super::*; |
| 46 | |
| 47 | #[tokio::test] |
| 48 | async fn test_from_url_for_opendev() { |
| 49 | let clientset = ClientSet::new(); |
| 50 | let repo = |
| 51 | Repository::from_url(&clientset, "https://opendev.org/openstack/nova.git").unwrap(); |
| 52 | |
| 53 | assert_eq!(repo.owner, "openstack"); |
| 54 | assert_eq!(repo.name, "nova"); |
| 55 | } |
| 56 | |
| 57 | #[tokio::test] |
| 58 | async fn test_from_url_for_github() { |
| 59 | let clientset = ClientSet::new(); |
| 60 | let repo = |
| 61 | Repository::from_url(&clientset, "https://github.com/vexxhost/atmosphere.git").unwrap(); |
| 62 | |
| 63 | assert_eq!(repo.owner, "vexxhost"); |
| 64 | assert_eq!(repo.name, "atmosphere"); |
| 65 | } |
| 66 | } |