@@ -547,6 +547,63 @@ fn fallback_cargo_calls_correct_rustc() {
547547 } ) ;
548548}
549549
550+ // Checks that cargo can recursively invoke itself with rustup shorthand (via
551+ // the proxy).
552+ //
553+ // This involves a series of chained commands:
554+ //
555+ // 1. Calls `cargo --recursive-cargo-subcommand`
556+ // 2. The rustup `cargo` proxy launches, and launches the "mock" nightly cargo exe.
557+ // 3. The nightly "mock" cargo sees --recursive-cargo-subcommand, and launches
558+ // `cargo-foo --recursive-cargo`
559+ // 4. `cargo-foo` sees `--recursive-cargo` and launches `cargo +nightly --version`
560+ // 5. The rustup `cargo` proxy launches, and launches the "mock" nightly cargo exe.
561+ // 6. The nightly "mock" cargo sees `--version` and prints the version.
562+ //
563+ // Previously, rustup would place the toolchain's `bin` directory in PATH for
564+ // Windows due to some DLL issues. However, those aren't necessary anymore.
565+ // If the toolchain `bin` directory is in PATH, then this test would fail in
566+ // step 5 because the `cargo` executable would be the "mock" nightly cargo,
567+ // and the first argument would be `+nightly` which would be an error.
568+ #[ test]
569+ fn recursive_cargo ( ) {
570+ test ( & |config| {
571+ config. with_scenario ( Scenario :: ArchivesV2 , & |config| {
572+ config. expect_ok ( & [ "rustup" , "default" , "nightly" ] ) ;
573+
574+ // We need an intermediary to run cargo itself.
575+ // The "mock" cargo can't do that because on Windows it will check
576+ // for a `cargo.exe` in the current directory before checking PATH.
577+ //
578+ // The solution here is to copy from the "mock" `cargo.exe` into
579+ // `~/.cargo/bin/cargo-foo`. This is just for convenience to avoid
580+ // needing to build another executable just for this test.
581+ let output = config. run ( "rustup" , & [ "which" , "cargo" ] , & [ ] ) ;
582+ let real_mock_cargo = output. stdout . trim ( ) ;
583+ let cargo_bin_path = config. cargodir . join ( "bin" ) ;
584+ let cargo_subcommand = cargo_bin_path. join ( format ! ( "cargo-foo{}" , EXE_SUFFIX ) ) ;
585+ fs:: create_dir_all ( & cargo_bin_path) . unwrap ( ) ;
586+ fs:: copy ( & real_mock_cargo, & cargo_subcommand) . unwrap ( ) ;
587+
588+ // Verify the default behavior, which is currently broken on Windows.
589+ let args = & [ "cargo" , "--recursive-cargo-subcommand" ] ;
590+ if cfg ! ( windows) {
591+ config. expect_err (
592+ & [ "cargo" , "--recursive-cargo-subcommand" ] ,
593+ "bad mock proxy commandline" ,
594+ ) ;
595+ }
596+
597+ // Try the opt-in, which should fix it.
598+ let out = config. run ( args[ 0 ] , & args[ 1 ..] , & [ ( "RUSTUP_WINDOWS_PATH_ADD_BIN" , "0" ) ] ) ;
599+ if !out. ok || !out. stdout . contains ( "hash-nightly-2" ) {
600+ clitools:: print_command ( args, & out) ;
601+ panic ! ( "expected hash-nightly-2 in output" ) ;
602+ }
603+ } ) ;
604+ } ) ;
605+ }
606+
550607#[ test]
551608fn show_home ( ) {
552609 test ( & |config| {
0 commit comments