From eae29de0457d4ce1d0913d2f89c8f76d1f1fec23 Mon Sep 17 00:00:00 2001 From: Alex Hope-O'Connor Date: Wed, 1 Apr 2026 11:52:21 +1000 Subject: [PATCH] Hosts: inline file comments (hosts(5)) and Comment column - HostEntry.InlineComment; parse at first # on data lines; ToLine + SanitizeInlineComment - HostsPageRow + HostsCache; pending change equality and save diff include comments - Hosts table: dedicated Comment column; edit in own cell; empty shown as em dash - Parser and pending-change tests --- .../PendingManagedHostsChangeTests.cs | 15 ++++ .../DnsmasqConfig/HostsFileLineParserTests.cs | 11 +++ src/DnsmasqWebUI/Components/Pages/Hosts.razor | 35 ++++++++- .../Components/Pages/Hosts.razor.css | 15 ++++ .../DnsmasqConfig/HostsFileLineParser.cs | 74 ++++++++++++++++--- .../Services/Dnsmasq/Hosts/HostsCache.cs | 6 +- .../ManagedHostsPendingChangeDiff.cs | 8 +- .../PendingManagedHostsChange.cs | 3 +- src/DnsmasqWebUI/Models/Hosts/HostEntry.cs | 3 + src/DnsmasqWebUI/Models/Hosts/HostsPageRow.cs | 3 +- 10 files changed, 154 insertions(+), 19 deletions(-) diff --git a/src/DnsmasqWebUI.Tests/Models/EffectiveConfig/PendingManagedHostsChangeTests.cs b/src/DnsmasqWebUI.Tests/Models/EffectiveConfig/PendingManagedHostsChangeTests.cs index fd17978..f47c07f 100644 --- a/src/DnsmasqWebUI.Tests/Models/EffectiveConfig/PendingManagedHostsChangeTests.cs +++ b/src/DnsmasqWebUI.Tests/Models/EffectiveConfig/PendingManagedHostsChangeTests.cs @@ -35,4 +35,19 @@ public class PendingManagedHostsChangeTests var pending = new PendingManagedHostsChange(oldEntries, newEntries, "/etc/hosts"); Assert.True(pending.HasChanges); } + + [Fact] + public void HasChanges_WhenInlineCommentDiffers_ReturnsTrue() + { + var oldEntries = new List + { + new() { Id = "1", Address = "10.0.0.1", Names = new List { "a" }, InlineComment = "old" } + }; + var newEntries = new List + { + new() { Id = "1", Address = "10.0.0.1", Names = new List { "a" }, InlineComment = "new" } + }; + var pending = new PendingManagedHostsChange(oldEntries, newEntries, "/etc/hosts"); + Assert.True(pending.HasChanges); + } } diff --git a/src/DnsmasqWebUI.Tests/Serialization/Parsers/DnsmasqConfig/HostsFileLineParserTests.cs b/src/DnsmasqWebUI.Tests/Serialization/Parsers/DnsmasqConfig/HostsFileLineParserTests.cs index 358fd31..0d7bcfc 100644 --- a/src/DnsmasqWebUI.Tests/Serialization/Parsers/DnsmasqConfig/HostsFileLineParserTests.cs +++ b/src/DnsmasqWebUI.Tests/Serialization/Parsers/DnsmasqConfig/HostsFileLineParserTests.cs @@ -139,6 +139,17 @@ public class HostsFileLineParserTests Assert.Equal(address, e.Address); Assert.Single(e.Names); Assert.Equal(name, e.Names[0]); + Assert.Equal(comment, e.InlineComment); + } + + [Fact] + public void ToLine_WithInlineComment_AppendsHashAndRoundTrips() + { + var line = "192.168.0.5 router # edge gateway"; + var e = HostsFileLineParser.ParseLine(line, 1); + Assert.NotNull(e); + var back = HostsFileLineParser.ToLine(e!); + Assert.Equal(line, back); } [Fact] diff --git a/src/DnsmasqWebUI/Components/Pages/Hosts.razor b/src/DnsmasqWebUI/Components/Pages/Hosts.razor index 12096e7..f18b82c 100644 --- a/src/DnsmasqWebUI/Components/Pages/Hosts.razor +++ b/src/DnsmasqWebUI/Components/Pages/Hosts.razor @@ -7,6 +7,7 @@ @using DnsmasqWebUI.Models.Hosts @using DnsmasqWebUI.Infrastructure.Services.EffectiveConfig.Abstractions @using DnsmasqWebUI.Infrastructure.Services.Dnsmasq.Hosts.Abstractions +@using DnsmasqWebUI.Infrastructure.Serialization.Parsers.DnsmasqConfig @using DnsmasqWebUI.Components.EffectiveConfig @using DnsmasqWebUI.Infrastructure.Services.UI.Notifications.Abstractions @using Microsoft.AspNetCore.Components.Web @@ -92,6 +93,7 @@ else Address Names + Comment Effective names