From c2050d0ec74e2c2d1d70b68e57bbb79e196796b9 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 22 Oct 2025 17:53:58 +0200 Subject: [PATCH] fix!: make gix-transport I/O mode features additive --- gitoxide-core/src/net.rs | 14 +++++++------ gitoxide-core/src/pack/receive.rs | 6 +++++- gix-protocol/src/fetch/arguments/async_io.rs | 9 +++++--- .../src/fetch/arguments/blocking_io.rs | 9 +++++--- gix-protocol/src/fetch/function.rs | 11 ++++++---- gix-protocol/src/fetch/handshake.rs | 8 +++++-- gix-protocol/src/fetch/refmap/init.rs | 5 ++++- gix-protocol/src/fetch/response/async_io.rs | 5 +++-- .../src/fetch/response/blocking_io.rs | 11 +++++----- gix-protocol/src/handshake/function.rs | 8 +++++-- gix-protocol/src/handshake/refs/async_io.rs | 5 +++-- .../src/handshake/refs/blocking_io.rs | 5 +++-- gix-protocol/src/lib.rs | 2 +- gix-protocol/src/ls_refs.rs | 6 +++++- gix-protocol/src/util.rs | 7 +++++-- gix-protocol/tests/protocol/fetch/_impl.rs | 15 ++++++------- .../tests/protocol/fetch/arguments.rs | 17 ++++++++++----- gix-protocol/tests/protocol/fetch/response.rs | 8 +++++-- gix-protocol/tests/protocol/handshake.rs | 4 ++-- gix-transport/Cargo.toml | 8 ++----- gix-transport/src/client/async_io/connect.rs | 10 ++++----- .../src/client/blocking_io/connect.rs | 6 ++++-- gix-transport/src/client/blocking_io/file.rs | 2 +- .../client/blocking_io/http/reqwest/mod.rs | 2 +- .../client/blocking_io/http/reqwest/remote.rs | 4 +++- .../src/client/blocking_io/http/traits.rs | 2 +- gix-transport/src/client/git/blocking_io.rs | 4 ++-- gix-transport/src/client/mod.rs | 21 ++++--------------- gix-transport/src/client/non_io_types.rs | 11 ++++++---- gix-transport/src/lib.rs | 12 +++-------- gix-transport/tests/client/git.rs | 6 +++++- gix/src/clone/mod.rs | 10 +++++++-- gix/src/config/tree/sections/http.rs | 20 ++++++++++-------- gix/src/config/tree/sections/ssh.rs | 8 ++++--- gix/src/remote/connect.rs | 12 +++++++---- gix/src/remote/connection/access.rs | 10 ++++++--- gix/src/remote/connection/fetch/mod.rs | 5 ++++- .../remote/connection/fetch/receive_pack.rs | 9 ++++---- gix/src/remote/connection/mod.rs | 7 ++++++- gix/src/remote/connection/ref_map.rs | 5 ++++- gix/src/repository/config/mod.rs | 5 +++-- gix/src/repository/config/transport.rs | 9 ++++---- gix/tests/gix/config/tree.rs | 10 ++++----- gix/tests/gix/repository/config/mod.rs | 7 +++++-- .../repository/config/transport_options.rs | 12 +++++------ 45 files changed, 222 insertions(+), 150 deletions(-) diff --git a/gitoxide-core/src/net.rs b/gitoxide-core/src/net.rs index e5c62d52927..533b8ec8758 100644 --- a/gitoxide-core/src/net.rs +++ b/gitoxide-core/src/net.rs @@ -1,5 +1,10 @@ use std::str::FromStr; +#[cfg(feature = "async-client")] +use gix::protocol::transport::client::async_io as io_mode; +#[cfg(feature = "blocking-client")] +use gix::protocol::transport::client::blocking_io as io_mode; + #[derive(Default, Clone, Eq, PartialEq, Debug)] pub enum Protocol { V1, @@ -39,17 +44,14 @@ mod impls { #[gix::protocol::maybe_async::maybe_async] pub async fn connect( url: Url, - options: gix::protocol::transport::client::connect::Options, -) -> Result< - gix::protocol::SendFlushOnDrop>, - gix::protocol::transport::client::connect::Error, -> + options: io_mode::connect::Options, +) -> Result>, io_mode::connect::Error> where Url: TryInto, gix::url::parse::Error: From, { Ok(gix::protocol::SendFlushOnDrop::new( - gix::protocol::transport::connect(url, options).await?, + io_mode::connect::connect(url, options).await?, false, )) } diff --git a/gitoxide-core/src/pack/receive.rs b/gitoxide-core/src/pack/receive.rs index 66b64d95f24..288133ca1c6 100644 --- a/gitoxide-core/src/pack/receive.rs +++ b/gitoxide-core/src/pack/receive.rs @@ -4,6 +4,10 @@ use std::{ sync::{atomic::AtomicBool, Arc}, }; +#[cfg(feature = "async-client")] +use gix::protocol::transport::client::async_io::connect; +#[cfg(feature = "blocking-client")] +use gix::protocol::transport::client::blocking_io::connect; use gix::{config::tree::Key, protocol::maybe_async, remote::fetch::Error, DynNestedProgress}; pub use gix::{ hash::ObjectId, @@ -47,7 +51,7 @@ where { let mut transport = net::connect( url, - gix::protocol::transport::client::connect::Options { + connect::Options { version: protocol.unwrap_or_default().into(), ..Default::default() }, diff --git a/gix-protocol/src/fetch/arguments/async_io.rs b/gix-protocol/src/fetch/arguments/async_io.rs index e92d8faab44..cd702720504 100644 --- a/gix-protocol/src/fetch/arguments/async_io.rs +++ b/gix-protocol/src/fetch/arguments/async_io.rs @@ -1,15 +1,18 @@ use futures_lite::io::AsyncWriteExt; -use gix_transport::{client, client::TransportV2Ext}; +use gix_transport::client::{ + self, + async_io::{ExtendedBufRead, Transport, TransportV2Ext}, +}; use crate::{fetch::Arguments, Command}; impl Arguments { /// Send fetch arguments to the server, and indicate this is the end of negotiations only if `add_done_argument` is present. - pub async fn send<'a, T: client::Transport + 'a>( + pub async fn send<'a, T: Transport + 'a>( &mut self, transport: &'a mut T, add_done_argument: bool, - ) -> Result + Unpin + 'a>, client::Error> { + ) -> Result + Unpin + 'a>, client::Error> { if self.haves.is_empty() { assert!(add_done_argument, "If there are no haves, is_done must be true."); } diff --git a/gix-protocol/src/fetch/arguments/blocking_io.rs b/gix-protocol/src/fetch/arguments/blocking_io.rs index 0852f5a888b..9ccee601220 100644 --- a/gix-protocol/src/fetch/arguments/blocking_io.rs +++ b/gix-protocol/src/fetch/arguments/blocking_io.rs @@ -1,16 +1,19 @@ use std::io::Write; -use gix_transport::{client, client::TransportV2Ext}; +use gix_transport::client::{ + self, + blocking_io::{ExtendedBufRead, Transport, TransportV2Ext}, +}; use crate::{fetch::Arguments, Command}; impl Arguments { /// Send fetch arguments to the server, and indicate this is the end of negotiations only if `add_done_argument` is present. - pub fn send<'a, T: client::Transport + 'a>( + pub fn send<'a, T: Transport + 'a>( &mut self, transport: &'a mut T, add_done_argument: bool, - ) -> Result + Unpin + 'a>, client::Error> { + ) -> Result + Unpin + 'a>, client::Error> { if self.haves.is_empty() { assert!(add_done_argument, "If there are no haves, is_done must be true."); } diff --git a/gix-protocol/src/fetch/function.rs b/gix-protocol/src/fetch/function.rs index 1ac524cd21b..8a52e8ace2f 100644 --- a/gix-protocol/src/fetch/function.rs +++ b/gix-protocol/src/fetch/function.rs @@ -5,6 +5,10 @@ use std::{ use gix_features::progress::DynNestedProgress; +#[cfg(feature = "async-client")] +use crate::transport::client::async_io::{ExtendedBufRead, HandleProgress, Transport}; +#[cfg(feature = "blocking-client")] +use crate::transport::client::blocking_io::{ExtendedBufRead, HandleProgress, Transport}; use crate::{ fetch::{ negotiate, Arguments, Context, Error, Negotiate, NegotiateOutcome, Options, Outcome, ProgressId, Shallow, Tags, @@ -56,7 +60,7 @@ pub async fn fetch( where P: gix_features::progress::NestedProgress, P::SubProgress: 'static, - T: gix_transport::client::Transport, + T: Transport, E: Into>, { let _span = gix_trace::coarse!("gix_protocol::fetch()"); @@ -251,10 +255,9 @@ fn add_shallow_args( fn setup_remote_progress<'a>( progress: &mut dyn gix_features::progress::DynNestedProgress, - reader: &mut Box + Unpin + 'a>, + reader: &mut Box + Unpin + 'a>, should_interrupt: &'a AtomicBool, ) { - use crate::transport::client::ExtendedBufRead; reader.set_progress_handler(Some(Box::new({ let mut remote_progress = progress.add_child_with_id("remote".to_string(), ProgressId::RemoteProgress.into()); move |is_err: bool, data: &[u8]| { @@ -265,5 +268,5 @@ fn setup_remote_progress<'a>( ProgressAction::Continue } } - }) as crate::transport::client::HandleProgress<'a>)); + }) as HandleProgress<'a>)); } diff --git a/gix-protocol/src/fetch/handshake.rs b/gix-protocol/src/fetch/handshake.rs index 9ffc184a8ba..0c5dde26d62 100644 --- a/gix-protocol/src/fetch/handshake.rs +++ b/gix-protocol/src/fetch/handshake.rs @@ -1,7 +1,11 @@ use gix_features::progress::Progress; -use gix_transport::{client, Service}; +use gix_transport::Service; use maybe_async::maybe_async; +#[cfg(feature = "async-client")] +use crate::transport::client::async_io::Transport; +#[cfg(feature = "blocking-client")] +use crate::transport::client::blocking_io::Transport; use crate::{ credentials, handshake::{Error, Outcome}, @@ -21,7 +25,7 @@ pub async fn upload_pack( ) -> Result where AuthFn: FnMut(credentials::helper::Action) -> credentials::protocol::Result, - T: client::Transport, + T: Transport, { crate::handshake(transport, Service::UploadPack, authenticate, extra_parameters, progress).await } diff --git a/gix-protocol/src/fetch/refmap/init.rs b/gix-protocol/src/fetch/refmap/init.rs index 7db8ea86dfd..ac005be60dd 100644 --- a/gix-protocol/src/fetch/refmap/init.rs +++ b/gix-protocol/src/fetch/refmap/init.rs @@ -3,13 +3,16 @@ use std::collections::HashSet; use bstr::{BString, ByteVec}; use gix_features::progress::Progress; +#[cfg(feature = "async-client")] +use crate::transport::client::async_io::Transport; +#[cfg(feature = "blocking-client")] +use crate::transport::client::blocking_io::Transport; use crate::{ fetch, fetch::{ refmap::{Mapping, Source, SpecIndex}, RefMap, }, - transport::client::Transport, }; /// The error returned by [`RefMap::new()`]. diff --git a/gix-protocol/src/fetch/response/async_io.rs b/gix-protocol/src/fetch/response/async_io.rs index 42be8b6e606..f5b3239e32a 100644 --- a/gix-protocol/src/fetch/response/async_io.rs +++ b/gix-protocol/src/fetch/response/async_io.rs @@ -1,5 +1,6 @@ use std::io; +use crate::transport::client::async_io::ExtendedBufRead; use gix_transport::{client, Protocol}; use crate::fetch::{ @@ -10,7 +11,7 @@ use crate::fetch::{ async fn parse_v2_section( line: &mut String, - reader: &mut (impl client::ExtendedBufRead<'_> + Unpin), + reader: &mut (impl ExtendedBufRead<'_> + Unpin), res: &mut Vec, parse: impl Fn(&str) -> Result, ) -> Result { @@ -44,7 +45,7 @@ impl Response { /// that `git` has to use to predict how many acks are supposed to be read. We also genuinely hope that this covers it all…. pub async fn from_line_reader( version: Protocol, - reader: &mut (impl client::ExtendedBufRead<'_> + Unpin), + reader: &mut (impl ExtendedBufRead<'_> + Unpin), client_expects_pack: bool, wants_to_negotiate: bool, ) -> Result { diff --git a/gix-protocol/src/fetch/response/blocking_io.rs b/gix-protocol/src/fetch/response/blocking_io.rs index 4143e93fb7f..80118a9c650 100644 --- a/gix-protocol/src/fetch/response/blocking_io.rs +++ b/gix-protocol/src/fetch/response/blocking_io.rs @@ -1,6 +1,7 @@ use std::io; -use gix_transport::{client, Protocol}; +use crate::transport::client::blocking_io::ExtendedBufRead; +use crate::transport::{client::MessageKind, Protocol}; use crate::fetch::{ response, @@ -10,7 +11,7 @@ use crate::fetch::{ fn parse_v2_section<'a, T>( line: &mut String, - reader: &mut impl client::ExtendedBufRead<'a>, + reader: &mut impl ExtendedBufRead<'a>, res: &mut Vec, parse: impl Fn(&str) -> Result, ) -> Result { @@ -20,7 +21,7 @@ fn parse_v2_section<'a, T>( line.clear(); } // End of message, or end of section? - Ok(if reader.stopped_at() == Some(client::MessageKind::Delimiter) { + Ok(if reader.stopped_at() == Some(MessageKind::Delimiter) { // try reading more sections reader.reset(Protocol::V2); false @@ -44,7 +45,7 @@ impl Response { /// that `git` has to use to predict how many acks are supposed to be read. We also genuinely hope that this covers it all…. pub fn from_line_reader<'a>( version: Protocol, - reader: &mut impl client::ExtendedBufRead<'a>, + reader: &mut impl ExtendedBufRead<'a>, client_expects_pack: bool, wants_to_negotiate: bool, ) -> Result { @@ -71,7 +72,7 @@ impl Response { // maybe we saw a shallow flush packet, let's reset and retry debug_assert_eq!( reader.stopped_at(), - Some(client::MessageKind::Flush), + Some(MessageKind::Flush), "If this isn't a flush packet, we don't know what's going on" ); reader.readline_str(&mut line)?; diff --git a/gix-protocol/src/handshake/function.rs b/gix-protocol/src/handshake/function.rs index 6e5a6cc041f..a4b9261c38a 100644 --- a/gix-protocol/src/handshake/function.rs +++ b/gix-protocol/src/handshake/function.rs @@ -1,8 +1,12 @@ use gix_features::{progress, progress::Progress}; -use gix_transport::{client, client::SetServiceResponse, Service}; +use gix_transport::{client, Service}; use maybe_async::maybe_async; use super::{Error, Outcome}; +#[cfg(feature = "async-client")] +use crate::transport::client::async_io::{SetServiceResponse, Transport}; +#[cfg(feature = "blocking-client")] +use crate::transport::client::blocking_io::{SetServiceResponse, Transport}; use crate::{credentials, handshake::refs}; /// Perform a handshake with the server on the other side of `transport`, with `authenticate` being used if authentication @@ -20,7 +24,7 @@ pub async fn handshake( ) -> Result where AuthFn: FnMut(credentials::helper::Action) -> credentials::protocol::Result, - T: client::Transport, + T: Transport, { let _span = gix_features::trace::detail!("gix_protocol::handshake()", service = ?service, extra_parameters = ?extra_parameters); let (server_protocol_version, refs, capabilities) = { diff --git a/gix-protocol/src/handshake/refs/async_io.rs b/gix-protocol/src/handshake/refs/async_io.rs index 996b83bca69..6dbecb304dc 100644 --- a/gix-protocol/src/handshake/refs/async_io.rs +++ b/gix-protocol/src/handshake/refs/async_io.rs @@ -1,10 +1,11 @@ +use crate::transport::client::async_io::ReadlineBufRead; use crate::{ fetch::response::ShallowUpdate, handshake::{refs, refs::parse::Error, Ref}, }; /// Parse refs from the given input line by line. Protocol V2 is required for this to succeed. -pub async fn from_v2_refs(in_refs: &mut dyn gix_transport::client::ReadlineBufRead) -> Result, Error> { +pub async fn from_v2_refs(in_refs: &mut dyn ReadlineBufRead) -> Result, Error> { let mut out_refs = Vec::new(); while let Some(line) = in_refs .readline() @@ -27,7 +28,7 @@ pub async fn from_v2_refs(in_refs: &mut dyn gix_transport::client::ReadlineBufRe /// Symbolic refs are shoe-horned into server capabilities whereas refs (without symbolic ones) are sent automatically as /// part of the handshake. Both symbolic and peeled refs need to be combined to fit into the [`Ref`] type provided here. pub async fn from_v1_refs_received_as_part_of_handshake_and_capabilities<'a>( - in_refs: &mut dyn gix_transport::client::ReadlineBufRead, + in_refs: &mut dyn ReadlineBufRead, capabilities: impl Iterator>, ) -> Result<(Vec, Vec), refs::parse::Error> { let mut out_refs = refs::shared::from_capabilities(capabilities)?; diff --git a/gix-protocol/src/handshake/refs/blocking_io.rs b/gix-protocol/src/handshake/refs/blocking_io.rs index 151f769586e..7f95ab0d322 100644 --- a/gix-protocol/src/handshake/refs/blocking_io.rs +++ b/gix-protocol/src/handshake/refs/blocking_io.rs @@ -1,10 +1,11 @@ +use crate::transport::client::blocking_io::ReadlineBufRead; use crate::{ fetch::response::ShallowUpdate, handshake::{refs, refs::parse::Error, Ref}, }; /// Parse refs from the given input line by line. Protocol V2 is required for this to succeed. -pub fn from_v2_refs(in_refs: &mut dyn gix_transport::client::ReadlineBufRead) -> Result, Error> { +pub fn from_v2_refs(in_refs: &mut dyn ReadlineBufRead) -> Result, Error> { let mut out_refs = Vec::new(); while let Some(line) = in_refs.readline().transpose()?.transpose()?.and_then(|l| l.as_bstr()) { out_refs.push(refs::shared::parse_v2(line)?); @@ -21,7 +22,7 @@ pub fn from_v2_refs(in_refs: &mut dyn gix_transport::client::ReadlineBufRead) -> /// Symbolic refs are shoe-horned into server capabilities whereas refs (without symbolic ones) are sent automatically as /// part of the handshake. Both symbolic and peeled refs need to be combined to fit into the [`Ref`] type provided here. pub fn from_v1_refs_received_as_part_of_handshake_and_capabilities<'a>( - in_refs: &mut dyn gix_transport::client::ReadlineBufRead, + in_refs: &mut dyn ReadlineBufRead, capabilities: impl Iterator>, ) -> Result<(Vec, Vec), Error> { let mut out_refs = refs::shared::from_capabilities(capabilities)?; diff --git a/gix-protocol/src/lib.rs b/gix-protocol/src/lib.rs index 2eea5911774..8c75512928d 100644 --- a/gix-protocol/src/lib.rs +++ b/gix-protocol/src/lib.rs @@ -2,7 +2,7 @@ //! //! Generally, there is the following order of operations. //! -//! * create a [`Transport`](gix_transport::client::Transport) +//! * create a `Transport`, either blocking or async //! * perform a [`handshake()`] //! * execute a [`Command`] //! - [list references](ls_refs()) diff --git a/gix-protocol/src/ls_refs.rs b/gix-protocol/src/ls_refs.rs index 6bd15108124..3a435c5cd53 100644 --- a/gix-protocol/src/ls_refs.rs +++ b/gix-protocol/src/ls_refs.rs @@ -47,10 +47,14 @@ pub(crate) mod function { use bstr::BString; use gix_features::progress::Progress; - use gix_transport::client::{Capabilities, Transport, TransportV2Ext}; + use gix_transport::client::Capabilities; use maybe_async::maybe_async; use super::{Action, Error}; + #[cfg(feature = "async-client")] + use crate::transport::client::async_io::{Transport, TransportV2Ext}; + #[cfg(feature = "blocking-client")] + use crate::transport::client::blocking_io::{Transport, TransportV2Ext}; use crate::{ handshake::{refs::from_v2_refs, Ref}, indicate_end_of_interaction, Command, diff --git a/gix-protocol/src/util.rs b/gix-protocol/src/util.rs index adba4bb7784..920395e20b1 100644 --- a/gix-protocol/src/util.rs +++ b/gix-protocol/src/util.rs @@ -8,13 +8,16 @@ pub fn agent(name: impl Into) -> String { } #[cfg(any(feature = "blocking-client", feature = "async-client"))] mod with_transport { - use gix_transport::client::Transport; + #[cfg(feature = "async-client")] + use gix_transport::client::async_io::Transport; + #[cfg(feature = "blocking-client")] + use gix_transport::client::blocking_io::Transport; /// Send a message to indicate the remote side that there is nothing more to expect from us, indicating a graceful shutdown. /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate. #[maybe_async::maybe_async] pub async fn indicate_end_of_interaction( - mut transport: impl gix_transport::client::Transport, + mut transport: impl Transport, trace: bool, ) -> Result<(), gix_transport::client::Error> { // An empty request marks the (early) end of the interaction. Only relevant in stateful transports though. diff --git a/gix-protocol/tests/protocol/fetch/_impl.rs b/gix-protocol/tests/protocol/fetch/_impl.rs index c4171e20e80..e3d7077d195 100644 --- a/gix-protocol/tests/protocol/fetch/_impl.rs +++ b/gix-protocol/tests/protocol/fetch/_impl.rs @@ -7,7 +7,10 @@ mod fetch_fn { fetch::{Arguments, Response}, indicate_end_of_interaction, Command, }; - use gix_transport::client; + #[cfg(feature = "async-client")] + use gix_transport::client::async_io::{ExtendedBufRead, HandleProgress, Transport}; + #[cfg(feature = "blocking-client")] + use gix_transport::client::blocking_io::{ExtendedBufRead, HandleProgress, Transport}; use maybe_async::maybe_async; use super::{Action, Delegate}; @@ -67,7 +70,7 @@ mod fetch_fn { where F: FnMut(credentials::helper::Action) -> credentials::protocol::Result, D: Delegate, - T: client::Transport, + T: Transport, P: NestedProgress + 'static, P::SubProgress: 'static, { @@ -171,10 +174,8 @@ mod fetch_fn { Ok(()) } - fn setup_remote_progress

( - progress: &mut P, - reader: &mut Box + Unpin + '_>, - ) where + fn setup_remote_progress<'a, P>(progress: &mut P, reader: &mut Box + Unpin + 'a>) + where P: NestedProgress, P::SubProgress: 'static, { @@ -184,7 +185,7 @@ mod fetch_fn { gix_protocol::RemoteProgress::translate_to_progress(is_err, data, &mut remote_progress); gix_transport::packetline::read::ProgressAction::Continue } - }) as gix_transport::client::HandleProgress<'_>)); + }) as HandleProgress<'a>)); } } pub use fetch_fn::{legacy_fetch as fetch, FetchConnection}; diff --git a/gix-protocol/tests/protocol/fetch/arguments.rs b/gix-protocol/tests/protocol/fetch/arguments.rs index 9debb359557..da5e37d50ac 100644 --- a/gix-protocol/tests/protocol/fetch/arguments.rs +++ b/gix-protocol/tests/protocol/fetch/arguments.rs @@ -23,7 +23,10 @@ mod impls { use bstr::BStr; use gix_transport::{ client, - client::{Error, MessageKind, RequestWriter, SetServiceResponse, WriteMode}, + client::{ + blocking_io::{RequestWriter, SetServiceResponse}, + Error, MessageKind, WriteMode, + }, Protocol, Service, }; @@ -54,7 +57,7 @@ mod impls { } } - impl client::Transport for Transport { + impl client::blocking_io::Transport for Transport { fn handshake<'a>( &mut self, service: Service, @@ -81,12 +84,16 @@ mod impls { use async_trait::async_trait; use bstr::BStr; use gix_transport::{ - client, - client::{Error, MessageKind, RequestWriter, SetServiceResponse, WriteMode}, + client::{ + self, + async_io::{RequestWriter, SetServiceResponse}, + Error, MessageKind, WriteMode, + }, Protocol, Service, }; use super::Transport; + impl client::TransportWithoutIO for Transport { fn set_identity(&mut self, identity: client::Account) -> Result<(), Error> { self.inner.set_identity(identity) @@ -113,7 +120,7 @@ mod impls { } #[async_trait(?Send)] - impl client::Transport for Transport { + impl client::async_io::Transport for Transport { async fn handshake<'a>( &mut self, service: Service, diff --git a/gix-protocol/tests/protocol/fetch/response.rs b/gix-protocol/tests/protocol/fetch/response.rs index 981ae139c83..db54e89be0a 100644 --- a/gix-protocol/tests/protocol/fetch/response.rs +++ b/gix-protocol/tests/protocol/fetch/response.rs @@ -215,6 +215,10 @@ mod v2 { self, response::{Acknowledgement, ShallowUpdate}, }; + #[cfg(feature = "async-client")] + use gix_transport::client::async_io::HandleProgress; + #[cfg(feature = "blocking-client")] + use gix_transport::client::blocking_io::HandleProgress; use gix_transport::Protocol; use crate::fetch::response::{id, mock_reader}; @@ -320,7 +324,7 @@ mod v2 { reader.set_progress_handler(Some(Box::new(|is_err: bool, _data: &[u8]| { assert!(!is_err, "fixture does not have an error"); ProgressAction::Continue - }) as gix_transport::client::HandleProgress)); + }) as HandleProgress)); let bytes_read = reader.read_to_end(&mut buf).await?; assert_eq!(bytes_read, 1643, "should be able to read the whole pack"); assert_eq!(&buf[..4], b"PACK"); @@ -376,7 +380,7 @@ mod v2 { reader.set_progress_handler(Some(Box::new(|a: bool, b: &[u8]| { gix_protocol::RemoteProgress::translate_to_progress(a, b, &mut gix_features::progress::Discard); ProgressAction::Continue - }) as gix_transport::client::HandleProgress)); + }) as HandleProgress)); let bytes_read = reader.read_to_end(&mut buf).await?; assert_eq!(bytes_read, 5360, "should be able to read the whole pack"); Ok(()) diff --git a/gix-protocol/tests/protocol/handshake.rs b/gix-protocol/tests/protocol/handshake.rs index b0d8e42d0a7..6aae74984a1 100644 --- a/gix-protocol/tests/protocol/handshake.rs +++ b/gix-protocol/tests/protocol/handshake.rs @@ -202,7 +202,7 @@ impl std::io::BufRead for Fixture<'_> { } #[cfg(feature = "blocking-client")] -impl gix_transport::client::ReadlineBufRead for Fixture<'_> { +impl gix_transport::client::blocking_io::ReadlineBufRead for Fixture<'_> { fn readline( &mut self, ) -> Option, gix_packetline::decode::Error>>> { @@ -266,7 +266,7 @@ impl futures_io::AsyncBufRead for Fixture<'_> { #[cfg(feature = "async-client")] #[async_trait::async_trait(?Send)] -impl gix_transport::client::ReadlineBufRead for Fixture<'_> { +impl gix_transport::client::async_io::ReadlineBufRead for Fixture<'_> { async fn readline( &mut self, ) -> Option, gix_packetline::decode::Error>>> { diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 735851388e3..80f3f2a4ccb 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -17,11 +17,7 @@ doctest = false [features] default = [] -#! ### _Mutually Exclusive Client_ -#! The _client_ portion of transport can be blocking or async. If none is selected, it will be missing entirely. -#! Specifying both causes a compile error, preventing the use of `--all-features`. - -## If set, blocking implementations of the typical git transports become available in `crate::client` +## If set, blocking implementations of the typical git transports become available in `crate::client::blocking_io` blocking-client = ["gix-packetline/blocking-io"] ## Implies `blocking-client`, and adds support for the http and https transports. http-client = [ @@ -49,7 +45,7 @@ http-client-reqwest-rust-tls-trust-dns = [ http-client-reqwest-native-tls = ["http-client-reqwest", "reqwest/default-tls"] ## Allows sending credentials over cleartext HTTP. For testing purposes only. http-client-insecure-credentials = [] -## If set, an async implementations of the git transports becomes available in `crate::client`. +## If set, an async implementations of the git transports becomes available in `crate::client::async_io`. ## Suitable for implementing your own transports while using git's way of communication, typically in conjunction with a custom server. ## **Note** that the _blocking_ client has a wide range of available transports, with the _async_ version of it supporting only the TCP based `git` transport leaving you ## with the responsibility to providing such an implementation of `futures-io::AsyncRead/AsyncWrite` yourself. diff --git a/gix-transport/src/client/async_io/connect.rs b/gix-transport/src/client/async_io/connect.rs index 72ba2289613..6b094328e4b 100644 --- a/gix-transport/src/client/async_io/connect.rs +++ b/gix-transport/src/client/async_io/connect.rs @@ -2,7 +2,7 @@ pub use crate::client::non_io_types::connect::{Error, Options}; #[cfg(feature = "async-std")] pub(crate) mod function { - use crate::client::{git, non_io_types::connect::Error}; + use crate::client::{async_io::Transport, git, non_io_types::connect::Error}; /// A general purpose connector connecting to a repository identified by the given `url`. /// @@ -10,10 +10,7 @@ pub(crate) mod function { /// [git daemons][crate::client::git::connect()] only at the moment. /// /// Use `options` to further control specifics of the transport resulting from the connection. - pub async fn connect( - url: Url, - options: super::Options, - ) -> Result, Error> + pub async fn connect(url: Url, options: super::Options) -> Result, Error> where Url: TryInto, gix_url::parse::Error: From, @@ -44,3 +41,6 @@ pub(crate) mod function { }) } } + +#[cfg(feature = "async-std")] +pub use function::connect; diff --git a/gix-transport/src/client/blocking_io/connect.rs b/gix-transport/src/client/blocking_io/connect.rs index ba9519d4b27..d96f3e4e7bd 100644 --- a/gix-transport/src/client/blocking_io/connect.rs +++ b/gix-transport/src/client/blocking_io/connect.rs @@ -12,8 +12,8 @@ pub(crate) mod function { /// This includes connections to /// [local repositories](crate::client::blocking_io::file::connect()), /// [repositories over ssh](crate::client::blocking_io::ssh::connect()), - /// [git daemons](crate::client::git::connect()), - /// and if compiled in connections to [git repositories over https](crate::client::http::connect()). + /// [git daemons](crate::client::blocking_io::connect::connect()), + /// and if compiled in connections to [git repositories over https](crate::client::blocking_io::http::connect()). /// /// Use `options` to further control specifics of the transport resulting from the connection. pub fn connect(url: Url, options: super::Options) -> Result, Error> @@ -74,3 +74,5 @@ pub(crate) mod function { }) } } + +pub use function::connect; diff --git a/gix-transport/src/client/blocking_io/file.rs b/gix-transport/src/client/blocking_io/file.rs index 520e160f847..b91f1c1a281 100644 --- a/gix-transport/src/client/blocking_io/file.rs +++ b/gix-transport/src/client/blocking_io/file.rs @@ -41,7 +41,7 @@ const ENV_VARS_TO_REMOVE: &[&str] = &[ /// A utility to spawn a helper process to actually transmit data, possibly over `ssh`. /// -/// It can only be instantiated using the local [`connect()`] or [ssh connect][crate::client::ssh::connect()]. +/// It can only be instantiated using the local [`connect()`] or [ssh connect][super::ssh::connect()]. pub struct SpawnProcessOnDemand { desired_version: Protocol, url: gix_url::Url, diff --git a/gix-transport/src/client/blocking_io/http/reqwest/mod.rs b/gix-transport/src/client/blocking_io/http/reqwest/mod.rs index 7c68b166ea2..1ca3113479c 100644 --- a/gix-transport/src/client/blocking_io/http/reqwest/mod.rs +++ b/gix-transport/src/client/blocking_io/http/reqwest/mod.rs @@ -7,7 +7,7 @@ pub struct Remote { /// A channel to receive the result of the prior request. response: std::sync::mpsc::Receiver, /// A mechanism for configuring the remote. - config: crate::client::http::Options, + config: crate::client::blocking_io::http::Options, } /// A function to configure a single request prior to sending it, support most complex configuration beyond what's possible with diff --git a/gix-transport/src/client/blocking_io/http/reqwest/remote.rs b/gix-transport/src/client/blocking_io/http/reqwest/remote.rs index 40b480b6ee7..50e1c36b2a7 100644 --- a/gix-transport/src/client/blocking_io/http/reqwest/remote.rs +++ b/gix-transport/src/client/blocking_io/http/reqwest/remote.rs @@ -7,7 +7,9 @@ use std::{ use gix_features::io::pipe; -use crate::client::http::{self, options::FollowRedirects, redirect, reqwest::Remote, traits::PostBodyDataKind}; +use crate::client::blocking_io::http::{ + self, options::FollowRedirects, redirect, reqwest::Remote, traits::PostBodyDataKind, +}; /// The error returned by the 'remote' helper, a purely internal construct to perform http requests. #[derive(Debug, thiserror::Error)] diff --git a/gix-transport/src/client/blocking_io/http/traits.rs b/gix-transport/src/client/blocking_io/http/traits.rs index b13473a38b0..fd59ef957ca 100644 --- a/gix-transport/src/client/blocking_io/http/traits.rs +++ b/gix-transport/src/client/blocking_io/http/traits.rs @@ -25,7 +25,7 @@ impl crate::IsSpuriousError for Error { return err.is_spurious(); } #[cfg(feature = "http-client-reqwest")] - if let Some(err) = source.downcast_ref::() { + if let Some(err) = source.downcast_ref::() { return err.is_spurious(); } false diff --git a/gix-transport/src/client/git/blocking_io.rs b/gix-transport/src/client/git/blocking_io.rs index 1f61bd970ec..22ae7318455 100644 --- a/gix-transport/src/client/git/blocking_io.rs +++ b/gix-transport/src/client/git/blocking_io.rs @@ -19,8 +19,8 @@ use crate::{ /// A TCP connection to either a `git` daemon or a spawned `git` process. /// -/// When connecting to a daemon, additional context information is sent with the first line of the handshake. Otherwise, that -/// context is passed using command line arguments to a [spawned `git` process](crate::client::file::SpawnProcessOnDemand). +/// When connecting to a daemon, additional context information is sent with the first line of the handshake. Otherwise that +/// context is passed using command line arguments to a [spawned `git` process][crate::client::blocking_io::file::SpawnProcessOnDemand]. pub struct Connection { pub(in crate::client) writer: W, pub(in crate::client) line_provider: StreamingPeekableIter, diff --git a/gix-transport/src/client/mod.rs b/gix-transport/src/client/mod.rs index b8970f99d6a..4b8aee804cb 100644 --- a/gix-transport/src/client/mod.rs +++ b/gix-transport/src/client/mod.rs @@ -1,26 +1,13 @@ +/// #[cfg(all(feature = "async-client", not(feature = "blocking-client")))] -mod async_io; -#[cfg(all(feature = "async-client", not(feature = "blocking-client")))] -pub use async_io::{ - connect, ExtendedBufRead, HandleProgress, ReadlineBufRead, RequestWriter, SetServiceResponse, Transport, - TransportV2Ext, -}; +pub mod async_io; mod traits; pub use traits::TransportWithoutIO; +/// #[cfg(feature = "blocking-client")] -mod blocking_io; -#[cfg(feature = "http-client")] -pub use blocking_io::http; -#[cfg(feature = "blocking-client")] -pub use blocking_io::{ - connect, file, ssh, ExtendedBufRead, HandleProgress, ReadlineBufRead, RequestWriter, SetServiceResponse, Transport, - TransportV2Ext, -}; -#[cfg(feature = "blocking-client")] -#[doc(inline)] -pub use connect::function::connect; +pub mod blocking_io; /// pub mod capabilities; diff --git a/gix-transport/src/client/non_io_types.rs b/gix-transport/src/client/non_io_types.rs index c28e628c34d..98f79020a46 100644 --- a/gix-transport/src/client/non_io_types.rs +++ b/gix-transport/src/client/non_io_types.rs @@ -1,4 +1,4 @@ -/// Configure how the [`RequestWriter`][crate::client::RequestWriter] behaves when writing bytes. +/// Configure how a `RequestWriter` behaves when writing bytes. #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum WriteMode { @@ -15,8 +15,9 @@ pub enum WriteMode { OneLfTerminatedLinePerWriteCall, } -/// The kind of packet line to write when transforming a [`RequestWriter`][crate::client::RequestWriter] into an -/// [`ExtendedBufRead`][crate::client::ExtendedBufRead]. +/// The kind of packet line to write when transforming a `RequestWriter` into an `ExtendedBufRead`. +/// +/// Both the type and the trait have different implementations for blocking vs async I/O. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum MessageKind { @@ -44,7 +45,9 @@ pub(crate) mod connect { pub trace: bool, } - /// The error used in [`connect()`][crate::connect()]. + /// The error used in `connect()`. + /// + /// (Both blocking and async I/O use the same error type.) #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum Error { diff --git a/gix-transport/src/lib.rs b/gix-transport/src/lib.rs index 5e44b00ae63..e29026a252e 100644 --- a/gix-transport/src/lib.rs +++ b/gix-transport/src/lib.rs @@ -1,5 +1,6 @@ -//! An implementation of the `git` transport layer, abstracting over all of its [versions][Protocol], providing -//! [`connect()`] to establish a connection given a repository URL. +//! An implementation of the `git` transport layer, abstracting over all of its [versions][Protocol]. +//! +//! Use `client::blocking_io::connect()` or `client::async_io::connect()` to establish a connection. //! //! All git transports are supported, including `ssh`, `git`, `http` and `https`, as well as local repository paths. //! ## Feature Flags @@ -83,10 +84,3 @@ pub use traits::IsSpuriousError; /// pub mod client; - -#[doc(inline)] -#[cfg(any(feature = "blocking-client", all(feature = "async-client", feature = "async-std")))] -pub use client::connect; - -#[cfg(all(feature = "async-client", feature = "blocking-client"))] -compile_error!("Cannot set both 'blocking-client' and 'async-client' features as they are mutually exclusive"); diff --git a/gix-transport/tests/client/git.rs b/gix-transport/tests/client/git.rs index cc8c5c40af7..88c9699aebc 100644 --- a/gix-transport/tests/client/git.rs +++ b/gix-transport/tests/client/git.rs @@ -9,9 +9,13 @@ use bstr::ByteSlice; #[cfg(feature = "async-client")] use futures_lite::{AsyncBufReadExt, AsyncWriteExt, StreamExt}; use gix_packetline::read::ProgressAction; +#[cfg(feature = "async-client")] +use gix_transport::client::async_io::{Transport, TransportV2Ext}; +#[cfg(feature = "blocking-client")] +use gix_transport::client::blocking_io::{Transport, TransportV2Ext}; use gix_transport::{ client, - client::{git, Transport, TransportV2Ext, TransportWithoutIO}, + client::{git, TransportWithoutIO}, Protocol, Service, }; diff --git a/gix/src/clone/mod.rs b/gix/src/clone/mod.rs index 23903943724..c3d50ad3d9b 100644 --- a/gix/src/clone/mod.rs +++ b/gix/src/clone/mod.rs @@ -1,12 +1,17 @@ #![allow(clippy::result_large_err)] use crate::{bstr::BString, remote}; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; + type ConfigureRemoteFn = Box) -> Result, Box>>; #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] type ConfigureConnectionFn = Box< dyn FnMut( - &mut remote::Connection<'_, '_, Box>, + &mut remote::Connection<'_, '_, Box>, ) -> Result<(), Box>, >; @@ -137,6 +142,7 @@ pub struct PrepareCheckout { // once async and clone are a thing. #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] mod access_feat { + use super::Transport; use crate::clone::PrepareFetch; /// Builder @@ -148,7 +154,7 @@ mod access_feat { pub fn configure_connection( mut self, f: impl FnMut( - &mut crate::remote::Connection<'_, '_, Box>, + &mut crate::remote::Connection<'_, '_, Box>, ) -> Result<(), Box> + 'static, ) -> Self { diff --git a/gix/src/config/tree/sections/http.rs b/gix/src/config/tree/sections/http.rs index 4fc733564de..af5e80472c2 100644 --- a/gix/src/config/tree/sections/http.rs +++ b/gix/src/config/tree/sections/http.rs @@ -125,10 +125,10 @@ mod key_impls { value: std::borrow::Cow<'_, crate::bstr::BStr>, boolean: impl FnOnce() -> Result, gix_config::value::Error>, ) -> Result< - crate::protocol::transport::client::http::options::FollowRedirects, + crate::protocol::transport::client::blocking_io::http::options::FollowRedirects, crate::config::key::GenericErrorWithValue, > { - use crate::{bstr::ByteSlice, protocol::transport::client::http::options::FollowRedirects}; + use crate::{bstr::ByteSlice, protocol::transport::client::blocking_io::http::options::FollowRedirects}; Ok(if value.as_ref().as_bytes() == b"initial" { FollowRedirects::Initial } else if let Some(value) = boolean().map_err(|err| { @@ -172,10 +172,10 @@ mod key_impls { &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result< - gix_protocol::transport::client::http::options::HttpVersion, + gix_protocol::transport::client::blocking_io::http::options::HttpVersion, crate::config::key::GenericErrorWithValue, > { - use gix_protocol::transport::client::http::options::HttpVersion; + use gix_protocol::transport::client::blocking_io::http::options::HttpVersion; use crate::bstr::ByteSlice; Ok(match value.as_ref().as_bytes() { @@ -200,10 +200,10 @@ mod key_impls { &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result< - gix_protocol::transport::client::http::options::ProxyAuthMethod, + gix_protocol::transport::client::blocking_io::http::options::ProxyAuthMethod, crate::config::key::GenericErrorWithValue, > { - use gix_protocol::transport::client::http::options::ProxyAuthMethod; + use gix_protocol::transport::client::blocking_io::http::options::ProxyAuthMethod; use crate::bstr::ByteSlice; Ok(match value.as_ref().as_bytes() { @@ -230,9 +230,11 @@ mod key_impls { pub fn try_into_ssl_version( &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, - ) -> Result - { - use gix_protocol::transport::client::http::options::SslVersion::*; + ) -> Result< + gix_protocol::transport::client::blocking_io::http::options::SslVersion, + crate::config::ssl_version::Error, + > { + use gix_protocol::transport::client::blocking_io::http::options::SslVersion::*; use crate::bstr::ByteSlice; Ok(match value.as_ref().as_bytes() { diff --git a/gix/src/config/tree/sections/ssh.rs b/gix/src/config/tree/sections/ssh.rs index 600ee663b59..72bc0105444 100644 --- a/gix/src/config/tree/sections/ssh.rs +++ b/gix/src/config/tree/sections/ssh.rs @@ -23,9 +23,11 @@ mod variant { pub fn try_into_variant( &'static self, value: Cow<'_, BStr>, - ) -> Result, config::key::GenericErrorWithValue> - { - use gix_protocol::transport::client::ssh::ProgramKind; + ) -> Result< + Option, + config::key::GenericErrorWithValue, + > { + use gix_protocol::transport::client::blocking_io::ssh::ProgramKind; use crate::bstr::ByteSlice; Ok(Some(match value.as_ref().as_bytes() { diff --git a/gix/src/remote/connect.rs b/gix/src/remote/connect.rs index 1c70928c5ec..c020d573ee0 100644 --- a/gix/src/remote/connect.rs +++ b/gix/src/remote/connect.rs @@ -2,11 +2,15 @@ use std::borrow::Cow; -use gix_protocol::transport::client::Transport; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::{connect, Transport}; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::{connect, Transport}; use crate::{config::tree::Protocol, remote::Connection, Remote}; mod error { + use super::connect; use crate::{bstr::BString, config, remote}; /// The error returned by [connect()][crate::Remote::connect()]. @@ -24,7 +28,7 @@ mod error { #[error("Protocol {scheme:?} of url {url:?} is denied per configuration")] ProtocolDenied { url: BString, scheme: gix_url::Scheme }, #[error(transparent)] - Connect(#[from] gix_protocol::transport::client::connect::Error), + Connect(#[from] connect::Error), #[error("The {} url was missing - don't know where to establish a connection to", direction.as_str())] MissingUrl { direction: remote::Direction }, #[error("The given protocol version was invalid. Choose between 1 and 2")] @@ -86,9 +90,9 @@ impl<'repo> Remote<'repo> { let (url, version) = self.sanitized_url_and_version(direction)?; #[cfg(feature = "blocking-network-client")] let scheme_is_ssh = url.scheme == gix_url::Scheme::Ssh; - let transport = gix_protocol::transport::connect( + let transport = connect::connect( url, - gix_protocol::transport::client::connect::Options { + connect::Options { version, #[cfg(feature = "blocking-network-client")] ssh: scheme_is_ssh diff --git a/gix/src/remote/connection/access.rs b/gix/src/remote/connection/access.rs index c97fdde912e..b8779dfe1d7 100644 --- a/gix/src/remote/connection/access.rs +++ b/gix/src/remote/connection/access.rs @@ -2,11 +2,15 @@ use crate::{ remote::{connection::AuthenticateFn, Connection}, Remote, }; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; /// Builder impl<'a, T> Connection<'a, '_, T> where - T: gix_transport::client::Transport, + T: Transport, { /// Set a custom credentials callback to provide credentials if the remotes require authentication. /// @@ -43,7 +47,7 @@ where /// Mutation impl<'a, T> Connection<'a, '_, T> where - T: gix_transport::client::Transport, + T: Transport, { /// Like [`with_credentials()`](Self::with_credentials()), but without consuming the connection. pub fn set_credentials( @@ -64,7 +68,7 @@ where /// Access impl<'repo, T> Connection<'_, 'repo, T> where - T: gix_transport::client::Transport, + T: Transport, { /// A utility to return a function that will use this repository's configuration to obtain credentials, similar to /// what `git credential` is doing. diff --git a/gix/src/remote/connection/fetch/mod.rs b/gix/src/remote/connection/fetch/mod.rs index 2e0014b4bea..91838be08b5 100644 --- a/gix/src/remote/connection/fetch/mod.rs +++ b/gix/src/remote/connection/fetch/mod.rs @@ -1,4 +1,7 @@ -use gix_protocol::transport::client::Transport; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; use crate::{ bstr::BString, diff --git a/gix/src/remote/connection/fetch/receive_pack.rs b/gix/src/remote/connection/fetch/receive_pack.rs index 579afebdcf3..b7b4e467f67 100644 --- a/gix/src/remote/connection/fetch/receive_pack.rs +++ b/gix/src/remote/connection/fetch/receive_pack.rs @@ -1,10 +1,11 @@ use std::{ops::DerefMut, path::PathBuf, sync::atomic::AtomicBool}; use gix_odb::store::RefreshMode; -use gix_protocol::{ - fetch::{negotiate, Arguments}, - transport::client::Transport, -}; +use gix_protocol::fetch::{negotiate, Arguments}; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; use crate::{ config::{ diff --git a/gix/src/remote/connection/mod.rs b/gix/src/remote/connection/mod.rs index fc3a37f5be1..9155a880ed2 100644 --- a/gix/src/remote/connection/mod.rs +++ b/gix/src/remote/connection/mod.rs @@ -1,3 +1,8 @@ +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; + use crate::Remote; /// A function that performs a given credential action, trying to obtain credentials for an operation that needs it. @@ -9,7 +14,7 @@ pub type AuthenticateFn<'a> = Box /// much like a remote procedure call. pub struct Connection<'a, 'repo, T> where - T: gix_transport::client::Transport, + T: Transport, { pub(crate) remote: &'a Remote<'repo>, pub(crate) authenticate: Option>, diff --git a/gix/src/remote/connection/ref_map.rs b/gix/src/remote/connection/ref_map.rs index 47b46b6cbdf..a66813ec0d0 100644 --- a/gix/src/remote/connection/ref_map.rs +++ b/gix/src/remote/connection/ref_map.rs @@ -1,5 +1,8 @@ use gix_features::progress::Progress; -use gix_protocol::transport::client::Transport; +#[cfg(feature = "async-network-client")] +use gix_transport::client::async_io::Transport; +#[cfg(feature = "blocking-network-client")] +use gix_transport::client::blocking_io::Transport; use crate::{ bstr::BString, diff --git a/gix/src/repository/config/mod.rs b/gix/src/repository/config/mod.rs index 93e91b7ae8a..15d109530ed 100644 --- a/gix/src/repository/config/mod.rs +++ b/gix/src/repository/config/mod.rs @@ -61,7 +61,8 @@ impl crate::Repository { #[cfg(feature = "blocking-network-client")] pub fn ssh_connect_options( &self, - ) -> Result { + ) -> Result + { use crate::config::{ cache::util::ApplyLeniency, tree::{gitoxide, Core, Ssh}, @@ -77,7 +78,7 @@ impl crate::Repository { config.string_filter(gitoxide::Ssh::COMMAND_WITHOUT_SHELL_FALLBACK, &mut trusted) }) .map(|cmd| gix_path::from_bstr(cmd).into_owned().into()); - let opts = gix_protocol::transport::client::ssh::connect::Options { + let opts = gix_protocol::transport::client::blocking_io::ssh::connect::Options { disallow_shell: fallback_active, command: ssh_command, kind: config diff --git a/gix/src/repository/config/transport.rs b/gix/src/repository/config/transport.rs index c7bb4592af3..3d1c7f70c65 100644 --- a/gix/src/repository/config/transport.rs +++ b/gix/src/repository/config/transport.rs @@ -48,9 +48,9 @@ impl crate::Repository { sync::{Arc, Mutex}, }; - use gix_transport::client::{ - http, - http::options::{ProxyAuthMethod, SslVersion, SslVersionRangeInclusive}, + use gix_transport::client::blocking_io::http::{ + self, + options::{ProxyAuthMethod, SslVersion, SslVersionRangeInclusive}, }; use crate::{ @@ -430,7 +430,8 @@ impl crate::Repository { .transpose() .with_leniency(lenient) .map_err(config::transport::http::Error::from)?; - let backend = gix_protocol::transport::client::http::curl::Options { schannel_check_revoke }; + let backend = + gix_protocol::transport::client::blocking_io::http::curl::Options { schannel_check_revoke }; opts.backend = Some(Arc::new(Mutex::new(backend)) as Arc>); } diff --git a/gix/tests/gix/config/tree.rs b/gix/tests/gix/config/tree.rs index 686f26f461d..1fdbd8915d8 100644 --- a/gix/tests/gix/config/tree.rs +++ b/gix/tests/gix/config/tree.rs @@ -122,7 +122,7 @@ mod ssh { #[cfg(feature = "blocking-network-client")] fn variant() -> crate::Result { use gix::config::tree::Ssh; - use gix_protocol::transport::client::ssh::ProgramKind; + use gix_protocol::transport::client::blocking_io::ssh::ProgramKind; use crate::config::tree::bcow; for (actual, expected) in [ @@ -931,7 +931,7 @@ mod http { #[test] fn follow_redirects() -> crate::Result { - use gix_transport::client::http::options::FollowRedirects; + use gix_transport::client::blocking_io::http::options::FollowRedirects; assert_eq!( Http::FOLLOW_REDIRECTS.try_into_follow_redirects(bcow("initial"), || unreachable!("no call"))?, FollowRedirects::Initial @@ -989,7 +989,7 @@ mod http { #[test] fn http_version() -> crate::Result { - use gix_transport::client::http::options::HttpVersion; + use gix_transport::client::blocking_io::http::options::HttpVersion; for (actual, expected) in [("HTTP/1.1", HttpVersion::V1_1), ("HTTP/2", HttpVersion::V2)] { assert_eq!(Http::VERSION.try_into_http_version(bcow(actual))?, expected); @@ -1009,7 +1009,7 @@ mod http { #[test] fn ssl_version() -> crate::Result { - use gix_transport::client::http::options::SslVersion::*; + use gix_transport::client::blocking_io::http::options::SslVersion::*; for (actual, expected) in [ ("default", Default), @@ -1039,7 +1039,7 @@ mod http { #[test] fn proxy_auth_method() -> crate::Result { - use gix_transport::client::http::options::ProxyAuthMethod::*; + use gix_transport::client::blocking_io::http::options::ProxyAuthMethod::*; for (actual, expected) in [ ("anyauth", AnyAuth), ("basic", Basic), diff --git a/gix/tests/gix/repository/config/mod.rs b/gix/tests/gix/repository/config/mod.rs index 35cbb3d1476..fff507d5155 100644 --- a/gix/tests/gix/repository/config/mod.rs +++ b/gix/tests/gix/repository/config/mod.rs @@ -27,7 +27,10 @@ mod ssh_options { let repo = repo("ssh-all-options"); let opts = repo.ssh_connect_options()?; assert_eq!(opts.command.as_deref(), Some(OsStr::new("ssh -VVV"))); - assert_eq!(opts.kind, Some(gix::protocol::transport::client::ssh::ProgramKind::Ssh)); + assert_eq!( + opts.kind, + Some(gix::protocol::transport::client::blocking_io::ssh::ProgramKind::Ssh) + ); assert!(!opts.disallow_shell, "we can use the shell by default"); Ok(()) } @@ -39,7 +42,7 @@ mod ssh_options { assert_eq!(opts.command.as_deref(), Some(OsStr::new("ssh --fallback"))); assert_eq!( opts.kind, - Some(gix::protocol::transport::client::ssh::ProgramKind::Putty) + Some(gix::protocol::transport::client::blocking_io::ssh::ProgramKind::Putty) ); assert!( opts.disallow_shell, diff --git a/gix/tests/gix/repository/config/transport_options.rs b/gix/tests/gix/repository/config/transport_options.rs index b411a19b776..faf9ed82d0c 100644 --- a/gix/tests/gix/repository/config/transport_options.rs +++ b/gix/tests/gix/repository/config/transport_options.rs @@ -3,7 +3,7 @@ feature = "blocking-http-transport-curl" ))] mod http { - use gix_transport::client::http::options::{ + use gix_transport::client::blocking_io::http::options::{ FollowRedirects, HttpVersion, ProxyAuthMethod, SslVersion, SslVersionRangeInclusive, }; @@ -13,12 +13,12 @@ mod http { repo: &gix::Repository, remote_name: Option<&str>, url: &str, - ) -> gix_transport::client::http::Options { + ) -> gix_transport::client::blocking_io::http::Options { let opts = repo .transport_options(url, remote_name.map(Into::into)) .expect("valid configuration") .expect("configuration available for http"); - opts.downcast_ref::() + opts.downcast_ref::() .expect("http options have been created") .to_owned() } @@ -26,7 +26,7 @@ mod http { #[test] fn remote_overrides() { let repo = repo("http-remote-override"); - let gix_transport::client::http::Options { + let gix_transport::client::blocking_io::http::Options { proxy, proxy_auth_method, follow_redirects, @@ -41,7 +41,7 @@ mod http { #[test] fn simple_configuration() { let repo = repo("http-config"); - let gix_transport::client::http::Options { + let gix_transport::client::blocking_io::http::Options { extra_headers, follow_redirects, low_speed_limit_bytes_per_second, @@ -91,7 +91,7 @@ mod http { .as_ref() .map(|b| b.lock().expect("not poisoned")) .expect("backend is set for curl due to specific options"); - match backend.downcast_ref::() { + match backend.downcast_ref::() { Some(opts) => { assert_eq!(opts.schannel_check_revoke, Some(true)); }