Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions cmd/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

var appCmd = &cobra.Command{
Use: "app",
Short: "Manage deployed applications",
Long: "Commands for managing deployed Kernel applications",
Use: "app",
Aliases: []string{"apps"},
Short: "Manage deployed applications",
Long: "Commands for managing deployed Kernel applications",
}

// --- app list subcommand
Expand Down Expand Up @@ -80,19 +81,13 @@ func runAppList(cmd *cobra.Command, args []string) error {
envVarsStr := "-"
if len(app.EnvVars) > 0 {
envVarsStr = strings.Join(lo.Keys(app.EnvVars), ", ")
if len(envVarsStr) > 50 {
envVarsStr = envVarsStr[:47] + "..."
}
}

actionsStr := "-"
if len(app.Actions) > 0 {
actionsStr = strings.Join(lo.Map(app.Actions, func(a kernel.AppAction, _ int) string {
return a.Name
}), ", ")
if len(actionsStr) > 50 {
actionsStr = actionsStr[:47] + "..."
}
}

tableData = append(tableData, []string{
Expand All @@ -105,7 +100,7 @@ func runAppList(cmd *cobra.Command, args []string) error {
})
}

printTableNoPad(tableData, true)
PrintTableNoPad(tableData, true)
return nil
}

Expand Down Expand Up @@ -156,6 +151,6 @@ func runAppHistory(cmd *cobra.Command, args []string) error {
}
}

printTableNoPad(tableData, true)
PrintTableNoPad(tableData, true)
return nil
}
18 changes: 9 additions & 9 deletions cmd/browsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (b BrowsersCmd) List(ctx context.Context) error {
})
}

printTableNoPad(tableData, true)
PrintTableNoPad(tableData, true)
return nil
}

Expand Down Expand Up @@ -208,7 +208,7 @@ func (b BrowsersCmd) Create(ctx context.Context, in BrowsersCreateInput) error {
tableData = append(tableData, []string{"Profile", profVal})
}

printTableNoPad(tableData, true)
PrintTableNoPad(tableData, true)
return nil
}

Expand Down Expand Up @@ -415,7 +415,7 @@ func (b BrowsersCmd) ReplaysList(ctx context.Context, in BrowsersReplaysListInpu
for _, r := range *items {
rows = append(rows, []string{r.ReplayID, util.FormatLocal(r.StartedAt), util.FormatLocal(r.FinishedAt), truncateURL(r.ReplayViewURL, 60)})
}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand All @@ -440,7 +440,7 @@ func (b BrowsersCmd) ReplaysStart(ctx context.Context, in BrowsersReplaysStartIn
return util.CleanedUpSdkError{Err: err}
}
rows := pterm.TableData{{"Property", "Value"}, {"Replay ID", res.ReplayID}, {"View URL", res.ReplayViewURL}, {"Started At", util.FormatLocal(res.StartedAt)}}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down Expand Up @@ -563,7 +563,7 @@ func (b BrowsersCmd) ProcessExec(ctx context.Context, in BrowsersProcessExecInpu
return util.CleanedUpSdkError{Err: err}
}
rows := pterm.TableData{{"Property", "Value"}, {"Exit Code", fmt.Sprintf("%d", res.ExitCode)}, {"Duration (ms)", fmt.Sprintf("%d", res.DurationMs)}}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
if res.StdoutB64 != "" {
data, err := base64.StdEncoding.DecodeString(res.StdoutB64)
if err != nil {
Expand Down Expand Up @@ -625,7 +625,7 @@ func (b BrowsersCmd) ProcessSpawn(ctx context.Context, in BrowsersProcessSpawnIn
return util.CleanedUpSdkError{Err: err}
}
rows := pterm.TableData{{"Property", "Value"}, {"Process ID", res.ProcessID}, {"PID", fmt.Sprintf("%d", res.Pid)}, {"Started At", util.FormatLocal(res.StartedAt)}}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down Expand Up @@ -669,7 +669,7 @@ func (b BrowsersCmd) ProcessStatus(ctx context.Context, in BrowsersProcessStatus
return util.CleanedUpSdkError{Err: err}
}
rows := pterm.TableData{{"Property", "Value"}, {"State", string(res.State)}, {"CPU %", fmt.Sprintf("%.2f", res.CPUPct)}, {"Mem Bytes", fmt.Sprintf("%d", res.MemBytes)}, {"Exit Code", fmt.Sprintf("%d", res.ExitCode)}}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down Expand Up @@ -928,7 +928,7 @@ func (b BrowsersCmd) FSFileInfo(ctx context.Context, in BrowsersFSFileInfoInput)
return util.CleanedUpSdkError{Err: err}
}
rows := pterm.TableData{{"Property", "Value"}, {"Path", res.Path}, {"Name", res.Name}, {"Mode", res.Mode}, {"IsDir", fmt.Sprintf("%t", res.IsDir)}, {"SizeBytes", fmt.Sprintf("%d", res.SizeBytes)}, {"ModTime", util.FormatLocal(res.ModTime)}}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down Expand Up @@ -957,7 +957,7 @@ func (b BrowsersCmd) FSListFiles(ctx context.Context, in BrowsersFSListFilesInpu
for _, f := range *res {
rows = append(rows, []string{f.Mode, fmt.Sprintf("%d", f.SizeBytes), util.FormatLocal(f.ModTime), f.Name, f.Path})
}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (p ProfilesCmd) List(ctx context.Context) error {
util.FormatLocal(prof.LastUsedAt),
})
}
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand All @@ -96,7 +96,7 @@ func (p ProfilesCmd) Get(ctx context.Context, in ProfilesGetInput) error {
rows = append(rows, []string{"Created At", util.FormatLocal(item.CreatedAt)})
rows = append(rows, []string{"Updated At", util.FormatLocal(item.UpdatedAt)})
rows = append(rows, []string{"Last Used At", util.FormatLocal(item.LastUsedAt)})
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand All @@ -118,7 +118,7 @@ func (p ProfilesCmd) Create(ctx context.Context, in ProfilesCreateInput) error {
rows = append(rows, []string{"Name", name})
rows = append(rows, []string{"Created At", util.FormatLocal(item.CreatedAt)})
rows = append(rows, []string{"Last Used At", util.FormatLocal(item.LastUsedAt)})
printTableNoPad(rows, true)
PrintTableNoPad(rows, true)
return nil
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/proxies/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/onkernel/cli/pkg/table"
"github.com/onkernel/cli/pkg/util"
"github.com/onkernel/kernel-go-sdk"
"github.com/pterm/pterm"
Expand Down Expand Up @@ -188,7 +189,7 @@ func (p ProxyCmd) Create(ctx context.Context, in ProxyCreateInput) error {
}
rows = append(rows, []string{"Protocol", protocol})

PrintTableNoPad(rows, true)
table.PrintTableNoPad(rows, true)
return nil
}

Expand Down
18 changes: 17 additions & 1 deletion cmd/proxies/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/onkernel/cli/pkg/table"
"github.com/onkernel/cli/pkg/util"
"github.com/onkernel/kernel-go-sdk"
"github.com/pterm/pterm"
Expand Down Expand Up @@ -38,7 +39,22 @@ func (p ProxyCmd) Get(ctx context.Context, in ProxyGetInput) error {
// Display type-specific config details
rows = append(rows, getProxyConfigRows(item)...)

PrintTableNoPad(rows, true)
// Display status with color
status := string(item.Status)
if status == "" {
status = "-"
} else if status == "available" {
status = pterm.Green(status)
} else if status == "unavailable" {
status = pterm.Red(status)
}
rows = append(rows, []string{"Status", status})

// Display last checked timestamp
lastChecked := util.FormatLocal(item.LastChecked)
rows = append(rows, []string{"Last Checked", lastChecked})

table.PrintTableNoPad(rows, true)
return nil
}

Expand Down
14 changes: 0 additions & 14 deletions cmd/proxies/helpers.go

This file was deleted.

3 changes: 2 additions & 1 deletion cmd/proxies/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strings"

"github.com/onkernel/cli/pkg/table"
"github.com/onkernel/cli/pkg/util"
"github.com/onkernel/kernel-go-sdk"
"github.com/pterm/pterm"
Expand Down Expand Up @@ -68,7 +69,7 @@ func (p ProxyCmd) List(ctx context.Context) error {
})
}

PrintTableNoPad(tableData, true)
table.PrintTableNoPad(tableData, true)
return nil
}

Expand Down
12 changes: 5 additions & 7 deletions cmd/proxies/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,33 +64,31 @@ func TestProxyList_WithProxies(t *testing.T) {
assert.NoError(t, err)
output := buf.String()

// Check table headers
// Check table headers (Config may be truncated in narrow terminals)
assert.Contains(t, output, "ID")
assert.Contains(t, output, "Name")
assert.Contains(t, output, "Type")
assert.Contains(t, output, "Protocol")
assert.Contains(t, output, "Config")
assert.Contains(t, output, "Status")

// Check proxy data
// Check proxy data - verify IDs and short columns are fully visible
assert.Contains(t, output, "dc-1")
assert.Contains(t, output, "https") // Protocol is shown
assert.Contains(t, output, "Country")
assert.Contains(t, output, "datacenter")

assert.Contains(t, output, "res-1")
assert.Contains(t, output, "residential")

assert.Contains(t, output, "custom-1")
assert.Contains(t, output, "My Proxy")
assert.Contains(t, output, "custom")
assert.Contains(t, output, "proxy") // Part of proxy.example.com, will be truncated

assert.Contains(t, output, "mobile-1")
assert.Contains(t, output, "mobile")
assert.Contains(t, output, "Carrier: verizon")

assert.Contains(t, output, "isp-1")
assert.Contains(t, output, "-") // Empty name shows as "-"
assert.Contains(t, output, "isp")
assert.Contains(t, output, "Country: EU")
}

func TestProxyList_Error(t *testing.T) {
Expand Down
110 changes: 4 additions & 106 deletions cmd/table.go
Original file line number Diff line number Diff line change
@@ -1,113 +1,11 @@
package cmd

import (
"strings"
"unicode/utf8"

"github.com/onkernel/cli/pkg/table"
"github.com/pterm/pterm"
)

// printTableNoPad renders a table similar to pterm.DefaultTable, but it avoids
// adding trailing padding spaces after the last column and does not add blank
// padded lines to match multi-line cells in other columns. The last column may
// contain multi-line content which will be printed as-is on following lines.
func printTableNoPad(data pterm.TableData, hasHeader bool) {
if len(data) == 0 {
return
}

// Determine number of columns from the first row
numCols := len(data[0])
if numCols == 0 {
return
}

// Pre-compute max width per column for all but the last column
maxColWidths := make([]int, numCols)
for _, row := range data {
for colIdx := 0; colIdx < numCols && colIdx < len(row); colIdx++ {
if colIdx == numCols-1 {
continue
}
for _, line := range strings.Split(row[colIdx], "\n") {
if w := utf8.RuneCountInString(line); w > maxColWidths[colIdx] {
maxColWidths[colIdx] = w
}
}
}
}

var b strings.Builder
sep := pterm.DefaultTable.Separator
sepStyled := pterm.ThemeDefault.TableSeparatorStyle.Sprint(sep)

renderRow := func(row []string, styleHeader bool) {
// Build first-line-only for non-last columns; last column is full string
firstLineParts := make([]string, 0, numCols)
for colIdx := 0; colIdx < numCols; colIdx++ {
var cell string
if colIdx < len(row) {
cell = row[colIdx]
}

if colIdx < numCols-1 {
// Only the first line for non-last columns
lines := strings.Split(cell, "\n")
first := ""
if len(lines) > 0 {
first = lines[0]
}
padCount := maxColWidths[colIdx] - utf8.RuneCountInString(first)
if padCount < 0 {
padCount = 0
}
firstLineParts = append(firstLineParts, first+strings.Repeat(" ", padCount))
} else {
// Last column: render the first line now; remaining lines after
lines := strings.Split(cell, "\n")
if len(lines) > 0 {
firstLineParts = append(firstLineParts, lines[0])
} else {
firstLineParts = append(firstLineParts, "")
}
}
}

line := strings.Join(firstLineParts[:numCols-1], sepStyled)
if numCols > 1 {
if line != "" {
line += sepStyled
}
line += firstLineParts[numCols-1]
}

if styleHeader {
b.WriteString(pterm.ThemeDefault.TableHeaderStyle.Sprint(line))
} else {
b.WriteString(line)
}
b.WriteString("\n")

// Print remaining lines from the last column without alignment padding
if numCols > 0 {
var lastCell string
if len(row) >= numCols {
lastCell = row[numCols-1]
}
lines := strings.Split(lastCell, "\n")
if len(lines) > 1 {
rest := strings.Join(lines[1:], "\n")
if rest != "" {
b.WriteString(rest)
b.WriteString("\n")
}
}
}
}

for idx, row := range data {
renderRow(row, hasHeader && idx == 0)
}

pterm.Print(b.String())
// PrintTableNoPad is a wrapper around pkg/table.PrintTableNoPad for backwards compatibility
func PrintTableNoPad(data pterm.TableData, hasHeader bool) {
table.PrintTableNoPad(data, hasHeader)
}
Loading