mirror of
https://github.com/kopia/kopia.git
synced 2026-01-25 23:08:01 -05:00
* cli: added standard --json flags to several commands Fixes #272 * Update flag description Co-authored-by: Julio López <julio+gh@kasten.io>
118 lines
2.1 KiB
Go
118 lines
2.1 KiB
Go
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/alecthomas/kingpin"
|
|
|
|
"github.com/kopia/kopia/snapshot"
|
|
)
|
|
|
|
var (
|
|
jsonOutput = false
|
|
jsonIndent = false
|
|
jsonVerbose = false // output addnon-essential stats as part of JSON
|
|
)
|
|
|
|
func registerJSONOutputFlags(cmd *kingpin.CmdClause) {
|
|
cmd.Flag("json", "Output result in JSON format to stdout").BoolVar(&jsonOutput)
|
|
cmd.Flag("json-indent", "Output result in indented JSON format to stdout").Hidden().BoolVar(&jsonIndent)
|
|
cmd.Flag("json-verbose", "Output non-essential data (e.g. statistics) in JSON format").Hidden().BoolVar(&jsonVerbose)
|
|
}
|
|
|
|
func cleanupSnapshotManifestForJSON(v *snapshot.Manifest) interface{} {
|
|
m := *v
|
|
|
|
if !jsonVerbose {
|
|
return struct {
|
|
*snapshot.Manifest
|
|
|
|
// trick to remove 'stats' completely.
|
|
Stats string `json:"stats,omitempty"`
|
|
}{Manifest: v}
|
|
}
|
|
|
|
return &m
|
|
}
|
|
|
|
func cleanupSnapshotManifestListForJSON(manifests []*snapshot.Manifest) interface{} {
|
|
var res []interface{}
|
|
|
|
for _, m := range manifests {
|
|
res = append(res, cleanupSnapshotManifestForJSON(m))
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func cleanupForJSON(v interface{}) interface{} {
|
|
switch v := v.(type) {
|
|
case *snapshot.Manifest:
|
|
return cleanupSnapshotManifestForJSON(v)
|
|
case []*snapshot.Manifest:
|
|
return cleanupSnapshotManifestListForJSON(v)
|
|
default:
|
|
return v
|
|
}
|
|
}
|
|
|
|
func jsonBytes(v interface{}) []byte {
|
|
return jsonIndentedBytes(v, "")
|
|
}
|
|
|
|
func jsonIndentedBytes(v interface{}, indent string) []byte {
|
|
v = cleanupForJSON(v)
|
|
|
|
var (
|
|
b []byte
|
|
err error
|
|
)
|
|
|
|
if jsonIndent {
|
|
b, err = json.MarshalIndent(v, indent+"", indent+" ")
|
|
} else {
|
|
b, err = json.Marshal(v)
|
|
}
|
|
|
|
if err != nil {
|
|
panic("error serializing JSON, that should not happen: " + err.Error())
|
|
}
|
|
|
|
return b
|
|
}
|
|
|
|
type jsonList struct {
|
|
separator string
|
|
}
|
|
|
|
func (l *jsonList) begin() {
|
|
if jsonOutput {
|
|
printStdout("[")
|
|
|
|
if !jsonIndent {
|
|
l.separator = "\n "
|
|
}
|
|
}
|
|
}
|
|
|
|
func (l *jsonList) end() {
|
|
if jsonOutput {
|
|
if !jsonIndent {
|
|
printStdout("\n")
|
|
}
|
|
|
|
printStdout("]")
|
|
}
|
|
}
|
|
|
|
func (l *jsonList) emit(v interface{}) {
|
|
printStdout(l.separator)
|
|
printStdout("%s", jsonBytes(v))
|
|
|
|
if jsonIndent {
|
|
l.separator = ","
|
|
} else {
|
|
l.separator = ",\n "
|
|
}
|
|
}
|