Files
superwork/tui/internal/store/prreview.go
T
2026-06-23 05:02:15 +08:00

98 lines
3.0 KiB
Go

// Package store persists workspace-level PR review confirmation state.
//
// Confirmations live in <workspace>/.spx/pr-review-confirmed.json as a
// map[string][]string. File-level confirmations use key "<issueNumber>:<sha>"
// and hold the confirmed file paths of that commit; commit-level confirmations
// use key "<issueNumber>:commits" and hold the confirmed commit SHAs. Directories
// are not tracked separately. A missing or malformed file reads as empty.
package store
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strconv"
"superwork-tui/internal/config"
)
type confirmedMap = map[string][]string
func confirmedFile(workspaceRoot string) string {
return filepath.Join(config.SpxDir(workspaceRoot), "pr-review-confirmed.json")
}
func fileKey(issueNumber int, sha string) string {
return strconv.Itoa(issueNumber) + ":" + sha
}
func commitsKey(issueNumber int) string {
return strconv.Itoa(issueNumber) + ":commits"
}
// readMap returns the whole confirmation map. A missing or unparseable file
// reads as an empty map rather than an error.
func readMap(workspaceRoot string) confirmedMap {
raw, err := os.ReadFile(confirmedFile(workspaceRoot))
if err != nil {
return confirmedMap{}
}
var parsed confirmedMap
if err := json.Unmarshal(raw, &parsed); err != nil {
return confirmedMap{}
}
return parsed
}
// writeMap persists the confirmation map, creating .spx if needed.
func writeMap(workspaceRoot string, m confirmedMap) error {
if err := os.MkdirAll(config.SpxDir(workspaceRoot), 0o755); err != nil {
return fmt.Errorf("create .spx dir: %w", err)
}
data, err := json.MarshalIndent(m, "", " ")
if err != nil {
return fmt.Errorf("marshal confirmations: %w", err)
}
if err := os.WriteFile(confirmedFile(workspaceRoot), append(data, '\n'), 0o644); err != nil {
return fmt.Errorf("write confirmations: %w", err)
}
return nil
}
// ReadConfirmed returns the confirmed file paths for a (issueNumber, sha) commit.
func ReadConfirmed(workspaceRoot string, issueNumber int, sha string) ([]string, error) {
return readMap(workspaceRoot)[fileKey(issueNumber, sha)], nil
}
// WriteConfirmed sets the confirmed file paths for a (issueNumber, sha) commit.
// An empty slice deletes the key.
func WriteConfirmed(workspaceRoot string, issueNumber int, sha string, paths []string) error {
m := readMap(workspaceRoot)
key := fileKey(issueNumber, sha)
if len(paths) > 0 {
m[key] = paths
} else {
delete(m, key)
}
return writeMap(workspaceRoot, m)
}
// ReadConfirmedCommits returns the confirmed commit SHAs for an issue.
func ReadConfirmedCommits(workspaceRoot string, issueNumber int) ([]string, error) {
return readMap(workspaceRoot)[commitsKey(issueNumber)], nil
}
// WriteConfirmedCommits sets the confirmed commit SHAs for an issue.
// An empty slice deletes the key.
func WriteConfirmedCommits(workspaceRoot string, issueNumber int, shas []string) error {
m := readMap(workspaceRoot)
key := commitsKey(issueNumber)
if len(shas) > 0 {
m[key] = shas
} else {
delete(m, key)
}
return writeMap(workspaceRoot, m)
}