@@ -4,6 +4,7 @@ extern crate url;
44
55use clap:: { Arg , ArgMatches , App } ;
66use reqwest:: { RequestBuilder } ;
7+ use rpassword;
78use url:: Url ;
89
910/// Connection information for Code Dx.
@@ -63,10 +64,11 @@ impl ClientConfig {
6364 . arg ( Arg :: with_name ( "base-url" )
6465 . short ( "b" )
6566 . long ( "base-url" )
66- . value_name ( "VALUE " )
67+ . value_name ( "BASE URL " )
6768 . help ( "Code Dx base url (e.g. 'https://localhost/codedx')" )
6869 . takes_value ( true )
6970 . required ( true )
71+ . index ( 1 )
7072 )
7173 . arg ( Arg :: with_name ( "username" )
7274 . short ( "u" )
@@ -101,29 +103,45 @@ impl ClientConfig {
101103 ) ;
102104 let matches = get_matches ( app) ;
103105
106+ // parse the base-url as a URI, then attempt to access the `path_segments_mut` to
107+ // ensure that will work once we pass the base url to the api client code.
104108 let base_uri = match matches. value_of ( "base-url" ) {
105109 None => Err ( ConfigError :: MissingUrl ) ,
106- Some ( raw) => Url :: parse ( raw) . map_err ( |_| ConfigError :: InvalidUrl ) ,
110+ Some ( raw) => Url :: parse ( raw) . map_err ( |_| ConfigError :: InvalidUrl ) . and_then ( |mut url| {
111+ let url_seems_ok = {
112+ let url_segments = url. path_segments_mut ( ) ;
113+ match url_segments {
114+ Ok ( _) => Ok ( ( ) ) ,
115+ Err ( _) => Err ( ConfigError :: InvalidUrl ) ,
116+ }
117+ } ;
118+ url_seems_ok. map ( |_| url)
119+ } ) ,
107120 } ;
108121
109- let client_auth_info = match matches. value_of ( "api-key" ) {
110- Some ( key) => Ok ( ClientAuth :: ApiKey ( String :: from ( key) ) ) ,
111- None => {
112- let username = matches. value_of ( "username" ) . map ( String :: from) ;
113- let password = matches. value_of ( "password" ) . map ( String :: from) ;
114- let foo = username. and_then ( |u| {
115- password. map ( |p| {
116- ClientAuth :: Basic { username : u, password : p }
117- } )
118- } ) ;
119- foo. ok_or_else ( || ConfigError :: MissingAuth )
120- } ,
121- } ;
122+ base_uri. and_then ( |uri| {
122123
123- let insecure = matches. is_present ( "insecure" ) ;
124- let no_prompt = matches. is_present ( "no-prompt" ) ;
124+ // interpret the authentication values
125+ let client_auth_info = match matches. value_of ( "api-key" ) {
126+ Some ( key) => Ok ( ClientAuth :: ApiKey ( String :: from ( key) ) ) ,
127+ None => {
128+ let username = matches. value_of ( "username" ) . map ( String :: from) ;
129+ let password = matches. value_of ( "password" ) . map ( String :: from) ;
130+ let foo = username. and_then ( |u| {
131+ password. or_else ( || {
132+ // prompt for the password without actually showing what the user types
133+ rpassword:: prompt_password_stdout ( "password: " ) . ok ( )
134+ } ) . map ( |p| {
135+ ClientAuth :: Basic { username : u, password : p }
136+ } )
137+ } ) ;
138+ foo. ok_or_else ( || ConfigError :: MissingAuth )
139+ } ,
140+ } ;
141+
142+ let insecure = matches. is_present ( "insecure" ) ;
143+ let no_prompt = matches. is_present ( "no-prompt" ) ;
125144
126- base_uri. and_then ( |uri| {
127145 client_auth_info. map ( |auth| {
128146 ClientConfig {
129147 base_url : uri,
0 commit comments