1
- use std:: process:: Stdio ;
1
+ use std:: {
2
+ ffi:: OsStr ,
3
+ process:: { Command , Stdio } ,
4
+ } ;
2
5
3
- use gix_url:: ArgumentSafety :: * ;
6
+ use gix_url:: { ArgumentSafety :: * , Url } ;
4
7
5
- use crate :: { client:: blocking_io, Protocol } ;
8
+ use crate :: {
9
+ client:: { self , blocking_io:: file:: SpawnProcessOnDemand } ,
10
+ Protocol ,
11
+ } ;
6
12
7
13
/// The error used in [`connect()`].
8
14
#[ derive( Debug , thiserror:: Error ) ]
@@ -100,44 +106,18 @@ pub mod connect {
100
106
/// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate.
101
107
#[ allow( clippy:: result_large_err) ]
102
108
pub fn connect (
103
- url : gix_url :: Url ,
109
+ url : Url ,
104
110
desired_version : Protocol ,
105
111
options : connect:: Options ,
106
112
trace : bool ,
107
- ) -> Result < blocking_io :: file :: SpawnProcessOnDemand , Error > {
113
+ ) -> Result < SpawnProcessOnDemand , Error > {
108
114
if url. scheme != gix_url:: Scheme :: Ssh || url. host ( ) . is_none ( ) {
109
115
return Err ( Error :: UnsupportedScheme ( url) ) ;
110
116
}
111
117
let ssh_cmd = options. ssh_command ( ) ;
112
- let mut kind = options. kind . unwrap_or_else ( || ProgramKind :: from ( ssh_cmd) ) ;
113
- if options. kind . is_none ( ) && kind == ProgramKind :: Simple {
114
- let mut cmd = std:: process:: Command :: from ( {
115
- let mut prepare = gix_command:: prepare ( ssh_cmd)
116
- . stderr ( Stdio :: null ( ) )
117
- . stdout ( Stdio :: null ( ) )
118
- . stdin ( Stdio :: null ( ) )
119
- . command_may_be_shell_script ( )
120
- . arg ( "-G" )
121
- . arg ( match url. host_as_argument ( ) {
122
- Usable ( host) => host,
123
- Dangerous ( host) => Err ( Error :: AmbiguousHostName { host : host. into ( ) } ) ?,
124
- Absent => panic ! ( "BUG: host should always be present in SSH URLs" ) ,
125
- } ) ;
126
- if options. disallow_shell {
127
- prepare. use_shell = false ;
128
- }
129
- prepare
130
- } ) ;
131
- gix_features:: trace:: debug!( cmd = ?cmd, "invoking `ssh` for feature check" ) ;
132
- kind = if cmd. status ( ) . ok ( ) . is_some_and ( |status| status. success ( ) ) {
133
- ProgramKind :: Ssh
134
- } else {
135
- ProgramKind :: Simple
136
- } ;
137
- }
138
-
118
+ let kind = determine_client_kind ( options. kind , ssh_cmd, & url, options. disallow_shell ) ?;
139
119
let path = gix_url:: expand_path:: for_shell ( url. path . clone ( ) ) ;
140
- Ok ( blocking_io :: file :: SpawnProcessOnDemand :: new_ssh (
120
+ Ok ( SpawnProcessOnDemand :: new_ssh (
141
121
url,
142
122
ssh_cmd,
143
123
path,
@@ -148,5 +128,42 @@ pub fn connect(
148
128
) )
149
129
}
150
130
131
+ fn determine_client_kind (
132
+ known_kind : Option < ProgramKind > ,
133
+ ssh_cmd : & OsStr ,
134
+ url : & Url ,
135
+ disallow_shell : bool ,
136
+ ) -> Result < ProgramKind , Error > {
137
+ let mut kind = known_kind. unwrap_or_else ( || ProgramKind :: from ( ssh_cmd) ) ;
138
+ if known_kind. is_none ( ) && kind == ProgramKind :: Simple {
139
+ let mut cmd = build_client_feature_check_command ( ssh_cmd, url, disallow_shell) ?;
140
+ gix_features:: trace:: debug!( cmd = ?cmd, "invoking `ssh` for feature check" ) ;
141
+ kind = if cmd. status ( ) . ok ( ) . is_some_and ( |status| status. success ( ) ) {
142
+ ProgramKind :: Ssh
143
+ } else {
144
+ ProgramKind :: Simple
145
+ } ;
146
+ }
147
+ Ok ( kind)
148
+ }
149
+
150
+ fn build_client_feature_check_command ( ssh_cmd : & OsStr , url : & Url , disallow_shell : bool ) -> Result < Command , Error > {
151
+ let mut prepare = gix_command:: prepare ( ssh_cmd)
152
+ . stderr ( Stdio :: null ( ) )
153
+ . stdout ( Stdio :: null ( ) )
154
+ . stdin ( Stdio :: null ( ) )
155
+ . command_may_be_shell_script ( )
156
+ . arg ( "-G" )
157
+ . arg ( match url. host_as_argument ( ) {
158
+ Usable ( host) => host,
159
+ Dangerous ( host) => Err ( Error :: AmbiguousHostName { host : host. into ( ) } ) ?,
160
+ Absent => panic ! ( "BUG: host should always be present in SSH URLs" ) ,
161
+ } ) ;
162
+ if disallow_shell {
163
+ prepare. use_shell = false ;
164
+ }
165
+ Ok ( prepare. into ( ) )
166
+ }
167
+
151
168
#[ cfg( test) ]
152
169
mod tests;
0 commit comments