Skip to content

Commit 224256c

Browse files
CopilotrmarinhoCopilot
authored
Use simctl --json-output flag to avoid stdout pollution (#170)
* Initial plan * fix: route ConsoleLogger Info/Warning/Debug to stderr instead of stdout LogInfo, LogWarning, and LogDebug in ConsoleLogger now use Console.Error.WriteLine (stderr) instead of Console.WriteLine (stdout). This prevents log messages from polluting structured output (e.g. JSON) for consumers that capture stdout. Fixes #2 Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/005240a3-2797-4f5f-865c-c920f0723994 Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * final progress update Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/005240a3-2797-4f5f-865c-c920f0723994 Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * remove accidentally committed .nuget/nuget.exe and add .nuget/ to .gitignore Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/005240a3-2797-4f5f-865c-c920f0723994 Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * revert ConsoleLogger stderr changes; add SimCtl.RunToFile for file-based output Per reviewer feedback: writing to stderr breaks MSBuild tasks. Instead, add SimCtl.RunToFile() so consumers can capture structured output (JSON) to a file, isolating it from any stdout noise. Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/2bbfd1eb-7c88-49ed-8bb9-6e335c369cee Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * address code review: use IsNullOrWhiteSpace and handle file write exceptions Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/2bbfd1eb-7c88-49ed-8bb9-6e335c369cee Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * remove .nuget/nuget.exe and add .nuget/ to .gitignore Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/2bbfd1eb-7c88-49ed-8bb9-6e335c369cee Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> * Use simctl --json-output flag instead of capturing stdout Per reviewer feedback, use xcrun simctl's native --json-output=<file> flag to write structured JSON output directly to a temp file, instead of capturing stdout and writing it ourselves. - Revert RunToFile/RunCore approach back to original Run() method - Add RunJson() that passes --json --json-output=<tempPath> to simctl and reads the result from the temp file - Update SimulatorService, RuntimeService, and tests to use RunJson() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix test runner: add Microsoft.NET.Test.Sdk, downgrade NUnit3TestAdapter to 4.6.0 NUnit3TestAdapter 5.0.0 pulled in Microsoft.Testing.Platform which brought a broken transitive dependency chain (ApplicationInsights, Telemetry DLLs not copied to output). Downgrade to 4.6.0 to avoid the Testing Platform migration issues. Add Microsoft.NET.Test.Sdk (implicitly referenced by .NET SDK) and CopyLocalLockFileAssemblies to ensure all test dependencies are resolved at runtime. Remove NUnit.ConsoleRunner (unused with dotnet test). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: use GetTempFileName and check Run() result in RunJson - Use Path.GetTempFileName() instead of GetRandomFileName() to atomically reserve the temp file path (avoids race condition). - Check Run() return value before reading the file, so simctl failures surface the correct error instead of a misleading 'no JSON output file' message. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix TestHelper.ProjectDir to find source tests dir, not build output The walk-up logic stopped at artifacts/bin/tests/ (first dir named 'tests') instead of the source tests/ directory. Fix by requiring tests.csproj to exist as a sentinel, disambiguating the source directory from the Arcade SDK output layout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI: suppress NETSDK1023/NU1504 for Microsoft.NET.Test.Sdk The explicit PackageReference is needed for testhost.runtimeconfig.json, but .NET SDK 10.0+ implicitly references it causing duplicate errors. Suppress NETSDK1023 and NU1504 in the test project. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore NUnit3TestAdapter to 5.0.0; no downgrade needed with explicit Microsoft.NET.Test.Sdk Tested: build succeeds and 118/119 tests pass (1 skipped) with NUnit3TestAdapter 5.0.0 + Microsoft.NET.Test.Sdk 17.12.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0c544e8 commit 224256c

7 files changed

Lines changed: 46 additions & 4 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ obj
77
*.nupkg
88
artifacts/
99
.packages/
10+
.nuget/

Xamarin.MacDev/RuntimeService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public RuntimeService (ICustomLogger log)
3131
/// </summary>
3232
public List<SimulatorRuntimeInfo> List (bool availableOnly = false)
3333
{
34-
var json = simctl.Run ("list", "runtimes", "--json");
34+
var json = simctl.RunJson ("list", "runtimes");
3535
if (json is null)
3636
return new List<SimulatorRuntimeInfo> ();
3737

Xamarin.MacDev/SimCtl.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,40 @@ public SimCtl (ICustomLogger log)
5757
return null;
5858
}
5959
}
60+
61+
/// <summary>
62+
/// Runs <c>xcrun simctl {args}</c> with <c>--json --json-output=&lt;file&gt;</c>
63+
/// so that structured JSON output is written to a temp file instead of stdout.
64+
/// Returns the file contents, or null on failure.
65+
/// This is intended for <c>simctl list</c> subcommands that support <c>--json-output</c>.
66+
/// </summary>
67+
public string? RunJson (params string [] args)
68+
{
69+
var tempPath = Path.GetTempFileName ();
70+
try {
71+
var jsonArgs = new string [args.Length + 2];
72+
Array.Copy (args, jsonArgs, args.Length);
73+
jsonArgs [args.Length] = "--json";
74+
jsonArgs [args.Length + 1] = "--json-output=" + tempPath;
75+
76+
var result = Run (jsonArgs);
77+
if (result is null)
78+
return null;
79+
80+
if (!File.Exists (tempPath)) {
81+
log.LogInfo ("simctl did not produce JSON output file at '{0}'.", tempPath);
82+
return null;
83+
}
84+
85+
var content = File.ReadAllText (tempPath);
86+
if (string.IsNullOrWhiteSpace (content)) {
87+
log.LogInfo ("simctl produced an empty JSON output file at '{0}'.", tempPath);
88+
return null;
89+
}
90+
91+
return content;
92+
} finally {
93+
try { if (File.Exists (tempPath)) File.Delete (tempPath); } catch { }
94+
}
95+
}
6096
}

Xamarin.MacDev/SimulatorService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public SimulatorService (ICustomLogger log)
3131
/// </summary>
3232
public List<SimulatorDeviceInfo> List (bool availableOnly = false)
3333
{
34-
var json = simctl.Run ("list", "devices", "--json");
34+
var json = simctl.RunJson ("list", "devices");
3535
if (json is null)
3636
return new List<SimulatorDeviceInfo> ();
3737

eng/Versions.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
<NUnitAnalyzersVersion>4.3.0</NUnitAnalyzersVersion>
2020
<NUnitConsoleRunnerVersion>3.18.1</NUnitConsoleRunnerVersion>
2121
<NUnit3TestAdapterVersion>5.0.0</NUnit3TestAdapterVersion>
22+
<MicrosoftNETTestSdkVersion>17.12.0</MicrosoftNETTestSdkVersion>
2223
</PropertyGroup>
2324
</Project>

tests/SimctlOutputParserTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ public void LiveSimctlList_ParsesWithoutExceptions ()
379379
// with no exceptions logged — per rolfbjarne review feedback
380380
var logger = new TestLogger ();
381381
var simctl = new SimCtl (logger);
382-
var json = simctl.Run ("list", "--json");
382+
var json = simctl.RunJson ("list");
383383
Assert.That (json, Is.Not.Null, "simctl list --json should return output");
384384

385385
var devices = SimctlOutputParser.ParseDevices (json, logger);

tests/tests.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88
<IsPackable>false</IsPackable>
99
<IsTestProject>true</IsTestProject>
1010
<IsShipping>false</IsShipping>
11+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
12+
<!-- Explicit Microsoft.NET.Test.Sdk is needed for testhost.runtimeconfig.json;
13+
suppress NETSDK1023 on SDKs that implicitly reference it. -->
14+
<NoWarn>$(NoWarn);NETSDK1023;NU1504</NoWarn>
1115
</PropertyGroup>
1216
<ItemGroup>
17+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkVersion)" />
1318
<PackageReference Include="NUnit" Version="$(NUnitVersion)" />
1419
<PackageReference Include="NUnit.Analyzers" Version="$(NUnitAnalyzersVersion)">
1520
<PrivateAssets>all</PrivateAssets>
1621
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1722
</PackageReference>
18-
<PackageReference Include="NUnit.ConsoleRunner" Version="$(NUnitConsoleRunnerVersion)" />
1923
<PackageReference Include="NUnit3TestAdapter" Version="$(NUnit3TestAdapterVersion)" />
2024
</ItemGroup>
2125
<ItemGroup>

0 commit comments

Comments
 (0)