Skip to content

Commit

Permalink
Merge pull request #2 from TLINDEN/development
Browse files Browse the repository at this point in the history
Merge latest dev
  • Loading branch information
TLINDEN authored Oct 3, 2022
2 parents 9f5fc69 + 76f49a5 commit f2acd2c
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 51 deletions.
4 changes: 0 additions & 4 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
Add a mode like FreeBSD stat(1):

stat -s dead.letter
st_dev=170671546954750497 st_ino=159667 st_mode=0100644 st_nlink=1 st_uid=1001 st_gid=1001 st_rdev=18446744073709551615 st_size=573 st_atime=1661994007 st_mtime=1661961878 st_ctime=1661961878 st_birthtime=1658394900 st_blksize=4096 st_blocks=3 st_flags=2048

6 changes: 4 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&lib.OutflagExtended, "extended", "X", false, "Enable extended output")
rootCmd.PersistentFlags().BoolVarP(&lib.OutflagMarkdown, "markdown", "M", false, "Enable markdown table output")
rootCmd.PersistentFlags().BoolVarP(&lib.OutflagOrgtable, "orgtbl", "O", false, "Enable org-mode table output")
rootCmd.MarkFlagsMutuallyExclusive("extended", "markdown", "orgtbl")
rootCmd.PersistentFlags().BoolVarP(&lib.OutflagShell, "shell", "S", false, "Enable shell mode output")
rootCmd.MarkFlagsMutuallyExclusive("extended", "markdown", "orgtbl", "shell")
rootCmd.Flags().MarkHidden("extended")
rootCmd.Flags().MarkHidden("orgtbl")
rootCmd.Flags().MarkHidden("markdown")
rootCmd.Flags().MarkHidden("shell")

// same thing but more common, takes precedence over above group
rootCmd.PersistentFlags().StringVarP(&lib.OutputMode, "output", "o", "", "Output mode - one of: orgtbl, markdown, extended, ascii(default)")
rootCmd.PersistentFlags().StringVarP(&lib.OutputMode, "output", "o", "", "Output mode - one of: orgtbl, markdown, extended, shell, ascii(default)")
}
3 changes: 2 additions & 1 deletion lib/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ var Separator string
var OutflagExtended bool
var OutflagMarkdown bool
var OutflagOrgtable bool
var OutflagShell bool
var OutputMode string

var Version = "v1.0.2"
var Version = "v1.0.3"
var validOutputmodes = "(orgtbl|markdown|extended|ascii)"
19 changes: 13 additions & 6 deletions lib/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,11 @@ package lib
import (
"errors"
"fmt"
"os"
"regexp"
"strconv"
"strings"
)

func die(v ...interface{}) {
fmt.Fprintln(os.Stderr, v...)
os.Exit(1)
}

func contains(s []int, e int) bool {
for _, a := range s {
if a == e {
Expand Down Expand Up @@ -63,6 +57,9 @@ func PrepareModeFlags() error {
OutputMode = "markdown"
case OutflagOrgtable:
OutputMode = "orgtbl"
case OutflagShell:
OutputMode = "shell"
NoNumbering = true
default:
OutputMode = "ascii"
}
Expand All @@ -82,3 +79,13 @@ func PrepareModeFlags() error {

return nil
}

func trimRow(row []string) []string {
// FIXME: remove this when we only use Tablewriter and strip in ParseFile()!
var fixedrow []string
for _, cell := range row {
fixedrow = append(fixedrow, strings.TrimSpace(cell))
}

return fixedrow
}
6 changes: 5 additions & 1 deletion lib/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ func ProcessFiles(args []string) error {
}

for _, fd := range fds {
printData(parseFile(fd, pattern))
data, err := parseFile(fd, pattern)
if err != nil {
return err
}
printData(&data)
}

return nil
Expand Down
12 changes: 5 additions & 7 deletions lib/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package lib

import (
"bufio"
"errors"
"fmt"
"github.com/alecthomas/repr"
"io"
Expand All @@ -43,7 +44,7 @@ type Tabdata struct {
way we can turn "tabular data" (with fields containing whitespaces)
into real tabular data. We re-tabulate our input if you will.
*/
func parseFile(input io.Reader, pattern string) Tabdata {
func parseFile(input io.Reader, pattern string) (Tabdata, error) {
data := Tabdata{}

var scanner *bufio.Scanner
Expand All @@ -65,7 +66,7 @@ func parseFile(input io.Reader, pattern string) Tabdata {

patternR, err := regexp.Compile(pattern)
if err != nil {
die(err)
return data, errors.Unwrap(fmt.Errorf("Regexp pattern %s is invalid: %w", pattern, err))
}

if !hadFirst {
Expand Down Expand Up @@ -145,20 +146,17 @@ func parseFile(input io.Reader, pattern string) Tabdata {

idx++
}
if Debug {
fmt.Println()
}
data.entries = append(data.entries, values)
}
}

if scanner.Err() != nil {
die(scanner.Err())
return data, errors.Unwrap(fmt.Errorf("Regexp pattern %s is invalid: %w", pattern, scanner.Err()))
}

if Debug {
repr.Print(data)
}

return data
return data, nil
}
7 changes: 6 additions & 1 deletion lib/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ asd igig cxxxncnc
19191 EDD 1 X`

readFd := strings.NewReader(table)
gotdata := parseFile(readFd, "")
gotdata, err := parseFile(readFd, "")

if err != nil {
t.Errorf("Parser returned error: %s\nData processed so far: %+v", err, gotdata)
}

if !reflect.DeepEqual(data, gotdata) {
t.Errorf("Parser returned invalid data\nExp: %+v\nGot: %+v\n", data, gotdata)
}
Expand Down
68 changes: 43 additions & 25 deletions lib/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,24 @@ import (
"strings"
)

func printData(data Tabdata) {
// prepare headers
// FIXME: maybe do this already in parseFile()?
if !NoNumbering {
numberedHeaders := []string{}
for i, head := range data.headers {
if len(Columns) > 0 {
if !contains(UseColumns, i+1) {
continue
}
func printData(data *Tabdata) {
// prepare headers: add numbers to headers
numberedHeaders := []string{}
for i, head := range data.headers {
if len(Columns) > 0 {
// -c specified
if !contains(UseColumns, i+1) {
// ignore this one
continue
}
}
if NoNumbering {
numberedHeaders = append(numberedHeaders, head)
} else {
numberedHeaders = append(numberedHeaders, fmt.Sprintf("%s(%d)", head, i+1))
}
data.headers = numberedHeaders
}
data.headers = numberedHeaders

// prepare data
if len(Columns) > 0 {
Expand Down Expand Up @@ -68,25 +71,17 @@ func printData(data Tabdata) {
printOrgmodeData(data)
case "markdown":
printMarkdownData(data)
case "shell":
printShellData(data)
default:
printAsciiData(data)
}
}

func trimRow(row []string) []string {
// FIXME: remove this when we only use Tablewriter and strip in ParseFile()!
var fixedrow []string
for _, cell := range row {
fixedrow = append(fixedrow, strings.TrimSpace(cell))
}

return fixedrow
}

/*
Emacs org-mode compatible table (also orgtbl-mode)
*/
func printOrgmodeData(data Tabdata) {
func printOrgmodeData(data *Tabdata) {
tableString := &strings.Builder{}
table := tablewriter.NewWriter(tableString)

Expand Down Expand Up @@ -118,7 +113,7 @@ func printOrgmodeData(data Tabdata) {
/*
Markdown table
*/
func printMarkdownData(data Tabdata) {
func printMarkdownData(data *Tabdata) {
table := tablewriter.NewWriter(os.Stdout)

table.SetHeader(data.headers)
Expand All @@ -136,7 +131,7 @@ func printMarkdownData(data Tabdata) {
/*
Simple ASCII table without any borders etc, just like the input we expect
*/
func printAsciiData(data Tabdata) {
func printAsciiData(data *Tabdata) {
table := tablewriter.NewWriter(os.Stdout)

table.SetHeader(data.headers)
Expand Down Expand Up @@ -164,7 +159,7 @@ func printAsciiData(data Tabdata) {
/*
We simulate the \x command of psql (the PostgreSQL client)
*/
func printExtendedData(data Tabdata) {
func printExtendedData(data *Tabdata) {
// needed for data output
format := fmt.Sprintf("%%%ds: %%s\n", data.maxwidthHeader) // FIXME: re-calculate if -c has been set

Expand All @@ -186,3 +181,26 @@ func printExtendedData(data Tabdata) {
}
}
}

/*
Shell output, ready to be eval'd. Just like FreeBSD stat(1)
*/
func printShellData(data *Tabdata) {
if len(data.entries) > 0 {
var idx int
for _, entry := range data.entries {
idx = 0
for i, value := range entry {
if len(Columns) > 0 {
if !contains(UseColumns, i+1) {
continue
}
}

fmt.Printf("%s=\"%s\" ", data.headers[idx], value)
idx++
}
fmt.Println()
}
}
}
9 changes: 7 additions & 2 deletions lib/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,13 @@ asd igig cxxxncnc
for mode, expect := range expects {
OutputMode = mode
fd := strings.NewReader(table)
data := parseFile(fd, "")
printData(data)
data, err := parseFile(fd, "")

if err != nil {
t.Errorf("Parser returned error: %s\nData processed so far: %+v", err, data)
}

printData(&data)

buf := make([]byte, 1024)
n, err := r.Read(buf)
Expand Down
15 changes: 13 additions & 2 deletions tablizer.pod
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The numbering can be suppressed by using the B<-n> option.
Finally the B<-d> option enables debugging output which is mostly
usefull for the developer.

?head2 OUTPUT MODES
=head2 OUTPUT MODES

There might be cases when the tabular output of a program is way too
large for your current terminal but you still need to see every
Expand All @@ -83,7 +83,7 @@ usefull which enables I<extended mode>. In this mode, each row will be
printed vertically, header left, value right, aligned by the field
widths. Here's an example:

kubectl get pods | ./tablizer -X
kubectl get pods | ./tablizer -o extended
NAME: repldepl-7bcd8d5b64-7zq4l
READY: 1/1
STATUS: Running
Expand All @@ -93,6 +93,17 @@ widths. Here's an example:
You can of course still use a regex to reduce the number of rows
displayed.

The option B<-o shell> can be used if the output has to be processed
by the shell, it prints variable assignments for each cell, one line
per row:

kubectl get pods | ./tablizer -o extended ./tablizer -o shell
NAME="repldepl-7bcd8d5b64-7zq4l" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"
NAME="repldepl-7bcd8d5b64-m48n8" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"
NAME="repldepl-7bcd8d5b64-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"

You can use this in an eval loop.

Beside normal ascii mode (the default) and extended mode there are
more output modes available: B<orgtbl> which prints an Emacs org-mode
table and B<markdown> which prints a Markdown table.
Expand Down

0 comments on commit f2acd2c

Please sign in to comment.