mirror of https://github.com/status-im/consul.git
Updates ryanuber/columnize.
This commit is contained in:
parent
5ad5fe42d4
commit
cc54dfa52f
|
@ -1,3 +0,0 @@
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
- tip
|
|
|
@ -4,6 +4,7 @@ Columnize
|
||||||
Easy column-formatted output for golang
|
Easy column-formatted output for golang
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/ryanuber/columnize.svg)](https://travis-ci.org/ryanuber/columnize)
|
[![Build Status](https://travis-ci.org/ryanuber/columnize.svg)](https://travis-ci.org/ryanuber/columnize)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/ryanuber/columnize?status.svg)](https://godoc.org/github.com/ryanuber/columnize)
|
||||||
|
|
||||||
Columnize is a really small Go package that makes building CLI's a little bit
|
Columnize is a really small Go package that makes building CLI's a little bit
|
||||||
easier. In some CLI designs, you want to output a number similar items in a
|
easier. In some CLI designs, you want to output a number similar items in a
|
||||||
|
@ -65,11 +66,4 @@ config.Empty = ""
|
||||||
You can then pass the `Config` in using the `Format` method (signature below) to
|
You can then pass the `Config` in using the `Format` method (signature below) to
|
||||||
have text formatted to your liking.
|
have text formatted to your liking.
|
||||||
|
|
||||||
Usage
|
See the [godoc](https://godoc.org/github.com/ryanuber/columnize) page for usage.
|
||||||
=====
|
|
||||||
|
|
||||||
```go
|
|
||||||
SimpleFormat(intput []string) string
|
|
||||||
|
|
||||||
Format(input []string, config *Config) string
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package columnize
|
package columnize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Config can be used to tune certain parameters which affect the way
|
||||||
|
// in which Columnize will format output text.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// The string by which the lines of input will be split.
|
// The string by which the lines of input will be split.
|
||||||
Delim string
|
Delim string
|
||||||
|
@ -19,66 +22,16 @@ type Config struct {
|
||||||
Empty string
|
Empty string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a Config with default values.
|
// DefaultConfig returns a *Config with default values.
|
||||||
func DefaultConfig() *Config {
|
func DefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Delim: "|",
|
Delim: "|",
|
||||||
Glue: " ",
|
Glue: " ",
|
||||||
Prefix: "",
|
Prefix: "",
|
||||||
|
Empty: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of elements, each representing a single item which will
|
|
||||||
// belong to a column of output.
|
|
||||||
func getElementsFromLine(config *Config, line string) []interface{} {
|
|
||||||
elements := make([]interface{}, 0)
|
|
||||||
for _, field := range strings.Split(line, config.Delim) {
|
|
||||||
value := strings.TrimSpace(field)
|
|
||||||
if value == "" && config.Empty != "" {
|
|
||||||
value = config.Empty
|
|
||||||
}
|
|
||||||
elements = append(elements, value)
|
|
||||||
}
|
|
||||||
return elements
|
|
||||||
}
|
|
||||||
|
|
||||||
// Examines a list of strings and determines how wide each column should be
|
|
||||||
// considering all of the elements that need to be printed within it.
|
|
||||||
func getWidthsFromLines(config *Config, lines []string) []int {
|
|
||||||
var widths []int
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
elems := getElementsFromLine(config, line)
|
|
||||||
for i := 0; i < len(elems); i++ {
|
|
||||||
l := len(elems[i].(string))
|
|
||||||
if len(widths) <= i {
|
|
||||||
widths = append(widths, l)
|
|
||||||
} else if widths[i] < l {
|
|
||||||
widths[i] = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return widths
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a set of column widths and the number of columns in the current line,
|
|
||||||
// returns a sprintf-style format string which can be used to print output
|
|
||||||
// aligned properly with other lines using the same widths set.
|
|
||||||
func (c *Config) getStringFormat(widths []int, columns int) string {
|
|
||||||
// Start with the prefix, if any was given.
|
|
||||||
stringfmt := c.Prefix
|
|
||||||
|
|
||||||
// Create the format string from the discovered widths
|
|
||||||
for i := 0; i < columns && i < len(widths); i++ {
|
|
||||||
if i == columns-1 {
|
|
||||||
stringfmt += "%s\n"
|
|
||||||
} else {
|
|
||||||
stringfmt += fmt.Sprintf("%%-%ds%s", widths[i], c.Glue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stringfmt
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeConfig merges two config objects together and returns the resulting
|
// MergeConfig merges two config objects together and returns the resulting
|
||||||
// configuration. Values from the right take precedence over the left side.
|
// configuration. Values from the right take precedence over the left side.
|
||||||
func MergeConfig(a, b *Config) *Config {
|
func MergeConfig(a, b *Config) *Config {
|
||||||
|
@ -105,21 +58,103 @@ func MergeConfig(a, b *Config) *Config {
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format is the public-facing interface that takes either a plain string
|
// stringFormat, given a set of column widths and the number of columns in
|
||||||
// or a list of strings and returns nicely aligned output.
|
// the current line, returns a sprintf-style format string which can be used
|
||||||
func Format(lines []string, config *Config) string {
|
// to print output aligned properly with other lines using the same widths set.
|
||||||
var result string
|
func stringFormat(c *Config, widths []int, columns int) string {
|
||||||
|
// Create the buffer with an estimate of the length
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, (6+len(c.Glue))*columns))
|
||||||
|
|
||||||
|
// Start with the prefix, if any was given. The buffer will not return an
|
||||||
|
// error so it does not need to be handled
|
||||||
|
buf.WriteString(c.Prefix)
|
||||||
|
|
||||||
|
// Create the format string from the discovered widths
|
||||||
|
for i := 0; i < columns && i < len(widths); i++ {
|
||||||
|
if i == columns-1 {
|
||||||
|
buf.WriteString("%s\n")
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(buf, "%%-%ds%s", widths[i], c.Glue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// elementsFromLine returns a list of elements, each representing a single
|
||||||
|
// item which will belong to a column of output.
|
||||||
|
func elementsFromLine(config *Config, line string) []interface{} {
|
||||||
|
seperated := strings.Split(line, config.Delim)
|
||||||
|
elements := make([]interface{}, len(seperated))
|
||||||
|
for i, field := range seperated {
|
||||||
|
value := strings.TrimSpace(field)
|
||||||
|
|
||||||
|
// Apply the empty value, if configured.
|
||||||
|
if value == "" && config.Empty != "" {
|
||||||
|
value = config.Empty
|
||||||
|
}
|
||||||
|
elements[i] = value
|
||||||
|
}
|
||||||
|
return elements
|
||||||
|
}
|
||||||
|
|
||||||
|
// widthsFromLines examines a list of strings and determines how wide each
|
||||||
|
// column should be considering all of the elements that need to be printed
|
||||||
|
// within it.
|
||||||
|
func widthsFromLines(config *Config, lines []string) []int {
|
||||||
|
widths := make([]int, 0, 8)
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
elems := elementsFromLine(config, line)
|
||||||
|
for i := 0; i < len(elems); i++ {
|
||||||
|
l := len(elems[i].(string))
|
||||||
|
if len(widths) <= i {
|
||||||
|
widths = append(widths, l)
|
||||||
|
} else if widths[i] < l {
|
||||||
|
widths[i] = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return widths
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format is the public-facing interface that takes a list of strings and
|
||||||
|
// returns nicely aligned column-formatted text.
|
||||||
|
func Format(lines []string, config *Config) string {
|
||||||
conf := MergeConfig(DefaultConfig(), config)
|
conf := MergeConfig(DefaultConfig(), config)
|
||||||
widths := getWidthsFromLines(conf, lines)
|
widths := widthsFromLines(conf, lines)
|
||||||
|
|
||||||
|
// Estimate the buffer size
|
||||||
|
glueSize := len(conf.Glue)
|
||||||
|
var size int
|
||||||
|
for _, w := range widths {
|
||||||
|
size += w + glueSize
|
||||||
|
}
|
||||||
|
size *= len(lines)
|
||||||
|
|
||||||
|
// Create the buffer
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, size))
|
||||||
|
|
||||||
|
// Create a cache for the string formats
|
||||||
|
fmtCache := make(map[int]string, 16)
|
||||||
|
|
||||||
// Create the formatted output using the format string
|
// Create the formatted output using the format string
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
elems := getElementsFromLine(conf, line)
|
elems := elementsFromLine(conf, line)
|
||||||
stringfmt := conf.getStringFormat(widths, len(elems))
|
|
||||||
result += fmt.Sprintf(stringfmt, elems...)
|
// Get the string format using cache
|
||||||
|
numElems := len(elems)
|
||||||
|
stringfmt, ok := fmtCache[numElems]
|
||||||
|
if !ok {
|
||||||
|
stringfmt = stringFormat(conf, widths, numElems)
|
||||||
|
fmtCache[numElems] = stringfmt
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(buf, stringfmt, elems...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the string result
|
||||||
|
result := buf.String()
|
||||||
|
|
||||||
// Remove trailing newline without removing leading/trailing space
|
// Remove trailing newline without removing leading/trailing space
|
||||||
if n := len(result); n > 0 && result[n-1] == '\n' {
|
if n := len(result); n > 0 && result[n-1] == '\n' {
|
||||||
result = result[:n-1]
|
result = result[:n-1]
|
||||||
|
@ -128,7 +163,7 @@ func Format(lines []string, config *Config) string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function for using Columnize as easy as possible.
|
// SimpleFormat is a convenience function to format text with the defaults.
|
||||||
func SimpleFormat(lines []string) string {
|
func SimpleFormat(lines []string) string {
|
||||||
return Format(lines, nil)
|
return Format(lines, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,9 +462,11 @@
|
||||||
"revisionTime": "2016-08-09T12:22:04Z"
|
"revisionTime": "2016-08-09T12:22:04Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"checksumSHA1": "ExnVEVNT8APpFTm26cUb5T09yR4=",
|
||||||
"comment": "v2.0.1-8-g983d3a5",
|
"comment": "v2.0.1-8-g983d3a5",
|
||||||
"path": "github.com/ryanuber/columnize",
|
"path": "github.com/ryanuber/columnize",
|
||||||
"revision": "983d3a5fab1bf04d1b412465d2d9f8430e2e917e"
|
"revision": "9b3edd62028f107d7cabb19353292afd29311a4e",
|
||||||
|
"revisionTime": "2016-07-12T16:32:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=",
|
"checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=",
|
||||||
|
|
Loading…
Reference in New Issue