Files
mfer/internal/cli/export.go
T
clawbot 0c3b342329
check / check (push) Waiting to run
Drop mimeType and ctime from the manifest format (closes #235)
Nothing goes in the 1.0 manifest that 1.0 does not read or write, and
mfer never wrote either field. mf.proto now reserves the numbers 301 and
303 and both names in MFFilePath, and mf.pb.go is regenerated. The
decoded-size check counts only file entries, hashes and timestamps,
export prints no ctime, and FileEntry loses the Ctime nothing set.
FORMAT.md and the README no longer describe either field.

The test of entries that decode too large gives each entry a second,
empty hash: an entry with one hash and a modification time can no
longer reach 8 times its size.

Model: opus-5-5
2026-10-19 18:20:43 +00:00

76 lines
1.5 KiB
Go

package cli
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"time"
"github.com/urfave/cli/v3"
"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"`
Mode string `json:"mode"` // octal, "0000" when none was recorded
}
func (mfa *CLIApp) exportManifestOperation(
ctx context.Context, cmd *cli.Command,
) error {
pathOrURL, err := mfa.resolveManifestArg(cmd)
if err != nil {
return err
}
rc, err := mfa.openManifestReader(ctx, pathOrURL)
if err != nil {
return err
}
defer func() { _ = rc.Close() }()
manifest, err := mfer.NewManifestFromReader(rc)
if err != nil {
return fmt.Errorf("parse manifest: %w", err)
}
files := manifest.Files()
entries := make([]ExportEntry, 0, len(files))
for _, f := range files {
entry := ExportEntry{
Path: f.GetPath(),
Size: f.GetSize(),
Hashes: make([]string, 0, len(f.GetHashes())),
Mode: fmt.Sprintf("%04o", f.GetMode()),
}
for _, h := range f.GetHashes() {
entry.Hashes = append(entry.Hashes, hex.EncodeToString(h.GetMultiHash()))
}
if mtime, ok := entryMtime(f); ok {
t := mtime.UTC().Format(time.RFC3339Nano)
entry.Mtime = &t
}
entries = append(entries, entry)
}
enc := json.NewEncoder(mfa.Stdout)
enc.SetIndent("", " ")
err = enc.Encode(entries)
if err != nil {
return fmt.Errorf("encode JSON: %w", err)
}
return nil
}