mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-04-09 20:06:50 +00:00
- rawcache: add Merge() that skips unchanged releases, logs added/ changed events to an append-only JSONL audit log with SHA-256 - rawcache: drop .json extension from filenames — raw cache stores opaque bytes (upstream may be JSON, CSV, XML, or bespoke) - fetchraw: add all 68 GitHub packages, use Merge instead of Put - fetchraw: log format shows +added ~changed =skipped
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package rawcache
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
// LogEntry records one event in the append-only audit log.
|
|
type LogEntry struct {
|
|
Time time.Time `json:"time"`
|
|
Tag string `json:"tag"`
|
|
Action string `json:"action"` // "added", "changed", "removed"
|
|
SHA256 string `json:"sha256,omitempty"`
|
|
}
|
|
|
|
// AuditLog is an append-only JSONL file that tracks when releases appear,
|
|
// change, or disappear from upstream. One file per package, lives alongside
|
|
// the double-buffer slots.
|
|
type AuditLog struct {
|
|
path string
|
|
}
|
|
|
|
// openLog returns the audit log for a Dir.
|
|
func (d *Dir) openLog() *AuditLog {
|
|
return &AuditLog{path: filepath.Join(d.root, "audit.jsonl")}
|
|
}
|
|
|
|
// Append writes one log entry.
|
|
func (l *AuditLog) Append(entry LogEntry) error {
|
|
if entry.Time.IsZero() {
|
|
entry.Time = time.Now().UTC()
|
|
}
|
|
data, err := json.Marshal(entry)
|
|
if err != nil {
|
|
return fmt.Errorf("rawcache: marshal log entry: %w", err)
|
|
}
|
|
data = append(data, '\n')
|
|
|
|
f, err := os.OpenFile(l.path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
|
if err != nil {
|
|
return fmt.Errorf("rawcache: open audit log: %w", err)
|
|
}
|
|
_, writeErr := f.Write(data)
|
|
closeErr := f.Close()
|
|
if writeErr != nil {
|
|
return fmt.Errorf("rawcache: write audit log: %w", writeErr)
|
|
}
|
|
if closeErr != nil {
|
|
return fmt.Errorf("rawcache: close audit log: %w", closeErr)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ContentHash returns the SHA-256 hex digest of data.
|
|
func ContentHash(data []byte) string {
|
|
h := sha256.Sum256(data)
|
|
return hex.EncodeToString(h[:])
|
|
}
|