diff --git a/gix/src/remote/build.rs b/gix/src/remote/build.rs index 45e99fff69e..23d14ef793f 100644 --- a/gix/src/remote/build.rs +++ b/gix/src/remote/build.rs @@ -2,8 +2,47 @@ use crate::{bstr::BStr, remote, Remote}; /// Builder methods impl Remote<'_> { + /// Override the `url` to be used when fetching data from a remote. + /// + /// Note that this URL is typically set during instantiation with [`crate::Repository::remote_at()`]. + pub fn with_url(self, url: Url) -> Result + where + Url: TryInto, + gix_url::parse::Error: From, + { + self.url_inner( + url.try_into().map_err(|err| remote::init::Error::Url(err.into()))?, + true, + ) + } + + /// Set the `url` to be used when fetching data from a remote, without applying rewrite rules in case these could be faulty, + /// eliminating one failure mode. + /// + /// Note that this URL is typically set during instantiation with [`crate::Repository::remote_at_without_url_rewrite()`]. + pub fn with_url_without_url_rewrite(self, url: Url) -> Result + where + Url: TryInto, + gix_url::parse::Error: From, + { + self.url_inner( + url.try_into().map_err(|err| remote::init::Error::Url(err.into()))?, + false, + ) + } + /// Set the `url` to be used when pushing data to a remote. + #[deprecated = "Use `with_push_url()` instead"] pub fn push_url(self, url: Url) -> Result + where + Url: TryInto, + gix_url::parse::Error: From, + { + self.with_push_url(url) + } + + /// Set the `url` to be used when pushing data to a remote. + pub fn with_push_url(self, url: Url) -> Result where Url: TryInto, gix_url::parse::Error: From, @@ -16,7 +55,18 @@ impl Remote<'_> { /// Set the `url` to be used when pushing data to a remote, without applying rewrite rules in case these could be faulty, /// eliminating one failure mode. + #[deprecated = "Use `with_push_url_without_rewrite()` instead"] pub fn push_url_without_url_rewrite(self, url: Url) -> Result + where + Url: TryInto, + gix_url::parse::Error: From, + { + self.with_push_url_without_url_rewrite(url) + } + + /// Set the `url` to be used when pushing data to a remote, without applying rewrite rules in case these could be faulty, + /// eliminating one failure mode. + pub fn with_push_url_without_url_rewrite(self, url: Url) -> Result where Url: TryInto, gix_url::parse::Error: From, @@ -50,6 +100,19 @@ impl Remote<'_> { Ok(self) } + fn url_inner(mut self, url: gix_url::Url, should_rewrite_urls: bool) -> Result { + self.url = url.into(); + + let (fetch_url_alias, _) = if should_rewrite_urls { + remote::init::rewrite_urls(&self.repo.config, self.url.as_ref(), None) + } else { + Ok((None, None)) + }?; + self.url_alias = fetch_url_alias; + + Ok(self) + } + /// Add `specs` as refspecs for `direction` to our list if they are unique, or ignore them otherwise. pub fn with_refspecs( mut self, diff --git a/gix/tests/gix/remote/save.rs b/gix/tests/gix/remote/save.rs index 69206763894..253cb304b87 100644 --- a/gix/tests/gix/remote/save.rs +++ b/gix/tests/gix/remote/save.rs @@ -63,7 +63,7 @@ mod save_as_to { let repo = basic_repo()?; let mut remote = repo .remote_at("https://example.com/path")? - .push_url("https://ein.hub/path")? + .with_push_url("https://ein.hub/path")? .with_fetch_tags(gix::remote::fetch::Tags::All) .with_refspecs( [ diff --git a/gix/tests/gix/repository/remote.rs b/gix/tests/gix/repository/remote.rs index 9c2923dd270..c6f50bf92b8 100644 --- a/gix/tests/gix/repository/remote.rs +++ b/gix/tests/gix/repository/remote.rs @@ -13,13 +13,17 @@ mod remote_at { assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), fetch_url); assert_eq!(remote.url(Direction::Push).unwrap().to_bstring(), fetch_url); - let mut remote = remote.push_url("user@host.xz:./relative")?; + let mut remote = remote.with_push_url("user@host.xz:./relative")?; assert_eq!( remote.url(Direction::Push).unwrap().to_bstring(), "user@host.xz:./relative" ); assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), fetch_url); + let new_fetch_url = "https://host.xz/byron/gitoxide"; + remote = remote.with_url(new_fetch_url)?; + assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), new_fetch_url); + for (spec, direction) in [ ("refs/heads/push", Direction::Push), ("refs/heads/fetch", Direction::Fetch), @@ -57,9 +61,21 @@ mod remote_at { "push is the same as fetch was rewritten" ); + let remote = remote.with_url("https://github.com/foobar/gitoxide")?; + assert_eq!( + remote.url(Direction::Fetch).unwrap().to_bstring(), + rewritten_fetch_url, + "fetch was rewritten" + ); + assert_eq!( + remote.url(Direction::Push).unwrap().to_bstring(), + rewritten_fetch_url, + "push is the same as fetch was rewritten" + ); + let remote = repo .remote_at("https://github.com/foobar/gitoxide".to_owned())? - .push_url("file://dev/null".to_owned())?; + .with_push_url("file://dev/null".to_owned())?; assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), rewritten_fetch_url); assert_eq!( remote.url(Direction::Push).unwrap().to_bstring(), @@ -87,15 +103,40 @@ mod remote_at { "push is the same as fetch was rewritten" ); + let remote = remote.with_url_without_url_rewrite("https://github.com/foobaz/gitoxide")?; + assert_eq!( + remote.url(Direction::Fetch).unwrap().to_bstring(), + "https://github.com/foobaz/gitoxide", + "fetch was rewritten" + ); + assert_eq!( + remote.url(Direction::Push).unwrap().to_bstring(), + "https://github.com/foobaz/gitoxide", + "push is the same as fetch was rewritten" + ); + let remote = repo .remote_at_without_url_rewrite("https://github.com/foobar/gitoxide".to_owned())? - .push_url_without_url_rewrite("file://dev/null".to_owned())?; + .with_push_url_without_url_rewrite("file://dev/null".to_owned())?; assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), fetch_url); assert_eq!( remote.url(Direction::Push).unwrap().to_bstring(), "file://dev/null", "push-url rewrite rules are not applied" ); + + let remote = remote + .with_url_without_url_rewrite("https://github.com/foobaz/gitoxide".to_owned())? + .with_push_url_without_url_rewrite("file://dev/null".to_owned())?; + assert_eq!( + remote.url(Direction::Fetch).unwrap().to_bstring(), + "https://github.com/foobaz/gitoxide" + ); + assert_eq!( + remote.url(Direction::Push).unwrap().to_bstring(), + "file://dev/null", + "push-url rewrite rules are not applied" + ); Ok(()) } }