diff --git a/crates/core/src/config/remote_url.rs b/crates/core/src/config/remote_url.rs index 273e46e..b188566 100644 --- a/crates/core/src/config/remote_url.rs +++ b/crates/core/src/config/remote_url.rs @@ -14,3 +14,13 @@ impl TryFrom for RemoteUrl { Ok(Self(parsed)) } } +impl RemoteUrl { + pub fn matches(&self, other: &Self) -> bool { + tracing::debug!(host = ?self.host, user = ?self.user, fullname = ?self.fullname, token = ?self.token, "a"); + tracing::debug!(host = ?other.host, user = ?other.user, fullname = ?other.fullname, token = ?other.token,"b"); + self.host.eq(&other.host) + && self.user.eq(&other.user) + && self.fullname.eq(&other.fullname) + && self.token.eq(&other.token) + } +} diff --git a/crates/core/src/git/repo_details.rs b/crates/core/src/git/repo_details.rs index 9463d65..ca196c3 100644 --- a/crates/core/src/git/repo_details.rs +++ b/crates/core/src/git/repo_details.rs @@ -81,9 +81,13 @@ impl RepoDetails { let user = self.forge.user(); use secrecy::ExposeSecret; let token = self.forge.token().expose_secret(); + let auth_delim = match token.is_empty() { + true => "", + false => ":", + }; let hostname = self.forge.hostname(); let repo_path = &self.repo_path; - format!("https://{user}:{token}@{hostname}/{repo_path}.git").into() + format!("https://{user}{auth_delim}{token}@{hostname}/{repo_path}.git").into() } #[allow(clippy::result_large_err)] @@ -118,7 +122,7 @@ impl RepoDetails { tracing::debug!("No remote url to assert against"); return Ok(()); }; - if found != expected { + if !found.matches(&expected) { tracing::debug!(?found, ?expected, "urls differ"); match self.gitdir.storage_path_type() { StoragePathType::External => { diff --git a/crates/core/src/git/validation/remotes.rs b/crates/core/src/git/validation/remotes.rs index d8ee487..66f2e2c 100644 --- a/crates/core/src/git/validation/remotes.rs +++ b/crates/core/src/git/validation/remotes.rs @@ -23,13 +23,13 @@ pub fn validate_default_remotes( )); }; info!(config = %remote_url, push = %push_remote, fetch = %fetch_remote, "Check remotes match"); - if remote_url != push_remote { + if !remote_url.matches(&push_remote) { return Err(Error::MismatchDefaultPushRemote { found: push_remote, expected: remote_url, }); } - if remote_url != fetch_remote { + if !remote_url.matches(&fetch_remote) { return Err(Error::MismatchDefaultFetchRemote { found: fetch_remote, expected: remote_url, diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index a944a28..c1b8b4f 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -27,6 +27,8 @@ actix-rt = { workspace = true } [dev-dependencies] # Testing assert2 = { workspace = true } +secrecy = { workspace = true } +test-log = { workspace = true } [lints.clippy] nursery = { level = "warn", priority = -1 } diff --git a/crates/server/src/lib.rs b/crates/server/src/lib.rs index 906833d..a413906 100644 --- a/crates/server/src/lib.rs +++ b/crates/server/src/lib.rs @@ -1,4 +1,7 @@ // +#[cfg(test)] +mod tests; + use actix::prelude::*; use git_next_core::git::RepositoryFactory; diff --git a/crates/server/src/tests.rs b/crates/server/src/tests.rs index 86ea69d..215cc92 100644 --- a/crates/server/src/tests.rs +++ b/crates/server/src/tests.rs @@ -1,13 +1,14 @@ // use assert2::let_assert; -use git::{repository::Direction, validation::remotes::validate_default_remotes}; -use git_next_config::{ - self as config, ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource, - RepoPath, +use git_next_core::{ + self as core, + git::{self, repository::Direction, validation::remotes::validate_default_remotes}, + ApiToken, ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource, RepoPath, + StoragePathType, User, }; -use git_next_git as git; +use secrecy::Secret; -type Result = core::result::Result>; +type Result = std::result::Result>; #[test] fn test_repo_config_load() -> Result<()> { @@ -34,7 +35,7 @@ fn test_repo_config_load() -> Result<()> { #[test] fn gitdir_should_display_as_pathbuf() { //given - let gitdir = GitDir::from("foo/dir"); + let gitdir = GitDir::new("foo/dir".into(), StoragePathType::External); //when let result = format!("{}", gitdir); //then @@ -48,50 +49,59 @@ fn gitdir_should_display_as_pathbuf() { fn repo_details_find_default_push_remote_finds_correct_remote() -> Result<()> { let cli_crate_dir = std::env::current_dir().map_err(git::validation::remotes::Error::Io)?; let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); - let mut repo_details = git::common::repo_details( + let mut repo_details = git::repo_details( 1, git::Generation::default(), - config::common::forge_details(1, ForgeType::MockForge), + core::common::forge_details(1, ForgeType::MockForge), None, - GitDir::new(root), // Server GitDir - should be ignored + GitDir::new(root.to_path_buf(), StoragePathType::External), // Server GitDir - should be ignored ); repo_details.forge = repo_details .forge + .with_user(User::new("git".to_string())) + .with_token(ApiToken::new(Secret::new("".to_string()))) .with_hostname(Hostname::new("git.kemitix.net")); repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string()); - let gitdir = &repo_details.gitdir; - let open_repository = git::repository::real().open(gitdir)?; + let open_repository = git::repository::factory::real().open(&repo_details)?; let_assert!( Some(found_git_remote) = open_repository.find_default_remote(Direction::Push), "Default Push Remote not found" ); - let config_git_remote = repo_details.git_remote(); + let_assert!(Some(config_git_remote) = repo_details.remote_url()); - assert_eq!( - found_git_remote, config_git_remote, + assert!( + found_git_remote.matches(&config_git_remote), "Default Push Remote must match config" ); Ok(()) } -#[test] +#[test_log::test] fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> { let cli_crate_dir = std::env::current_dir().map_err(git::validation::remotes::Error::Io)?; let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); - let mut repo_details = git::common::repo_details( + let mut repo_details = git::repo_details( 1, git::Generation::default(), - config::common::forge_details(1, ForgeType::MockForge), + core::common::forge_details(1, ForgeType::MockForge), None, - GitDir::new(root), // Server GitDir - should be ignored + GitDir::new(root.to_path_buf(), StoragePathType::External), // Server GitDir - should be ignored ) .with_repo_path(RepoPath::new("kemitix/git-next".to_string())); repo_details.forge = repo_details .forge + .with_user(User::new("git".to_string())) + .with_token(ApiToken::new(Secret::new("".to_string()))) .with_hostname(Hostname::new("git.kemitix.net")); - let gitdir = &repo_details.gitdir; - let repository = git::repository::real().open(gitdir)?; + tracing::debug!("opening..."); + let_assert!( + Ok(repository) = git::repository::factory::real().open(&repo_details), + "open repository" + ); + tracing::debug!("open okay"); + tracing::info!(?repository, "FOO"); + tracing::info!(?repo_details, "BAR"); validate_default_remotes(&*repository, &repo_details)?; Ok(()) @@ -103,16 +113,24 @@ fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> { Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validation::remotes::Error::Io) ); let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); - let repo_details = git::common::repo_details( + let mut repo_details = git::repo_details( 1, git::Generation::default(), - config::common::forge_details(1, ForgeType::MockForge), + core::common::forge_details(1, ForgeType::MockForge), None, - GitDir::new(root), // Server GitDir - should be ignored + GitDir::new(root.to_path_buf(), StoragePathType::External), // Server GitDir - should be ignored ) - .with_repo_path(RepoPath::new("hello/world".to_string())); - let gitdir = &repo_details.gitdir; - let repository = git::repository::real().open(gitdir)?; + .with_repo_path(RepoPath::new("kemitix/git-next".to_string())); + repo_details.forge = repo_details + .forge + .with_user(User::new("git".to_string())) + .with_token(ApiToken::new(Secret::new("".to_string()))) + .with_hostname(Hostname::new("git.kemitix.net")); + let repository = git::repository::factory::real().open(&repo_details)?; + let mut repo_details = repo_details.clone(); + repo_details.forge = repo_details + .forge + .with_hostname(Hostname::new("code.kemitix.net")); let_assert!(Err(_) = validate_default_remotes(&*repository, &repo_details)); Ok(())