// 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"` 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"` 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} 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() } 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)\n", v.UnlockAt, v.Round, v.AccessPolicy) } }