Skip to content

Commit

Permalink
Make UI activable using --ui or MONDAY_ENABLE_UI env var
Browse files Browse the repository at this point in the history
  • Loading branch information
eko committed Aug 29, 2019
1 parent 23fd98b commit 7203c94
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 26 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -101,13 +101,15 @@ $ monday init
Once your configuration file is ready, you can simply run Monday:

```bash
$ monday
$ monday [--ui]
```

Note the `--ui` option that will allow you to enable the user interface (you can also define a `MONDAY_ENABLE_UI` environment variable to enable it).

Or, you can run a specific project directly by running:

```bash
$ monday run <project name>
$ monday run [--ui] <project name>
```

When you want to edit your configuration again, simply run this command to open it in your favorite editor:
Expand Down
37 changes: 26 additions & 11 deletions cmd/main.go
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"os/signal"
"runtime"
"strconv"
"syscall"

"github.com/eko/monday/pkg/config"
Expand Down Expand Up @@ -33,13 +34,19 @@ var (
watcherComponent *watcher.Watcher

openerCommand string

uiEnabled = len(os.Getenv("MONDAY_ENABLE_UI")) > 0
)

func main() {
initRuntimeEnvironment()

rootCmd := &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
if !uiEnabled {
uiEnabled, _ = strconv.ParseBool(cmd.Flag("ui").Value.String())
}

conf, err := config.Load()
if err != nil {
fmt.Printf("❌ %v", err)
Expand All @@ -53,6 +60,10 @@ func main() {
},
}

// UI-enable flag (for both root and run commands)
runCmd.Flags().Bool("ui", false, "Enable the terminal UI")
rootCmd.Flags().Bool("ui", false, "Enable the terminal UI")

rootCmd.AddCommand(completionCmd)
rootCmd.AddCommand(editCmd)
rootCmd.AddCommand(initCmd)
Expand Down Expand Up @@ -94,16 +105,10 @@ func selectProject(conf *config.Config) string {
}

func run(conf *config.Config, choice string) {
layout := ui.NewLayout()
layout := ui.NewLayout(uiEnabled)
layout.Init()
defer layout.GetGui().Close()

if err := layout.GetGui().SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
panic(err)
}

layout.GetStatusView().Writef(" ⇢ %s | Commands: ←/→: select view | ↑/↓: scroll up/down | a: toggle autoscroll | f: toggle fullscreen", choice)

// Retrieve selected project configuration by its name
project, err := conf.GetProjectByName(choice)
if err != nil {
panic(err)
Expand All @@ -122,9 +127,19 @@ func run(conf *config.Config, choice string) {
watcherComponent = watcher.NewWatcher(runnerComponent, forwarderComponent, conf.Watcher, project)
watcherComponent.Watch()

if err := layout.GetGui().MainLoop(); err != nil && err != gocui.ErrQuit {
fmt.Println(err)
stopAll()
if uiEnabled {
defer layout.GetGui().Close()

if err := layout.GetGui().SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
panic(err)
}

layout.GetStatusView().Writef(" ⇢ %s | Commands: ←/→: select view | ↑/↓: scroll up/down | a: toggle autoscroll | f: toggle fullscreen", choice)

if err := layout.GetGui().MainLoop(); err != nil && err != gocui.ErrQuit {
fmt.Println(err)
stopAll()
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions cmd/run.go
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"strconv"

"github.com/eko/monday/pkg/config"
"github.com/spf13/cobra"
Expand All @@ -13,6 +14,10 @@ var runCmd = &cobra.Command{
Long: `In case you already have the project name you want to launch, you can launch it directly by using the run command
and passing it as an argument`,
Run: func(cmd *cobra.Command, args []string) {
if !uiEnabled {
uiEnabled, _ = strconv.ParseBool(cmd.Flag("ui").Value.String())
}

conf, err := config.Load()
if err != nil {
fmt.Printf("❌ %v", err)
Expand Down
3 changes: 3 additions & 0 deletions pkg/runner/logstreamer.go
Expand Up @@ -53,6 +53,9 @@ func (l *Logstreamer) Write(p []byte) (n int, err error) {
}

err = l.output()
if err != nil {
panic(err)
}
return
}

Expand Down
29 changes: 23 additions & 6 deletions pkg/ui/layout.go
Expand Up @@ -9,6 +9,7 @@ import (

// Layout is the structure of the gui layout
type Layout struct {
uiEnabled bool
gui *gocui.Gui
highlighted *View
statusView *View
Expand All @@ -20,19 +21,35 @@ type Layout struct {
}

// NewLayout returns a new layout instance
func NewLayout() *Layout {
gui, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
panic(err)
func NewLayout(uiEnabled bool) *Layout {
layout := &Layout{
uiEnabled: uiEnabled,
}

return &Layout{
gui: gui,
if uiEnabled {
gui, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
panic(err)
}

layout.gui = gui
}

return layout
}

// Init initializes the gui layout
func (l *Layout) Init() {
if !l.uiEnabled {
l.statusView = NewEmptyView("status")
l.fullscreenView = NewEmptyView("fullscreen")
l.logsView = NewEmptyView("logs")
l.forwardsView = NewEmptyView("forwards")
l.proxyView = NewEmptyView("proxy")

return
}

maxX, maxY := l.gui.Size()

statusView, err := l.setStatusView("status", 0, 0, maxX-1, 2)
Expand Down
37 changes: 30 additions & 7 deletions pkg/ui/layout_test.go
Expand Up @@ -10,7 +10,7 @@ import (

func TestNewLayout(t *testing.T) {
// When
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

// Then
Expand All @@ -20,7 +20,7 @@ func TestNewLayout(t *testing.T) {

func TestInit(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

// When
Expand All @@ -34,9 +34,32 @@ func TestInit(t *testing.T) {
assert.IsType(t, new(View), layout.proxyView)
}

func TestTestInitWhenUINotEnabled(t *testing.T) {
// When
layout := NewLayout(false)
layout.Init()

// Then
assert.IsType(t, new(Layout), layout)

assert.Nil(t, layout.gui)

assert.IsType(t, new(View), layout.statusView)
assert.IsType(t, new(View), layout.fullscreenView)
assert.IsType(t, new(View), layout.logsView)
assert.IsType(t, new(View), layout.forwardsView)
assert.IsType(t, new(View), layout.proxyView)

assert.Nil(t, layout.statusView.GetView())
assert.Nil(t, layout.fullscreenView.GetView())
assert.Nil(t, layout.logsView.GetView())
assert.Nil(t, layout.forwardsView.GetView())
assert.Nil(t, layout.proxyView.GetView())
}

func TestGetGui(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

layout.Init()
Expand All @@ -50,7 +73,7 @@ func TestGetGui(t *testing.T) {

func TestGetLogsView(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

layout.Init()
Expand All @@ -67,7 +90,7 @@ func TestGetLogsView(t *testing.T) {

func TestGetForwardsView(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

layout.Init()
Expand All @@ -84,7 +107,7 @@ func TestGetForwardsView(t *testing.T) {

func TestGetProxyView(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

layout.Init()
Expand All @@ -101,7 +124,7 @@ func TestGetProxyView(t *testing.T) {

func TestGetStatusView(t *testing.T) {
// Given
layout := NewLayout()
layout := NewLayout(true)
layout.gui.Close()

layout.Init()
Expand Down
17 changes: 17 additions & 0 deletions pkg/ui/view.go
Expand Up @@ -28,6 +28,13 @@ func NewView(name, title string, view *gocui.View) *View {
}
}

// NewEmptyView returns a new instance of an empty view
func NewEmptyView(name string) *View {
return &View{
name: name,
}
}

// GetName returns the name of the view
func (v *View) GetName() string {
return v.name
Expand All @@ -45,10 +52,20 @@ func (v *View) GetView() *gocui.View {

// Write allows to write a string to the view
func (v *View) Write(str string) {
if v.view == nil {
fmt.Print(str)
return
}

v.view.Write([]byte(str))
}

// Writef allows to write a string to the view with some given arguments
func (v *View) Writef(str string, args ...interface{}) {
if v.view == nil {
fmt.Print(fmt.Sprintf(str, args...))
return
}

v.view.Write([]byte(fmt.Sprintf(str, args...)))
}

0 comments on commit 7203c94

Please sign in to comment.