package cli import ( "encoding/hex" "encoding/json" "fmt" "time" "github.com/urfave/cli/v2" "sneak.berlin/go/mfer/mfer" ) // ExportEntry represents a single file entry in the exported JSON output. type ExportEntry struct { Path string `json:"path"` Size int64 `json:"size"` Hashes []string `json:"hashes"` Mtime *string `json:"mtime,omitempty"` Ctime *string `json:"ctime,omitempty"` } func (mfa *CLIApp) exportManifestOperation(ctx *cli.Context) error { pathOrURL, err := mfa.resolveManifestArg(ctx) if err != nil { return fmt.Errorf("export: %w", err) } rc, err := mfa.openManifestReader(pathOrURL) if err != nil { return fmt.Errorf("export: %w", err) } defer func() { _ = rc.Close() }() manifest, err := mfer.NewManifestFromReader(rc) if err != nil { return fmt.Errorf("export: failed to parse manifest: %w", err) } files := manifest.Files() entries := make([]ExportEntry, 0, len(files)) for _, f := range files { entry := ExportEntry{ Path: f.Path, Size: f.Size, Hashes: make([]string, 0, len(f.Hashes)), } for _, h := range f.Hashes { entry.Hashes = append(entry.Hashes, hex.EncodeToString(h.MultiHash)) } if f.Mtime != nil { t := time.Unix(f.Mtime.Seconds, int64(f.Mtime.Nanos)).UTC().Format(time.RFC3339Nano) entry.Mtime = &t } if f.Ctime != nil { t := time.Unix(f.Ctime.Seconds, int64(f.Ctime.Nanos)).UTC().Format(time.RFC3339Nano) entry.Ctime = &t } entries = append(entries, entry) } enc := json.NewEncoder(mfa.Stdout) enc.SetIndent("", " ") if err := enc.Encode(entries); err != nil { return fmt.Errorf("export: failed to encode JSON: %w", err) } return nil }