// Package inspectview renders the result of capsule.Inspect as the // "datekeys inspect" command prints it. The command and the generator of the // frozen inspect outputs (testdata/fixtures/*.inspect.json) share it, so that // the frozen files are exactly what the command prints. package inspectview import ( "encoding/json" "fmt" "io" "time" datekeys "g.activething.com/go/DateKeys" "g.activething.com/go/DateKeys/capsule" ) // View is the result of "datekeys inspect"; "-json" prints it as JSON. type View struct { File string `json:"file"` // Format is the capsule format, once the prelude is valid (spec §70). Format int `json:"format,omitempty"` CapsuleID string `json:"capsule_id,omitempty"` DateKey string `json:"datekey,omitempty"` Profile string `json:"profile,omitempty"` Round uint64 `json:"round,omitempty"` UnlockAt string `json:"unlock_at,omitempty"` AccessPolicy string `json:"access_policy,omitempty"` // PublicNote is the public note, text of the creator that nobody has // checked (spec v0.11, §24.1). PublicNote string `json:"public_note,omitempty"` // UnusableNote is true when the capsule has a public note that breaks the // rules of text, which is not shown (§24.1). UnusableNote bool `json:"public_note_unusable,omitempty"` Valid bool `json:"valid"` Error string `json:"error,omitempty"` Checks []capsule.CheckResult `json:"checks"` } // New returns the view of the inspection of file: the result and the error // of capsule.Inspect. func New(file string, result *capsule.Inspection, err error) View { v := View{File: file, Valid: err == nil, Error: datekeys.Code(err), Checks: result.Checks, Format: int(result.Prelude.Format)} if h := result.Header; h != nil { v.CapsuleID, v.DateKey, v.Profile, v.Round, v.AccessPolicy = h.CapsuleIDHex(), h.DateKey.Compact(), h.DateKey.ProfileID, h.DateKey.Round, h.Policy.String() v.PublicNote, _ = h.PublicNote() v.UnusableNote = h.UnusableNote() } if !result.UnlockAt.IsZero() { v.UnlockAt = result.UnlockAt.Format(time.RFC3339) } return v } // WriteJSON writes v as indented JSON followed by a newline. func (v View) WriteJSON(w io.Writer) error { enc := json.NewEncoder(w) enc.SetIndent("", " ") return enc.Encode(v) } // WriteText writes v as lines of text, one per check. func (v View) WriteText(w io.Writer) { fmt.Fprintf(w, "%s\n", v.File) for _, c := range v.Checks { mark := "ok " if !c.OK { mark = "FAIL" } fmt.Fprintf(w, " [%s] step %2d %-26s %s\n", mark, c.Step, c.Name, c.Detail) } if v.Valid { fmt.Fprintf(w, " valid before unlock; opens at %s (round %d, %s, format %d)\n", v.UnlockAt, v.Round, v.AccessPolicy, v.Format) } }