@@ -7,13 +7,14 @@ extern crate toml;
77#[ macro_use] extern crate log;
88
99use std:: collections:: BTreeSet ;
10+ use std:: collections:: HashMap ;
1011use std:: env;
1112use std:: fs;
1213use std:: path:: { Path , PathBuf } ;
1314
1415use cargo:: core:: shell:: Verbosity ;
1516use cargo:: execute_main_without_stdin;
16- use cargo:: util:: { self , CliResult , lev_distance, Config , human} ;
17+ use cargo:: util:: { self , CliResult , lev_distance, Config , human, CargoResult } ;
1718use cargo:: util:: CliError ;
1819use cargo:: util:: process_builder:: process;
1920
@@ -138,7 +139,7 @@ fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
138139 return Ok ( None )
139140 }
140141
141- let args = match & flags. arg_command [ ..] {
142+ let mut args = match & flags. arg_command [ ..] {
142143 // For the commands `cargo` and `cargo help`, re-execute ourselves as
143144 // `cargo -h` so we can go through the normal process of printing the
144145 // help message.
@@ -166,9 +167,30 @@ fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
166167 // For all other invocations, we're of the form `cargo foo args...`. We
167168 // use the exact environment arguments to preserve tokens like `--` for
168169 // example.
169- _ => env:: args ( ) . collect ( ) ,
170+ _ => {
171+ let mut default_alias = HashMap :: new ( ) ;
172+ default_alias. insert ( "b" , "build" . to_string ( ) ) ;
173+ default_alias. insert ( "t" , "test" . to_string ( ) ) ;
174+ default_alias. insert ( "r" , "run" . to_string ( ) ) ;
175+ let mut args: Vec < String > = env:: args ( ) . collect ( ) ;
176+ if let Some ( new_command) = default_alias. get ( & args[ 1 ] [ ..] ) {
177+ args[ 1 ] = new_command. clone ( ) ;
178+ }
179+ args
180+ }
170181 } ;
171182
183+ let alias_list = try!( aliased_command ( & config, & args[ 1 ] ) ) ;
184+ if let Some ( alias_command) = alias_list {
185+ // Replace old command with new command and flags
186+ let chain = args. iter ( ) . take ( 1 )
187+ . chain ( alias_command. iter ( ) )
188+ . chain ( args. iter ( ) . skip ( 2 ) )
189+ . map ( |s| s. to_string ( ) )
190+ . collect ( ) ;
191+ args = chain;
192+ }
193+
172194 macro_rules! cmd{
173195 ( $name: ident) => ( if args[ 1 ] == stringify!( $name) . replace( "_" , "-" ) {
174196 config. shell( ) . set_verbosity( Verbosity :: Verbose ) ;
@@ -186,6 +208,30 @@ fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
186208 Ok ( None )
187209}
188210
211+ fn aliased_command ( config : & Config , command : & String ) -> CargoResult < Option < Vec < String > > > {
212+ let alias_name = format ! ( "alias.{}" , command) ;
213+ let mut result = Ok ( None ) ;
214+ match config. get_string ( & alias_name) {
215+ Ok ( value) => {
216+ if let Some ( record) = value {
217+ let alias_commands = record. val . split_whitespace ( )
218+ . map ( |s| s. to_string ( ) )
219+ . collect ( ) ;
220+ result = Ok ( Some ( alias_commands) ) ;
221+ }
222+ } ,
223+ Err ( _) => {
224+ let value = try!( config. get_list ( & alias_name) ) ;
225+ if let Some ( record) = value {
226+ let alias_commands: Vec < String > = record. val . iter ( )
227+ . map ( |s| s. 0 . to_string ( ) ) . collect ( ) ;
228+ result = Ok ( Some ( alias_commands) ) ;
229+ }
230+ }
231+ }
232+ result
233+ }
234+
189235fn find_closest ( config : & Config , cmd : & str ) -> Option < String > {
190236 let cmds = list_commands ( config) ;
191237 // Only consider candidates with a lev_distance of 3 or less so we don't
0 commit comments