feat(headless): establish portable Linux host boundary
Add the presentation-free acdream-headless executable, strict no-connect configuration validation, dependency and assembly guards, and a Windows/Ubuntu CI lane that builds and tests only the portable runtime closure. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
953c469cac
commit
aada8a37c1
14 changed files with 613 additions and 8 deletions
82
src/AcDream.Headless/HeadlessEntryPoint.cs
Normal file
82
src/AcDream.Headless/HeadlessEntryPoint.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using AcDream.Headless.Configuration;
|
||||
|
||||
namespace AcDream.Headless;
|
||||
|
||||
internal static class HeadlessEntryPoint
|
||||
{
|
||||
private const string HelpText =
|
||||
"""
|
||||
acdream-headless
|
||||
|
||||
Usage:
|
||||
acdream-headless --help
|
||||
acdream-headless validate --config <path>
|
||||
|
||||
Commands:
|
||||
validate Validate a versioned headless configuration without connecting.
|
||||
|
||||
Secrets are never accepted on the command line.
|
||||
""";
|
||||
|
||||
internal static int Run(
|
||||
IReadOnlyList<string> arguments,
|
||||
TextWriter output,
|
||||
TextWriter error)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(arguments);
|
||||
ArgumentNullException.ThrowIfNull(output);
|
||||
ArgumentNullException.ThrowIfNull(error);
|
||||
|
||||
if (arguments.Count == 0
|
||||
|| IsHelp(arguments[0]))
|
||||
{
|
||||
output.WriteLine(HelpText);
|
||||
return (int)HeadlessExitCode.Success;
|
||||
}
|
||||
|
||||
if (!string.Equals(
|
||||
arguments[0],
|
||||
"validate",
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
error.WriteLine("Unknown command. Run --help for usage.");
|
||||
return (int)HeadlessExitCode.UsageError;
|
||||
}
|
||||
|
||||
if (arguments.Count != 3
|
||||
|| !string.Equals(
|
||||
arguments[1],
|
||||
"--config",
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
error.WriteLine(
|
||||
"validate requires exactly: --config <path>");
|
||||
return (int)HeadlessExitCode.UsageError;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
HeadlessConfiguration configuration =
|
||||
HeadlessConfigurationLoader.Load(arguments[2]);
|
||||
output.WriteLine(
|
||||
$"Configuration valid: version {configuration.Version}, "
|
||||
+ $"{configuration.Sessions.Count} session(s).");
|
||||
return (int)HeadlessExitCode.Success;
|
||||
}
|
||||
catch (Exception exception)
|
||||
when (exception is IOException
|
||||
or UnauthorizedAccessException
|
||||
or ArgumentException
|
||||
or NotSupportedException
|
||||
or System.Text.Json.JsonException
|
||||
or HeadlessConfigurationException)
|
||||
{
|
||||
error.WriteLine($"Configuration invalid: {exception.Message}");
|
||||
return (int)HeadlessExitCode.ConfigurationError;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsHelp(string argument) =>
|
||||
string.Equals(argument, "--help", StringComparison.Ordinal)
|
||||
|| string.Equals(argument, "-h", StringComparison.Ordinal);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue