This showed an issue with remote name handling as well which needs fixing once remote names are affecting the configuration.
Unified · Split
| @@ -107,6 +107,31 @@ pub mod checkout_options { · 106 unmodified lines | |||
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | /// | ||
| 111 | pub mod transport { | ||
| 112 | |||
| 113 | /// The error produced when configuring a transport for a particular protocol. | ||
| 114 | #[derive(Debug, thiserror::Error)] | ||
| 115 | #[allow(missing_docs)] | ||
| 116 | pub enum Error { | ||
| 117 | #[error("Invalid URL passed for configuration")] | ||
| 118 | ParseUrl(#[from] git_url::parse::Error), | ||
| 119 | #[error("Could obtain configuration for an HTTP url")] | ||
| 120 | Http(#[from] http::Error), | ||
| 121 | } | ||
| 122 | |||
| 123 | /// | ||
| 124 | pub mod http { | ||
| 125 | /// The error produced when configuring a HTTP transport. | ||
| 126 | #[derive(Debug, thiserror::Error)] | ||
| 127 | #[allow(missing_docs)] | ||
| 128 | pub enum Error { | ||
| 129 | #[error("TBD")] | ||
| 130 | TBD, | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 110 | /// Utility type to keep pre-obtained configuration values, only for those required during initial setup | 135 | /// Utility type to keep pre-obtained configuration values, only for those required during initial setup |
| 111 | /// and other basic operations that are common enough to warrant a permanent cache. | 136 | /// and other basic operations that are common enough to warrant a permanent cache. |
| 112 | /// | 137 | /// |
| @@ -5,6 +5,10 @@ use crate::{bstr::BStr, remote, Remote}; · 4 unmodified lines | |||
| 5 | /// Access | 5 | /// Access |
| 6 | impl Remote<'_> { | 6 | impl Remote<'_> { |
| 7 | /// Return the name of this remote or `None` if it wasn't persisted to disk yet. | 7 | /// Return the name of this remote or `None` if it wasn't persisted to disk yet. |
| 8 | // TODO: name can also be a URL but we don't see it like this. There is a problem with accessing such names | ||
| 9 | // too as they would require a BStr, but valid subsection names are strings, so some degeneration must happen | ||
| 10 | // for access at least. Argh. Probably use `reference::remote::Name` and turn it into `remote::Name` as it's | ||
| 11 | // actually correct. | ||
| 8 | pub fn name(&self) -> Option<&str> { | 12 | pub fn name(&self) -> Option<&str> { |
| 9 | self.name.as_deref() | 13 | self.name.as_deref() |
| 10 | } | 14 | } |
| @@ -41,7 +41,13 @@ impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> { · 40 unmodified lines | |||
| 41 | self.remote | 41 | self.remote |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | /// Provide a mutable transport to allow configuring it with [`configure()`][git_protocol::transport::client::TransportWithoutIO::configure()] | 44 | /// Provide a mutable transport to allow configuring it with [`configure()`][git_protocol::transport::client::TransportWithoutIO::configure()]. |
| 45 | /// | ||
| 46 | /// Please note that it is pre-configured, but can be configured again right after the [`Connection`] was instantiated without | ||
| 47 | /// the previous configuration having ever been used. | ||
| 48 | /// | ||
| 49 | /// Also note that all of the default configuration is created from `git` configuration, which can also be manipulated through overrides | ||
| 50 | /// to affect the default configuration. | ||
| 45 | pub fn transport_mut(&mut self) -> &mut T { | 51 | pub fn transport_mut(&mut self) -> &mut T { |
| 46 | &mut self.transport | 52 | &mut self.transport |
| 47 | } | 53 | } |
| @@ -33,6 +33,34 @@ impl crate::Repository { · 32 unmodified lines | |||
| 33 | } | 33 | } |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))] | ||
| 37 | mod transport { | ||
| 38 | use crate::bstr::BStr; | ||
| 39 | use std::any::Any; | ||
| 40 | |||
| 41 | impl crate::Repository { | ||
| 42 | /// Produce configuration suitable for `url`, as differentiated by its protocol/scheme, to be passed to a transport instance via | ||
| 43 | /// [configure()][git_transport::client::Transport::configure()]. | ||
| 44 | /// `None` is returned if there is no known configuration. | ||
| 45 | /// | ||
| 46 | /// Note that the caller may cast the instance themselves to modify it before passing it on. | ||
| 47 | pub fn transport_config<'a>( | ||
| 48 | &self, | ||
| 49 | url: impl Into<&'a BStr>, | ||
| 50 | ) -> Result<Option<Box<dyn Any>>, crate::config::transport::Error> { | ||
| 51 | let url = git_url::parse(url.into())?; | ||
| 52 | use git_url::Scheme::*; | ||
| 53 | |||
| 54 | match &url.scheme { | ||
| 55 | Http | Https => { | ||
| 56 | todo!() | ||
| 57 | } | ||
| 58 | File | Git | Ssh | Ext(_) => Ok(None), | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 36 | mod remote { | 64 | mod remote { |
| 37 | use std::{borrow::Cow, collections::BTreeSet}; | 65 | use std::{borrow::Cow, collections::BTreeSet}; |
| 38 | 66 | ||
| @@ -19,8 +19,7 @@ git clone --shared base two-origins · 18 unmodified lines | |||
| 19 | ) | 19 | ) |
| 20 | 20 | ||
| 21 | git clone --shared base worktree-root | 21 | git clone --shared base worktree-root |
| 22 | ( | 22 | (cd worktree-root |
| 23 | cd worktree-root | ||
| 24 | 23 | ||
| 25 | git worktree add ../wt-a | 24 | git worktree add ../wt-a |
| 26 | git worktree add ../prev/wt-a-nested | 25 | git worktree add ../prev/wt-a-nested |
| @@ -29,3 +28,16 @@ git clone --shared base worktree-root · 2 unmodified lines | |||
| 29 | git worktree add --lock ../wt-c-locked | 28 | git worktree add --lock ../wt-c-locked |
| 30 | git worktree add ../wt-deleted && rm -Rf ../wt-deleted | 29 | git worktree add ../wt-deleted && rm -Rf ../wt-deleted |
| 31 | ) | 30 | ) |
| 31 | |||
| 32 | git init http-config | ||
| 33 | (cd http-config | ||
| 34 | git config http.extraHeader "ExtraHeader: value1" | ||
| 35 | git config --add http.extraHeader "ExtraHeader: value2" | ||
| 36 | git config http.followRedirects initial | ||
| 37 | git config http.lowSpeedLimit 5k | ||
| 38 | git config http.lowSpeedTime 10 | ||
| 39 | git config http.postBuffer 8k | ||
| 40 | git config http.proxy localhost:9090 | ||
| 41 | git config http.proxyAuthMethod anyauth | ||
| 42 | git config http.userAgent agentJustForHttp | ||
| 43 | ) | ||
| @@ -8,7 +8,6 @@ mod blocking_io { · 7 unmodified lines | |||
| 8 | use git_testtools::hex_to_id; | 8 | use git_testtools::hex_to_id; |
| 9 | 9 | ||
| 10 | use crate::remote; | 10 | use crate::remote; |
| 11 | |||
| 12 | fn repo_rw(name: &str) -> (git::Repository, git_testtools::tempfile::TempDir) { | 11 | fn repo_rw(name: &str) -> (git::Repository, git_testtools::tempfile::TempDir) { |
| 13 | let dir = git_testtools::scripted_fixture_repo_writable_with_args( | 12 | let dir = git_testtools::scripted_fixture_repo_writable_with_args( |
| 14 | "make_fetch_repos.sh", | 13 | "make_fetch_repos.sh", |
| @@ -17,7 +17,7 @@ pub(crate) fn cow_str(s: &str) -> Cow<str> { · 16 unmodified lines | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | mod connect; | 19 | mod connect; |
| 20 | mod fetch; | 20 | pub(crate) mod fetch; |
| 21 | mod ref_map; | 21 | mod ref_map; |
| 22 | mod save; | 22 | mod save; |
| 23 | mod name { | 23 | mod name { |
| @@ -1,3 +1,5 @@ | |||
| 1 | mod config_snapshot; | 1 | mod config_snapshot; |
| 2 | mod identity; | 2 | mod identity; |
| 3 | mod remote; | 3 | mod remote; |
| 4 | #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))] | ||
| 5 | mod transport_config; | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | #[cfg(feature = "blocking-http-transport")] | ||
| 2 | mod http { | ||
| 3 | use git_repository as git; | ||
| 4 | |||
| 5 | fn base_repo_path() -> String { | ||
| 6 | git::path::realpath( | ||
| 7 | git_testtools::scripted_fixture_repo_read_only("make_remote_repos.sh") | ||
| 8 | .unwrap() | ||
| 9 | .join("base"), | ||
| 10 | ) | ||
| 11 | .unwrap() | ||
| 12 | .to_string_lossy() | ||
| 13 | .into_owned() | ||
| 14 | } | ||
| 15 | |||
| 16 | pub(crate) fn repo(name: &str) -> git::Repository { | ||
| 17 | let dir = git_testtools::scripted_fixture_repo_read_only_with_args("make_fetch_repos.sh", [base_repo_path()]) | ||
| 18 | .unwrap(); | ||
| 19 | git::open_opts(dir.join(name), git::open::Options::isolated()).unwrap() | ||
| 20 | } | ||
| 21 | |||
| 22 | #[test] | ||
| 23 | #[ignore] | ||
| 24 | fn simple_configuration() { | ||
| 25 | let repo = repo("http-config"); | ||
| 26 | let http_config = repo | ||
| 27 | .transport_config("https://example.com/does/not/matter") | ||
| 28 | .expect("valid configuration") | ||
| 29 | .expect("configuration available for http"); | ||
| 30 | let _options = http_config | ||
| 31 | .downcast_ref::<git_transport::client::http::Options>() | ||
| 32 | .expect("http options have been created"); | ||
| 33 | } | ||
| 34 | } | ||