Skip to content

Commit

Permalink
Update dependencies. (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibrt authored Dec 15, 2024
1 parent e3b7908 commit df0fdc7
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 362 deletions.
100 changes: 40 additions & 60 deletions consolez/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,21 @@ import (
"sync"

"github.com/alecthomas/kong"
"github.com/fatih/color"
"github.com/ibrt/golang-utils/errorz"
"github.com/ibrt/golang-utils/filez"
"github.com/ibrt/golang-utils/outz"
"github.com/rodaine/table"
)

// Known icons.
var (
const (
IconRocket = "\U0001F680"
IconHighVoltage = "\U000026A1"
IconBackhandIndexPointingRight = "\U0001F449"
IconRunner = "\U0001F3C3"
IconCollision = "\U0001F4A5"
)

// Known colors.
var (
ColorDefault = color.New(color.Reset)
ColorHighlight = color.New(color.Bold)
ColorSecondaryHighlight = color.New(color.Bold, color.Faint)
ColorSecondary = color.New(color.Faint)
ColorInfo = color.New(color.FgCyan)
ColorSuccess = color.New(color.FgGreen)
ColorWarning = color.New(color.FgYellow)
ColorError = color.New(color.FgHiRed)
)

var (
_ CLIOption = CLIOptionFunc(nil)
)

// CLIOption describes a [*CLI] option.
type CLIOption interface {
Apply(*CLI)
}

// CLIOptionFunc describes a [*CLI] option.
type CLIOptionFunc func(*CLI)

// Apply implements the [CLIOption] interface.
func (f CLIOptionFunc) Apply(c *CLI) {
f(c)
}

// CLIExit returns a [CLIOptionFunc] that allows to provide an alternative implementation for [os.Exit].
func CLIExit(exit func(code int)) CLIOptionFunc {
return func(c *CLI) {
c.exit = exit
}
}

var (
defaultCLI = NewCLI()
)
Expand All @@ -74,23 +38,39 @@ func RestoreDefaultCLI() {

// CLI provides some utilities for printing messages in CLI tools.
type CLI struct {
m *sync.Mutex
hL int
exit func(code int)
m *sync.Mutex
hL int
styles outz.Styles
exit func(code int)
}

// NewCLI initializes a new [*CLI].
func NewCLI(options ...CLIOption) *CLI {
func NewCLI() *CLI {
c := &CLI{
m: &sync.Mutex{},
hL: 0,
exit: os.Exit,
m: &sync.Mutex{},
hL: 0,
styles: outz.DefaultStyles,
exit: os.Exit,
}

for _, option := range options {
option.Apply(c)
}
return c
}

// SetStyles sets the styles.
func (c *CLI) SetStyles(styles outz.Styles) *CLI {
c.m.Lock()
defer c.m.Unlock()

c.styles = styles
return c
}

// SetExit sets the exit implementation.
func (c *CLI) SetExit(exit func(code int)) *CLI {
c.m.Lock()
defer c.m.Unlock()

c.exit = exit
return c
}

Expand Down Expand Up @@ -130,7 +110,7 @@ func (c *CLI) Banner(title, tagLine string) {

fmt.Print("┌", strings.Repeat("─", len(title)+len(tagLine)+6), "┐\n")
fmt.Print("│ ", IconRocket, " ")
_, _ = ColorHighlight.Print(title)
_, _ = c.styles.Highlight().Print(title)
fmt.Print(" ")
fmt.Print(tagLine)
fmt.Print(" │\n")
Expand All @@ -151,16 +131,16 @@ func (c *CLI) Header(format string, a ...any) func() {
case 0:
fmt.Print(IconHighVoltage)
fmt.Print(" ")
_, _ = ColorHighlight.Printf(format, a...)
_, _ = c.styles.Highlight().Printf(format, a...)
fmt.Println()
case 1:
fmt.Print(IconBackhandIndexPointingRight)
fmt.Print(" ")
fmt.Printf(format, a...)
fmt.Println()
default:
_, _ = ColorSecondaryHighlight.Print("—— ")
_, _ = ColorSecondaryHighlight.Printf(format, a...)
_, _ = c.styles.SecondaryHighlight().Print("—— ")
_, _ = c.styles.SecondaryHighlight().Printf(format, a...)
fmt.Println()
}

Expand Down Expand Up @@ -189,11 +169,11 @@ func (c *CLI) Notice(scope string, highlight string, secondary ...string) {
c.m.Lock()
defer c.m.Unlock()

_, _ = ColorSecondary.Printf("[%v]", alignRight(scope, 24))
_, _ = ColorDefault.Print(" ", highlight)
_, _ = c.styles.Secondary().Printf("[%v]", alignRight(scope, 24))
_, _ = c.styles.Default().Print(" ", highlight)

for _, v := range secondary {
_, _ = ColorSecondary.Print(" ", v)
_, _ = c.styles.Secondary().Print(" ", v)
}

fmt.Println()
Expand All @@ -206,16 +186,16 @@ func (c *CLI) Command(cmd string, params ...string) {

fmt.Print(IconRunner)
fmt.Printf(" %v ", filez.MustRelForDisplay(cmd))
_, _ = ColorSecondary.Print(strings.Join(params, " "))
_, _ = c.styles.Secondary().Print(strings.Join(params, " "))
fmt.Println()
}

// NewTable creates a new table.
func (c *CLI) NewTable(columnHeaders ...any) table.Table {
return table.
New(columnHeaders...).
WithHeaderFormatter(ColorHighlight.SprintfFunc()).
WithFirstColumnFormatter(ColorWarning.SprintfFunc())
WithHeaderFormatter(c.styles.Highlight().SprintfFunc()).
WithFirstColumnFormatter(c.styles.Warning().SprintfFunc())
}

// Error prints an error.
Expand All @@ -226,8 +206,8 @@ func (c *CLI) Error(err error, debug bool) {
fmt.Println()
fmt.Print(IconCollision)
fmt.Print(" ")
_, _ = ColorHighlight.Println("Error")
_, _ = ColorError.Println(err.Error())
_, _ = c.styles.Highlight().Println("Error")
_, _ = c.styles.Error().Println(err.Error())

if debug {
fmt.Println(errorz.SDump(err))
Expand Down
74 changes: 38 additions & 36 deletions consolez/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/alecthomas/kong"
"github.com/ibrt/golang-utils/filez"
"github.com/ibrt/golang-utils/fixturez"
"github.com/ibrt/golang-utils/outz"
. "github.com/onsi/gomega"

"github.com/ibrt/golang-dev/consolez"
Expand Down Expand Up @@ -42,30 +43,30 @@ func (*CLISuite) TestTool(g *WithT) {
kCtx, err := k.Parse([]string{"--flag=flag-value", "command", "arg-value"})
g.Expect(err).To(Succeed())

fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Tool("Tool", kCtx)

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal(fmt.Sprintf("┌─────────────────┐\n│ %v \x1b[1mTool\x1b[0m command │\n└─────────────────┘\n\n\x1b[1mInput Value \n\x1b[22m\x1b[33m--flag=STRING \x1b[0mflag-value \n\x1b[33m<arg> \x1b[0marg-value \n", consolez.IconRocket)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestBanner(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Banner("Title", "tagline")

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal(fmt.Sprintf("┌──────────────────┐\n│ %v \x1b[1mTitle\x1b[0m tagline │\n└──────────────────┘\n", consolez.IconRocket)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestHeader(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

f1 := consolez.DefaultCLI.Header("H1 %v", 1)
f2 := consolez.DefaultCLI.Header("H2 %v", 1)
Expand All @@ -82,7 +83,7 @@ func (*CLISuite) TestHeader(g *WithT) {

f1()

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()

g.Expect(outBuf).To(Equal(strings.Join(
[]string{
Expand All @@ -97,8 +98,8 @@ func (*CLISuite) TestHeader(g *WithT) {
}

func (*CLISuite) TestWithHeader(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.WithHeader(
"H1 %v", []any{1},
Expand All @@ -125,7 +126,7 @@ func (*CLISuite) TestWithHeader(g *WithT) {
// intentionally empty
})

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()

g.Expect(outBuf).To(Equal(strings.Join(
[]string{
Expand All @@ -140,82 +141,83 @@ func (*CLISuite) TestWithHeader(g *WithT) {
}

func (*CLISuite) TestNotice(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Notice("scope", "p1", "p2", "p3")

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal("\x1b[2m[...................scope]\x1b[0m\x1b[0m p1\x1b[0m\x1b[2m p2\x1b[0m\x1b[2m p3\x1b[0m\n"))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestCommand_Rel(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Command("cmd", "p1", "p2")

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal(fmt.Sprintf("%v cmd \x1b[2mp1 p2\x1b[0m\n", consolez.IconRunner)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestCommand_Abs(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Command(filez.MustAbs("cmd"), "p1", "p2")

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal(fmt.Sprintf("%v cmd \x1b[2mp1 p2\x1b[0m\n", consolez.IconRunner)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestNewTable(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.NewTable("A", "B").AddRow("a", "b").Print()

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal("\x1b[1mA B \n\x1b[22m\x1b[33ma \x1b[0mb \n"))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestError_DebugFalse(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Error(fmt.Errorf("test error"), false)

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(Equal(fmt.Sprintf("\n%v \x1b[1mError\x1b[22m\n\x1b[91mtest error\x1b[0m\n", consolez.IconCollision)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestError_DebugTrue(g *WithT) {
fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

consolez.DefaultCLI.Error(fmt.Errorf("test error"), true)

outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(HavePrefix(fmt.Sprintf("\n%v \x1b[1mError\x1b[22m\n\x1b[91mtest error\x1b[0m\n(errorz.dump)", consolez.IconCollision)))
g.Expect(errBuf).To(BeEmpty())
}

func (*CLISuite) TestRecover(g *WithT) {
c := consolez.NewCLI(
consolez.CLIExit(func(code int) {
c := consolez.NewCLI().
SetStyles(outz.DefaultStyles).
SetExit(func(code int) {
g.Expect(code).To(Equal(1))
}))
})

fixturez.MustBeginOutputCapture(fixturez.OutputSetupStandard, fixturez.GetOutputSetupFatihColor(false), fixturez.OutputSetupRodaineTable)
defer fixturez.ResetOutputCapture()
outz.MustBeginOutputCapture(outz.OutputSetupStandard, outz.GetOutputSetupFatihColor(false), outz.OutputSetupRodaineTable)
defer outz.ResetOutputCapture()

defer func() {
outBuf, errBuf := fixturez.MustEndOutputCapture()
outBuf, errBuf := outz.MustEndOutputCapture()
g.Expect(outBuf).To(HavePrefix(fmt.Sprintf("\n%v \x1b[1mError\x1b[22m\n\x1b[91mtest panic\x1b[0m\n(errorz.dump)", consolez.IconCollision)))
g.Expect(errBuf).To(BeEmpty())
}()
Expand Down
Loading

0 comments on commit df0fdc7

Please sign in to comment.