@@ -59,6 +59,7 @@ use core::PackageIdSpec;
59
59
use core:: { Dependency , PackageId , Registry , Summary } ;
60
60
use util:: config:: Config ;
61
61
use util:: errors:: { CargoError , CargoResult } ;
62
+ use util:: lev_distance:: lev_distance;
62
63
use util:: profile;
63
64
64
65
use self :: context:: { Activations , Context } ;
@@ -230,7 +231,9 @@ fn activate_deps_loop(
230
231
// to amortize the cost of the current time lookup.
231
232
ticks += 1 ;
232
233
if let Some ( config) = config {
233
- if config. shell ( ) . is_err_tty ( ) && !printed && ticks % 1000 == 0
234
+ if config. shell ( ) . is_err_tty ( )
235
+ && !printed
236
+ && ticks % 1000 == 0
234
237
&& start. elapsed ( ) - deps_time > time_to_print
235
238
{
236
239
printed = true ;
@@ -857,12 +860,14 @@ fn activation_error(
857
860
msg. push_str ( "\n versions that meet the requirements `" ) ;
858
861
msg. push_str ( & dep. version_req ( ) . to_string ( ) ) ;
859
862
msg. push_str ( "` are: " ) ;
860
- msg. push_str ( & candidates
861
- . iter ( )
862
- . map ( |v| v. summary . version ( ) )
863
- . map ( |v| v. to_string ( ) )
864
- . collect :: < Vec < _ > > ( )
865
- . join ( ", " ) ) ;
863
+ msg. push_str (
864
+ & candidates
865
+ . iter ( )
866
+ . map ( |v| v. summary . version ( ) )
867
+ . map ( |v| v. to_string ( ) )
868
+ . collect :: < Vec < _ > > ( )
869
+ . join ( ", " ) ,
870
+ ) ;
866
871
867
872
let mut conflicting_activations: Vec < _ > = conflicting_activations. iter ( ) . collect ( ) ;
868
873
conflicting_activations. sort_unstable ( ) ;
@@ -922,17 +927,16 @@ fn activation_error(
922
927
return format_err ! ( "{}" , msg) ;
923
928
}
924
929
925
- // Once we're all the way down here, we're definitely lost in the
926
- // weeds! We didn't actually find any candidates, so we need to
930
+ // We didn't actually find any candidates, so we need to
927
931
// give an error message that nothing was found.
928
932
//
929
- // Note that we re-query the registry with a new dependency that
930
- // allows any version so we can give some nicer error reporting
931
- // which indicates a few versions that were actually found.
933
+ // Maybe the user mistyped the ver_req? Like `dep="2"` when `dep="0.2"`
934
+ // was meant. So we re-query the registry with `deb="*"` so we can
935
+ // list a few versions that were actually found.
932
936
let all_req = semver:: VersionReq :: parse ( "*" ) . unwrap ( ) ;
933
937
let mut new_dep = dep. clone ( ) ;
934
938
new_dep. set_version_req ( all_req) ;
935
- let mut candidates = match registry. query_vec ( & new_dep) {
939
+ let mut candidates = match registry. query_vec ( & new_dep, false ) {
936
940
Ok ( candidates) => candidates,
937
941
Err ( e) => return e,
938
942
} ;
@@ -977,12 +981,41 @@ fn activation_error(
977
981
978
982
msg
979
983
} else {
984
+ // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
985
+ // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
986
+ let mut candidates = Vec :: new ( ) ;
987
+ if let Err ( e) = registry. query ( & new_dep, & mut |s| candidates. push ( s. name ( ) ) , true ) {
988
+ return e;
989
+ } ;
990
+ candidates. sort_unstable ( ) ;
991
+ candidates. dedup ( ) ;
992
+ let mut candidates: Vec < _ > = candidates
993
+ . iter ( )
994
+ . map ( |n| ( lev_distance ( & * new_dep. name ( ) , & * n) , n) )
995
+ . filter ( |& ( d, _) | d < 4 )
996
+ . collect ( ) ;
997
+ candidates. sort_by_key ( |o| o. 0 ) ;
980
998
let mut msg = format ! (
981
999
"no matching package named `{}` found\n \
982
1000
location searched: {}\n ",
983
1001
dep. name( ) ,
984
1002
dep. source_id( )
985
1003
) ;
1004
+ if !candidates. is_empty ( ) {
1005
+ let mut names = candidates
1006
+ . iter ( )
1007
+ . take ( 3 )
1008
+ . map ( |c| c. 1 . as_str ( ) )
1009
+ . collect :: < Vec < _ > > ( ) ;
1010
+
1011
+ if candidates. len ( ) > 3 {
1012
+ names. push ( "..." ) ;
1013
+ }
1014
+
1015
+ msg. push_str ( "did you mean: " ) ;
1016
+ msg. push_str ( & names. join ( ", " ) ) ;
1017
+ msg. push_str ( "\n " ) ;
1018
+ }
986
1019
msg. push_str ( "required by " ) ;
987
1020
msg. push_str ( & describe_path ( & graph. path_to_top ( parent. package_id ( ) ) ) ) ;
988
1021
0 commit comments