@@ -297,7 +297,7 @@ impl<'gctx> InstallablePackage<'gctx> {
297297 Ok ( duplicates)
298298 }
299299
300- fn install_one ( mut self ) -> CargoResult < bool > {
300+ fn install_one ( mut self , dry_run : bool ) -> CargoResult < bool > {
301301 self . gctx . shell ( ) . status ( "Installing" , & self . pkg ) ?;
302302
303303 let dst = self . root . join ( "bin" ) . into_path_unlocked ( ) ;
@@ -321,6 +321,7 @@ impl<'gctx> InstallablePackage<'gctx> {
321321 self . check_yanked_install ( ) ?;
322322
323323 let exec: Arc < dyn Executor > = Arc :: new ( DefaultExecutor ) ;
324+ self . opts . build_config . dry_run = dry_run;
324325 let compile = ops:: compile_ws ( & self . ws , & self . opts , & exec) . with_context ( || {
325326 if let Some ( td) = td_opt. take ( ) {
326327 // preserve the temporary directory, so the user can inspect it
@@ -419,13 +420,15 @@ impl<'gctx> InstallablePackage<'gctx> {
419420 let staging_dir = TempFileBuilder :: new ( )
420421 . prefix ( "cargo-install" )
421422 . tempdir_in ( & dst) ?;
422- for & ( bin, src) in binaries. iter ( ) {
423- let dst = staging_dir. path ( ) . join ( bin) ;
424- // Try to move if `target_dir` is transient.
425- if !self . source_id . is_path ( ) && fs:: rename ( src, & dst) . is_ok ( ) {
426- continue ;
423+ if !dry_run {
424+ for & ( bin, src) in binaries. iter ( ) {
425+ let dst = staging_dir. path ( ) . join ( bin) ;
426+ // Try to move if `target_dir` is transient.
427+ if !self . source_id . is_path ( ) && fs:: rename ( src, & dst) . is_ok ( ) {
428+ continue ;
429+ }
430+ paths:: copy ( src, & dst) ?;
427431 }
428- paths:: copy ( src, & dst) ?;
429432 }
430433
431434 let ( to_replace, to_install) : ( Vec < & str > , Vec < & str > ) = binaries
@@ -441,11 +444,13 @@ impl<'gctx> InstallablePackage<'gctx> {
441444 let src = staging_dir. path ( ) . join ( bin) ;
442445 let dst = dst. join ( bin) ;
443446 self . gctx . shell ( ) . status ( "Installing" , dst. display ( ) ) ?;
444- fs:: rename ( & src, & dst) . with_context ( || {
445- format ! ( "failed to move `{}` to `{}`" , src. display( ) , dst. display( ) )
446- } ) ?;
447- installed. bins . push ( dst) ;
448- successful_bins. insert ( bin. to_string ( ) ) ;
447+ if !dry_run {
448+ fs:: rename ( & src, & dst) . with_context ( || {
449+ format ! ( "failed to move `{}` to `{}`" , src. display( ) , dst. display( ) )
450+ } ) ?;
451+ installed. bins . push ( dst) ;
452+ successful_bins. insert ( bin. to_string ( ) ) ;
453+ }
449454 }
450455
451456 // Repeat for binaries which replace existing ones but don't pop the error
@@ -456,10 +461,12 @@ impl<'gctx> InstallablePackage<'gctx> {
456461 let src = staging_dir. path ( ) . join ( bin) ;
457462 let dst = dst. join ( bin) ;
458463 self . gctx . shell ( ) . status ( "Replacing" , dst. display ( ) ) ?;
459- fs:: rename ( & src, & dst) . with_context ( || {
460- format ! ( "failed to move `{}` to `{}`" , src. display( ) , dst. display( ) )
461- } ) ?;
462- successful_bins. insert ( bin. to_string ( ) ) ;
464+ if !dry_run {
465+ fs:: rename ( & src, & dst) . with_context ( || {
466+ format ! ( "failed to move `{}` to `{}`" , src. display( ) , dst. display( ) )
467+ } ) ?;
468+ successful_bins. insert ( bin. to_string ( ) ) ;
469+ }
463470 }
464471 Ok ( ( ) )
465472 } ;
@@ -476,9 +483,14 @@ impl<'gctx> InstallablePackage<'gctx> {
476483 & self . rustc . verbose_version ,
477484 ) ;
478485
479- if let Err ( e) =
480- remove_orphaned_bins ( & self . ws , & mut tracker, & duplicates, & self . pkg , & dst)
481- {
486+ if let Err ( e) = remove_orphaned_bins (
487+ & self . ws ,
488+ & mut tracker,
489+ & duplicates,
490+ & self . pkg ,
491+ & dst,
492+ dry_run,
493+ ) {
482494 // Don't hard error on remove.
483495 self . gctx
484496 . shell ( )
@@ -515,7 +527,10 @@ impl<'gctx> InstallablePackage<'gctx> {
515527 }
516528 }
517529
518- if duplicates. is_empty ( ) {
530+ if dry_run {
531+ self . gctx . shell ( ) . warn ( "aborting install due to dry run" ) ?;
532+ Ok ( true )
533+ } else if duplicates. is_empty ( ) {
519534 self . gctx . shell ( ) . status (
520535 "Installed" ,
521536 format ! (
@@ -620,6 +635,7 @@ pub fn install(
620635 opts : & ops:: CompileOptions ,
621636 force : bool ,
622637 no_track : bool ,
638+ dry_run : bool ,
623639) -> CargoResult < ( ) > {
624640 let root = resolve_root ( root, gctx) ?;
625641 let dst = root. join ( "bin" ) . into_path_unlocked ( ) ;
@@ -654,7 +670,7 @@ pub fn install(
654670 ) ?;
655671 let mut installed_anything = true ;
656672 if let Some ( installable_pkg) = installable_pkg {
657- installed_anything = installable_pkg. install_one ( ) ?;
673+ installed_anything = installable_pkg. install_one ( dry_run ) ?;
658674 }
659675 ( installed_anything, false )
660676 } else {
@@ -705,7 +721,7 @@ pub fn install(
705721
706722 let install_results: Vec < _ > = pkgs_to_install
707723 . into_iter ( )
708- . map ( |( krate, installable_pkg) | ( krate, installable_pkg. install_one ( ) ) )
724+ . map ( |( krate, installable_pkg) | ( krate, installable_pkg. install_one ( dry_run ) ) )
709725 . collect ( ) ;
710726
711727 for ( krate, result) in install_results {
@@ -857,6 +873,7 @@ fn remove_orphaned_bins(
857873 duplicates : & BTreeMap < String , Option < PackageId > > ,
858874 pkg : & Package ,
859875 dst : & Path ,
876+ dry_run : bool ,
860877) -> CargoResult < ( ) > {
861878 let filter = ops:: CompileFilter :: new_all_targets ( ) ;
862879 let all_self_names = exe_names ( pkg, & filter) ;
@@ -894,8 +911,10 @@ fn remove_orphaned_bins(
894911 old_pkg
895912 ) ,
896913 ) ?;
897- paths:: remove_file ( & full_path)
898- . with_context ( || format ! ( "failed to remove {:?}" , full_path) ) ?;
914+ if !dry_run {
915+ paths:: remove_file ( & full_path)
916+ . with_context ( || format ! ( "failed to remove {:?}" , full_path) ) ?;
917+ }
899918 }
900919 }
901920 }
0 commit comments