Files
OpenNest/OpenNest.Server/ServerOptions.cs
T
ajandClaude Opus 5.5 277ca36f42 feat(server): mirror the desktop update feed for Database-mode clients
Every installed copy checked GitHub Releases on its own, so a shop's
workstations shared GitHub's 60-requests-per-hour unauthenticated limit
per public address and each downloaded the ~90 MB package over the
internet. Shops large enough to hit that already run the nest server.

The server now mirrors the Velopack feed at /updates/{stable|dev}: one
GitHub API request per 30-minute refresh, each package downloaded once
and checked against the feed's size and SHA-256 before it is served. A
channel is mirrored only while clients ask for it, so stable-only shops
never download development builds. Database-mode clients read the
server first and fall back to GitHub when it has no feed (old server,
mirror off, not mirrored yet), downloading each package from whichever
source listed it. A hand-set feed URL still takes precedence.
OPENNEST_UPDATES=off turns the mirror off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:05:20 -04:00

56 lines
2.3 KiB
C#

namespace OpenNest.Server;
/// <summary>Startup settings read from the command line and environment.</summary>
public static class ServerOptions
{
public const string DatabaseVariable = "OPENNEST_DB";
public const string UpdatesVariable = "OPENNEST_UPDATES";
/// <summary>
/// True unless <c>OPENNEST_UPDATES</c> is <c>off</c>: the server mirrors the desktop
/// app's update feed from GitHub (see <see cref="UpdateMirror"/>).
/// </summary>
public static bool UpdatesEnabled(string? value) =>
!string.Equals(value?.Trim(), "off", StringComparison.OrdinalIgnoreCase);
/// <summary>The mirrored update feed lives in an <c>updates</c> directory beside the database.</summary>
public static string UpdatesPath(string databasePath) =>
Path.Combine(Path.GetDirectoryName(Path.GetFullPath(databasePath))!, "updates");
/// <summary>
/// The database path: <c>--database=&lt;path&gt;</c> or <c>--database &lt;path&gt;</c>, then
/// <c>OPENNEST_DB</c>, then <c>./data/nests.db</c>. A <c>--database</c> without a path,
/// or given twice, fails startup instead of silently storing nests elsewhere.
/// </summary>
public static string DatabasePath(IReadOnlyList<string> args, string? environmentPath)
{
string? path = null;
for (var i = 0; i < args.Count; i++)
{
string value;
if (args[i] == "--database")
{
if (i + 1 >= args.Count || args[i + 1].StartsWith("--", StringComparison.Ordinal))
throw new ArgumentException("--database requires a path.", nameof(args));
value = args[++i];
}
else if (args[i].StartsWith("--database=", StringComparison.Ordinal))
{
value = args[i]["--database=".Length..];
}
else
{
continue;
}
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("--database requires a path.", nameof(args));
if (path is not null)
throw new ArgumentException("--database was given more than once.", nameof(args));
path = value;
}
return path ?? environmentPath ?? Path.Combine("data", "nests.db");
}
}