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