feat: command line arguments parsing

This commit is contained in:
2026-02-16 12:46:35 +03:00
parent 50df69edf5
commit 9c4f12d45e
4 changed files with 203 additions and 92 deletions
+1
View File
@@ -24,6 +24,7 @@
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="System.CommandLine" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
+41 -92
View File
@@ -1,48 +1,61 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Console;
using Avalonia;
using Avalonia.OpenGL.Egl;
using GSS2.Core;
using GSS2.Core.Logging;
using GSS2.Core.Analysis.AmineContent.Database;
using ConsoleFormatter = GSS2.Core.Logging.ConsoleFormatter;
using System.CommandLine;
namespace GSS2.Test;
public class Program
public partial class Program
{
public static IHost ApplicationHost { get; } = BuildHostApp();
private enum RenderingMode
{
X11,
DRM
}
private static string[]? _args = null;
private static readonly RootCommand _rootCommand = new("GranuSight Software 2");
private static readonly Command _cameraTuningCommand = new("camera-tuning")
{
Description = "Tune camera parameters"
};
private static readonly Option<RenderingMode> _renderingModeArgument = new("--rendering-mode")
{
Description = "Rendering mode to use",
DefaultValueFactory = (_) => RenderingMode.X11
};
private static readonly Option<bool> _hideConsoleArgument = new("--hide-console")
{
Description = "Suppress console output",
DefaultValueFactory = (result) => result.GetRequiredValue(_renderingModeArgument) == RenderingMode.DRM
};
public static event ConsoleCancelEventHandler? ShutdownRequested;
[STAThread]
public static int Main(string[] args)
{
var builder = BuildAvaloniaApp();
_args = args;
if (args.Contains("--drm"))
{
if (!args.Contains("--console"))
SilenceConsole();
return builder.StartLinuxDrm(args, "/dev/dri/card1", 1.0);
}
if (args.Contains("--help"))
{
Console.WriteLine($"Usage of {Assembly.GetEntryAssembly()?.GetName().Name}:");
Console.WriteLine($"\t--help - show this help");
Console.WriteLine($"\t--drm - use DRM rendering mode");
Console.WriteLine($"\t--console - in DRM rendering mode do not suppress console output");
return 0;
}
_rootCommand.Add(_cameraTuningCommand);
_rootCommand.Add(_renderingModeArgument);
_rootCommand.Add(_hideConsoleArgument);
_rootCommand.SetAction(Ui);
_cameraTuningCommand.SetAction(CameraTuning);
Console.CancelKeyPress += new ConsoleCancelEventHandler(OnProgramShutdown);
Console.WriteLine("Press Ctrl+C to shut down.");
return builder.StartWithClassicDesktopLifetime(args);
var parseResult = _rootCommand.Parse(_args);
if (parseResult.Errors.Count() != 0)
{
foreach (var parseError in parseResult.Errors)
Console.Error.WriteLine(parseError.Message);
return 1;
}
return parseResult.Invoke();
}
private static void OnProgramShutdown(object? sender, ConsoleCancelEventArgs ea)
@@ -50,68 +63,4 @@ public class Program
ShutdownRequested?.Invoke(sender, ea);
ea.Cancel = true;
}
private static void SilenceConsole()
{
new Thread(() =>
{
Console.CursorVisible = false;
while (true)
Console.ReadKey(true);
})
{ IsBackground = true }.Start();
}
private static IHost BuildHostApp()
{
var builder = Host.CreateApplicationBuilder();
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter));
builder.Logging.AddConsoleFormatter<ConsoleFormatter, ConsoleFormatterOptions>();
builder.Logging.AddProvider(new FileLoggerProvider("full.log", true));
builder.Logging.AddProvider(new FileLoggerProvider("last_run.log", false));
builder.Services.AddSingleton<LibCameraLogSink>();
builder.Services.AddAmineContentCalibrationContext(builder.Configuration);
builder.Services.AddAmineContentResultsContext(builder.Configuration);
builder.Services.AddLightsService("Hardware:Lights");
builder.Services.AddTemperatureHumidityService("Hardware:TemperatureHumidity");
builder.Services.AddIlluminatorService("Hardware:Illuminator");
builder.Services.AddCameraService("Hardware:Camera", true);
builder.Services.AddComputeResourcesService();
builder.Services.AddViewsAndModels();
var host = builder.Build();
host.Services.GetRequiredService<LibCameraLogSink>();
using (var scope = host.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AmineContentCalibrationContext>();
context.Database.Migrate();
}
using (var scope = host.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AmineContentResultsContext>();
context.Database.Migrate();
}
return host;
}
private static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseSkia()
.LogToTrace()
.With(new X11PlatformOptions
{
RenderingMode = [X11RenderingMode.Egl]
})
.With(new EglDisplayOptions
{
SupportsContextSharing = true
});
}
+57
View File
@@ -0,0 +1,57 @@
using System.CommandLine;
using GSS2.Core;
using GSS2.Core.Hardware;
using GSS2.Core.Logging;
using Microsoft.Extensions.Logging.Console;
using ConsoleFormatter = GSS2.Core.Logging.ConsoleFormatter;
namespace GSS2.Test;
public partial class Program
{
private class CameraTuningWorker : BackgroundService
{
private readonly ILogger<CameraTuningWorker> _logger;
private readonly IHostApplicationBuilder _applicationLifetime;
private readonly CameraService _cameraService;
private readonly IlluminatorService _illuminatorService;
public CameraTuningWorker(ILogger<CameraTuningWorker> logger, IHostApplicationBuilder applicationLifetime, CameraService cameraService, IlluminatorService illuminatorService)
{
_applicationLifetime = applicationLifetime;
_logger = logger;
_cameraService = cameraService;
_illuminatorService = illuminatorService;
_logger.LogInformation("Initialized");
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Running camera fine tuning");
}
}
private static void CameraTuning(ParseResult parseResult)
{
var builder = Host.CreateApplicationBuilder();
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter));
builder.Logging.AddConsoleFormatter<ConsoleFormatter, ConsoleFormatterOptions>();
builder.Logging.AddProvider(new FileLoggerProvider("full.log", true));
builder.Logging.AddProvider(new FileLoggerProvider("last_run.log", false));
builder.Services.AddSingleton<LibCameraLogSink>();
builder.Services.AddIlluminatorService("Hardware:Illuminator");
builder.Services.AddCameraService("Hardware:Camera", true);
builder.Services.AddHostedService<CameraTuningWorker>();
var host = builder.Build();
host.Services.GetRequiredService<LibCameraLogSink>();
host.Run();
}
}
+104
View File
@@ -0,0 +1,104 @@
using System.CommandLine;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Console;
using Avalonia;
using Avalonia.OpenGL.Egl;
using GSS2.Core;
using GSS2.Core.Logging;
using GSS2.Core.Analysis.AmineContent.Database;
using ConsoleFormatter = GSS2.Core.Logging.ConsoleFormatter;
namespace GSS2.Test;
public partial class Program
{
public static IHost ApplicationHost { get; } = BuildHostApp();
private static void Ui(ParseResult parseResult)
{
var builder = BuildAvaloniaApp();
var renderingMode = parseResult.GetValue(_renderingModeArgument);
var hideConsole = parseResult.GetValue(_hideConsoleArgument);
if (hideConsole)
SilenceConsole();
switch (renderingMode)
{
case RenderingMode.X11:
builder.StartWithClassicDesktopLifetime(_args ?? []);
break;
case RenderingMode.DRM:
builder.StartLinuxDrm(_args ?? [], "/dev/dri/card1", 1.0);
break;
}
}
private static void SilenceConsole()
{
new Thread(() =>
{
Console.CursorVisible = false;
while (true)
Console.ReadKey(true);
})
{ IsBackground = true }.Start();
}
private static IHost BuildHostApp()
{
var builder = Host.CreateApplicationBuilder();
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter));
builder.Logging.AddConsoleFormatter<ConsoleFormatter, ConsoleFormatterOptions>();
builder.Logging.AddProvider(new FileLoggerProvider("full.log", true));
builder.Logging.AddProvider(new FileLoggerProvider("last_run.log", false));
builder.Services.AddSingleton<LibCameraLogSink>();
builder.Services.AddAmineContentCalibrationContext(builder.Configuration);
builder.Services.AddAmineContentResultsContext(builder.Configuration);
builder.Services.AddLightsService("Hardware:Lights");
builder.Services.AddTemperatureHumidityService("Hardware:TemperatureHumidity");
builder.Services.AddIlluminatorService("Hardware:Illuminator");
builder.Services.AddCameraService("Hardware:Camera", true);
builder.Services.AddComputeResourcesService();
builder.Services.AddViewsAndModels();
var host = builder.Build();
host.Services.GetRequiredService<LibCameraLogSink>();
using (var scope = host.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AmineContentCalibrationContext>();
context.Database.Migrate();
}
using (var scope = host.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AmineContentResultsContext>();
context.Database.Migrate();
}
return host;
}
private static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseSkia()
.LogToTrace()
.With(new X11PlatformOptions
{
RenderingMode = [X11RenderingMode.Egl]
})
.With(new EglDisplayOptions
{
SupportsContextSharing = true
});
}