Extract shared read-only session inspection checks

This commit is contained in:
2026-05-23 16:00:31 +00:00
parent 9fe44cd00d
commit c366912586
5 changed files with 418 additions and 101 deletions

View File

@@ -5,8 +5,10 @@ import (
"flag"
"fmt"
"io"
"sort"
"strings"
"gitea.maximumdirect.net/eric/narratio/internal/adapters/storage"
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
"gitea.maximumdirect.net/eric/narratio/internal/config"
)
@@ -35,6 +37,8 @@ func Status(ctx context.Context, args []string, out io.Writer) error {
fmt.Fprintf(out, "Campaign: %s\n", cfg.Session.Campaign)
fmt.Fprintf(out, "Workspace: %s\n", paths.Root)
fmt.Fprintf(out, "Session config: %s\n", sessionSourceSummary(cfg))
writeStatusStableInputs(out, inspectStableInputs(cfg))
writeStatusLocalAudio(out, inspectLocalAudioPresence(cfg))
if m, err := loadLocalManifest(ctx, paths.ManifestPath); err != nil {
fmt.Fprintf(out, "Local manifest: error: %v\n", err)
@@ -49,21 +53,30 @@ func Status(ctx context.Context, args []string, out io.Writer) error {
if storeErr != nil {
fmt.Fprintf(out, "Remote publish: unavailable: %v\n", storeErr)
} else if store != nil {
current, err := discoverRemoteCurrentStateFn(ctx, cfg, store)
if err != nil {
fmt.Fprintf(out, "Remote publish: missing or unavailable: %v\n", err)
current := inspectRemoteCurrentState(ctx, cfg, store)
if current.Err != nil {
fmt.Fprintf(out, "Remote publish: missing or unavailable: %v\n", current.Err)
} else {
fmt.Fprintf(out, "Remote publish: current run %s\n", current.RunID)
fmt.Fprintf(out, "Remote manifest: %s\n", current.CurrentManifestKey)
fmt.Fprintf(out, "Remote publish: current run %s\n", current.State.RunID)
fmt.Fprintf(out, "Remote manifest: %s\n", current.State.CurrentManifestKey)
}
}
writeStatusRemoteAudio(ctx, out, cfg, store, storeErr)
writeStatusPreviousArtifacts(out, inspectPreviousArtifactReadiness(
ctx,
cfg,
store,
artifacts.CollectPreviousArtifactRequirements(configuredScriptoriumArtifacts(cfg)),
))
locks, err := loadEffectiveLocks(ctx, cfg, store)
lockChecks := inspectEffectiveLocks(ctx, cfg, store)
locks := lockChecks.Locks
lockErr := lockChecks.Err
if catalog, catalogErr := buildHelperArtifactCatalog(cfg); catalogErr != nil {
fmt.Fprintf(out, "Remote outputs: error: %v\n", catalogErr)
} else if storeErr == nil {
catalogLocks := locks
if err != nil {
if lockErr != nil {
catalogLocks = &effectiveLocks{
Static: staticPublishLocks(cfg),
All: staticPublishLocks(cfg),
@@ -76,8 +89,8 @@ func Status(ctx context.Context, args []string, out io.Writer) error {
fmt.Fprintln(out, "Remote outputs:")
writeArtifactList(out, cfg, catalog, catalogLocks, publishedRemoteState)
}
if err != nil {
fmt.Fprintf(out, "Publish locks: error: %v\n", err)
if lockErr != nil {
fmt.Fprintf(out, "Publish locks: error: %v\n", lockErr)
} else {
writeLocks(out, cfg, locks)
}
@@ -86,3 +99,68 @@ func Status(ctx context.Context, args []string, out io.Writer) error {
fmt.Fprintf(out, "- narratio session restore %s --dry-run\n", cfg.Session.SessionID)
return nil
}
func writeStatusStableInputs(out io.Writer, checks []stableInputCheck) {
if len(checks) == 0 {
return
}
for _, check := range checks {
if check.Err != nil {
if strings.TrimSpace(check.Path) != "" {
fmt.Fprintf(out, "Stable input %s: unavailable: %v\n", check.Name, check.Err)
} else {
fmt.Fprintf(out, "Stable input %s: unavailable: %s\n", check.Name, check.Err.Error())
}
continue
}
fmt.Fprintf(out, "Stable input %s: %s\n", check.Name, check.Path)
}
}
func writeStatusLocalAudio(out io.Writer, check localAudioCheck) {
if !check.Checked {
return
}
if check.Err != nil {
fmt.Fprintf(out, "Local audio: unavailable: %v\n", check.Err)
return
}
fmt.Fprintf(out, "Local audio: %d file(s)\n", len(check.Paths))
}
func writeStatusRemoteAudio(ctx context.Context, out io.Writer, cfg *config.Config, store storage.ObjectStore, storeErr error) {
if cfg.Session.Inputs.AudioS3 == nil {
return
}
if storeErr != nil {
fmt.Fprintf(out, "Remote audio: unavailable: %v\n", storeErr)
return
}
check := inspectRemoteAudioPresence(ctx, cfg, store)
if check.Err != nil {
fmt.Fprintf(out, "Remote audio: unavailable: %v\n", check.Err)
return
}
fmt.Fprintf(out, "Remote audio: %d .flac object(s)\n", len(check.Keys))
}
func writeStatusPreviousArtifacts(out io.Writer, readiness previousArtifactReadiness) {
if len(readiness.Requirements) == 0 {
fmt.Fprintln(out, "Previous-session artifacts: not required")
return
}
if readiness.MissingID {
fmt.Fprintln(out, "Previous-session artifacts: unavailable: previous_session_id is required by configured previous-session artifacts")
return
}
if readiness.Err != nil {
fmt.Fprintf(out, "Previous-session artifacts: unavailable: %v\n", readiness.Err)
return
}
names := make([]string, 0, len(readiness.Requirements))
for _, req := range readiness.Requirements {
names = append(names, fmt.Sprintf("%s(required=%t)", req.Name, req.Required))
}
sort.Strings(names)
fmt.Fprintf(out, "Previous-session artifacts: ready: %s\n", strings.Join(names, ", "))
}