Centralize atomic artifact writes

This commit is contained in:
2026-05-29 20:33:35 +00:00
parent 7dc2ac9253
commit 1355605e70
13 changed files with 207 additions and 181 deletions

View File

@@ -10,9 +10,9 @@ import (
"strings"
"time"
"gitea.maximumdirect.net/eric/weatherreporter/internal/adapters/scriptorium"
"gitea.maximumdirect.net/eric/weatherreporter/internal/briefing"
"gitea.maximumdirect.net/eric/weatherreporter/internal/config"
"gitea.maximumdirect.net/eric/weatherreporter/internal/fileutil"
"gitea.maximumdirect.net/eric/weatherreporter/internal/promptinput"
"gitea.maximumdirect.net/eric/weatherreporter/internal/report"
)
@@ -99,7 +99,7 @@ func (s *FilesystemStore) SaveBriefing(_ context.Context, resolved report.Resolv
if err != nil {
return "", err
}
if err := writeJSONAtomic(paths.Briefing, pkg); err != nil {
if err := fileutil.WriteJSONAtomic(paths.Briefing, pkg); err != nil {
return "", err
}
return paths.Briefing, nil
@@ -113,21 +113,18 @@ func (s *FilesystemStore) SaveDataPackage(_ context.Context, resolved report.Res
if err := promptinput.Validate(pkg); err != nil {
return "", err
}
if err := writeJSONAtomic(paths.DataPackage, pkg); err != nil {
if err := fileutil.WriteJSONAtomic(paths.DataPackage, pkg); err != nil {
return "", err
}
return paths.DataPackage, nil
}
func (s *FilesystemStore) SavePreflight(_ context.Context, resolved report.Resolved, result *scriptorium.RenderResult) (string, error) {
if result == nil {
return "", fmt.Errorf("render result is required")
}
func (s *FilesystemStore) SavePreflight(_ context.Context, resolved report.Resolved, artifact PreflightArtifact) (string, error) {
paths, err := s.Paths(resolved)
if err != nil {
return "", err
}
if err := writeJSONAtomic(paths.Preflight, result); err != nil {
if err := fileutil.WriteJSONAtomic(paths.Preflight, artifact); err != nil {
return "", err
}
return paths.Preflight, nil
@@ -161,7 +158,7 @@ func (s *FilesystemStore) SaveMetadata(_ context.Context, metadata Metadata) (st
if path == "" {
return "", fmt.Errorf("metadata path cannot be resolved")
}
if err := writeJSONAtomic(path, metadata); err != nil {
if err := fileutil.WriteJSONAtomic(path, metadata); err != nil {
return "", err
}
return path, nil
@@ -362,33 +359,6 @@ func validateRelativeDir(name string, value string) error {
return nil
}
func writeJSONAtomic(path string, value any) error {
data, err := json.MarshalIndent(value, "", " ")
if err != nil {
return fmt.Errorf("marshal %q: %w", path, err)
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return fmt.Errorf("create directory %q: %w", filepath.Dir(path), err)
}
tmp, err := os.CreateTemp(filepath.Dir(path), "."+filepath.Base(path)+".*.tmp")
if err != nil {
return fmt.Errorf("create temporary file for %q: %w", path, err)
}
tmpName := tmp.Name()
defer os.Remove(tmpName)
if _, err := tmp.Write(data); err != nil {
tmp.Close()
return fmt.Errorf("write temporary file for %q: %w", path, err)
}
if err := tmp.Close(); err != nil {
return fmt.Errorf("close temporary file for %q: %w", path, err)
}
if err := os.Rename(tmpName, path); err != nil {
return fmt.Errorf("save %q: %w", path, err)
}
return nil
}
func readJSON(path string, target any) error {
data, err := os.ReadFile(path)
if err != nil {