setup cobra for wsh

This commit is contained in:
sawka 2024-06-14 12:19:36 -07:00
parent 9743395eb7
commit 8a3a527343
6 changed files with 162 additions and 68 deletions

41
cmd/wsh/cmd/html.go Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(htmlCmd)
}
func htmlRun(cmd *cobra.Command, args []string) {
defer doShutdown("normal exit", 0)
setTermHtmlMode()
for {
var buf [1]byte
_, err := os.Stdin.Read(buf[:])
if err != nil {
doShutdown(fmt.Sprintf("stdin closed/error (%v)", err), 1)
}
if buf[0] == 0x03 {
doShutdown("read Ctrl-C from stdin", 1)
break
}
if buf[0] == 'x' {
doShutdown("read 'x' from stdin", 0)
break
}
}
}
var htmlCmd = &cobra.Command{
Use: "html",
Short: "Launch a demo html-mode terminal",
Run: htmlRun,
}

84
cmd/wsh/cmd/root.go Normal file
View File

@ -0,0 +1,84 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"fmt"
"log"
"os"
"os/signal"
"sync"
"syscall"
"github.com/spf13/cobra"
"github.com/wavetermdev/thenextwave/pkg/wshutil"
"golang.org/x/term"
)
var (
rootCmd = &cobra.Command{
Use: "wsh",
Short: "CLI tool to control Wave Terminal",
Long: `wsh is a small utility that lets you do cool things with Wave Terminal, right from the command line`,
}
)
var shutdownOnce sync.Once
var origTermState *term.State
var usingHtmlMode bool
var shutdownSignalHandlersInstalled bool
func doShutdown(reason string, exitCode int) {
shutdownOnce.Do(func() {
defer os.Exit(exitCode)
log.Printf("shutting down: %s\r\n", reason)
if usingHtmlMode {
cmd := &wshutil.BlockSetMetaCommand{
Command: wshutil.BlockCommand_SetMeta,
Meta: map[string]any{"term:mode": nil},
}
barr, _ := wshutil.EncodeWaveOSCMessage(cmd)
os.Stdout.Write(barr)
}
if origTermState != nil {
term.Restore(int(os.Stdin.Fd()), origTermState)
}
})
}
func setTermHtmlMode() {
installShutdownSignalHandlers()
origState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
fmt.Fprintf(os.Stderr, "Error setting raw mode: %v\n", err)
return
}
origTermState = origState
cmd := &wshutil.BlockSetMetaCommand{
Command: wshutil.BlockCommand_SetMeta,
Meta: map[string]any{"term:mode": "html"},
}
barr, _ := wshutil.EncodeWaveOSCMessage(cmd)
os.Stdout.Write(barr)
usingHtmlMode = true
}
func installShutdownSignalHandlers() {
if shutdownSignalHandlersInstalled {
return
}
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT)
go func() {
for sig := range sigCh {
doShutdown(fmt.Sprintf("got signal %v", sig), 1)
break
}
}()
}
// Execute executes the root command.
func Execute() error {
return rootCmd.Execute()
}

22
cmd/wsh/cmd/version.go Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of wsh",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("wsh v0.1.0\n")
},
}

View File

@ -4,75 +4,10 @@
package main
import (
"fmt"
"log"
"os"
"os/signal"
"sync"
"syscall"
"github.com/wavetermdev/thenextwave/pkg/wshutil"
"golang.org/x/term"
"github.com/wavetermdev/thenextwave/cmd/wsh/cmd"
)
var shutdownOnce sync.Once
var origTermState *term.State
func doShutdown(reason string, exitCode int) {
shutdownOnce.Do(func() {
defer os.Exit(exitCode)
log.Printf("shutting down: %s\r\n", reason)
cmd := &wshutil.BlockSetMetaCommand{
Command: wshutil.BlockCommand_SetMeta,
Meta: map[string]any{"term:mode": nil},
}
barr, _ := wshutil.EncodeWaveOSCMessage(cmd)
if origTermState != nil {
term.Restore(int(os.Stdin.Fd()), origTermState)
}
os.Stdout.Write(barr)
})
}
func installShutdownSignalHandlers() {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT)
go func() {
for sig := range sigCh {
doShutdown(fmt.Sprintf("got signal %v", sig), 1)
break
}
}()
}
func main() {
installShutdownSignalHandlers()
defer doShutdown("normal exit", 0)
origState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
fmt.Fprintf(os.Stderr, "Error setting raw mode: %v\n", err)
return
}
origTermState = origState
cmd := &wshutil.BlockSetMetaCommand{
Command: wshutil.BlockCommand_SetMeta,
Meta: map[string]any{"term:mode": "html"},
}
barr, _ := wshutil.EncodeWaveOSCMessage(cmd)
os.Stdout.Write(barr)
for {
var buf [1]byte
_, err := os.Stdin.Read(buf[:])
if err != nil {
doShutdown(fmt.Sprintf("stdin closed/error (%v)", err), 1)
}
if buf[0] == 0x03 {
doShutdown("read Ctrl-C from stdin", 1)
break
}
if buf[0] == 'x' {
doShutdown("read 'x' from stdin", 0)
break
}
}
cmd.Execute()
}

3
go.mod
View File

@ -15,6 +15,7 @@ require (
github.com/mattn/go-sqlite3 v1.14.22
github.com/mitchellh/mapstructure v1.5.0
github.com/sawka/txwrap v0.2.0
github.com/spf13/cobra v1.8.0
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94
golang.org/x/sys v0.20.0
golang.org/x/term v0.17.0
@ -24,6 +25,8 @@ require (
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.4 // indirect
go.uber.org/atomic v1.7.0 // indirect
)

9
go.sum
View File

@ -1,5 +1,6 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -24,6 +25,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
@ -34,8 +37,13 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sawka/txwrap v0.2.0 h1:V3LfvKVLULxcYSxdMguLwFyQFMEU9nFDJopg0ZkL+94=
github.com/sawka/txwrap v0.2.0/go.mod h1:wwQ2SQiN4U+6DU/iVPhbvr7OzXAtgZlQCIGuvOswEfA=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
@ -48,5 +56,6 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=