package cmd import ( "fmt" "io" "strings" "text/tabwriter" "gitea.hostxtra.co.uk/vantage/vantage-shared/backup" "github.com/spf13/cobra" ) func newInspectCmd() *cobra.Command { return &cobra.Command{ Use: "inspect ARCHIVE", Short: "Print an archive's manifest", Long: "inspect reads an archive and prints what it holds. It contacts no\n" + "database, so it is safe to run against an archive of unknown origin\n" + "and is the fastest way to find out whether one is worth anything.", Args: cobra.ExactArgs(1), RunE: func(c *cobra.Command, args []string) error { archive, err := backup.Open(args[0]) if err != nil { return err } defer archive.Close() renderManifest(c.OutOrStdout(), archive.Manifest()) return nil }, } } // renderManifest prints a manifest for a human. func renderManifest(w io.Writer, m backup.Manifest) { fmt.Fprintf(w, "Created %s\n", m.CreatedAt.UTC().Format("2006-01-02 15:04:05 MST")) fmt.Fprintf(w, "Database %s\n", m.MongoDB) fmt.Fprintf(w, "MongoDB %s\n", m.MongoServerVersion) fmt.Fprintf(w, "Written by vantagectl %s on %s\n", m.VantageVersion, m.Hostname) fmt.Fprintf(w, "Format version %d\n", m.FormatVersion) if m.KeyFingerprint == nil { fmt.Fprintf(w, "Key none recorded — this archive cannot be checked "+ "against any KEY_ENCRYPTION_KEY\n") } else { fmt.Fprintf(w, "Key %s\n", *m.KeyFingerprint) } if len(m.Excluded) > 0 { fmt.Fprintf(w, "Excluded %s\n", strings.Join(m.Excluded, ", ")) } var docs, bytes int64 for _, c := range m.Collections { docs += c.Documents bytes += c.Bytes } fmt.Fprintf(w, "\n%d collections, %d documents, %s\n\n", len(m.Collections), docs, humanBytes(bytes)) tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0) fmt.Fprintln(tw, "COLLECTION\tDOCUMENTS\tSIZE") for _, c := range m.Collections { fmt.Fprintf(tw, "%s\t%d\t%s\n", c.Name, c.Documents, humanBytes(c.Bytes)) } tw.Flush() } func humanBytes(n int64) string { const unit = 1024 if n < unit { return fmt.Sprintf("%d B", n) } div, exp := int64(unit), 0 for v := n / unit; v >= unit; v /= unit { div *= unit exp++ } return fmt.Sprintf("%.1f %cB", float64(n)/float64(div), "KMGTP"[exp]) }