feat: add motd-assist TUI for managing dynamic MOTDs

Initial Go project built with Bubble Tea and Lip Gloss:
- Live preview and management of /etc/update-motd.d scripts
- Embedded presets (ubuntu-default, minimal, server-dashboard)
- Bundled POSIX sh style scripts (brand header, sysinfo panel, footer)
- Snapshot/restore safety around applying changes
- CLI subcommands preview, apply, restore, list-presets
- Unit tests for detect, sanitize, and apply logic
This commit is contained in:
Tronax 2026-08-24 14:19:28 +02:00
commit d56659e21a
Signed by: Tronax
SSH key fingerprint: SHA256:2pKKXDZucWvaF/GzXNz0FY53EAO1YDLN80bqS+TTz/o
34 changed files with 3260 additions and 0 deletions

View file

@ -0,0 +1,40 @@
package motd
import (
"os"
"path/filepath"
"reflect"
"testing"
)
func TestDiscoverListsValidNamesSorted(t *testing.T) {
root := t.TempDir()
dir := MotdDir(root)
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
for _, name := range []string{"10-sysinfo", "00-header", "notes.txt", ".hidden", "README"} {
if err := os.WriteFile(filepath.Join(dir, name), []byte("#!/bin/sh\n"), 0o644); err != nil {
t.Fatal(err)
}
}
scripts, err := Discover(root)
if err != nil {
t.Fatal(err)
}
var names []string
for _, s := range scripts {
names = append(names, s.Name)
}
// README ist ein valider run-parts-Name und bleibt dabei.
if !reflect.DeepEqual(names, []string{"00-header", "10-sysinfo", "README"}) {
t.Errorf("names = %v", names)
}
}
func TestDiscoverMissingDir(t *testing.T) {
if _, err := Discover(t.TempDir()); err == nil {
t.Error("Fehler erwartet, wenn update-motd.d fehlt")
}
}