add aspire for otel

This commit is contained in:
Matt Parker
2025-09-29 19:07:38 +10:00
parent b7029e7dce
commit e0ddcc55f2
16 changed files with 358 additions and 1 deletions

13
tools/AppHost/AppHost.cs Normal file
View File

@@ -0,0 +1,13 @@
using AppHost;
using Projects;
var builder = DistributedApplication.CreateBuilder(args);
//var photino = builder.AddProject<SharpIDE_Photino>("photino");
builder.AddGodot("../../src/SharpIDE.Godot/SharpIDE.Godot.csproj", "sharpide-godot")
.WithOtlpExporter();
var appHost = builder.Build();
await appHost.RunAsync();

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.5.0"/>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>c8b6b3c2-8acc-412d-9d58-38b990d2f79f</UserSecretsId>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.5.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,156 @@
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace AppHost;
// https://github.com/maddymontaquila/Godot-SnakeCS/blob/maddy/aspire/AppHost/GodotExtensions.cs
public static class GodotExtensions
{
/// <summary>
/// Adds a Godot project to the application model.
/// </summary>
/// <param name="builder">The distributed application builder.</param>
/// <param name="projectPath">The path to the Godot project file (.godot).</param>
/// <param name="name">The name of the resource.</param>
/// <param name="args">Optional arguments to pass to the Godot executable.</param>
/// <returns>A reference to the Godot project resource.</returns>
public static IResourceBuilder<ExecutableResource> AddGodot(
this IDistributedApplicationBuilder builder,
string projectPath,
string? name = null,
params string[] args)
{
name ??= Path.GetFileNameWithoutExtension(projectPath);
var projectDirectory = Path.GetDirectoryName(projectPath) ?? ".";
var godotPath = GetGodotExecutablePath();
// Build the arguments list
var arguments = new List<string>
{
"--path",
projectDirectory,
//"--verbose"
};
// Add any custom args
arguments.AddRange(args);
// Create a standard ExecutableResource (since custom ones don't seem to work well)
var godotResource = builder.AddExecutable(
name: name,
command: godotPath,
workingDirectory: projectDirectory,
args: arguments.ToArray());
//.WithEnvironment("OTEL_EXPORTER_OTLP_ENDPOINT", Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ?? throw new InvalidOperationException("OTEL_EXPORTER_OTLP_ENDPOINT environment variable is not set"));
// Add a lifecycle hook to handle building before startup
builder.Services.AddSingleton<IDistributedApplicationLifecycleHook>(sp =>
new GodotBuildHook(
projectPath,
projectDirectory,
sp.GetRequiredService<ILogger<GodotBuildHook>>()));
return godotResource;
}
/// <summary>
/// Gets the Godot executable path based on the current platform.
/// </summary>
private static string GetGodotExecutablePath()
{
// First check for GODOT environment variable
var godotPath = Environment.GetEnvironmentVariable("GODOT");
if (!string.IsNullOrWhiteSpace(godotPath))
{
return godotPath;
}
// Fallback to platform-specific defaults
if (OperatingSystem.IsMacOS())
{
return "godot";
}
else if (OperatingSystem.IsWindows())
{
return "godot.exe";
}
else if (OperatingSystem.IsLinux())
{
return "godot";
}
throw new PlatformNotSupportedException("Current platform is not supported for Godot execution.");
}
/// <summary>
/// Lifecycle hook to build the Godot project before launching
/// </summary>
private class GodotBuildHook : IDistributedApplicationLifecycleHook
{
private readonly string _projectPath;
private readonly string _projectDirectory;
private readonly ILogger<GodotBuildHook> _logger;
public GodotBuildHook(string projectPath, string projectDirectory, ILogger<GodotBuildHook> logger)
{
_projectPath = projectPath;
_projectDirectory = projectDirectory;
_logger = logger;
}
public async Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
{
_logger.LogInformation("Building Godot project: {ProjectPath}", _projectPath);
// Execute dotnet build on the project
var buildProcess = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "dotnet",
Arguments = $"build \"{_projectPath}\" --configuration Debug",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDirectory = _projectDirectory
}
};
buildProcess.OutputDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
{
_logger.LogInformation("[Godot Build] {Data}", e.Data);
}
};
buildProcess.ErrorDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
{
_logger.LogError("[Godot Build] {Data}", e.Data);
}
};
buildProcess.Start();
buildProcess.BeginOutputReadLine();
buildProcess.BeginErrorReadLine();
await buildProcess.WaitForExitAsync(cancellationToken);
if (buildProcess.ExitCode != 0)
{
_logger.LogError("Failed to build Godot project: {ProjectPath}", _projectPath);
return;
}
_logger.LogInformation("Successfully built Godot project: {ProjectPath}", _projectPath);
}
public Task AfterStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17042",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21295",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22130",
"GODOT": "C:/Users/Matthew/Documents/Godot/4.5/Godot_v4.5-stable_mono_win64.exe"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}