blob: 2f1a2747f59f882210b6f3486372ab34f10f1f00 [file] [log] [blame]
Mohammed Naser5e52f872025-02-17 16:02:00 -05001use crate::clients::ClientSet;
2use crate::RepositoryClient;
3use std::error::Error;
4use url::Url;
5
6pub struct Repository<'a> {
7 pub owner: String,
8 pub name: String,
9 client: &'a dyn RepositoryClient,
10}
11
12impl<'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)]
44mod 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}