aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-15 14:01:07 +0200
committerDanilo M. <danix@danix.xyz>2026-09-15 14:01:07 +0200
commit52765e0350629bd22aea8eead630c9efe09ec5f9 (patch)
tree1d0b4de4377877b60fd91e472b0c00adbbadd22f
parent20bb69d641c5242d026df5d3fcc9681064758ad6 (diff)
downloadnotifyd-52765e0350629bd22aea8eead630c9efe09ec5f9.tar.gz
notifyd-52765e0350629bd22aea8eead630c9efe09ec5f9.zip
fix: close the review nits in the write path, query path and tests
Remove the temp file on every writeJSON failure path, not just the write and close ones. A failed rename left the temp behind with no cleanup. Surface the list path's unmarshal error instead of printing null with exit 0, and make a non-positive history limit print an empty array rather than falling through to the whole ring. Assert the evicted item actually lands in the history ring, so the "files to history" half of eviction is covered rather than just its signal. Add the missing README License section beside the GPLv2 text and headers.
-rw-r--r--README.md4
-rw-r--r--cmd/notifyctl/main.go9
-rw-r--r--internal/notify/files.go15
-rw-r--r--internal/notify/store_test.go7
4 files changed, 31 insertions, 4 deletions
diff --git a/README.md b/README.md
index d93968a..b7ef38d 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,10 @@ dunst is not removed until this proves itself. To switch:
The renderer that draws the balloons is a separate plan; until it ships the
queue is visible through `notifyctl list`.
+## License
+
+GPLv2 only. See [LICENSE](LICENSE).
+
## Development Approach
This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback.
diff --git a/cmd/notifyctl/main.go b/cmd/notifyctl/main.go
index ca1db86..e0875e7 100644
--- a/cmd/notifyctl/main.go
+++ b/cmd/notifyctl/main.go
@@ -52,6 +52,10 @@ func main() {
}
limit = n
}
+ if limit < 1 {
+ fmt.Println("[]")
+ return
+ }
printFile("history.json", limit)
case "close":
need(3)
@@ -106,7 +110,10 @@ func printFile(name string, limit int) {
return
}
var pretty any
- json.Unmarshal(data, &pretty)
+ if err := json.Unmarshal(data, &pretty); err != nil {
+ fmt.Fprintf(os.Stderr, "notifyctl: %v\n", err)
+ os.Exit(1)
+ }
out, _ := json.MarshalIndent(pretty, "", " ")
fmt.Println(string(out))
}
diff --git a/internal/notify/files.go b/internal/notify/files.go
index 22e0ea9..53e7f3f 100644
--- a/internal/notify/files.go
+++ b/internal/notify/files.go
@@ -54,14 +54,23 @@ func writeJSON(path string, v any) error {
if err != nil {
return err
}
+ tmpName := tmp.Name()
+ renamed := false
+ defer func() {
+ if !renamed {
+ os.Remove(tmpName)
+ }
+ }()
if _, err := tmp.Write(data); err != nil {
tmp.Close()
- os.Remove(tmp.Name())
return err
}
if err := tmp.Close(); err != nil {
- os.Remove(tmp.Name())
return err
}
- return os.Rename(tmp.Name(), path)
+ if err := os.Rename(tmpName, path); err != nil {
+ return err
+ }
+ renamed = true
+ return nil
}
diff --git a/internal/notify/store_test.go b/internal/notify/store_test.go
index 4e4dd79..1fb8bdc 100644
--- a/internal/notify/store_test.go
+++ b/internal/notify/store_test.go
@@ -112,6 +112,13 @@ func TestQueueCapEvictsToHistory(t *testing.T) {
if len(*emitted) == 0 {
t.Fatal("eviction emitted nothing")
}
+ history := s.historySnapshot()
+ if len(history) != 1 {
+ t.Fatalf("history length = %d, want 1", len(history))
+ }
+ if !history[0].Closed {
+ t.Error("evicted entry not marked closed in history")
+ }
}
func TestHistoryRingCapsAtTwenty(t *testing.T) {