68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
package manifest
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
// Entry is one copied file record
|
|
type Entry struct {
|
|
Source string `json:"source"`
|
|
LocalDest string `json:"localDest"`
|
|
S3Path string `json:"s3Path,omitempty"`
|
|
SHA256 string `json:"sha256"`
|
|
Bytes int64 `json:"bytes"`
|
|
Status string `json:"status"` // "local" | "s3" | "done" | "error"
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
// Manifest holds all entries for a session
|
|
type Manifest struct {
|
|
SessionID string `json:"sessionID"`
|
|
Entries []Entry `json:"entries"`
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// New creates a new manifest
|
|
func New(sessionID string) *Manifest {
|
|
return &Manifest{SessionID: sessionID}
|
|
}
|
|
|
|
// Append adds an entry atomically
|
|
func (m *Manifest) Append(e Entry) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.Entries = append(m.Entries, e)
|
|
}
|
|
|
|
// Save writes manifest atomically via temp file + rename
|
|
func (m *Manifest) Save(path string) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
data, err := json.MarshalIndent(m, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmp := path + ".tmp"
|
|
if err := os.WriteFile(tmp, data, 0644); err != nil {
|
|
return err
|
|
}
|
|
return os.Rename(tmp, path)
|
|
}
|
|
|
|
// Load reads a manifest from disk
|
|
func Load(path string) (*Manifest, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var m Manifest
|
|
if err := json.Unmarshal(data, &m); err != nil {
|
|
return nil, err
|
|
}
|
|
return &m, nil
|
|
}
|