Skip to content
Draft
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9485b14
Initial plan
Copilot Jun 25, 2025
5b4a5f1
Create DeviceRunners source generator with basic functionality
Copilot Jun 25, 2025
847d793
Complete working source generator with template system (embedded reso…
Copilot Jun 25, 2025
afd68d7
Remove unnecessary template files and update DeviceTestingKitApp.Devi…
Copilot Jun 25, 2025
b29c268
Fix source generator resource loading to use correct embedded resourc…
Copilot Jun 25, 2025
69bc566
Remove DeviceRunners.SourceGenerators.Attributes project and simplify…
Copilot Jun 25, 2025
b0d69a2
Complete source generator targets and MSBuild integration
Copilot Jun 25, 2025
5d1ccdc
Finalize working source generator with comprehensive MSBuild integration
Copilot Jun 25, 2025
abdc8b3
Add Package.appxmanifest support, fix Windows XAML build action, and …
Copilot Jun 25, 2025
ef4070f
rename
mattleibow Jun 25, 2025
a1292e4
Remove source generator completely and replace with MSBuild targets f…
Copilot Jun 25, 2025
13d8302
Refactor MSBuild targets to use reusable ProcessTemplate target
Copilot Jun 25, 2025
c868ea5
Rename SourceGen to Bootstrap to better reflect the current purpose
Copilot Jun 26, 2025
f8c36fa
Update DeviceTestingKitApp.DeviceTests.csproj
mattleibow Jun 26, 2025
bae90d0
more
mattleibow Jun 26, 2025
63a87aa
Refactor MSBuild targets to use CallTarget instead of MSBuild task
Copilot Jun 26, 2025
da8eb70
Delete preprocessed.xml
mattleibow Jun 26, 2025
7155889
Simplify MSBuild targets using item groups with metadata and % operat…
Copilot Jun 26, 2025
f58838f
Address feedback: move props to top, standardize templating, and impr…
Copilot Jun 26, 2025
358c652
Refactor MSBuild targets to use metadata and improve clean support
Copilot Jun 26, 2025
23512d8
Now it works
mattleibow Jun 26, 2025
a6a6d68
publisher now
mattleibow Jun 26, 2025
910a686
Update DeviceRunners.VisualRunners.Maui.Bootstrap.targets
mattleibow Jun 27, 2025
ca5d396
Update DeviceRunners.VisualRunners.Maui.Bootstrap.targets
mattleibow Jun 27, 2025
573763f
Update DeviceRunners.VisualRunners.Maui.Bootstrap.targets
mattleibow Jun 27, 2025
0badc69
ApplicationDefinition
mattleibow Jun 27, 2025
a84733f
Update DeviceRunners.VisualRunners.Maui.Bootstrap.targets
mattleibow Jun 27, 2025
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
196 changes: 196 additions & 0 deletions DeviceRunners.sln

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<PackageVersion Include="AndroidSdk" Version="0.25.0" />
<PackageVersion Include="AppleDev" Version="0.6.6" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.DotNet.XHarness.DefaultAndroidEntryPoint.Xunit" Version="9.0.0-prerelease.24066.3" />
<PackageVersion Include="Microsoft.DotNet.XHarness.TestRunners.Common" Version="9.0.0-prerelease.24066.3" />
<PackageVersion Include="Microsoft.DotNet.XHarness.TestRunners.Xunit" Version="9.0.0-prerelease.24066.3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,8 @@
</PropertyGroup>

<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />

<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
Expand All @@ -44,10 +37,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Microsoft.Maui.Controls" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.utility" />
</ItemGroup>

<ItemGroup>
Expand All @@ -58,18 +47,16 @@
<ProjectReference Include="..\..\..\src\DeviceRunners.VisualRunners.Xunit\DeviceRunners.VisualRunners.Xunit.csproj" />
<ProjectReference Include="..\..\..\src\DeviceRunners.VisualRunners.NUnit\DeviceRunners.VisualRunners.NUnit.csproj" />
<ProjectReference Include="..\..\..\src\DeviceRunners.VisualRunners.Maui\DeviceRunners.VisualRunners.Maui.csproj" />
<ProjectReference Include="..\..\..\src\DeviceRunners.VisualRunners.Maui.Bootstrap\DeviceRunners.VisualRunners.Maui.Bootstrap.csproj" />
</ItemGroup>

<!-- Import the device test app generation targets from Bootstrap package -->
<Import Project="..\..\..\src\DeviceRunners.VisualRunners.Maui.Bootstrap\build\DeviceRunners.VisualRunners.Maui.Bootstrap.props" />
Copy link
Owner

Choose a reason for hiding this comment

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

The props should be right at the top of the file. The first thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the props imports to the top of the project file, right after the Project element. Commit 7155889.

<Import Project="..\..\..\src\DeviceRunners.VisualRunners.Maui.Bootstrap\build\DeviceRunners.VisualRunners.Maui.Bootstrap.targets" />

<ItemGroup Condition="'$(TestingMode)' == 'XHarness'">
<ProjectReference Include="..\..\..\src\DeviceRunners.XHarness.Xunit\DeviceRunners.XHarness.Xunit.csproj" />
<ProjectReference Include="..\..\..\src\DeviceRunners.XHarness.Maui\DeviceRunners.XHarness.Maui.csproj" />
</ItemGroup>

<Target Name="RemoveVisualStudioTestRunner" BeforeTargets="_ComputeAppxPackagePayload">
<ItemGroup>
<_VisualStudioTestRunnerFiles Include="@(PackagingOutputs)" Condition="$([System.String]::Copy('%(PackagingOutputs.FullPath)').Contains('xunit.runner.visualstudio'))" />
<PackagingOutputs Remove="@(_VisualStudioTestRunnerFiles)" />
</ItemGroup>
</Target>

</Project>

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>

<ItemGroup>
<None Include="build\DeviceRunners.VisualRunners.Maui.Bootstrap.targets" Pack="true" PackagePath="build\" />
<None Include="build\DeviceRunners.VisualRunners.Maui.Bootstrap.props" Pack="true" PackagePath="build\" />
<None Include="build\templates\**\*" Pack="true" PackagePath="build\templates\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- Auto-detect if we should generate device test app files -->
<PropertyGroup>
<_ShouldGenerateDeviceTestApp Condition="'$(UseMaui)' == 'true' AND '$(DesignTimeBuild)' != 'true'">true</_ShouldGenerateDeviceTestApp>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>

<!-- Define all template files and their destinations -->
<ItemGroup>
<!-- Android templates -->
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/Android/MainActivity.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/Android/MainActivity.cs</Destination>
<Platform>android</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/Android/MainApplication.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/Android/MainApplication.cs</Destination>
<Platform>android</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>

<!-- iOS templates -->
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/iOS/Program.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/iOS/Program.cs</Destination>
<Platform>ios</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/iOS/AppDelegate.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/iOS/AppDelegate.cs</Destination>
<Platform>ios</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>

<!-- macOS Catalyst templates -->
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/MacCatalyst/Program.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/MacCatalyst/Program.cs</Destination>
<Platform>maccatalyst</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/MacCatalyst/AppDelegate.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/MacCatalyst/AppDelegate.cs</Destination>
<Platform>maccatalyst</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>

<!-- Windows templates -->
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Platforms/Windows/App.xaml.cs.template">
<Destination>$(IntermediateOutputPath)Platforms/Windows/App.xaml.cs</Destination>
<Platform>windows</Platform>
<BuildAction>Compile</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Windows/App.xaml">
<Destination>$(IntermediateOutputPath)Platforms/Windows/App.xaml</Destination>
<Platform>windows</Platform>
<BuildAction>Page</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Windows/app.manifest">
<Destination>$(IntermediateOutputPath)Platforms/Windows/app.manifest</Destination>
<Platform>windows</Platform>
<BuildAction>ApplicationManifest</BuildAction>
</TemplateFile>
<TemplateFile Include="$(MSBuildThisFileDirectory)templates/Windows/Package.appxmanifest">
<Destination>$(IntermediateOutputPath)Platforms/Windows/Package.appxmanifest</Destination>
<Platform>windows</Platform>
<BuildAction>AppxManifest</BuildAction>
</TemplateFile>
</ItemGroup>

<!-- Process all template files in one target using batching -->
<Target Name="ProcessAllTemplates" BeforeTargets="BeforeCompile" Condition="'$(_ShouldGenerateDeviceTestApp)' == 'true'"
Inputs="@(TemplateFile)" Outputs="%(TemplateFile.Destination)">

<!-- Create output directory -->
<MakeDir Directories="$([System.IO.Path]::GetDirectoryName('%(TemplateFile.Destination)'))" />

<!-- Read template file as single string -->
<PropertyGroup>
<_TemplateContent>$([System.IO.File]::ReadAllText('%(TemplateFile.Identity)'))</_TemplateContent>
<_ProcessedContent>$(_TemplateContent.Replace('{{RootNamespace}}', '$(RootNamespace)'))</_ProcessedContent>
<_ProcessedContent>$(_ProcessedContent.Replace('{{ApplicationTitle}}', '$(ApplicationTitle)'))</_ProcessedContent>
<_ProcessedContent>$(_ProcessedContent.Replace('{{ApplicationId}}', '$(ApplicationId)'))</_ProcessedContent>
<_ProcessedContent>$(_ProcessedContent.Replace('{{AppId}}', '$(ApplicationId)'))</_ProcessedContent>
Copy link
Owner

Choose a reason for hiding this comment

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

Replace all AppId templating instances with ApplicationId. No need to have of the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replaced all AppId templating instances with ApplicationId in both the targets file and template files. Commit 7155889.

</PropertyGroup>

<!-- Write processed file -->
<WriteLinesToFile File="%(TemplateFile.Destination)" Lines="$(_ProcessedContent)" Overwrite="true" />
Copy link
Owner

Choose a reason for hiding this comment

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

This task has a WriteOnlyWhenDifferent which we want to be true to reduce build churn

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added WriteOnlyWhenDifferent="true" to the WriteLinesToFile task to reduce build churn. Commit 7155889.

</Target>

<!-- Add iOS partial app manifest -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'ios'">
<PartialAppManifest Include="$(MSBuildThisFileDirectory)templates/iOS/Info.plist" />
</ItemGroup>

<!-- Add macOS Catalyst partial app manifest -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'maccatalyst'">
<PartialAppManifest Include="$(MSBuildThisFileDirectory)templates/MacCatalyst/Info.plist" />
</ItemGroup>

<!-- Include processed files in build based on platform and build action -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'android' AND '$(_ShouldGenerateDeviceTestApp)' == 'true'">
<Compile Include="$(IntermediateOutputPath)Platforms/Android/MainActivity.cs" />
<Compile Include="$(IntermediateOutputPath)Platforms/Android/MainApplication.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'ios' AND '$(_ShouldGenerateDeviceTestApp)' == 'true'">
<Compile Include="$(IntermediateOutputPath)Platforms/iOS/Program.cs" />
<Compile Include="$(IntermediateOutputPath)Platforms/iOS/AppDelegate.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'maccatalyst' AND '$(_ShouldGenerateDeviceTestApp)' == 'true'">
<Compile Include="$(IntermediateOutputPath)Platforms/MacCatalyst/Program.cs" />
<Compile Include="$(IntermediateOutputPath)Platforms/MacCatalyst/AppDelegate.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows' AND '$(_ShouldGenerateDeviceTestApp)' == 'true'">
<Compile Include="$(IntermediateOutputPath)Platforms/Windows/App.xaml.cs" />
<Page Include="$(IntermediateOutputPath)Platforms/Windows/App.xaml" />
<ApplicationManifest Include="$(IntermediateOutputPath)Platforms/Windows/app.manifest" />
<AppxManifest Include="$(IntermediateOutputPath)Platforms/Windows/Package.appxmanifest" />
</ItemGroup>

<!-- Exclude default Visual Studio test runner files from packaging -->
<Target Name="RemoveVisualStudioTestRunner" BeforeTargets="_ComputeAppxPackagePayload">
<ItemGroup>
<_VisualStudioTestRunnerFiles Include="@(PackagingOutputs)" Condition="$([System.String]::Copy('%(PackagingOutputs.FullPath)').Contains('xunit.runner.visualstudio'))" />
<PackagingOutputs Remove="@(_VisualStudioTestRunnerFiles)" />
</ItemGroup>
</Target>

<!-- Add default app icon and splash screen from templates -->
<ItemGroup>
<MauiIcon Include="$(MSBuildThisFileDirectory)templates/Resources/AppIcon/appicon.svg" ForegroundFile="$(MSBuildThisFileDirectory)templates/Resources/AppIcon/appiconfg.svg" Color="#512BD4" />
<MauiSplashScreen Include="$(MSBuildThisFileDirectory)templates/Resources/Splash/splash.svg" Color="#512BD4" BaseSize="128,128" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Android.App;
using Android.Content.PM;
using Android.OS;

namespace {{RootNamespace}};

[Activity(Name = "{{AppId}}.MainActivity", Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ο»Ώusing Android.App;
using Android.App;
using Android.Runtime;

namespace DeviceTestingKitApp.DeviceTests;
namespace {{RootNamespace}};

[Application]
[Application(Icon = "@mipmap/appicon", RoundIcon = "@mipmap/appicon_round")]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
Expand All @@ -12,4 +12,4 @@ public MainApplication(IntPtr handle, JniHandleOwnership ownership)
}

protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Foundation;

namespace {{RootNamespace}};

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ο»Ώusing UIKit;
using ObjCRuntime;
using UIKit;

namespace DeviceTestingKitApp.DeviceTests;
namespace {{RootNamespace}};

public class Program
{
Expand All @@ -11,4 +12,4 @@ static void Main(string[] args)
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ο»Ώusing Microsoft.UI.Xaml;
using Microsoft.UI.Xaml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace DeviceTestingKitApp.DeviceTests.WinUI;
namespace {{RootNamespace}};
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
namespace {{RootNamespace}};
namespace {{RootNamespace}}.WinUI;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed the namespace template to use {{RootNamespace}}.WinUI as suggested. Commit 7155889.


/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
Expand All @@ -20,5 +20,4 @@ public App()
}

protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Foundation;

namespace {{RootNamespace}};

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ο»Ώusing ObjCRuntime;
using ObjCRuntime;
using UIKit;

namespace DeviceTestingKitApp.DeviceTests;
namespace {{RootNamespace}};

public class Program
{
Expand All @@ -12,4 +12,4 @@ static void Main(string[] args)
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
Loading
Loading