Start Housecarl: the logo, the wordmark and the skeleton

Housecarl will be a firewall manager for nftables, built the way Jarl and
Steward are: housecarld (a daemon with a REST API and web UI), hc (the
CLI) and SQLite.

- The logo: a carved Nordic doorway in Jarl's blue (artwork/logo.svg),
  with a small version without the carvings, lighter on dark
  backgrounds. scripts/logo.py builds the web UI's copies and
  scripts/banner.py the README banner.
- The HOUSECARL wordmark in Jarl's and Steward's angular letters, with
  new H, O, U and C (assets/brand.js), and the UI's color tokens.
- housecarld and hc print their version; the Makefile, version package,
  AGENTS.md, CHANGELOG and the design sketch (docs/design.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-18 21:20:05 +01:00
commit 54beb0bba3
24 files changed
+949

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
package version
import "testing"
func TestDescribe(t *testing.T) {
const c = "4d00be5e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c"
for _, tc := range []struct {
tag, commit string
modified bool
label, url string
}{
{"v0.1.0", c, true, "v0.1.0", Repo + "/releases/tag/v0.1.0"},
{"", c, false, "4d00be5e1f0a", Repo + "/commit/" + c},
{"", c, true, "4d00be5e1f0a-modified", Repo + "/commit/" + c},
{"", "", false, "0.1.0", Repo},
} {
b := describe("0.1.0", tc.tag, tc.commit, tc.modified)
if b.Label != tc.label || b.URL != tc.url {
t.Errorf("describe(%q, %q, %v) = %q %q, want %q %q", tc.tag, tc.commit, tc.modified, b.Label, b.URL, tc.label, tc.url)
}
}
}
func TestString(t *testing.T) {
const c = "ca0f148b78b6e1f0a9b8c7d6e5f4a3b2c1d0e9f8"
build := func(tag, commit string, modified bool, desc string) Build {
b := describe("0.2.0-rc.1", tag, commit, modified)
b.Since, b.Ahead = parseDescribe(desc, b.Commit)
return b
}
for _, tc := range []struct {
b Build
want string
}{
{build("v0.2.0-rc.1", c, false, "v0.2.0-rc.1-0-gca0f148b78b6"), "0.2.0-rc.1"},
{build("", c, false, "v0.2.0-rc.1-3-gca0f148b78b6"), "dev ca0f148b78b6 (3 commits after v0.2.0-rc.1)"},
{build("", c, true, "v0.2.0-rc.1-1-gca0f148b78b6"), "dev ca0f148b78b6-modified (1 commit after v0.2.0-rc.1)"},
{build("", c, true, "v0.2.0-rc.1-0-gca0f148b78b6"), "dev ca0f148b78b6-modified (v0.2.0-rc.1 with uncommitted changes)"},
{build("", c, false, "v0.1.0-0-gca0f148b78b6"), "dev ca0f148b78b6 (at v0.1.0)"},
{build("", c, false, ""), "dev ca0f148b78b6"},
// A describe of another commit (stale ldflags) is ignored.
{build("", c, false, "v0.2.0-rc.1-3-gdeadbeef0000"), "dev ca0f148b78b6"},
{build("", "", false, ""), "0.2.0-rc.1 (source build)"},
} {
if got := tc.b.String(); got != tc.want {
t.Errorf("String() = %q, want %q", got, tc.want)
}
}
}