33extern crate cargo_metadata;
44
55use std:: path:: { PathBuf , Path } ;
6- use std:: io:: { self , Write } ;
6+ use std:: io:: { self , Write , BufRead } ;
77use std:: process:: Command ;
88use std:: fs:: { self , File } ;
99
@@ -114,6 +114,36 @@ fn list_targets() -> impl Iterator<Item=cargo_metadata::Target> {
114114 package. targets . into_iter ( )
115115}
116116
117+ fn xargo_version ( ) -> Option < ( u32 , u32 , u32 ) > {
118+ let out = Command :: new ( "xargo" ) . arg ( "--version" ) . output ( ) . ok ( ) ?;
119+ if !out. status . success ( ) {
120+ return None ;
121+ }
122+ // Parse output. The first line looks like "xargo 0.3.12 (b004f1c 2018-12-13)".
123+ let line = out. stderr . lines ( ) . nth ( 0 )
124+ . expect ( "malformed `xargo --version` output: not at least one line" )
125+ . expect ( "malformed `xargo --version` output: error reading first line" ) ;
126+ let version = line. split ( ' ' ) . nth ( 1 )
127+ . expect ( "malformed `xargo --version` output: not at least two words" ) ;
128+ let mut version_pieces = version. split ( '.' ) ;
129+ let major = version_pieces. next ( )
130+ . expect ( "malformed `xargo --version` output: not a major version piece" )
131+ . parse ( )
132+ . expect ( "malformed `xargo --version` output: major version is not an integer" ) ;
133+ let minor = version_pieces. next ( )
134+ . expect ( "malformed `xargo --version` output: not a minor version piece" )
135+ . parse ( )
136+ . expect ( "malformed `xargo --version` output: minor version is not an integer" ) ;
137+ let patch = version_pieces. next ( )
138+ . expect ( "malformed `xargo --version` output: not a patch version piece" )
139+ . parse ( )
140+ . expect ( "malformed `xargo --version` output: patch version is not an integer" ) ;
141+ if !version_pieces. next ( ) . is_none ( ) {
142+ panic ! ( "malformed `xargo --version` output: more than three pieces in version" ) ;
143+ }
144+ Some ( ( major, minor, patch) )
145+ }
146+
117147fn ask ( question : & str ) {
118148 let mut buf = String :: new ( ) ;
119149 print ! ( "{} [Y/n] " , question) ;
@@ -134,14 +164,15 @@ fn setup(ask_user: bool) {
134164 }
135165
136166 // First, we need xargo
137- if Command :: new ( " xargo" ) . arg ( "--version" ) . output ( ) . is_err ( )
138- {
167+ let xargo = xargo_version ( ) ;
168+ if xargo . map_or ( true , |v| v < ( 0 , 3 , 13 ) ) {
139169 if ask_user {
140- ask ( "It seems you do not have xargo installed. I will run `cargo install xargo`. Proceed?" ) ;
170+ ask ( "It seems you do not have a recent enough xargo installed. I will run `cargo install xargo -f `. Proceed?" ) ;
141171 } else {
142- println ! ( "Installing xargo: `cargo install xargo`" ) ;
172+ println ! ( "Installing xargo: `cargo install xargo -f `" ) ;
143173 }
144- if !Command :: new ( "cargo" ) . args ( & [ "install" , "xargo" ] ) . status ( ) . unwrap ( ) . success ( ) {
174+ // FIXME: Go back to using releases, once a 0.3.13 got released.
175+ if !Command :: new ( "cargo" ) . args ( & [ "install" , "xargo" , "-f" , "--git" , "https://github.com/japaric/xargo" ] ) . status ( ) . unwrap ( ) . success ( ) {
145176 show_error ( format ! ( "Failed to install xargo" ) ) ;
146177 }
147178 }
0 commit comments