CLI options : -c configurqtion-file.json

This commit is contained in:
Paul Schneider 2026-09-21 18:53:17 +01:00
commit 70a123b840
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
6 changed files with 59 additions and 19 deletions

View file

@ -22,6 +22,7 @@
<PackageVersion Include="Material.Avalonia" Version="3.20.0" /> <PackageVersion Include="Material.Avalonia" Version="3.20.0" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" /> <PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.2" /> <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.2" />
<PackageVersion Include="Mono.Options" Version="6.12.0.148" />
<PackageVersion Include="Xamarin.AndroidX.Browser" Version="1.10.0.1" /> <PackageVersion Include="Xamarin.AndroidX.Browser" Version="1.10.0.1" />
<PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.2.0.3" /> <PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.2.0.3" />
<PackageVersion Include="Xamarin.AndroidX.Lifecycle.Runtime" Version="2.11.0.1" /> <PackageVersion Include="Xamarin.AndroidX.Lifecycle.Runtime" Version="2.11.0.1" />

View file

@ -12,6 +12,8 @@ sealed class Program
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
CLIOptionHandler.HandleArgs(args);
// Short-circuit 2nd-instance launches (OS handing us the // Short-circuit 2nd-instance launches (OS handing us the
// postit://callback URL) BEFORE Avalonia spins up a window. // postit://callback URL) BEFORE Avalonia spins up a window.
// If we let Avalonia initialise, the new MainWindow flashes // If we let Avalonia initialise, the new MainWindow flashes

View file

@ -17,6 +17,7 @@ namespace PostIt;
public partial class App : Application public partial class App : Application
{ {
private int _bootStarted; private int _bootStarted;
public string? CliConfigFileSpecification {  get; private set; }
/// <summary> /// <summary>
/// DI container the platform entry points hand to ViewModels so /// DI container the platform entry points hand to ViewModels so
@ -203,4 +204,9 @@ public partial class App : Application
{ {
await View!.NavRoot.PopAsync(); await View!.NavRoot.PopAsync();
} }
internal void UseConfigFileWhenLoading(string configFile)
{
this.CliConfigFileSpecification = configFile;
}
} }

View file

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Mono.Options;
using PostIt;
using PostIt.ViewModels;
public static class CLIOptionHandler
{
public static void HandleArgs(string[] args)
{
bool showHelp = false;
string configFile = null;
var options = new OptionSet {
{ "c|configuration=", "Configuration file to load", (string v) => configFile = v },
{ "h|help", "Show this message and exit", v => showHelp = true }
};
List<string> extra = options.Parse(args);
if (showHelp)
{
Console.WriteLine("Usage: app [OPTIONS]+");
options.WriteOptionDescriptions(Console.Out);
return;
}
if (configFile != null)
{
var app = App.Current as App;
app.UseConfigFileWhenLoading(configFile);
}
}
}

View file

@ -36,6 +36,7 @@
<PackageReference Include="IdentityModel.OidcClient" /> <PackageReference Include="IdentityModel.OidcClient" />
<PackageReference Include="MarkdownViewer.Core" /> <PackageReference Include="MarkdownViewer.Core" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Mono.Options" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../../Yavsc.Abstract/Yavsc.Abstract.csproj" /> <ProjectReference Include="../../Yavsc.Abstract/Yavsc.Abstract.csproj" />

View file

@ -259,25 +259,13 @@ public partial class Settings : ViewModelBase
return; return;
} }
} }
if (Environment.GetEnvironmentVariable("POSTIT_SETTINGS_JSON") is string envJson
&& !string.IsNullOrWhiteSpace(envJson)) var app = App.Current as App;
if (app!=null)
if (app.CliConfigFileSpecification!=null)
{ {
Console.WriteLine("🔎 Loading settings from POSTIT_SETTINGS_JSON environment variable."); SettingsFileFullName = app.CliConfigFileSpecification;
FileInfo configByEnvFileInfo = new FileInfo(envJson);
if (!configByEnvFileInfo.Exists)
{
throw new Exception($"🩎 Settings file not found at {configByEnvFileInfo.FullName}");
}
string json = File.ReadAllText(configByEnvFileInfo.FullName);
ApplyJson(json, "POSTIT_SETTINGS_JSON");
SettingsFileFullName = configByEnvFileInfo.FullName;
Loaded = true;
return;
} }
string configDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"PostIt"
);
if (SettingsFileFullName is not null) if (SettingsFileFullName is not null)
{ {
@ -287,10 +275,18 @@ public partial class Settings : ViewModelBase
else if (Environment.GetEnvironmentVariable("POSTIT_SETTINGS_JSON") is string envPath else if (Environment.GetEnvironmentVariable("POSTIT_SETTINGS_JSON") is string envPath
&& !string.IsNullOrWhiteSpace(envPath)) && !string.IsNullOrWhiteSpace(envPath))
{ {
SettingsFileFullName = envPath; FileInfo configByEnvFileInfo = new FileInfo(envPath);
if (!configByEnvFileInfo.Exists)
{
throw new Exception($"🩎 Settings file not found at {configByEnvFileInfo.FullName}");
}
SettingsFileFullName = configByEnvFileInfo.FullName;
} }
else else
{ {
string configDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"PostIt");
SettingsFileFullName = Path.Combine(configDir, "postit-settings.json"); SettingsFileFullName = Path.Combine(configDir, "postit-settings.json");
} }
@ -536,6 +532,7 @@ public partial class Settings : ViewModelBase
/// </summary> /// </summary>
partial void OnIsDirtyChanged(bool value) => SaveCommand.NotifyCanExecuteChanged(); partial void OnIsDirtyChanged(bool value) => SaveCommand.NotifyCanExecuteChanged();
public override bool CanNavigateNext { get => false; protected set => throw new System.NotImplementedException(); } public override bool CanNavigateNext { get => false; protected set => throw new System.NotImplementedException(); }
public override bool CanNavigatePrevious { get => true; protected set => throw new System.NotImplementedException(); } public override bool CanNavigatePrevious { get => true; protected set => throw new System.NotImplementedException(); }
} }