diff --git a/src/interactors/bitbucket.rs b/src/interactors/bitbucket.rs deleted file mode 100644 index 4703f71..0000000 --- a/src/interactors/bitbucket.rs +++ /dev/null @@ -1,21 +0,0 @@ -use anyhow::Error; -use hyper::Uri; -use relative_path::RelativePathBuf; - -use crate::models::repo::RepoPath; - -const BITBUCKET_USER_CONTENT_BASE_URI: &'static str = "https://bitbucket.org"; - -pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result { - let path_str: &str = path.as_ref(); - - let url = format!( - "{}/{}/{}/raw/HEAD/{}", - BITBUCKET_USER_CONTENT_BASE_URI, - repo_path.qual.as_ref(), - repo_path.name.as_ref(), - path_str - ); - - Ok(url.parse::()?) -} diff --git a/src/interactors/github.rs b/src/interactors/github.rs index 961f3b6..2c3ea12 100644 --- a/src/interactors/github.rs +++ b/src/interactors/github.rs @@ -8,25 +8,11 @@ use futures::{ use hyper::{ body, header::USER_AGENT, service::Service, Body, Error as HyperError, Request, Response, Uri, }; -use relative_path::RelativePathBuf; use serde::Deserialize; use crate::models::repo::{RepoPath, Repository}; const GITHUB_API_BASE_URI: &'static str = "https://api.github.com"; -const GITHUB_USER_CONTENT_BASE_URI: &'static str = "https://raw.githubusercontent.com"; - -pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result { - let path_str: &str = path.as_ref(); - Ok(format!( - "{}/{}/{}/HEAD/{}", - GITHUB_USER_CONTENT_BASE_URI, - repo_path.qual.as_ref(), - repo_path.name.as_ref(), - path_str - ) - .parse::()?) -} #[derive(Deserialize)] struct GithubSearchResponse { diff --git a/src/interactors/gitlab.rs b/src/interactors/gitlab.rs deleted file mode 100644 index 72f7936..0000000 --- a/src/interactors/gitlab.rs +++ /dev/null @@ -1,26 +0,0 @@ -use anyhow::Error; -use hyper::Uri; -use relative_path::RelativePathBuf; - -use crate::models::repo::RepoPath; - -const GITLAB_USER_CONTENT_BASE_URI: &'static str = "https://gitlab.com"; - -pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result { - let path_str: &str = path.as_ref(); - // gitlab will return a 308 if the Uri ends with, say, `.../raw/HEAD//Cargo.toml`, so make - // sure that last slash isn't doubled - let slash_path = if path_str.starts_with("/") { - &path_str[1..] - } else { - path_str - }; - Ok(format!( - "{}/{}/{}/raw/HEAD/{}", - GITLAB_USER_CONTENT_BASE_URI, - repo_path.qual.as_ref(), - repo_path.name.as_ref(), - slash_path - ) - .parse::()?) -} diff --git a/src/interactors/mod.rs b/src/interactors/mod.rs index efef47e..a2f8eec 100644 --- a/src/interactors/mod.rs +++ b/src/interactors/mod.rs @@ -11,12 +11,10 @@ use hyper::{ }; use relative_path::RelativePathBuf; -use crate::models::repo::{RepoPath, RepoSite}; +use crate::models::repo::RepoPath; -pub mod bitbucket; pub mod crates; pub mod github; -pub mod gitlab; pub mod rustsec; #[derive(Debug, Clone)] @@ -37,12 +35,8 @@ where fn call(&mut self, req: (RepoPath, RelativePathBuf)) -> Self::Future { let (repo_path, path) = req; - let uri = match &repo_path.site { - RepoSite::Github => github::get_manifest_uri(&repo_path, &path), - RepoSite::Gitlab => gitlab::get_manifest_uri(&repo_path, &path), - RepoSite::Bitbucket => bitbucket::get_manifest_uri(&repo_path, &path), - }; + let uri = repo_path.to_usercontent_file_uri(&path); let uri = match uri { Ok(uri) => uri, Err(error) => return Box::pin(err(error)), diff --git a/src/models/repo.rs b/src/models/repo.rs index 6b0adc8..9e980d5 100644 --- a/src/models/repo.rs +++ b/src/models/repo.rs @@ -1,6 +1,8 @@ use std::str::FromStr; use anyhow::{anyhow, ensure, Error}; +use hyper::Uri; +use relative_path::RelativePath; #[derive(Clone, Debug)] pub struct Repository { @@ -23,6 +25,19 @@ impl RepoPath { name: name.parse()?, }) } + + pub fn to_usercontent_file_uri(&self, path: &RelativePath) -> Result { + let url = format!( + "{}/{}/{}/{}/{}", + self.site.to_usercontent_base_uri(), + self.qual.as_ref(), + self.name.as_ref(), + self.site.to_usercontent_repo_suffix(), + path.normalize() + ); + + Ok(url.parse::()?) + } } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] @@ -40,6 +55,21 @@ impl RepoSite { &RepoSite::Bitbucket => "https://bitbucket.org", } } + + pub fn to_usercontent_base_uri(&self) -> &'static str { + match self { + RepoSite::Github => "https://raw.githubusercontent.com", + RepoSite::Gitlab => "https://gitlab.com", + RepoSite::Bitbucket => "https://bitbucket.org", + } + } + + pub fn to_usercontent_repo_suffix(&self) -> &'static str { + match self { + RepoSite::Github => "HEAD", + RepoSite::Gitlab | RepoSite::Bitbucket => "raw/HEAD", + } + } } impl FromStr for RepoSite { @@ -108,3 +138,56 @@ impl AsRef for RepoName { self.0.as_ref() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn correct_raw_url_generation() { + let paths = [ + ("Cargo.toml", "Cargo.toml"), + ("/Cargo.toml", "Cargo.toml"), + ("libs/badge/Cargo.toml", "libs/badge/Cargo.toml"), + ("/libs/badge/Cargo.toml", "libs/badge/Cargo.toml"), + ("src/../libs/badge/Cargo.toml", "libs/badge/Cargo.toml"), + ("/src/../libs/badge/Cargo.toml", "libs/badge/Cargo.toml"), + ]; + + for (input, expected) in &paths { + let repo = RepoPath::from_parts("github", "deps-rs", "deps.rs").unwrap(); + let out = repo + .to_usercontent_file_uri(RelativePath::new(input)) + .unwrap(); + + let exp = format!( + "https://raw.githubusercontent.com/deps-rs/deps.rs/HEAD/{}", + expected + ); + assert_eq!(out.to_string(), exp); + } + + for (input, expected) in &paths { + let repo = RepoPath::from_parts("gitlab", "deps-rs", "deps.rs").unwrap(); + let out = repo + .to_usercontent_file_uri(RelativePath::new(input)) + .unwrap(); + + let exp = format!("https://gitlab.com/deps-rs/deps.rs/raw/HEAD/{}", expected); + assert_eq!(out.to_string(), exp); + } + + for (input, expected) in &paths { + let repo = RepoPath::from_parts("bitbucket", "deps-rs", "deps.rs").unwrap(); + let out = repo + .to_usercontent_file_uri(RelativePath::new(input)) + .unwrap(); + + let exp = format!( + "https://bitbucket.org/deps-rs/deps.rs/raw/HEAD/{}", + expected + ); + assert_eq!(out.to_string(), exp); + } + } +}