feat(diary): component loggers through a redacting console and daily stack
- New diary module: For, Bootstrap, Setup, SetVerbosity, Reset, Close, ParseConfig - Proxy component handler safe in package vars; styled console handler in bonfire's palette - Daily writer: one file per day, 0640, lazy open, retention, disables itself on open failure - Every channel leaf wrapped by sunscreen.Wrap; stack via slog.NewMultiHandler - bonfire: ColorMode, Palette, DefaultPalette, DetectProfile (lipgloss v2, colorprofile) - Generated main runs diary.Bootstrap first and diary.Setup after compass.Load - Ignore /storage/ and /examples/hello/storage/
This commit is contained in:
@@ -104,10 +104,10 @@ func generateMain(m Manifest) ([]byte, error) {
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/cabana\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/compass\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/conga\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/diary\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/lagoon\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/pact\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/party\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/sunscreen\"\n")
|
||||
b.WriteString("\t\"git.golem15.com/golem15/summercms/modules/surf\"\n")
|
||||
b.WriteString(")\n\n")
|
||||
b.WriteString("func main() {\n")
|
||||
@@ -117,11 +117,14 @@ func generateMain(m Manifest) ([]byte, error) {
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("}\n\n")
|
||||
b.WriteString("func run(args []string, out io.Writer) error {\n")
|
||||
b.WriteString("\tsunscreen.InstallDefault(os.Stderr)\n")
|
||||
b.WriteString("\tdiary.Bootstrap(os.Stderr, diary.Options{})\n")
|
||||
b.WriteString("\tcfg, err := compass.Load(\"config\")\n")
|
||||
b.WriteString("\tif err != nil {\n")
|
||||
b.WriteString("\t\treturn err\n")
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("\tif err := diary.Setup(cfg, diary.Options{}); err != nil {\n")
|
||||
b.WriteString("\t\treturn err\n")
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("\tapp := backpack.New(cfg)\n")
|
||||
b.WriteString("\tplugins, err := party.Activate(app, PluginIDs)\n")
|
||||
b.WriteString("\tif err != nil {\n")
|
||||
|
||||
@@ -142,29 +142,40 @@ func TestGenerateMainRegistersCongaRuntimeCommands(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestGenerateMainInstallsRedactingLogger: the first statement of run makes
|
||||
// the credential-redacting handler the default logger, before config loads
|
||||
// or any plugin can log.
|
||||
func TestGenerateMainInstallsRedactingLogger(t *testing.T) {
|
||||
// TestGenerateMainInstallsDiary: the first statement of run installs the
|
||||
// diary console logger, before config loads or any plugin can log, and
|
||||
// diary.Setup applies config/log.yaml right after compass loads it and before
|
||||
// the application container exists.
|
||||
func TestGenerateMainInstallsDiary(t *testing.T) {
|
||||
mainSrc, err := generateMain(Manifest{Module: "example.com/app", Binary: "hello"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := []byte("sunscreen.InstallDefault(os.Stderr)")
|
||||
if n := bytes.Count(mainSrc, line); n != 1 {
|
||||
t.Fatalf("InstallDefault count = %d, want 1\n%s", n, mainSrc)
|
||||
bootstrap := []byte("diary.Bootstrap(os.Stderr, diary.Options{})")
|
||||
setup := []byte("diary.Setup(cfg, diary.Options{})")
|
||||
if n := bytes.Count(mainSrc, bootstrap); n != 1 {
|
||||
t.Fatalf("Bootstrap count = %d, want 1\n%s", n, mainSrc)
|
||||
}
|
||||
if !bytes.Contains(mainSrc, []byte(`"git.golem15.com/golem15/summercms/modules/sunscreen"`)) {
|
||||
t.Fatalf("generated main does not import sunscreen:\n%s", mainSrc)
|
||||
if n := bytes.Count(mainSrc, setup); n != 1 {
|
||||
t.Fatalf("Setup count = %d, want 1\n%s", n, mainSrc)
|
||||
}
|
||||
install := bytes.Index(mainSrc, line)
|
||||
runStart := bytes.Index(mainSrc, []byte("func run(args []string, out io.Writer) error {"))
|
||||
if !bytes.Contains(mainSrc, []byte(`"git.golem15.com/golem15/summercms/modules/diary"`)) {
|
||||
t.Fatalf("generated main does not import diary:\n%s", mainSrc)
|
||||
}
|
||||
if bytes.Contains(mainSrc, []byte(`"git.golem15.com/golem15/summercms/modules/sunscreen"`)) {
|
||||
t.Fatalf("generated main still imports sunscreen:\n%s", mainSrc)
|
||||
}
|
||||
runSig := []byte("func run(args []string, out io.Writer) error {")
|
||||
runStart := bytes.Index(mainSrc, runSig)
|
||||
boot := bytes.Index(mainSrc, bootstrap)
|
||||
load := bytes.Index(mainSrc, []byte("compass.Load("))
|
||||
if runStart < 0 || load < 0 || !(runStart < install && install < load) {
|
||||
t.Fatalf("InstallDefault must be the first statement of run, before compass.Load:\n%s", mainSrc)
|
||||
set := bytes.Index(mainSrc, setup)
|
||||
newApp := bytes.Index(mainSrc, []byte("backpack.New("))
|
||||
if runStart < 0 || load < 0 || newApp < 0 || !(runStart < boot && boot < load && load < set && set < newApp) {
|
||||
t.Fatalf("want run { Bootstrap; compass.Load; Setup; backpack.New }:\n%s", mainSrc)
|
||||
}
|
||||
if between := bytes.TrimSpace(mainSrc[runStart+len("func run(args []string, out io.Writer) error {") : install]); len(between) != 0 {
|
||||
t.Fatalf("statements before InstallDefault: %q", between)
|
||||
if between := bytes.TrimSpace(mainSrc[runStart+len(runSig) : boot]); len(between) != 0 {
|
||||
t.Fatalf("statements before Bootstrap: %q", between)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
internal/build/testdata/new/main.go.golden
vendored
7
internal/build/testdata/new/main.go.golden
vendored
@@ -12,10 +12,10 @@ import (
|
||||
"git.golem15.com/golem15/summercms/modules/cabana"
|
||||
"git.golem15.com/golem15/summercms/modules/compass"
|
||||
"git.golem15.com/golem15/summercms/modules/conga"
|
||||
"git.golem15.com/golem15/summercms/modules/diary"
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
"git.golem15.com/golem15/summercms/modules/party"
|
||||
"git.golem15.com/golem15/summercms/modules/sunscreen"
|
||||
"git.golem15.com/golem15/summercms/modules/surf"
|
||||
)
|
||||
|
||||
@@ -27,11 +27,14 @@ func main() {
|
||||
}
|
||||
|
||||
func run(args []string, out io.Writer) error {
|
||||
sunscreen.InstallDefault(os.Stderr)
|
||||
diary.Bootstrap(os.Stderr, diary.Options{})
|
||||
cfg, err := compass.Load("config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := diary.Setup(cfg, diary.Options{}); err != nil {
|
||||
return err
|
||||
}
|
||||
app := backpack.New(cfg)
|
||||
plugins, err := party.Activate(app, PluginIDs)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user