@@ -391,10 +391,13 @@ fn cargo_subcommand_env() {
391
391
. canonicalize ( )
392
392
. unwrap ( ) ;
393
393
let envtest_bin = envtest_bin. to_str ( ) . unwrap ( ) ;
394
+ // Previously, `$CARGO` would be left at `envtest_bin`. However, with the
395
+ // fix for #15099, `$CARGO` is now overwritten with the path to the current
396
+ // exe when it is detected to be a cargo binary.
394
397
cargo_process ( "envtest" )
395
398
. env ( "PATH" , & path)
396
399
. env ( cargo:: CARGO_ENV , & envtest_bin)
397
- . with_stdout_data ( format ! ( "{}\n " , envtest_bin ) . raw ( ) . raw ( ) )
400
+ . with_stdout_data ( format ! ( "{}\n " , cargo . display ( ) ) . raw ( ) )
398
401
. run ( ) ;
399
402
}
400
403
@@ -570,3 +573,87 @@ fn full_did_you_mean() {
570
573
"# ] ] )
571
574
. run ( ) ;
572
575
}
576
+
577
+ #[ cargo_test]
578
+ fn overwrite_cargo_environment_variable ( ) {
579
+ // If passed arguments `arg1 arg2 ...`, this program runs them as a command.
580
+ // If passed no arguments, this program simply prints `$CARGO`.
581
+ let p = project ( )
582
+ . file ( "Cargo.toml" , & basic_manifest ( "foo" , "1.0.0" ) )
583
+ . file (
584
+ "src/main.rs" ,
585
+ r#"
586
+ fn main() {
587
+ let mut args = std::env::args().skip(1);
588
+ if let Some(arg1) = args.next() {
589
+ let status = std::process::Command::new(arg1)
590
+ .args(args)
591
+ .status()
592
+ .unwrap();
593
+ assert!(status.success());
594
+ } else {
595
+ eprintln!("{}", std::env::var("CARGO").unwrap());
596
+ }
597
+ }
598
+ "# ,
599
+ )
600
+ . build ( ) ;
601
+
602
+ // Create two other cargo binaries in the project root, one with the wrong
603
+ // name and one with the right name.
604
+ let cargo_exe = cargo_test_support:: cargo_exe ( ) ;
605
+ let wrong_name_path = p
606
+ . root ( )
607
+ . join ( format ! ( "wrong_name{}" , env:: consts:: EXE_SUFFIX ) ) ;
608
+ let other_cargo_path = p. root ( ) . join ( cargo_exe. file_name ( ) . unwrap ( ) ) ;
609
+ std:: fs:: hard_link ( & cargo_exe, & wrong_name_path) . unwrap ( ) ;
610
+ std:: fs:: hard_link ( & cargo_exe, & other_cargo_path) . unwrap ( ) ;
611
+
612
+ // The output of each of the following commands should be `path-to-cargo`:
613
+ // ```
614
+ // cargo run
615
+ // cargo run -- cargo run
616
+ // cargo run -- wrong_name run
617
+ // ```
618
+
619
+ let cargo = cargo_exe. display ( ) . to_string ( ) ;
620
+ let wrong_name = wrong_name_path. display ( ) . to_string ( ) ;
621
+ let stderr_cargo = format ! (
622
+ "{}[EXE]\n " ,
623
+ cargo_exe
624
+ . canonicalize( )
625
+ . unwrap( )
626
+ . with_extension( "" )
627
+ . to_str( )
628
+ . unwrap( )
629
+ ) ;
630
+
631
+ for cmd in [
632
+ "run" ,
633
+ & format ! ( "run -- {cargo} run" ) ,
634
+ & format ! ( "run -- {wrong_name} run" ) ,
635
+ ] {
636
+ p. cargo ( cmd) . with_stderr_contains ( & stderr_cargo) . run ( ) ;
637
+ }
638
+
639
+ // The output of the following command should be `path-to-other-cargo`:
640
+ // ```
641
+ // cargo run -- other_cargo run
642
+ // ```
643
+
644
+ let other_cargo = other_cargo_path. display ( ) . to_string ( ) ;
645
+ let stderr_other_cargo = format ! (
646
+ "{}[EXE]\n " ,
647
+ other_cargo_path
648
+ . canonicalize( )
649
+ . unwrap( )
650
+ . with_extension( "" )
651
+ . to_str( )
652
+ . unwrap( )
653
+ . replace( p. root( ) . parent( ) . unwrap( ) . to_str( ) . unwrap( ) , "[ROOT]" )
654
+ ) ;
655
+
656
+ p. cargo ( & format ! ( "run -- {other_cargo} run" ) )
657
+ . with_stderr_contains ( stderr_other_cargo)
658
+ . run ( ) ;
659
+ }
0 commit comments