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
4 changes: 1 addition & 3 deletions cmd/clip/paste.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ var pasteCmd = &cobra.Command{
Use: "paste",
Short: "Paste clipboard content to the terminal",
RunE: func(cmd *cobra.Command, args []string) error {
service := clipboard.NewService()

return service.Paste(cmd.OutOrStdout())
return clipboard.Paste(cmd.OutOrStdout())
},
}

Expand Down
50 changes: 50 additions & 0 deletions cmd/info/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package info

import (
"fmt"
"io"
"sort"
"strings"

"github.com/kloudkit/ws-cli/internals/env"
"github.com/kloudkit/ws-cli/internals/styles"
"github.com/spf13/cobra"
)

func showEnvironment(writer io.Writer) {
fmt.Fprintln(writer, styles.HeaderStyle().Render("Environment Variables"))

var envVars [][]string
for key, value := range env.GetAll() {
if strings.HasPrefix(key, "WS_") {
envVars = append(envVars, []string{key, value})
}
}

if len(envVars) == 0 {
fmt.Fprintln(writer, styles.WarningStyle().Render(" No environment variables found"))
return
}

sort.Slice(envVars, func(i, j int) bool {
return envVars[i][0] < envVars[j][0]
})

t := styles.Table("Variable", "Value").
Rows(envVars...)

fmt.Fprintln(writer)
fmt.Fprintln(writer, t.Render())
}

var envCmd = &cobra.Command{
Use: "env",
Short: "Display effective workspace environment variables",
Run: func(cmd *cobra.Command, args []string) {
showEnvironment(cmd.OutOrStdout())
},
}

func init() {
InfoCmd.AddCommand(envCmd)
}
52 changes: 52 additions & 0 deletions cmd/info/extensions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package info

import (
"bufio"
"bytes"
"fmt"
"github.com/kloudkit/ws-cli/internals/styles"
"github.com/spf13/cobra"
"io"
"os/exec"
"strings"
)

func fetchExtensions() [][]string {
out, _ := exec.Command("code", "--list-extensions", "--show-versions").Output()

var extensions [][]string
scanner := bufio.NewScanner(bytes.NewReader(out))

for scanner.Scan() {
line := scanner.Text()
parts := strings.Split(line, "@")

if len(parts) == 2 {
extensions = append(extensions, []string{parts[0], parts[1]})
}
}

return extensions
}

func showExtensions(writer io.Writer) {
fmt.Fprintln(writer, styles.HeaderStyle().Render("Extensions"))
fmt.Fprintln(writer)

t := styles.Table("Name", "Version").
Rows(fetchExtensions()...)

fmt.Fprintln(writer, t.Render())
}

var extensionsCmd = &cobra.Command{
Use: "extensions",
Short: "Display installed extensions",
Run: func(cmd *cobra.Command, args []string) {
showExtensions(cmd.OutOrStdout())
},
}

func init() {
InfoCmd.AddCommand(extensionsCmd)
}
87 changes: 32 additions & 55 deletions cmd/info/info.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,18 @@
package info

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"time"
"io"

"encoding/json"
"github.com/kloudkit/ws-cli/internals/styles"
"github.com/spf13/cobra"
"os"
"strings"
)

func fetchExtensions() string {
out, _ := exec.Command("code", "--list-extensions", "--show-versions").Output()

var buf bytes.Buffer
scanner := bufio.NewScanner(bytes.NewReader(out))
skipHeader := true

for scanner.Scan() {
if skipHeader {
skipHeader = false
continue
}

buf.WriteString("\t\t ")
buf.WriteString(scanner.Text())
buf.WriteByte('\n')
}

return buf.String()
}

func readJsonFile() map[string]interface{} {
var content map[string]interface{}
func readJsonFile() map[string]any {
var content map[string]any

data, _ := os.ReadFile("/var/lib/workspace/manifest.json")

Expand All @@ -44,12 +21,12 @@ func readJsonFile() map[string]interface{} {
return content
}

func readJson(content map[string]interface{}, key string) string {
func readJson(content map[string]any, key string) string {
keys := strings.Split(key, ".")
var value interface{} = content
var value any = content

for _, k := range keys {
m, ok := value.(map[string]interface{})
m, ok := value.(map[string]any)
if !ok {
return ""
}
Expand All @@ -64,35 +41,35 @@ func readJson(content map[string]interface{}, key string) string {
return fmt.Sprintf("%v", value)
}

func readStartup() (time.Time, time.Duration, error) {
data, err := os.ReadFile("/var/lib/workspace/state/initialized")
if err != nil {
return time.Time{}, 0, err
}
func showVersion(writer io.Writer) {
content := readJsonFile()

parsedTime, err := time.Parse(time.RFC3339, strings.TrimSpace(string(data)))
if err != nil {
return time.Time{}, 0, err
}
fmt.Fprintln(writer, styles.HeaderStyle().Render("Versions"))
fmt.Fprintln(writer)

return parsedTime, time.Since(parsedTime), nil
t := styles.Table("", "Value").
Rows(
[]string{"workspace", readJson(content, "version")},
[]string{"ws-cli", Version},
[]string{"VSCode", readJson(content, "vscode.version")},
)

fmt.Fprintln(writer, t.Render())
}

var InfoCmd = &cobra.Command{
Use: "info",
Short: "Display workspace information",
}

var showVersionCmd = &cobra.Command{
Use: "version",
Short: "Display installed workspace version",
Run: func(cmd *cobra.Command, args []string) {
var content = readJsonFile()
started, running, _ := readStartup()

fmt.Fprintln(cmd.OutOrStdout(), "Uptime")
fmt.Fprintln(cmd.OutOrStdout(), " started\t", started)
fmt.Fprintln(cmd.OutOrStdout(), " running\t", running)
fmt.Fprintln(cmd.OutOrStdout(), "Versions")
fmt.Fprintln(cmd.OutOrStdout(), " workspace\t", readJson(content, "version"))
fmt.Fprintln(cmd.OutOrStdout(), " ws-cli\t", Version)
fmt.Fprintln(cmd.OutOrStdout(), " VSCode\t", readJson(content, "vscode.version"))
fmt.Fprintln(cmd.OutOrStdout(), "Extensions")
fmt.Fprint(cmd.OutOrStdout(), fetchExtensions())
showVersion(cmd.OutOrStdout())
},
}

func init() {
InfoCmd.AddCommand(showVersionCmd)
}
79 changes: 79 additions & 0 deletions cmd/info/uptime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package info

import (
"fmt"
"io"

"github.com/kloudkit/ws-cli/internals/styles"
"github.com/spf13/cobra"
"os"
"strings"
"time"
)

func readStartup() (time.Time, time.Duration, error) {
data, err := os.ReadFile("/var/lib/workspace/state/initialized")
if err != nil {
return time.Time{}, 0, err
}

parsedTime, err := time.Parse(time.RFC3339, strings.TrimSpace(string(data)))
if err != nil {
return time.Time{}, 0, err
}

return parsedTime, time.Since(parsedTime), nil
}

func humanizeDuration(duration time.Duration) string {
days := int(duration.Hours() / 24)
hours := int(duration.Hours()) % 24
minutes := int(duration.Minutes()) % 60

var parts []string

if days > 0 {
parts = append(parts, fmt.Sprintf("%d days", days))
}

if hours > 0 {
parts = append(parts, fmt.Sprintf("%d hours", hours))
}

if minutes > 0 {
parts = append(parts, fmt.Sprintf("%d minutes", minutes))
}

if len(parts) == 0 {
return "just now"
}

return strings.Join(parts, ", ") + " ago"
}

func showUptime(writer io.Writer) {
started, running, _ := readStartup()

fmt.Fprintln(writer, styles.HeaderStyle().Render("Uptime"))
fmt.Fprintln(writer)

t := styles.Table("", "Value").
Rows(
[]string{"started", started.String()},
[]string{"running", humanizeDuration(running)},
)

fmt.Fprintln(writer, t.Render())
}

var uptimeCmd = &cobra.Command{
Use: "uptime",
Short: "Display the workspace uptime",
Run: func(cmd *cobra.Command, args []string) {
showUptime(cmd.OutOrStdout())
},
}

func init() {
InfoCmd.AddCommand(uptimeCmd)
}
6 changes: 3 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/kloudkit/ws-cli/cmd/get"
"github.com/kloudkit/ws-cli/cmd/info"
"github.com/kloudkit/ws-cli/cmd/log"
ilog "github.com/kloudkit/ws-cli/internals/log"
"github.com/kloudkit/ws-cli/internals/styles"
"github.com/spf13/cobra"
)

Expand All @@ -36,11 +36,11 @@ func init() {

cobra.OnInitialize(func() {
if _, exists := os.LookupEnv("WS_LOGGING_NO_COLOR"); exists {
ilog.ColorEnabled = false
styles.ColorEnabled = false
}

if noColor {
ilog.ColorEnabled = false
styles.ColorEnabled = false
}
})

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/apenella/go-common-utils/data v0.0.0-20220913191136-86daaa87e7df // indirect
github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/catppuccin/go v0.3.0 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df h1:
github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df/go.mod h1:+3dyIlHX350xJIUIffwMLswZXU+N2FwDE05VuKqxYdw=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
Expand Down
8 changes: 1 addition & 7 deletions internals/clipboard/clipboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ import (
"github.com/kloudkit/ws-cli/internals/net"
)

type Service struct{}

func NewService() *Service {
return &Service{}
}

func (s *Service) Paste(writer io.Writer) error {
func Paste(writer io.Writer) error {
client := net.GetIPCClient()

resp, err := client.Get("http://localhost/clipboard")
Expand Down
Loading
Loading