klo

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2023 License: Apache-2.0 Imports: 16 Imported by: 4

README

klo

Go Reference GitHub build and test Go Report Card Coverage

klo is a Go package for kubectl-like output of Go values (such as structs, maps, et cetera) in several output formats. You might want to use this package in your CLI tools to easily offer kubectl-like output formatting to your Kubernetes-spoiled users.

The Only True Go Way mandates package names to be short, concise, evocative. Thus, the package name klo was chosen to represent the essence of kubectl-like output in a manner as short, concise and evocative as ever. If you happen to have sanitary associations, then better flush them now.

Supported Output Formats

The following output formats are supported:

  • ASCII columns, which optionally can be customized (-o custom-columns= and -o custom-columns-file=).
    • optional sorting by specific column(s) using JSONPath expressions.
  • JSON and JSONPath-customized (-o json, -o jsonpath=, and -o jsonpath-file=).
  • YAML (-o yaml).
  • Go templates (-o go-template= and -o go-template-file=).

Note: -o name and -o wide are application-specific and are basically customized ASCII column formats, with just varying custom column configurations. Thus, they can be easily implemented in your appliaction itself and then use the existing klo package features.

In addition, sorting is supported by wrapping an output-format printer into a sorting printer. This allows to sort the rows in a custom-columns output based on row values taken from one or even multiple columns.

Basic Usage

The following code example prints a table with multiple columns, and the rows sorted by the NAME column.

import (
    "os"
    "github.com/thediveo/klo"
)

func main() {
    // Some data structure we want to print in tables.
    type myobj struct {
        Name string
        Foo  int
        Bar  string
    }
    // A slice of objects we want to print as a table with custom columns.
    list := []myobj{
        myobj{Name: "One", Foo: 42},
        myobj{Name: "Two", Foo: 666, Bar: "Bar"},
        myobj{Name: "Another Two", Foo: 123, Bar: "Bar"},
    }
    // Create a table printer with custom columns, to be filled from fields
    // of the objects (namely, Name, Foo, and Bar fields).
    prn, err := klo.PrinterFromFlag("",
        &klo.Specs{DefaultColumnSpec: "NAME:{.Name},FOO:{.Foo},BAR:{.Bar}"})
    if err != nil {
        panic(err)
    }
    // Use a table sorter and tell it to sort by the Name field of our column objects.
    table, err := klo.NewSortingPrinter("{.Name}", prn)
    if err != nil {
        panic(err)
    }
    table.Fprint(os.Stdout, list)

This will output:

NAME        FOO  BAR
Another Two 123  Bar
One         42
Two         666  Bar

-o Usage

For supporting "-o" output format control via CLI args, choose any CLI arg handling package you like, such as flag, pflag, cobra, et cetera. Then, call PrinterFromFlag(oflagvalue, &myspecs), where oflagvalue is the set/default value of the CLI arg you use for controlling the output format in your own app's CLI. Your myspecs should specify the default custom-columns format, and optionally a wide custom-clumns format variant. If you support go templates for output formatting, then you should also pass in the value of your --template= CLI arg.

import (
    "github.com/thediveo/klo"
)

func main() {
    // Get your -o and -template flag values depending on your CLI arg toolkit.
    templateflagvalue := ""
    oflagvalue := "wide"
    // Set up the specs and get a suitable output formatting printer according
    // to the specific output format choosen and the auxiliary information given
    // on specs and an optional Go template arg.
    myspecs := klo.Specs{
        DefaultColumnSpec: "FOO:{.Foo}",
        WideColumnSpec: "FOO:{.Foo},BAR:{.Bar}",
        GoTemplateArg: templateflagvalue,
    }
    prn, err := PrinterFromFlag(oflagvalue, &myspecs)
    //...
}

klo is Copyright 2019 Harald Albrecht, and licensed under the Apache License, Version 2.0.

Documentation

Overview

Package klo is a "kubectl-like outputter" that prints Go values, such as structs, maps, et cetera, in several output formats, very similar to what "kubectl -o" has to offer. In particular, it offers ASCII table formatting with custom columns including column headers and self-adjusting column widths.

Example (Sortedtable)
package main

import (
	"os"

	"github.com/thediveo/klo"
	"github.com/thediveo/klo/testutil"
)

func main() {
	/* ignore/for testing */ out := testutil.NewTestWriter(os.Stdout) /* end ignore */
	// Some data structure we want to print in tables.
	type myobj struct {
		Name string
		Foo  int
		Bar  string
	}
	// A slice of objects we want to print as a table with custom columns.
	list := []myobj{
		{Name: "One", Foo: 42},
		{Name: "Two", Foo: 666, Bar: "Bar"},
		{Name: "Another Two", Foo: 123, Bar: "Bar"},
	}
	// Create a table printer with custom columns, to be filled from fields
	// of the objects (namely, Name, Foo, and Bar fields).
	prn, err := klo.PrinterFromFlag("",
		&klo.Specs{DefaultColumnSpec: "NAME:{.Name},FOO:{.Foo},BAR:{.Bar}"})
	if err != nil {
		panic(err)
	}
	// Use a table sorter and tell it to sort by the Name field of our column objects.
	table, err := klo.NewSortingPrinter("{.Name}", prn)
	if err != nil {
		panic(err)
	}
	table.Fprint(out, list)
}
Output:

NAME________FOO__BAR↵
Another_Two_123__Bar↵
One_________42___↵
Two_________666__Bar↵

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Column

type Column struct {
	Name     string             // Column name, for error reporting.
	Header   string             // Column header text.
	Template *jsonpath.JSONPath // Compiled JSONPath expression.
	Raw      string             // Original JSONPath expression.
}

Column stores the header text and the JSONPath for fetching column values. In addition, it features a column name, which is used to identify a specific column when reporting errors.

func (*Column) SetExpression

func (c *Column) SetExpression(exp string) error

SetExpression sets the JSONPath expression for a specific column. It accepts a more relaxed JSONPath expression syntax in the same way kubectl does for its custom columns. In particular, it accepts:

  • x.y.z ... without leading "." or curly braces.
  • {x.y.z} ... without leading ".", but at least curly braces.
  • .x.y.z ... without curly braces.
  • {.x.y.z} ... and finally as "standard".

Additionally, the empty expression "" also gets accepted.

type CustomColumnsPrinter

type CustomColumnsPrinter struct {
	// The individual columns with their headers and JSONPath expressions.
	Columns []*Column
	// Hide column headers
	HideHeaders bool
	// Padding between columns
	Padding int
}

CustomColumnsPrinter prints neatly formatted tables with custom columns.

func (*CustomColumnsPrinter) Fprint

func (p *CustomColumnsPrinter) Fprint(w io.Writer, v interface{}) error

Fprint prints the value v in a neatly formatted table according to the custom-column spec or template given when creating this custom-columns printer. The table is then written to the specified writer. If this writer is already a tabwriter, then it is the caller's responsibility to flush the tabwriter when it's the right point to do so.

type GoTemplatePrinter

type GoTemplatePrinter struct {
	Template *template.Template // The compiled golang template.
	// contains filtered or unexported fields
}

GoTemplatePrinter prints values in JSON format.

func (*GoTemplatePrinter) Fprint

func (p *GoTemplatePrinter) Fprint(w io.Writer, v interface{}) (err error)

Fprint prints a value in JSON format.

type JSONPathPrinter

type JSONPathPrinter struct {
	Expr *jsonpath.JSONPath // Compiled JSONPath expression.
	// contains filtered or unexported fields
}

JSONPathPrinter prints values in JSON format.

func (*JSONPathPrinter) Fprint

func (p *JSONPathPrinter) Fprint(w io.Writer, v interface{}) error

Fprint prints fields of a value in text format, where the values are selected using JSONPath expressions.

type JSONPrinter

type JSONPrinter struct{}

JSONPrinter prints values in JSON format.

func (*JSONPrinter) Fprint

func (p *JSONPrinter) Fprint(w io.Writer, v interface{}) error

Fprint prints a value in JSON format.

type SortingPrinter

type SortingPrinter struct {
	ChainedPrinter ValuePrinter       // Next ValuePrinter we chain to.
	SortExpr       *jsonpath.JSONPath // Compiled JSONPath expression.
	// contains filtered or unexported fields
}

SortingPrinter sorts slice values first, before it writes them to the next printer in the chain.

func (*SortingPrinter) Fprint

func (sp *SortingPrinter) Fprint(w io.Writer, v interface{}) error

Fprint first sorts values according to a JSONPath expression used for sorting, then chains to the next ValuePrinter for printing.

type Specs

type Specs struct {
	// default custom-columns spec in format
	// "<header>:<json-path-expr>[,<header>:json-path-expr>]..."
	DefaultColumnSpec string
	// wide custom-columns spec in format
	// "<header>:<json-path-expr>[,<header>:json-path-expr>]..."
	WideColumnSpec string
	// optional separate Go template argument to output formats "go-template"
	// and "go-template-file". For "go-template" the arg contains the
	// template, for "go-template-file" it contains the template filename.
	GoTemplateArg string
}

Specs specifies custom-column formats for the default columns in "-o=customcolumns" mode, and for the "-o=wide" wide columns mode.

type ValuePrinter

type ValuePrinter interface {
	Fprint(w io.Writer, v interface{}) error
}

ValuePrinter neatly prints values (especially slices of structs) to a writer, applying printer-specific formatting.

func NewCustomColumnsPrinterFromSpec

func NewCustomColumnsPrinterFromSpec(spec string) (ValuePrinter, error)

NewCustomColumnsPrinterFromSpec returns a new custom columns printer for the given specification. This specification is in form of a string consisting of a series of <column-header-name>:<json-path-expr> elements, separated by ",". The default padding between columns is set to 0, but can be changed later using the Padding field of the printer returned.

func NewCustomColumnsPrinterFromTemplate

func NewCustomColumnsPrinterFromTemplate(tr io.Reader) (ValuePrinter, error)

NewCustomColumnsPrinterFromTemplate returns a new custom columns printer for a template read from the given template stream. The template must consist of two lines, the first specifying the column headers, and the second giving the JSONPath expressions for each column. The

func NewGoTemplatePrinter

func NewGoTemplatePrinter(tmpl string) (ValuePrinter, error)

NewGoTemplatePrinter returns a printer for outputting values in JSON format.

func NewJSONPathPrinter

func NewJSONPathPrinter(expr string) (ValuePrinter, error)

NewJSONPathPrinter returns a printer for outputting the values that were filtered using a JSONPath expression. Please note that the JSONPath expression here must be strictly conforming to the syntax rules, in particular: it must be enclosed in "{...}" and leading "." must be present. In addition, the elements addresses must exist, or otherwise an error will be raised when printing objects using this expression. In consequence, JSONPath printers are much less forgiving than the custom-column printers.

func NewJSONPrinter

func NewJSONPrinter() (ValuePrinter, error)

NewJSONPrinter returns a printer for outputting values in JSON format.

func NewSortingPrinter

func NewSortingPrinter(expr string, p ValuePrinter) (ValuePrinter, error)

NewSortingPrinter returns a printer for outputting values in YAML format.

func NewYAMLPrinter

func NewYAMLPrinter() (ValuePrinter, error)

NewYAMLPrinter returns a printer for outputting values in YAML format.

func PrinterFromFlag

func PrinterFromFlag(flagvalue string, specs *Specs) (ValuePrinter, error)

PrinterFromFlag returns a suitable value printer according to the output format specified as the flagvalue. The "-o" flag value is passed in via the flagvalue parameter (without the "-o") and should denote one of the supported output formats, such as "json", "yaml", "custom-columns", et cetera. The Specs parameter specifies the default custom-columns output format for "-o=" and "-o=wide". If Specs is nil, then no default custom-column formats will apply.

type YAMLPrinter

type YAMLPrinter struct{}

YAMLPrinter prints values in JSON format.

func (*YAMLPrinter) Fprint

func (p *YAMLPrinter) Fprint(w io.Writer, v interface{}) error

Fprint prints a value in YAML format.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL