mirror of
https://codeberg.org/scip/tablizer.git
synced 2025-12-19 05:21:03 +01:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c87da34f2 | ||
|
|
6f0f5afb27 | ||
|
|
62b606e7da | ||
|
|
567d23b175 | ||
|
|
14f24533f0 | ||
|
|
4e413c02b5 | ||
|
|
6d8c0c0936 | ||
|
|
21b607af7c | ||
|
|
06a5d74fb6 |
10
.github/workflows/ci.yaml
vendored
10
.github/workflows/ci.yaml
vendored
@@ -1,16 +1,16 @@
|
|||||||
name: build-and-test-tablizer
|
name: build-and-test-tablizer
|
||||||
on: [push, pull_request]
|
on: [push]
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: ['1.23']
|
version: ['1.24']
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.version }}
|
- name: Set up Go ${{ matrix.version }}
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: '${{ matrix.version }}'
|
go-version: '${{ matrix.version }}'
|
||||||
id: go
|
id: go
|
||||||
@@ -28,9 +28,9 @@ jobs:
|
|||||||
name: lint
|
name: lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: 1.23
|
go-version: 1.24
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v6
|
||||||
|
|||||||
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: 1.22.11
|
go-version: 1.22.11
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -65,7 +65,7 @@ clean:
|
|||||||
rm -rf $(tool) releases coverage.out
|
rm -rf $(tool) releases coverage.out
|
||||||
|
|
||||||
test: clean
|
test: clean
|
||||||
go test ./... $(OPTS)
|
go test -cover ./... $(OPTS)
|
||||||
|
|
||||||
singletest:
|
singletest:
|
||||||
@echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'"
|
@echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'"
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ Operational Flags:
|
|||||||
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
||||||
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
||||||
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
||||||
|
-j, --json Read JSON input (must be array of hashes)
|
||||||
-I, --interactive Interactively filter and select rows
|
-I, --interactive Interactively filter and select rows
|
||||||
|
|
||||||
Output Flags (mutually exclusive):
|
Output Flags (mutually exclusive):
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const DefaultSeparator string = `(\s\s+|\t)`
|
const DefaultSeparator string = `(\s\s+|\t)`
|
||||||
const Version string = "v1.5.5"
|
const Version string = "v1.5.7"
|
||||||
const MAXPARTS = 2
|
const MAXPARTS = 2
|
||||||
|
|
||||||
var DefaultConfigfile = os.Getenv("HOME") + "/.config/tablizer/config"
|
var DefaultConfigfile = os.Getenv("HOME") + "/.config/tablizer/config"
|
||||||
@@ -79,6 +79,7 @@ type Config struct {
|
|||||||
UseFuzzySearch bool
|
UseFuzzySearch bool
|
||||||
UseHighlight bool
|
UseHighlight bool
|
||||||
Interactive bool
|
Interactive bool
|
||||||
|
InputJSON bool
|
||||||
|
|
||||||
SortMode string
|
SortMode string
|
||||||
SortDescending bool
|
SortDescending bool
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
// "reflect"
|
// "reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrepareModeFlags(t *testing.T) {
|
func TestPrepareModeFlags(t *testing.T) {
|
||||||
@@ -44,9 +46,8 @@ func TestPrepareModeFlags(t *testing.T) {
|
|||||||
conf := Config{}
|
conf := Config{}
|
||||||
|
|
||||||
conf.PrepareModeFlags(testdata.flag)
|
conf.PrepareModeFlags(testdata.flag)
|
||||||
if conf.OutputMode != testdata.expect {
|
|
||||||
t.Errorf("got: %d, expect: %d", conf.OutputMode, testdata.expect)
|
assert.EqualValues(t, testdata.expect, conf.OutputMode)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,9 +71,7 @@ func TestPrepareSortFlags(t *testing.T) {
|
|||||||
|
|
||||||
conf.PrepareSortFlags(testdata.flag)
|
conf.PrepareSortFlags(testdata.flag)
|
||||||
|
|
||||||
if conf.SortMode != testdata.expect {
|
assert.EqualValues(t, testdata.expect, conf.SortMode)
|
||||||
t.Errorf("got: %s, expect: %s", conf.SortMode, testdata.expect)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,7 @@ func TestPreparePattern(t *testing.T) {
|
|||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
patterns []*Pattern
|
patterns []*Pattern
|
||||||
name string
|
name string
|
||||||
wanterr bool
|
wanterror bool
|
||||||
wanticase bool
|
wanticase bool
|
||||||
wantneg bool
|
wantneg bool
|
||||||
}{
|
}{
|
||||||
@@ -123,16 +122,16 @@ func TestPreparePattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, testdata := range tests {
|
for _, testdata := range tests {
|
||||||
testname := fmt.Sprintf("PreparePattern-pattern-%s-wanterr-%t", testdata.name, testdata.wanterr)
|
testname := fmt.Sprintf("PreparePattern-pattern-%s-wanterr-%t", testdata.name, testdata.wanterror)
|
||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
conf := Config{}
|
conf := Config{}
|
||||||
|
|
||||||
err := conf.PreparePattern(testdata.patterns)
|
err := conf.PreparePattern(testdata.patterns)
|
||||||
|
|
||||||
if err != nil {
|
if testdata.wanterror {
|
||||||
if !testdata.wanterr {
|
assert.Error(t, err)
|
||||||
t.Errorf("PreparePattern returned error: %s", err)
|
} else {
|
||||||
}
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
10
cmd/root.go
10
cmd/root.go
@@ -20,6 +20,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -131,9 +132,11 @@ func Execute() {
|
|||||||
rootCmd.PersistentFlags().StringVarP(&conf.TransposeColumns, "transpose-columns", "T", "",
|
rootCmd.PersistentFlags().StringVarP(&conf.TransposeColumns, "transpose-columns", "T", "",
|
||||||
"Transpose the speficied columns (separated by ,)")
|
"Transpose the speficied columns (separated by ,)")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false,
|
rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false,
|
||||||
"interactive mode (experimental)")
|
"interactive mode")
|
||||||
rootCmd.PersistentFlags().StringVarP(&conf.OFS, "ofs", "", "",
|
rootCmd.PersistentFlags().StringVarP(&conf.OFS, "ofs", "", "",
|
||||||
"Output field separator (' ' for ascii table, ',' for CSV)")
|
"Output field separator (' ' for ascii table, ',' for CSV)")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&conf.InputJSON, "json", "j", false,
|
||||||
|
"JSON input mode")
|
||||||
|
|
||||||
// sort options
|
// sort options
|
||||||
rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "",
|
rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "",
|
||||||
@@ -185,6 +188,11 @@ func Execute() {
|
|||||||
|
|
||||||
rootCmd.SetUsageTemplate(strings.TrimSpace(usage) + "\n")
|
rootCmd.SetUsageTemplate(strings.TrimSpace(usage) + "\n")
|
||||||
|
|
||||||
|
if slices.Contains(os.Args, "-h") {
|
||||||
|
fmt.Println(shortusage)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
err := rootCmd.Execute()
|
err := rootCmd.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
16
cmd/shortusage.go
Normal file
16
cmd/shortusage.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
const shortusage = `tablizer [regex,...] [-r file] [flags]
|
||||||
|
-c col,... show specified columns -L highlight matching lines
|
||||||
|
-k col,... sort by specified columns -j read JSON input
|
||||||
|
-F col=reg filter field with regexp -v invert match
|
||||||
|
-T col,... transpose specified columns -n numberize columns
|
||||||
|
-R /from/to/ apply replacement to columns in -T -N do not use colors
|
||||||
|
-y col,... yank columns to clipboard -H do not show headers
|
||||||
|
--ofs char output field separator -s specify field separator
|
||||||
|
-r file read input from file -z use fuzzy search
|
||||||
|
-f file read config from file -I interactive filter mode
|
||||||
|
-d debug
|
||||||
|
-O org -C CSV -M md -X ext -S shell -Y yaml -D sort descending order
|
||||||
|
-m show manual --help show detailed help -v show version
|
||||||
|
-a sort by age -i sort numerically -t sort by time`
|
||||||
@@ -20,6 +20,7 @@ SYNOPSIS
|
|||||||
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
||||||
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
||||||
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
||||||
|
-j, --json Read JSON input (must be array of hashes)
|
||||||
-I, --interactive Interactively filter and select rows
|
-I, --interactive Interactively filter and select rows
|
||||||
|
|
||||||
Output Flags (mutually exclusive):
|
Output Flags (mutually exclusive):
|
||||||
@@ -463,6 +464,7 @@ Operational Flags:
|
|||||||
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
||||||
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
||||||
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
||||||
|
-j, --json Read JSON input (must be array of hashes)
|
||||||
-I, --interactive Interactively filter and select rows
|
-I, --interactive Interactively filter and select rows
|
||||||
|
|
||||||
Output Flags (mutually exclusive):
|
Output Flags (mutually exclusive):
|
||||||
|
|||||||
25
go.mod
25
go.mod
@@ -1,22 +1,22 @@
|
|||||||
module github.com/tlinden/tablizer
|
module github.com/tlinden/tablizer
|
||||||
|
|
||||||
go 1.23.0
|
go 1.24.0
|
||||||
|
|
||||||
toolchain go1.23.5
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/repr v0.5.1
|
github.com/alecthomas/repr v0.5.2
|
||||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
||||||
github.com/charmbracelet/bubbles v0.21.0
|
github.com/charmbracelet/bubbles v0.21.0
|
||||||
github.com/charmbracelet/bubbletea v1.3.6
|
github.com/charmbracelet/bubbletea v1.3.10
|
||||||
github.com/charmbracelet/lipgloss v1.1.0
|
github.com/charmbracelet/lipgloss v1.1.0
|
||||||
github.com/evertras/bubble-table v0.19.0
|
github.com/evertras/bubble-table v0.19.2
|
||||||
github.com/gookit/color v1.6.0
|
github.com/gookit/color v1.6.0
|
||||||
github.com/hashicorp/hcl/v2 v2.24.0
|
github.com/hashicorp/hcl/v2 v2.24.0
|
||||||
github.com/lithammer/fuzzysearch v1.1.8
|
github.com/lithammer/fuzzysearch v1.1.8
|
||||||
github.com/olekukonko/tablewriter v1.0.9
|
github.com/mattn/go-isatty v0.0.20
|
||||||
|
github.com/olekukonko/tablewriter v1.1.0
|
||||||
github.com/rogpeppe/go-internal v1.14.1
|
github.com/rogpeppe/go-internal v1.14.1
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.10.1
|
||||||
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/tiagomelo/go-clipboard v0.1.2
|
github.com/tiagomelo/go-clipboard v0.1.2
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
@@ -27,16 +27,16 @@ require (
|
|||||||
github.com/atotto/clipboard v0.1.4 // indirect
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/charmbracelet/colorprofile v0.3.1 // indirect
|
github.com/charmbracelet/colorprofile v0.3.1 // indirect
|
||||||
github.com/charmbracelet/x/ansi v0.9.3 // indirect
|
github.com/charmbracelet/x/ansi v0.10.1 // indirect
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
|
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
|
||||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
||||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
@@ -47,14 +47,15 @@ require (
|
|||||||
github.com/olekukonko/errors v1.1.0 // indirect
|
github.com/olekukonko/errors v1.1.0 // indirect
|
||||||
github.com/olekukonko/ll v0.0.9 // indirect
|
github.com/olekukonko/ll v0.0.9 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.9 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
github.com/zclconf/go-cty v1.16.3 // indirect
|
github.com/zclconf/go-cty v1.16.3 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||||
golang.org/x/mod v0.21.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/sync v0.15.0 // indirect
|
golang.org/x/sync v0.15.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.36.0 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/text v0.25.0 // indirect
|
||||||
golang.org/x/tools v0.26.0 // indirect
|
golang.org/x/tools v0.26.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
36
go.sum
36
go.sum
@@ -1,7 +1,7 @@
|
|||||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg=
|
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||||
github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
|
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
|
||||||
@@ -12,14 +12,14 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
|
|||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
|
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
|
||||||
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
|
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
|
||||||
github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU=
|
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
|
||||||
github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc=
|
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
|
||||||
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
|
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
|
||||||
github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
|
github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||||
github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0=
|
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
|
||||||
github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
|
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
|
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||||
@@ -30,8 +30,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||||
github.com/evertras/bubble-table v0.19.0 h1:+JlXRUjNuBN1JI7XU1PapmW1wglbcqZUKkiPnVKPgrc=
|
github.com/evertras/bubble-table v0.19.2 h1:u77oiM6JlRR+CvS5FZc3Hz+J6iEsvEDcR5kO8OFb1Yw=
|
||||||
github.com/evertras/bubble-table v0.19.0/go.mod h1:ifHujS1YxwnYSOgcR2+m3GnJ84f7CVU/4kUOxUCjEbQ=
|
github.com/evertras/bubble-table v0.19.2/go.mod h1:ifHujS1YxwnYSOgcR2+m3GnJ84f7CVU/4kUOxUCjEbQ=
|
||||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||||
@@ -74,8 +74,8 @@ github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5
|
|||||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||||
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
|
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
|
||||||
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
|
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
|
||||||
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
|
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
|
||||||
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
@@ -88,14 +88,14 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
|||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/tiagomelo/go-clipboard v0.1.2 h1:Ph2icR0vZRIj3v5ExvsGweBwsbbDUTlS6HoF40MkQD8=
|
github.com/tiagomelo/go-clipboard v0.1.2 h1:Ph2icR0vZRIj3v5ExvsGweBwsbbDUTlS6HoF40MkQD8=
|
||||||
github.com/tiagomelo/go-clipboard v0.1.2/go.mod h1:kXtjJBIMimZaGbxmcKZ8+JqK+acSNf5tAJiChlZBOr8=
|
github.com/tiagomelo/go-clipboard v0.1.2/go.mod h1:kXtjJBIMimZaGbxmcKZ8+JqK+acSNf5tAJiChlZBOr8=
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||||
@@ -130,8 +130,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ package lib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,13 +56,11 @@ func TestMatchPattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err := conf.PreparePattern(inputdata.patterns)
|
err := conf.PreparePattern(inputdata.patterns)
|
||||||
if err != nil {
|
|
||||||
t.Errorf("PreparePattern returned error: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !matchPattern(conf, inputdata.line) {
|
assert.NoError(t, err)
|
||||||
t.Errorf("matchPattern() did not match\nExp: true\nGot: false\n")
|
|
||||||
}
|
res := matchPattern(conf, inputdata.line)
|
||||||
|
assert.EqualValues(t, true, res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,14 +161,12 @@ func TestFilterByFields(t *testing.T) {
|
|||||||
conf := cfg.Config{Rawfilters: inputdata.filter, InvertMatch: inputdata.invert}
|
conf := cfg.Config{Rawfilters: inputdata.filter, InvertMatch: inputdata.invert}
|
||||||
|
|
||||||
err := conf.PrepareFilters()
|
err := conf.PrepareFilters()
|
||||||
if err != nil {
|
|
||||||
t.Errorf("PrepareFilters returned error: %s", err)
|
assert.NoError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
data, _, _ := FilterByFields(conf, &data)
|
data, _, _ := FilterByFields(conf, &data)
|
||||||
if !reflect.DeepEqual(*data, inputdata.expect) {
|
|
||||||
t.Errorf("Filtered data does not match expected data:\ngot: %+v\nexp: %+v", data, inputdata.expect)
|
assert.EqualValues(t, inputdata.expect, *data)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ package lib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,9 +39,8 @@ func TestContains(t *testing.T) {
|
|||||||
testname := fmt.Sprintf("contains-%d,%d,%t", tt.list, tt.search, tt.want)
|
testname := fmt.Sprintf("contains-%d,%d,%t", tt.list, tt.search, tt.want)
|
||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
answer := contains(tt.list, tt.search)
|
answer := contains(tt.list, tt.search)
|
||||||
if answer != tt.want {
|
|
||||||
t.Errorf("got %t, want %t", answer, tt.want)
|
assert.EqualValues(t, tt.want, answer)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,14 +76,12 @@ func TestPrepareColumns(t *testing.T) {
|
|||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
conf := cfg.Config{Columns: testdata.input}
|
conf := cfg.Config{Columns: testdata.input}
|
||||||
err := PrepareColumns(&conf, &data)
|
err := PrepareColumns(&conf, &data)
|
||||||
if err != nil {
|
|
||||||
if !testdata.wanterror {
|
if testdata.wanterror {
|
||||||
t.Errorf("got error: %v", err)
|
assert.Error(t, err)
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if !reflect.DeepEqual(conf.UseColumns, testdata.exp) {
|
assert.NoError(t, err)
|
||||||
t.Errorf("got: %v, expected: %v", conf.UseColumns, testdata.exp)
|
assert.EqualValues(t, testdata.exp, conf.UseColumns)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -153,18 +150,13 @@ func TestPrepareTransposerColumns(t *testing.T) {
|
|||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
conf := cfg.Config{TransposeColumns: testdata.input, Transposers: testdata.transp}
|
conf := cfg.Config{TransposeColumns: testdata.input, Transposers: testdata.transp}
|
||||||
err := PrepareTransposerColumns(&conf, &data)
|
err := PrepareTransposerColumns(&conf, &data)
|
||||||
if err != nil {
|
|
||||||
if !testdata.wanterror {
|
|
||||||
t.Errorf("got error: %v", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(conf.UseTransposeColumns) != testdata.exp {
|
|
||||||
t.Errorf("got %d, want %d", conf.UseTransposeColumns, testdata.exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(conf.Transposers) != len(conf.UseTransposeColumns) {
|
if testdata.wanterror {
|
||||||
t.Errorf("got %d, want %d", conf.UseTransposeColumns, testdata.exp)
|
assert.Error(t, err)
|
||||||
}
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, testdata.exp, len(conf.UseTransposeColumns))
|
||||||
|
assert.EqualValues(t, len(conf.UseTransposeColumns), len(conf.Transposers))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -202,10 +194,8 @@ func TestReduceColumns(t *testing.T) {
|
|||||||
c := cfg.Config{Columns: "x", UseColumns: testdata.columns}
|
c := cfg.Config{Columns: "x", UseColumns: testdata.columns}
|
||||||
data := Tabdata{entries: input}
|
data := Tabdata{entries: input}
|
||||||
reduceColumns(c, &data)
|
reduceColumns(c, &data)
|
||||||
if !reflect.DeepEqual(data.entries, testdata.expect) {
|
|
||||||
t.Errorf("reduceColumns returned invalid data:\ngot: %+v\nexp: %+v",
|
assert.EqualValues(t, testdata.expect, data.entries)
|
||||||
data.entries, testdata.expect)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,10 +223,8 @@ func TestNumberizeHeaders(t *testing.T) {
|
|||||||
conf := cfg.Config{Columns: "x", UseColumns: testdata.columns, Numbering: testdata.numberize}
|
conf := cfg.Config{Columns: "x", UseColumns: testdata.columns, Numbering: testdata.numberize}
|
||||||
usedata := data
|
usedata := data
|
||||||
numberizeAndReduceHeaders(conf, &usedata)
|
numberizeAndReduceHeaders(conf, &usedata)
|
||||||
if !reflect.DeepEqual(usedata.headers, testdata.expect) {
|
|
||||||
t.Errorf("numberizeAndReduceHeaders returned invalid data:\ngot: %+v\nexp: %+v",
|
assert.EqualValues(t, testdata.expect, usedata.headers)
|
||||||
usedata.headers, testdata.expect)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
110
lib/parser.go
110
lib/parser.go
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright © 2022-2024 Thomas von Dein
|
Copyright © 2022-2025 Thomas von Dein
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,8 +20,11 @@ package lib
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ func Parse(conf cfg.Config, input io.Reader) (Tabdata, error) {
|
|||||||
// first step, parse the data
|
// first step, parse the data
|
||||||
if len(conf.Separator) == 1 {
|
if len(conf.Separator) == 1 {
|
||||||
data, err = parseCSV(conf, input)
|
data, err = parseCSV(conf, input)
|
||||||
|
} else if conf.InputJSON {
|
||||||
|
data, err = parseJSON(conf, input)
|
||||||
} else {
|
} else {
|
||||||
data, err = parseTabular(conf, input)
|
data, err = parseTabular(conf, input)
|
||||||
}
|
}
|
||||||
@@ -172,6 +177,109 @@ func parseTabular(conf cfg.Config, input io.Reader) (Tabdata, error) {
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse JSON input. We only support an array of maps.
|
||||||
|
*/
|
||||||
|
func parseRawJSON(conf cfg.Config, input io.Reader) (Tabdata, error) {
|
||||||
|
dec := json.NewDecoder(input)
|
||||||
|
headers := []string{}
|
||||||
|
idxmap := map[string]int{}
|
||||||
|
data := [][]string{}
|
||||||
|
row := []string{}
|
||||||
|
iskey := true
|
||||||
|
haveheaders := false
|
||||||
|
var currentfield string
|
||||||
|
var idx int
|
||||||
|
var isjson bool
|
||||||
|
|
||||||
|
for {
|
||||||
|
t, err := dec.Token()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch val := t.(type) {
|
||||||
|
case string:
|
||||||
|
if iskey {
|
||||||
|
if !haveheaders {
|
||||||
|
// consider only the keys of the first item as headers
|
||||||
|
headers = append(headers, val)
|
||||||
|
}
|
||||||
|
currentfield = val
|
||||||
|
} else {
|
||||||
|
if !haveheaders {
|
||||||
|
// the first row uses the order as it comes in
|
||||||
|
row = append(row, val)
|
||||||
|
} else {
|
||||||
|
// use the pre-determined order, that way items
|
||||||
|
// can be in any order as long as they contain all
|
||||||
|
// neccessary fields. They may also contain less
|
||||||
|
// fields than the first item, these will contain
|
||||||
|
// the empty string
|
||||||
|
row[idxmap[currentfield]] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case json.Delim:
|
||||||
|
if val.String() == "}" {
|
||||||
|
data = append(data, row)
|
||||||
|
row = make([]string, len(headers))
|
||||||
|
idx++
|
||||||
|
|
||||||
|
if !haveheaders {
|
||||||
|
// remember the array position of header fields,
|
||||||
|
// which we use to assign elements to the correct
|
||||||
|
// row index
|
||||||
|
for i, header := range headers {
|
||||||
|
idxmap[header] = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
haveheaders = true
|
||||||
|
}
|
||||||
|
isjson = true
|
||||||
|
}
|
||||||
|
|
||||||
|
iskey = !iskey
|
||||||
|
}
|
||||||
|
|
||||||
|
if isjson && (len(headers) == 0 || len(data) == 0) {
|
||||||
|
return Tabdata{}, errors.New("failed to parse JSON, input did not contain array of hashes")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Tabdata{headers: headers, entries: data, columns: len(headers)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseJSON(conf cfg.Config, input io.Reader) (Tabdata, error) {
|
||||||
|
// parse raw json
|
||||||
|
data, err := parseRawJSON(conf, input)
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply filter, if any
|
||||||
|
filtered := [][]string{}
|
||||||
|
var line string
|
||||||
|
|
||||||
|
for _, row := range data.entries {
|
||||||
|
line = strings.Join(row, " ")
|
||||||
|
|
||||||
|
if matchPattern(conf, line) == conf.InvertMatch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered = append(filtered, row)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(filtered) != len(data.entries) {
|
||||||
|
data.entries = filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
func PostProcess(conf cfg.Config, data *Tabdata) (*Tabdata, bool, error) {
|
func PostProcess(conf cfg.Config, data *Tabdata) (*Tabdata, bool, error) {
|
||||||
var modified bool
|
var modified bool
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright © 2022 Thomas von Dein
|
Copyright © 2022-2025 Thomas von Dein
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,10 +19,11 @@ package lib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,27 +68,21 @@ func TestParser(t *testing.T) {
|
|||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
readFd := strings.NewReader(strings.TrimSpace(testdata.text))
|
readFd := strings.NewReader(strings.TrimSpace(testdata.text))
|
||||||
conf := cfg.Config{Separator: testdata.separator}
|
conf := cfg.Config{Separator: testdata.separator}
|
||||||
gotdata, err := Parse(conf, readFd)
|
gotdata, err := wrapValidateParser(conf, readFd)
|
||||||
|
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Errorf("Parser returned error: %s\nData processed so far: %+v", err, gotdata)
|
assert.EqualValues(t, data, gotdata)
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(data, gotdata) {
|
|
||||||
t.Errorf("Parser returned invalid data\nExp: %+v\nGot: %+v\n",
|
|
||||||
data, gotdata)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserPatternmatching(t *testing.T) {
|
func TestParserPatternmatching(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
entries [][]string
|
entries [][]string
|
||||||
patterns []*cfg.Pattern
|
patterns []*cfg.Pattern
|
||||||
invert bool
|
invert bool
|
||||||
want bool
|
wanterror bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "match",
|
name: "match",
|
||||||
@@ -121,18 +116,13 @@ func TestParserPatternmatching(t *testing.T) {
|
|||||||
_ = conf.PreparePattern(testdata.patterns)
|
_ = conf.PreparePattern(testdata.patterns)
|
||||||
|
|
||||||
readFd := strings.NewReader(strings.TrimSpace(inputdata.text))
|
readFd := strings.NewReader(strings.TrimSpace(inputdata.text))
|
||||||
gotdata, err := Parse(conf, readFd)
|
data, err := wrapValidateParser(conf, readFd)
|
||||||
|
|
||||||
if err != nil {
|
if testdata.wanterror {
|
||||||
if !testdata.want {
|
assert.Error(t, err)
|
||||||
t.Errorf("Parser returned error: %s\nData processed so far: %+v",
|
|
||||||
err, gotdata)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if !reflect.DeepEqual(testdata.entries, gotdata.entries) {
|
assert.NoError(t, err)
|
||||||
t.Errorf("Parser returned invalid data (pattern: %s, invert: %t)\nExp: %+v\nGot: %+v\n",
|
assert.EqualValues(t, testdata.entries, data.entries)
|
||||||
testdata.name, testdata.invert, testdata.entries, gotdata.entries)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -159,14 +149,147 @@ asd igig
|
|||||||
|
|
||||||
readFd := strings.NewReader(strings.TrimSpace(table))
|
readFd := strings.NewReader(strings.TrimSpace(table))
|
||||||
conf := cfg.Config{Separator: cfg.DefaultSeparator}
|
conf := cfg.Config{Separator: cfg.DefaultSeparator}
|
||||||
gotdata, err := Parse(conf, readFd)
|
gotdata, err := wrapValidateParser(conf, readFd)
|
||||||
|
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Errorf("Parser returned error: %s\nData processed so far: %+v", err, gotdata)
|
assert.EqualValues(t, data, gotdata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParserJSONInput(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expect Tabdata
|
||||||
|
wanterror bool // true: expect fail, false: expect success
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// too deep nesting
|
||||||
|
name: "invalidjson",
|
||||||
|
wanterror: true,
|
||||||
|
input: `[
|
||||||
|
{
|
||||||
|
"item": {
|
||||||
|
"NAME": "postgres-operator-7f4c7c8485-ntlns",
|
||||||
|
"READY": "1/1",
|
||||||
|
"STATUS": "Running",
|
||||||
|
"RESTARTS": "0",
|
||||||
|
"AGE": "24h"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expect: Tabdata{},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// one field missing + different order
|
||||||
|
// but shall not fail
|
||||||
|
name: "kgpfail",
|
||||||
|
wanterror: false,
|
||||||
|
input: `[
|
||||||
|
{
|
||||||
|
"NAME": "postgres-operator-7f4c7c8485-ntlns",
|
||||||
|
"READY": "1/1",
|
||||||
|
"STATUS": "Running",
|
||||||
|
"RESTARTS": "0",
|
||||||
|
"AGE": "24h"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NAME": "wal-g-exporter-778dcd95f5-wcjzn",
|
||||||
|
"RESTARTS": "0",
|
||||||
|
"READY": "1/1",
|
||||||
|
"AGE": "24h"
|
||||||
|
}
|
||||||
|
]`,
|
||||||
|
expect: Tabdata{
|
||||||
|
columns: 5,
|
||||||
|
headers: []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"},
|
||||||
|
entries: [][]string{
|
||||||
|
[]string{
|
||||||
|
"postgres-operator-7f4c7c8485-ntlns",
|
||||||
|
"1/1",
|
||||||
|
"Running",
|
||||||
|
"0",
|
||||||
|
"24h",
|
||||||
|
},
|
||||||
|
[]string{
|
||||||
|
"wal-g-exporter-778dcd95f5-wcjzn",
|
||||||
|
"1/1",
|
||||||
|
"",
|
||||||
|
"0",
|
||||||
|
"24h",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "kgp",
|
||||||
|
wanterror: false,
|
||||||
|
input: `[
|
||||||
|
{
|
||||||
|
"NAME": "postgres-operator-7f4c7c8485-ntlns",
|
||||||
|
"READY": "1/1",
|
||||||
|
"STATUS": "Running",
|
||||||
|
"RESTARTS": "0",
|
||||||
|
"AGE": "24h"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NAME": "wal-g-exporter-778dcd95f5-wcjzn",
|
||||||
|
"STATUS": "Running",
|
||||||
|
"READY": "1/1",
|
||||||
|
"RESTARTS": "0",
|
||||||
|
"AGE": "24h"
|
||||||
|
}
|
||||||
|
]`,
|
||||||
|
expect: Tabdata{
|
||||||
|
columns: 5,
|
||||||
|
headers: []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"},
|
||||||
|
entries: [][]string{
|
||||||
|
[]string{
|
||||||
|
"postgres-operator-7f4c7c8485-ntlns",
|
||||||
|
"1/1",
|
||||||
|
"Running",
|
||||||
|
"0",
|
||||||
|
"24h",
|
||||||
|
},
|
||||||
|
[]string{
|
||||||
|
"wal-g-exporter-778dcd95f5-wcjzn",
|
||||||
|
"1/1",
|
||||||
|
"Running",
|
||||||
|
"0",
|
||||||
|
"24h",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(data, gotdata) {
|
for _, testdata := range tests {
|
||||||
t.Errorf("Parser returned invalid data, Regex: %s\nExp: %+v\nGot: %+v\n",
|
testname := fmt.Sprintf("parse-json-%s", testdata.name)
|
||||||
conf.Separator, data, gotdata)
|
t.Run(testname, func(t *testing.T) {
|
||||||
|
conf := cfg.Config{InputJSON: true}
|
||||||
|
|
||||||
|
readFd := strings.NewReader(strings.TrimSpace(testdata.input))
|
||||||
|
data, err := wrapValidateParser(conf, readFd)
|
||||||
|
|
||||||
|
if testdata.wanterror {
|
||||||
|
assert.Error(t, err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, testdata.expect, data)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wrapValidateParser(conf cfg.Config, input io.Reader) (Tabdata, error) {
|
||||||
|
data, err := Parse(conf, input)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ValidateConsistency(&data)
|
||||||
|
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -307,13 +308,7 @@ func TestPrinter(t *testing.T) {
|
|||||||
|
|
||||||
got := strings.TrimSpace(writer.String())
|
got := strings.TrimSpace(writer.String())
|
||||||
|
|
||||||
if got != exp {
|
assert.EqualValues(t, exp, got)
|
||||||
t.Errorf("not rendered correctly:\n+++ got:\n%s\n+++ want:\n%s",
|
|
||||||
got, exp,
|
|
||||||
// strings.ReplaceAll(got, " ", "_"),
|
|
||||||
// strings.ReplaceAll(exp, " ", "_")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,9 +42,7 @@ func TestDuration2Seconds(t *testing.T) {
|
|||||||
testname := fmt.Sprintf("duration-%s", testdata.dur)
|
testname := fmt.Sprintf("duration-%s", testdata.dur)
|
||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
seconds := duration2int(testdata.dur)
|
seconds := duration2int(testdata.dur)
|
||||||
if seconds != testdata.expect {
|
assert.EqualValues(t, testdata.expect, seconds)
|
||||||
t.Errorf("got %d, want %d", seconds, testdata.expect)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,9 +73,7 @@ func TestCompare(t *testing.T) {
|
|||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
c := cfg.Config{SortMode: testdata.mode, SortDescending: testdata.desc}
|
c := cfg.Config{SortMode: testdata.mode, SortDescending: testdata.desc}
|
||||||
got := compare(&c, testdata.a, testdata.b)
|
got := compare(&c, testdata.a, testdata.b)
|
||||||
if got != testdata.want {
|
assert.EqualValues(t, testdata.want, got)
|
||||||
t.Errorf("got %d, want %d", got, testdata.want)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tiagomelo/go-clipboard/clipboard"
|
"github.com/tiagomelo/go-clipboard/clipboard"
|
||||||
"github.com/tlinden/tablizer/cfg"
|
"github.com/tlinden/tablizer/cfg"
|
||||||
)
|
)
|
||||||
@@ -59,14 +60,9 @@ func DISABLED_TestYankColumns(t *testing.T) {
|
|||||||
printData(&writer, conf, &data)
|
printData(&writer, conf, &data)
|
||||||
|
|
||||||
got, err := cb.PasteText()
|
got, err := cb.PasteText()
|
||||||
if err != nil {
|
|
||||||
t.Errorf("failed to fetch yanked text from clipboard")
|
|
||||||
}
|
|
||||||
|
|
||||||
if got != testdata.expect {
|
assert.NoError(t, err)
|
||||||
t.Errorf("not yanked correctly:\n+++ got:\n%s\n+++ want:\n%s",
|
assert.EqualValues(t, testdata.expect, got)
|
||||||
got, testdata.expect)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
# usage
|
# usage
|
||||||
exec tablizer -h
|
exec tablizer --help
|
||||||
stdout Usage
|
stdout Usage
|
||||||
|
|
||||||
|
exec tablizer -h
|
||||||
|
stdout show
|
||||||
|
|
||||||
# version
|
# version
|
||||||
exec tablizer -V
|
exec tablizer -V
|
||||||
stdout version
|
stdout version
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "TABLIZER 1"
|
.IX Title "TABLIZER 1"
|
||||||
.TH TABLIZER 1 "2025-09-30" "1" "User Commands"
|
.TH TABLIZER 1 "2025-10-01" "1" "User Commands"
|
||||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
.\" way too many mistakes in technical documents.
|
.\" way too many mistakes in technical documents.
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
@@ -158,6 +158,7 @@ tablizer \- Manipulate tabular output of other programs
|
|||||||
\& \-F, \-\-filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
\& \-F, \-\-filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
||||||
\& \-T, \-\-transpose\-columns string Transpose the speficied columns (separated by ,)
|
\& \-T, \-\-transpose\-columns string Transpose the speficied columns (separated by ,)
|
||||||
\& \-R, \-\-regex\-transposer </from/to/> Apply /search/replace/ regexp to fields given in \-T
|
\& \-R, \-\-regex\-transposer </from/to/> Apply /search/replace/ regexp to fields given in \-T
|
||||||
|
\& \-j, \-\-json Read JSON input (must be array of hashes)
|
||||||
\& \-I, \-\-interactive Interactively filter and select rows
|
\& \-I, \-\-interactive Interactively filter and select rows
|
||||||
\&
|
\&
|
||||||
\& Output Flags (mutually exclusive):
|
\& Output Flags (mutually exclusive):
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ tablizer - Manipulate tabular output of other programs
|
|||||||
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
-F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
|
||||||
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
|
||||||
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
-R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
|
||||||
|
-j, --json Read JSON input (must be array of hashes)
|
||||||
-I, --interactive Interactively filter and select rows
|
-I, --interactive Interactively filter and select rows
|
||||||
|
|
||||||
Output Flags (mutually exclusive):
|
Output Flags (mutually exclusive):
|
||||||
|
|||||||
Reference in New Issue
Block a user