diff --git a/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs b/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs index 20e7e97a628e96..12501889471756 100644 --- a/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs +++ b/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs @@ -82,6 +82,35 @@ public void InvalidFileOrCommand_NoSDK_ListsPossibleIssues() .And.FindAnySdk(false); } + [Fact] + public void DotNetInfo_NoSDK() + { + sharedTestState.BuiltDotNet.Exec("--info") + .CaptureStdOut() + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutMatching($@"Architecture:\s*{RepoDirectoriesProvider.Default.BuildArchitecture}") + .And.HaveStdOutMatching($@"RID:\s*{RepoDirectoriesProvider.Default.BuildRID}"); + } + + [Fact] + public void DotNetInfo_WithSDK() + { + DotNetCli dotnet = new DotNetBuilder(sharedTestState.BaseDirectory.Location, RepoDirectoriesProvider.Default.BuiltDotnet, "withSdk") + .AddMicrosoftNETCoreAppFrameworkMockHostPolicy("1.0.0") + .AddMockSDK("1.0.0", "1.0.0") + .Build(); + + dotnet.Exec("--info") + .WorkingDirectory(sharedTestState.BaseDirectory.Location) + .CaptureStdOut() + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.NotHaveStdOutMatching($@"RID:\s*{RepoDirectoriesProvider.Default.BuildRID}"); + } + // Return a non-existent path that contains a mix of / and \ private string GetNonexistentAndUnnormalizedPath() { diff --git a/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs b/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs index f939ba1388336b..f312913aff8a05 100644 --- a/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs +++ b/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs @@ -74,6 +74,13 @@ public AndConstraint HaveStdOutMatching(string pattern, return new AndConstraint(this); } + public AndConstraint NotHaveStdOutMatching(string pattern, RegexOptions options = RegexOptions.None) + { + Execute.Assertion.ForCondition(!Regex.IsMatch(Result.StdOut, pattern, options)) + .FailWith($"The command output matched a pattern is should not have matched. Pattern: '{pattern}'{GetDiagnosticsInfo()}"); + return new AndConstraint(this); + } + public AndConstraint HaveStdErr() { Execute.Assertion.ForCondition(!string.IsNullOrEmpty(Result.StdErr)) diff --git a/src/native/corehost/fxr/command_line.cpp b/src/native/corehost/fxr/command_line.cpp index 7f0a4d5a929594..3c85d3669ec7b3 100644 --- a/src/native/corehost/fxr/command_line.cpp +++ b/src/native/corehost/fxr/command_line.cpp @@ -280,17 +280,18 @@ int command_line::parse_args_for_sdk_command( return parse_args(host_info, 1, argc, argv, false, host_mode_t::muxer, new_argoff, app_candidate, opts); } -void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path) +void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path, bool skip_sdk_info_output) { pal::string_t commit = _STRINGIFY(REPO_COMMIT_HASH); trace::println(_X("\n") _X("Host:\n") _X(" Version: ") _STRINGIFY(HOST_VERSION) _X("\n") _X(" Architecture: ") _STRINGIFY(CURRENT_ARCH_NAME) _X("\n") - _X(" Commit: %s\n") - _X(" RID: %s"), - commit.substr(0, 10).c_str(), - get_runtime_id().c_str()); + _X(" Commit: %s"), + commit.substr(0, 10).c_str()); + + if (!skip_sdk_info_output) + trace::println(_X(" RID: %s"), get_runtime_id().c_str()); trace::println(_X("\n") _X(".NET SDKs installed:")); diff --git a/src/native/corehost/fxr/command_line.h b/src/native/corehost/fxr/command_line.h index 4880ea60f0e45c..935e66800870e5 100644 --- a/src/native/corehost/fxr/command_line.h +++ b/src/native/corehost/fxr/command_line.h @@ -57,7 +57,9 @@ namespace command_line /*out*/ pal::string_t &app_candidate, /*out*/ opt_map_t &opts); - void print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path); + // skip_sdk_info_output indicates whether or not to skip any information that the SDK would have + // already printed. Related: https://github.com/dotnet/sdk/issues/33697 + void print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path, bool skip_sdk_info_output); void print_muxer_usage(bool is_sdk_present); }; diff --git a/src/native/corehost/fxr/fx_muxer.cpp b/src/native/corehost/fxr/fx_muxer.cpp index 53e454c9803052..cbaf90aa69cba2 100644 --- a/src/native/corehost/fxr/fx_muxer.cpp +++ b/src/native/corehost/fxr/fx_muxer.cpp @@ -1055,7 +1055,7 @@ int fx_muxer_t::handle_cli( } else if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path()); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path(), false /*skip_sdk_info_output*/); return StatusCode::Success; } @@ -1107,7 +1107,7 @@ int fx_muxer_t::handle_cli( if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path()); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path(), result == 0 /*skip_sdk_info_output*/); } return result;