diff --git a/cli/cmd/apply.go b/cli/cmd/apply.go index e6a0b3c8..514b8371 100644 --- a/cli/cmd/apply.go +++ b/cli/cmd/apply.go @@ -43,9 +43,8 @@ func NewApplyCommand() *cobra.Command { } defer client.Close() - p, output := output.NewTaskOutput() - defer p.Wait() - defer output.Quit() + output := output.NewTaskOutput() + defer output.Close() err = client.Apply(manifests, output) if err != nil { diff --git a/cli/cmd/delete.go b/cli/cmd/delete.go index c3998fa5..f61f04b7 100644 --- a/cli/cmd/delete.go +++ b/cli/cmd/delete.go @@ -42,9 +42,8 @@ func NewDeleteCommand() *cobra.Command { } defer client.Close() - p, output := output.NewTaskOutput() - defer p.Wait() - defer output.Quit() + output := output.NewTaskOutput() + defer output.Close() err = client.Delete(manifests, output) if err != nil { diff --git a/cli/cmd/init.go b/cli/cmd/init.go index 08e51d8e..87894255 100644 --- a/cli/cmd/init.go +++ b/cli/cmd/init.go @@ -62,9 +62,8 @@ func NewInitCommand() *cobra.Command { } fmt.Printf("Installing Drasi with version %s from registry %s\n", version, registry) - p, output := output.NewTaskOutput() - defer p.Wait() - defer output.Quit() + output := output.NewTaskOutput() + defer output.Close() if err := installer.Install(local, registry, version, output, namespace); err != nil { return err diff --git a/cli/cmd/wait.go b/cli/cmd/wait.go index d56cd1f8..43a3c1aa 100644 --- a/cli/cmd/wait.go +++ b/cli/cmd/wait.go @@ -42,9 +42,8 @@ func NewWaitCommand() *cobra.Command { } defer client.Close() - p, output := output.NewTaskOutput() - defer p.Wait() - defer output.Quit() + output := output.NewTaskOutput() + defer output.Close() err = client.ReadyWait(manifests, timeout, output) if err != nil { diff --git a/cli/go.mod b/cli/go.mod index 9661c859..2bf4cdb2 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -139,8 +139,8 @@ require ( golang.org/x/crypto v0.26.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect diff --git a/cli/go.sum b/cli/go.sum index 9268375e..bbe8f0a0 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -472,11 +472,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/cli/service/output/interface.go b/cli/service/output/interface.go index e0e34297..5363d412 100644 --- a/cli/service/output/interface.go +++ b/cli/service/output/interface.go @@ -1,5 +1,13 @@ package output +import ( + "fmt" + tea "github.com/charmbracelet/bubbletea" + "golang.org/x/term" + "os" + "sync" +) + type TaskOutput interface { AddTask(name, message string) FailTask(name, message string) @@ -7,6 +15,27 @@ type TaskOutput interface { InfoTask(name, message string) InfoMessage(message string) Error(message string) - Quit() + Close() GetChildren(name string) TaskOutput } + +func NewTaskOutput() TaskOutput { + if term.IsTerminal(int(os.Stdout.Fd())) { + m := taskOutputBubbleTea{ + lock: &sync.RWMutex{}, + tasks: make(map[string]*task), + queue: make(chan interface{}, 10), + } + p := tea.NewProgram(m) + m.program = p + go func() { + _, e := p.Run() + if e != nil { + fmt.Println("Error: " + e.Error()) + } + }() + return &m + } else { + return taskOutputNoTerm{} + } +} diff --git a/cli/service/output/task_output.go b/cli/service/output/task_output.go index 53801307..37f0108c 100644 --- a/cli/service/output/task_output.go +++ b/cli/service/output/task_output.go @@ -9,22 +9,6 @@ import ( "sync" ) -func NewTaskOutput() (*tea.Program, TaskOutput) { - m := taskOutputBubbleTea{ - lock: &sync.RWMutex{}, - tasks: make(map[string]*task), - queue: make(chan interface{}, 10), - } - p := tea.NewProgram(m) - go func() { - _, e := p.Run() - if e != nil { - fmt.Println("Error: " + e.Error()) - } - }() - return p, &m -} - type itemStatus = int const ( @@ -85,10 +69,11 @@ type task struct { } type taskOutputBubbleTea struct { - lock *sync.RWMutex - tasks map[string]*task - keys []string - queue chan interface{} + lock *sync.RWMutex + tasks map[string]*task + keys []string + queue chan interface{} + program *tea.Program } func (m taskOutputBubbleTea) AddTask(name, message string) { @@ -115,8 +100,9 @@ func (m taskOutputBubbleTea) Error(message string) { m.queue <- errorMsg{message, ""} } -func (m taskOutputBubbleTea) Quit() { +func (m taskOutputBubbleTea) Close() { m.queue <- tea.Quit() + m.program.Wait() } func (m taskOutputBubbleTea) GetChildren(name string) TaskOutput { @@ -290,8 +276,8 @@ func (m childTaskOutput) Error(message string) { m.queue <- errorMsg{message, m.parentName} } -func (m childTaskOutput) Quit() { - m.parent.Quit() +func (m childTaskOutput) Close() { + m.parent.Close() } func (m childTaskOutput) GetChildren(name string) TaskOutput { diff --git a/cli/service/output/task_output_noterm.go b/cli/service/output/task_output_noterm.go new file mode 100644 index 00000000..3526180b --- /dev/null +++ b/cli/service/output/task_output_noterm.go @@ -0,0 +1,37 @@ +package output + +import "fmt" + +type taskOutputNoTerm struct { +} + +func (m taskOutputNoTerm) AddTask(name, message string) { + fmt.Printf("[BUSY] %s: %s", name, message) +} + +func (m taskOutputNoTerm) FailTask(name, message string) { + fmt.Printf("[FAILED] %s: %s", name, message) +} + +func (m taskOutputNoTerm) SucceedTask(name, message string) { + fmt.Printf("[SUCCESS] %s: %s", name, message) +} + +func (m taskOutputNoTerm) InfoTask(name, message string) { + fmt.Printf("[INFO] %s: %s", name, message) +} + +func (m taskOutputNoTerm) InfoMessage(message string) { + fmt.Printf("[INFO] %s", message) +} + +func (m taskOutputNoTerm) Error(message string) { + fmt.Printf("[ERROR] %s", message) +} + +func (m taskOutputNoTerm) Close() { +} + +func (m taskOutputNoTerm) GetChildren(name string) TaskOutput { + return &m +}