Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/ci-devflow.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: CI - DevFlow
name: CI

on:
push:
branches: [main]
paths:
- 'src/DevFlow/**'
- 'src/Client/**'
- 'eng/**'
- 'Directory.Build.props'
- 'Directory.Build.targets'
Expand All @@ -15,6 +16,7 @@ on:
branches: [main]
paths:
- 'src/DevFlow/**'
- 'src/Client/**'
- 'eng/**'
- 'Directory.Build.props'
- 'Directory.Build.targets'
Expand Down
9 changes: 8 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@
<PackageVersion Include="Fizzler" Version="$(FizzlerVersion)" />
<PackageVersion Include="SkiaSharp" Version="$(SkiaSharpVersion)" />
<PackageVersion Include="Spectre.Console" Version="$(SpectreConsoleVersion)" />
<PackageVersion Include="System.CommandLine" Version="$(SystemCommandLineVersion)" />
<PackageVersion Include="Spectre.Console.Testing" Version="$(SpectreConsoleVersion)" />
<PackageVersion Include="System.CommandLine" Version="$(SystemCommandLineStableVersion)" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
<PackageVersion Include="Websocket.Client" Version="$(WebsocketClientVersion)" />
<PackageVersion Include="XenoAtom.Terminal.UI" Version="$(XenoAtomTerminalUIVersion)" />
<PackageVersion Include="ModelContextProtocol" Version="$(ModelContextProtocolVersion)" />
<PackageVersion Include="Interop.UIAutomationClient" Version="$(InteropUIAutomationClientVersion)" />
</ItemGroup>

<!-- MAUI Client Tool dependencies -->
<ItemGroup Label="Client">
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionVersion)" />
<PackageVersion Include="Xamarin.Android.Tools.AndroidSdk" Version="$(XamarinAndroidToolsAndroidSdkVersion)" />
</ItemGroup>

<!-- Platform extensions (pinned) -->
<ItemGroup Label="Platform">
<PackageVersion Include="Platform.Maui.MacOS" Version="$(PlatformMauiMacOSVersion)" />
Expand Down
33 changes: 33 additions & 0 deletions MauiLabs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevFlow.Sample", "samples\D
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevFlow.Sample.MacOS", "samples\DevFlow.Sample.MacOS\DevFlow.Sample.MacOS.csproj", "{AFD6683E-10FC-445C-9139-7F4FDFBFA232}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{79F3B28B-5908-7582-5384-B77713FD2B1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Maui.Client", "src\Client\Microsoft.Maui.Client\Microsoft.Maui.Client.csproj", "{C48C1D82-906D-4626-96BD-43D9D49B7A79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Maui.Client.UnitTests", "src\Client\Microsoft.Maui.Client.UnitTests\Microsoft.Maui.Client.UnitTests.csproj", "{74377069-050C-4C39-A34D-88307E0C19B8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -207,6 +213,30 @@ Global
{AFD6683E-10FC-445C-9139-7F4FDFBFA232}.Release|x64.Build.0 = Release|Any CPU
{AFD6683E-10FC-445C-9139-7F4FDFBFA232}.Release|x86.ActiveCfg = Release|Any CPU
{AFD6683E-10FC-445C-9139-7F4FDFBFA232}.Release|x86.Build.0 = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|x64.ActiveCfg = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|x64.Build.0 = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|x86.ActiveCfg = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Debug|x86.Build.0 = Debug|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|Any CPU.Build.0 = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|x64.ActiveCfg = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|x64.Build.0 = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|x86.ActiveCfg = Release|Any CPU
{C48C1D82-906D-4626-96BD-43D9D49B7A79}.Release|x86.Build.0 = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|x64.ActiveCfg = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|x64.Build.0 = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|x86.ActiveCfg = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Debug|x86.Build.0 = Debug|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|Any CPU.Build.0 = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|x64.ActiveCfg = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|x64.Build.0 = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|x86.ActiveCfg = Release|Any CPU
{74377069-050C-4C39-A34D-88307E0C19B8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -227,5 +257,8 @@ Global
{13978349-2CD3-4F84-B9C8-EDB5F9B1CB18} = {12E5C810-18C6-BE57-4EA6-3F3BE821652E}
{B843C880-C1FE-4A2B-A41E-5A6D251929DD} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
{AFD6683E-10FC-445C-9139-7F4FDFBFA232} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
{C48C1D82-906D-4626-96BD-43D9D49B7A79} = {79F3B28B-5908-7582-5384-B77713FD2B1E}
{74377069-050C-4C39-A34D-88307E0C19B8} = {79F3B28B-5908-7582-5384-B77713FD2B1E}
{79F3B28B-5908-7582-5384-B77713FD2B1E} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
EndGlobalSection
EndGlobal
1 change: 1 addition & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" protocolVersion="3" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" protocolVersion="3" />
<add key="dotnet10" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json" protocolVersion="3" />
<add key="dotnet11" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json" protocolVersion="3" />
</packageSources>
<disabledPackageSources>
<clear />
Expand Down
5 changes: 5 additions & 0 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Dependencies>
<ProductDependencies>
<!-- dotnet/android-tools: Android SDK tooling (SdkManager, AdbRunner, JdkInstaller, etc.) -->
<Dependency Name="Xamarin.Android.Tools.AndroidSdk" Version="1.0.143-preview.8">
<Uri>https://github.com/dotnet/android-tools</Uri>
<Sha>ec5040ad5158f240a67d887133dd56cfa5eb74ba</Sha>
</Dependency>
<!-- dotnet/maui -->
<Dependency Name="Microsoft.Maui.Controls" Version="10.0.41">
<Uri>https://github.com/dotnet/maui</Uri>
Expand Down
6 changes: 6 additions & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<MicrosoftAspNetCoreComponentsWebViewMauiVersion>$(MicrosoftMauiControlsVersion)</MicrosoftAspNetCoreComponentsWebViewMauiVersion>
</PropertyGroup>
<PropertyGroup Label="Dotnet Runtime / Extensions">
<MicrosoftExtensionsDependencyInjectionVersion>10.0.5</MicrosoftExtensionsDependencyInjectionVersion>
<MicrosoftExtensionsHttpVersion>10.0.5</MicrosoftExtensionsHttpVersion>
<MicrosoftExtensionsHostingVersion>10.0.5</MicrosoftExtensionsHostingVersion>
<MicrosoftExtensionsLoggingAbstractionsVersion>10.0.5</MicrosoftExtensionsLoggingAbstractionsVersion>
Expand All @@ -34,11 +35,16 @@
<SkiaSharpVersion>3.119.2</SkiaSharpVersion>
<SpectreConsoleVersion>0.54.0</SpectreConsoleVersion>
<SystemCommandLineVersion>2.0.0-beta4.22272.1</SystemCommandLineVersion>
<SystemCommandLineStableVersion>2.0.5</SystemCommandLineStableVersion>
<WebsocketClientVersion>5.3.0</WebsocketClientVersion>
<XenoAtomTerminalUIVersion>1.7.1</XenoAtomTerminalUIVersion>
<ModelContextProtocolVersion>1.1.0</ModelContextProtocolVersion>
<InteropUIAutomationClientVersion>10.19041.0</InteropUIAutomationClientVersion>
</PropertyGroup>
<!-- Android platform tooling (managed via darc/maestro — see eng/Version.Details.xml) -->
<PropertyGroup Label="Android Tools">
<XamarinAndroidToolsAndroidSdkVersion>1.0.143-preview.8</XamarinAndroidToolsAndroidSdkVersion>
</PropertyGroup>
<PropertyGroup Label="Platform Extensions">
<PlatformMauiMacOSVersion>0.3.0</PlatformMauiMacOSVersion>
<PlatformMauiMacOSBlazorWebViewVersion>$(PlatformMauiMacOSVersion)</PlatformMauiMacOSBlazorWebViewVersion>
Expand Down
204 changes: 204 additions & 0 deletions src/Client/Microsoft.Maui.Client.UnitTests/AndroidCommandsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.CommandLine;
using System.CommandLine.Parsing;
using Microsoft.Maui.Client.Commands;
using Xunit;

namespace Microsoft.Maui.Client.UnitTests;

public class AndroidCommandsTests
{
[Fact]
public void InstallCommand_ParsesCommaSeparatedPackages()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var installCommand = androidCommand.Subcommands.First(c => c.Name == "install");
var packagesOption = installCommand.Options.First(o => o.Name == "--packages");

// Act
var parseResult = installCommand.Parse("install --packages platform-tools,build-tools;35.0.0,platforms;android-35");

// Assert
Assert.Empty(parseResult.Errors);
var packages = parseResult.GetValue((Option<string[]>)packagesOption);
Assert.NotNull(packages);
// The raw value will be a single string with commas - the handler splits it
Assert.Single(packages);
Assert.Equal("platform-tools,build-tools;35.0.0,platforms;android-35", packages[0]);
}

[Fact]
public void InstallCommand_ParsesMultiplePackageFlags()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var installCommand = androidCommand.Subcommands.First(c => c.Name == "install");
var packagesOption = installCommand.Options.First(o => o.Name == "--packages");

// Act
var parseResult = installCommand.Parse("install --packages platform-tools --packages build-tools;35.0.0");

// Assert
Assert.Empty(parseResult.Errors);
var packages = parseResult.GetValue((Option<string[]>)packagesOption);
Assert.NotNull(packages);
Assert.Equal(2, packages.Length);
}

[Fact]
public void InstallCommand_HasCorrectOptions()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var installCommand = androidCommand.Subcommands.First(c => c.Name == "install");

// Assert
Assert.Contains(installCommand.Options, o => o.Name == "--sdk-path");
Assert.Contains(installCommand.Options, o => o.Name == "--jdk-path");
Assert.Contains(installCommand.Options, o => o.Name == "--jdk-version");
Assert.Contains(installCommand.Options, o => o.Name == "--packages");
}

[Fact]
public void EmulatorCreateCommand_PackageIsOptional()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");
var createCommand = emulatorCommand.Subcommands.First(c => c.Name == "create");
var packageOption = createCommand.Options.First(o => o.Name == "--package");

// Assert
Assert.False(packageOption.Required);
}

[Fact]
public void EmulatorCreateCommand_HasRequiredNameArgument()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");
var createCommand = emulatorCommand.Subcommands.First(c => c.Name == "create");

// Assert
Assert.Single(createCommand.Arguments);
Assert.Equal("name", createCommand.Arguments.First().Name);
}

[Fact]
public void EmulatorDeleteCommand_Exists()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");

// Assert
Assert.Contains(emulatorCommand.Subcommands, c => c.Name == "delete");
}

[Fact]
public void EmulatorCommand_HasStopSubcommand()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");

// Assert
Assert.Contains(emulatorCommand.Subcommands, c => c.Name == "stop");
}

[Fact]
public void EmulatorStopCommand_HasRequiredNameArgument()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");
var stopCommand = emulatorCommand.Subcommands.First(c => c.Name == "stop");

// Assert
Assert.Single(stopCommand.Arguments);
Assert.Equal("name", stopCommand.Arguments.First().Name);
}

[Fact]
public void EmulatorDeleteCommand_HasRequiredNameArgument()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");
var deleteCommand = emulatorCommand.Subcommands.First(c => c.Name == "delete");

// Assert
Assert.Single(deleteCommand.Arguments);
Assert.Equal("name", deleteCommand.Arguments.First().Name);
}

[Fact]
public void EmulatorStartCommand_HasColdBootOption()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var emulatorCommand = androidCommand.Subcommands.First(c => c.Name == "emulator");
var startCommand = emulatorCommand.Subcommands.First(c => c.Name == "start");

// Assert
Assert.Contains(startCommand.Options, o => o.Name == "--cold-boot");
Assert.Contains(startCommand.Options, o => o.Name == "--wait");
}

[Fact]
public void JdkCommand_HasAllSubcommands()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var jdkCommand = androidCommand.Subcommands.First(c => c.Name == "jdk");

// Assert
Assert.Contains(jdkCommand.Subcommands, c => c.Name == "check");
Assert.Contains(jdkCommand.Subcommands, c => c.Name == "install");
Assert.Contains(jdkCommand.Subcommands, c => c.Name == "list");
}

[Fact]
public void SdkCommand_HasAllSubcommands()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var sdkCommand = androidCommand.Subcommands.First(c => c.Name == "sdk");

// Assert
Assert.Contains(sdkCommand.Subcommands, c => c.Name == "check");
Assert.Contains(sdkCommand.Subcommands, c => c.Name == "install");
Assert.Contains(sdkCommand.Subcommands, c => c.Name == "list");
Assert.Contains(sdkCommand.Subcommands, c => c.Name == "accept-licenses");
}

[Fact]
public void SdkListCommand_HasAvailableAndAllOptions()
{
// Arrange
var androidCommand = AndroidCommands.Create();
var sdkCommand = androidCommand.Subcommands.First(c => c.Name == "sdk");
var listCommand = sdkCommand.Subcommands.First(c => c.Name == "list");

// Assert
Assert.Contains(listCommand.Options, o => o.Name == "--available");
Assert.Contains(listCommand.Options, o => o.Name == "--all");
}

[Fact]
public void AndroidCommand_HasAllSubcommands()
{
// Arrange
var androidCommand = AndroidCommands.Create();

// Assert
Assert.Contains(androidCommand.Subcommands, c => c.Name == "install");
Assert.Contains(androidCommand.Subcommands, c => c.Name == "jdk");
Assert.Contains(androidCommand.Subcommands, c => c.Name == "sdk");
Assert.Contains(androidCommand.Subcommands, c => c.Name == "emulator");
}
}
Loading