Skip to content

Add ProcessUtils helper and output models for Apple CLI APIs#155

Merged
rmarinho merged 9 commits intomainfrom
feature/output-models
Feb 27, 2026
Merged

Add ProcessUtils helper and output models for Apple CLI APIs#155
rmarinho merged 9 commits intomainfrom
feature/output-models

Conversation

@rmarinho
Copy link
Copy Markdown
Member

Summary

Foundation PR for the Apple CLI library APIs (spec). Must merge first — all subsequent PRs depend on these shared types and helpers.

What's included

Xamarin.MacDev/ProcessUtils.cs — Static helper for running external processes, inspired by dotnet/android-tools ProcessUtils. Provides:

  • StartProcess — async with cancellation and stdout/stderr capture
  • RunAsync — convenience, returns stdout or throws on failure
  • TryRunAsync — returns stdout or null on failure
  • Exec — sync wrapper returning exit code + stdout + stderr

Xamarin.MacDev/Models/ — Output model POCOs:

  • XcodeInfo — Xcode installation details
  • SimulatorDeviceInfo — simulator device info
  • SimulatorRuntimeInfo — simulator runtime info
  • CommandLineToolsInfo — CLT status
  • EnvironmentCheckResult — composite environment status with DeriveStatus()

Tests — 14 new tests (26 total pass)

.github/copilot-instructions.md — Updated with code style conventions

Closes #153

rmarinho and others added 5 commits February 26, 2026 16:23
Add ProcessUtils static helper (inspired by dotnet/android-tools) for
async process execution with cancellation and stdout/stderr capture.

Add output model POCOs in Xamarin.MacDev.Models namespace:
- XcodeInfo, SimulatorDeviceInfo, SimulatorRuntimeInfo
- CommandLineToolsInfo, EnvironmentCheckResult

Update copilot-instructions.md with code style conventions.

Closes #153

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace manual Process boilerplate in TryGetSystemXcode with
ProcessUtils.Exec, which handles the same stdout/stderr capture
and cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace hardcoded /bin/echo, /bin/sh, /bin/sleep paths with
platform-aware helpers using RuntimeInformation.IsOSPlatform.
On Windows, uses cmd.exe /c for echo/exit and timeout for sleep.
Also adds using blocks on StringWriter per coding conventions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename directory, project, and namespace from UnitTests to tests.
Update all references in solution, CI pipelines, documentation,
embedded resource names, and TestHelper path resolution.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds foundational utilities and model classes for Apple CLI APIs, serving as a dependency for subsequent PRs in the Apple CLI library implementation. It introduces ProcessUtils for external process execution, model POCOs for Apple developer environment data, and refactors the test project structure.

Changes:

  • Added ProcessUtils helper class with async/sync process execution methods inspired by dotnet/android-tools
  • Added five model classes (XcodeInfo, SimulatorDeviceInfo, SimulatorRuntimeInfo, CommandLineToolsInfo, EnvironmentCheckResult) to represent Apple environment data
  • Renamed test project from "UnitTests" to "tests" with corresponding namespace and path updates throughout
  • Updated XcodeLocator to use ProcessUtils.Exec instead of manual Process creation
  • Added 14 new tests covering ProcessUtils and model classes

Reviewed changes

Copilot reviewed 18 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Xamarin.MacDev/ProcessUtils.cs New static helper class for running external processes with async stdout/stderr capture and cancellation support
Xamarin.MacDev/Models/XcodeInfo.cs New model representing Xcode installation details (path, version, build)
Xamarin.MacDev/Models/SimulatorDeviceInfo.cs New model for simulator device information from xcrun simctl
Xamarin.MacDev/Models/SimulatorRuntimeInfo.cs New model for simulator runtime information (platform, version, availability)
Xamarin.MacDev/Models/CommandLineToolsInfo.cs New model for Xcode Command Line Tools installation status
Xamarin.MacDev/Models/EnvironmentCheckResult.cs New model aggregating environment check results with DeriveStatus() method
Xamarin.MacDev/XcodeLocator.cs Refactored to use ProcessUtils.Exec instead of manual Process creation
tests/ProcessUtilsTests.cs New comprehensive tests for ProcessUtils methods (8 tests)
tests/XcodeInfoTests.cs New tests for XcodeInfo model (2 tests)
tests/EnvironmentCheckResultTests.cs New tests for environment models and status derivation (6 tests)
tests/TestHelper.cs Updated to use "tests" namespace and directory name
tests/TestMobileProvisionIndex.cs Updated namespace from UnitTests to Tests
tests/PListObjectTests.cs Updated namespace and manifest resource stream paths
tests/tests.csproj Renamed from UnitTests.csproj with proper embedded resource configuration
Xamarin.MacDev.sln Updated project reference from UnitTests to tests
.github/workflows/ci.yml Updated test project path
azure-pipelines.yaml Updated test project path
.github/copilot-instructions.md Added code style guidelines, error handling patterns, and testing requirements
.github/CSharpExpert.agent.md Updated test project name reference
tests/TestData/PropertyLists/*.plist Added test data files for plist parsing tests

- Fix potential deadlock in Exec: read stdout/stderr asynchronously
  before WaitForExit to prevent buffer blocking
- Fix race condition in exit detection: check HasExited after Start()
  in case process exits before Exited event fires
- Replace bare catch with specific Win32Exception and
  InvalidOperationException catches in TryRunAsync

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Provide TextWriter.Null sink when ProcessStartInfo has redirection
enabled but caller passes null writer, preventing NullReferenceException.
Catch Win32Exception in process termination helper for platforms where
the call may fail with access denied.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Change ProcessUtils arguments from single string to params string[]
  to avoid quoting issues. Uses ArgumentList on net5.0+ and a
  QuoteArguments fallback on netstandard2.0.
- Add convenience overloads without CancellationToken for RunAsync
  and TryRunAsync.
- Replace "CLT" abbreviation with "Command Line Tools" in
  CommandLineToolsInfo comments and ToString().
- Update tests to pass argument arrays instead of pre-formatted strings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho requested a review from rolfbjarne February 27, 2026 09:27
Pass "echo text" as single /c argument to cmd.exe so ArgumentList
does not individually quote the text argument with spaces.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho merged commit 95f7788 into main Feb 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Xcode Command Line Tools detection and installation API

3 participants