Skip to content

Commit

Permalink
feat(cmd): remove tablewriter in favor of charm (#374)
Browse files Browse the repository at this point in the history
  • Loading branch information
rektdeckard authored Jul 23, 2024
1 parent 913d521 commit a3545d0
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 87 deletions.
12 changes: 5 additions & 7 deletions cmd/lk/egress.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"syscall"
"time"

"github.com/olekukonko/tablewriter"
"github.com/pkg/browser"
"github.com/urfave/cli/v3"
"google.golang.org/protobuf/encoding/protojson"
Expand Down Expand Up @@ -596,8 +595,8 @@ func listEgress(ctx context.Context, cmd *cli.Command) error {
items = res.Items
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"EgressID", "Status", "Type", "Source", "Started At", "Error"})
table := CreateTable().
Headers("EgressID", "Status", "Type", "Source", "Started At", "Error")
for _, item := range items {
var startedAt string
if item.StartedAt != 0 {
Expand Down Expand Up @@ -628,17 +627,16 @@ func listEgress(ctx context.Context, cmd *cli.Command) error {
egressType = "track"
egressSource = fmt.Sprintf("%s/%s", req.Track.RoomName, req.Track.TrackId)
}

table.Append([]string{
table.Row(
item.EgressId,
item.Status.String(),
egressType,
egressSource,
startedAt,
item.Error,
})
)
}
table.Render()
fmt.Println(table)

return nil
}
Expand Down
12 changes: 5 additions & 7 deletions cmd/lk/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ package main
import (
"context"
"fmt"
"os"

"github.com/olekukonko/tablewriter"
"github.com/urfave/cli/v3"

"github.com/livekit/protocol/livekit"
Expand Down Expand Up @@ -225,8 +223,8 @@ func listIngress(ctx context.Context, cmd *cli.Command) error {
return err
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"IngressID", "Name", "Room", "StreamKey", "URL", "Status", "Error"})
table := CreateTable().
Headers("IngressID", "Name", "Room", "StreamKey", "URL", "Status", "Error")
for _, item := range res.Items {
if item == nil {
continue
Expand All @@ -238,17 +236,17 @@ func listIngress(ctx context.Context, cmd *cli.Command) error {
errorStr = item.State.Error
}

table.Append([]string{
table.Row(
item.IngressId,
item.Name,
item.RoomName,
item.StreamKey,
item.Url,
status,
errorStr,
})
)
}
table.Render()
fmt.Println(table)

if cmd.Bool("verbose") {
PrintJSON(res)
Expand Down
27 changes: 21 additions & 6 deletions cmd/lk/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"regexp"

"github.com/charmbracelet/huh"
"github.com/olekukonko/tablewriter"
"github.com/charmbracelet/lipgloss"
"github.com/urfave/cli/v3"

"github.com/livekit/livekit-cli/pkg/config"
Expand Down Expand Up @@ -242,13 +242,28 @@ func listProjects(ctx context.Context, cmd *cli.Command) error {
return nil
}

table := tablewriter.NewWriter(os.Stdout)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetHeader([]string{"Name", "URL", "API Key", "Default"})
re := lipgloss.NewRenderer(os.Stdout)
baseStyle := re.NewStyle().Padding(0, 1)
headerStyle := baseStyle.Bold(true)
selectedStyle := baseStyle.Foreground(cyan)

table := CreateTable().
StyleFunc(func(row, col int) lipgloss.Style {
switch {
case row == 0:
return headerStyle
case cliConfig.Projects[row-1].Name == cliConfig.DefaultProject:
return selectedStyle
default:
return baseStyle
}
}).
Headers("Name", "URL", "API Key", "Default")
for _, p := range cliConfig.Projects {
table.Append([]string{p.Name, p.URL, p.APIKey, fmt.Sprint(p.Name == cliConfig.DefaultProject)})
table.Row(p.Name, p.URL, p.APIKey, fmt.Sprint(p.Name == cliConfig.DefaultProject))
}
table.Render()
fmt.Println(table)

return nil
}

Expand Down
12 changes: 7 additions & 5 deletions cmd/lk/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ package main
import (
"context"
"errors"
"fmt"
"os"
"reflect"

"github.com/olekukonko/tablewriter"
"github.com/urfave/cli/v3"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
Expand Down Expand Up @@ -183,8 +183,8 @@ func listAndPrint[
return err
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader(header)
table := CreateTable().
Headers(header...)
for _, item := range res.GetItems() {
if item == nil {
continue
Expand All @@ -193,11 +193,13 @@ func listAndPrint[
if len(row) == 0 {
continue
}
table.Append(row)
table.Row(row...)
}
table.Render()
fmt.Println(table)

if cmd.Bool("verbose") {
PrintJSON(res)
}

return nil
}
11 changes: 3 additions & 8 deletions cmd/lk/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import (
"context"
"fmt"
"net/http"
"os"

"github.com/olekukonko/tablewriter"
"github.com/twitchtv/twirp"
"github.com/urfave/cli/v3"

Expand Down Expand Up @@ -127,14 +125,11 @@ func listReplays(ctx context.Context, _ *cli.Command) error {
return err
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"ReplayID"})
table := CreateTable().Headers("ReplayID")
for _, info := range res.Replays {
table.Append([]string{
info.ReplayId,
})
table.Row(info.ReplayId)
}
table.Render()
fmt.Println(table)

return nil
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/lk/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func listSipTrunk(ctx context.Context, cmd *cli.Command) error {
}
//lint:ignore SA1019 we still support it
return listAndPrint(ctx, cmd, cli.ListSIPTrunk, &livekit.ListSIPTrunkRequest{}, []string{
"SipTrunkId", "Name", "Kind", "Number",
"SipTrunkID", "Name", "Kind", "Number",
"AllowAddresses", "AllowNumbers", "InboundAuth",
"OutboundAddress", "OutboundAuth",
"Metadata",
Expand All @@ -285,7 +285,7 @@ func listSipInboundTrunk(ctx context.Context, cmd *cli.Command) error {
return err
}
return listAndPrint(ctx, cmd, cli.ListSIPInboundTrunk, &livekit.ListSIPInboundTrunkRequest{}, []string{
"SipTrunkId", "Name", "Numbers",
"SipTrunkID", "Name", "Numbers",
"AllowedAddresses", "AllowedNumbers",
"Authentication",
"Metadata",
Expand All @@ -305,7 +305,7 @@ func listSipOutboundTrunk(ctx context.Context, cmd *cli.Command) error {
return err
}
return listAndPrint(ctx, cmd, cli.ListSIPOutboundTrunk, &livekit.ListSIPOutboundTrunkRequest{}, []string{
"SipTrunkId", "Name",
"SipTrunkID", "Name",
"Address", "Transport",
"Numbers",
"Authentication",
Expand Down Expand Up @@ -387,7 +387,7 @@ func listSipDispatchRule(ctx context.Context, cmd *cli.Command) error {
return err
}
return listAndPrint(ctx, cmd, cli.ListSIPDispatchRule, &livekit.ListSIPDispatchRuleRequest{}, []string{
"SipDispatchRuleId", "Name", "SipTrunks", "Type", "RoomName", "Pin", "HidePhone", "Metadata",
"SipDispatchRuleID", "Name", "SipTrunks", "Type", "RoomName", "Pin", "HidePhone", "Metadata",
}, func(item *livekit.SIPDispatchRuleInfo) []string {
var room, typ, pin string
switch r := item.GetRule().GetRule().(type) {
Expand Down
66 changes: 66 additions & 0 deletions cmd/lk/style.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"github.com/charmbracelet/huh"
"github.com/charmbracelet/lipgloss"
)

var (
normalFg = lipgloss.AdaptiveColor{Light: "235", Dark: "252"}
normalBg = lipgloss.AdaptiveColor{Light: "20", Dark: "0"}
dimFg = lipgloss.AdaptiveColor{Light: "", Dark: "243"}
placeholderFg = lipgloss.AdaptiveColor{Light: "248", Dark: "238"}
cyan = lipgloss.AdaptiveColor{Light: "#06B7DB", Dark: "#1FD5F9"}
red = lipgloss.AdaptiveColor{Light: "#CE4A3B", Dark: "#FF6352"}
yellow = lipgloss.AdaptiveColor{Light: "#DB9406", Dark: "#F9B11F"}
green = lipgloss.AdaptiveColor{Light: "#036D26", Dark: "#06DB4D"}

theme = func() *huh.Theme {
t := huh.ThemeBase()

t.Focused.Base = t.Focused.Base.BorderForeground(lipgloss.Color("238"))
t.Focused.Title = t.Focused.Title.Foreground(cyan).Bold(true)
t.Focused.NoteTitle = t.Focused.NoteTitle.Foreground(cyan).Bold(true).MarginBottom(1)
t.Focused.Directory = t.Focused.Directory.Foreground(cyan)
t.Focused.Description = t.Focused.Description.Foreground(dimFg)
t.Focused.ErrorIndicator = t.Focused.ErrorIndicator.Foreground(red)
t.Focused.ErrorMessage = t.Focused.ErrorMessage.Foreground(red)
t.Focused.SelectSelector = t.Focused.SelectSelector.Foreground(yellow)
t.Focused.NextIndicator = t.Focused.NextIndicator.Foreground(yellow)
t.Focused.PrevIndicator = t.Focused.PrevIndicator.Foreground(yellow)
t.Focused.Option = t.Focused.Option.Foreground(normalFg)
t.Focused.MultiSelectSelector = t.Focused.MultiSelectSelector.Foreground(yellow)
t.Focused.SelectedOption = t.Focused.SelectedOption.Foreground(green)
t.Focused.SelectedPrefix = lipgloss.NewStyle().Foreground(green).SetString("✓ ")
t.Focused.UnselectedPrefix = lipgloss.NewStyle().Foreground(dimFg).SetString("• ")
t.Focused.UnselectedOption = t.Focused.UnselectedOption.Foreground(normalFg)
t.Focused.FocusedButton = t.Focused.FocusedButton.Foreground(normalBg).Background(cyan)
t.Focused.Next = t.Focused.FocusedButton
t.Focused.BlurredButton = t.Focused.BlurredButton.Foreground(normalFg).Background(lipgloss.AdaptiveColor{Light: "252", Dark: "237"})

// t.Focused.TextInput.Cursor = t.Focused.TextInput.Cursor.Foreground(yellow)
t.Focused.TextInput.Placeholder = t.Focused.TextInput.Placeholder.Foreground(placeholderFg)
t.Focused.TextInput.Prompt = t.Focused.TextInput.Prompt.Foreground(yellow)

t.Blurred = t.Focused
t.Blurred.Base = t.Focused.Base.BorderStyle(lipgloss.HiddenBorder())
t.Blurred.NextIndicator = lipgloss.NewStyle()
t.Blurred.PrevIndicator = lipgloss.NewStyle()

return t
}()
)
67 changes: 21 additions & 46 deletions cmd/lk/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"path/filepath"
"strings"

"github.com/charmbracelet/huh"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
"github.com/livekit/protocol/utils/interceptors"
"github.com/twitchtv/twirp"
"github.com/urfave/cli/v3"
Expand Down Expand Up @@ -81,51 +81,6 @@ var (
Persistent: true,
},
}
theme = func() *huh.Theme {
t := huh.ThemeBase()

var (
normalFg = lipgloss.AdaptiveColor{Light: "235", Dark: "252"}
normalBg = lipgloss.AdaptiveColor{Light: "20", Dark: "0"}
dimFg = lipgloss.AdaptiveColor{Light: "", Dark: "243"}
placeholderFg = lipgloss.AdaptiveColor{Light: "248", Dark: "238"}
cyan = lipgloss.AdaptiveColor{Light: "#06B7DB", Dark: "#1FD5F9"}
red = lipgloss.AdaptiveColor{Light: "#CE4A3B", Dark: "#FF6352"}
yellow = lipgloss.AdaptiveColor{Light: "#DB9406", Dark: "#F9B11F"}
green = lipgloss.AdaptiveColor{Light: "#036D26", Dark: "#06DB4D"}
)

t.Focused.Base = t.Focused.Base.BorderForeground(lipgloss.Color("238"))
t.Focused.Title = t.Focused.Title.Foreground(cyan).Bold(true)
t.Focused.NoteTitle = t.Focused.NoteTitle.Foreground(cyan).Bold(true).MarginBottom(1)
t.Focused.Directory = t.Focused.Directory.Foreground(cyan)
t.Focused.Description = t.Focused.Description.Foreground(dimFg)
t.Focused.ErrorIndicator = t.Focused.ErrorIndicator.Foreground(red)
t.Focused.ErrorMessage = t.Focused.ErrorMessage.Foreground(red)
t.Focused.SelectSelector = t.Focused.SelectSelector.Foreground(yellow)
t.Focused.NextIndicator = t.Focused.NextIndicator.Foreground(yellow)
t.Focused.PrevIndicator = t.Focused.PrevIndicator.Foreground(yellow)
t.Focused.Option = t.Focused.Option.Foreground(normalFg)
t.Focused.MultiSelectSelector = t.Focused.MultiSelectSelector.Foreground(yellow)
t.Focused.SelectedOption = t.Focused.SelectedOption.Foreground(green)
t.Focused.SelectedPrefix = lipgloss.NewStyle().Foreground(green).SetString("✓ ")
t.Focused.UnselectedPrefix = lipgloss.NewStyle().Foreground(dimFg).SetString("• ")
t.Focused.UnselectedOption = t.Focused.UnselectedOption.Foreground(normalFg)
t.Focused.FocusedButton = t.Focused.FocusedButton.Foreground(normalBg).Background(cyan)
t.Focused.Next = t.Focused.FocusedButton
t.Focused.BlurredButton = t.Focused.BlurredButton.Foreground(normalFg).Background(lipgloss.AdaptiveColor{Light: "252", Dark: "237"})

// t.Focused.TextInput.Cursor = t.Focused.TextInput.Cursor.Foreground(yellow)
t.Focused.TextInput.Placeholder = t.Focused.TextInput.Placeholder.Foreground(placeholderFg)
t.Focused.TextInput.Prompt = t.Focused.TextInput.Prompt.Foreground(yellow)

t.Blurred = t.Focused
t.Blurred.Base = t.Focused.Base.BorderStyle(lipgloss.HiddenBorder())
t.Blurred.NextIndicator = lipgloss.NewStyle()
t.Blurred.PrevIndicator = lipgloss.NewStyle()

return t
}()
)

func optional[T any, C any, VC cli.ValueCreator[T, C]](flag *cli.FlagBase[T, C, VC]) *cli.FlagBase[T, C, VC] {
Expand Down Expand Up @@ -199,6 +154,26 @@ func PrintJSON(obj any) {
fmt.Println(string(txt))
}

func CreateTable() *table.Table {
re := lipgloss.NewRenderer(os.Stdout)
baseStyle := re.NewStyle().Padding(0, 1)
headerStyle := baseStyle.Bold(true)

styleFunc := func(row, col int) lipgloss.Style {
if row == 0 {
return headerStyle
}
return baseStyle
}

t := table.New().
Border(lipgloss.NormalBorder()).
BorderStyle(re.NewStyle().Foreground(normalFg)).
StyleFunc(styleFunc)

return t
}

func ExpandUser(p string) string {
if strings.HasPrefix(p, "~") {
home, _ := os.UserHomeDir()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ toolchain go1.22.2

require (
github.com/charmbracelet/huh v0.5.1
github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6
github.com/charmbracelet/lipgloss v0.12.1
github.com/frostbyte73/core v0.0.10
github.com/go-logr/logr v1.4.2
github.com/livekit/protocol v1.19.2-0.20240710171229-73ece66d30e0
github.com/livekit/server-sdk-go/v2 v2.2.0
github.com/olekukonko/tablewriter v0.0.5
github.com/pion/rtcp v1.2.14
github.com/pion/rtp v1.8.7
github.com/pion/webrtc/v3 v3.2.49
Expand Down
Loading

0 comments on commit a3545d0

Please sign in to comment.