Skip to content

Commit

Permalink
feat: use bubbletea
Browse files Browse the repository at this point in the history
  • Loading branch information
Madh93 committed May 14, 2023
1 parent 8626497 commit 066858c
Show file tree
Hide file tree
Showing 10 changed files with 308 additions and 29 deletions.
12 changes: 7 additions & 5 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"log"
"runtime"

"github.com/Madh93/tpm/cmd/tui"
"github.com/Madh93/tpm/internal/terraform"
"github.com/Madh93/tpm/internal/tpm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var installCmd = &cobra.Command{
Expand All @@ -25,9 +27,11 @@ var installCmd = &cobra.Command{
return nil
},
Run: func(cmd *cobra.Command, args []string) {
viper.Set("force", getBoolFlag(cmd, "force"))
var providers []*terraform.Provider
var err error

// Parse providers to install
if getStringFlag(cmd, "from-file") != "" {
providers, err = tpm.ParseProvidersFromFile(getStringFlag(cmd, "from-file"))
if err != nil {
Expand All @@ -46,11 +50,9 @@ var installCmd = &cobra.Command{
}

// Install providers
for _, provider := range providers {
err := tpm.Install(provider, getBoolFlag(cmd, "force"))
if err != nil {
log.Fatal("Error: ", err)
}
err = tui.RunInstaller(providers)
if err != nil {
log.Fatal("Error: ", err)
}
},
}
Expand Down
99 changes: 99 additions & 0 deletions cmd/tui/installer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package tui

import (
"fmt"

"github.com/Madh93/tpm/internal/terraform"
"github.com/Madh93/tpm/internal/tpm"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/spf13/viper"
)

type installer struct {
spinner spinner.Model
providers []*terraform.Provider
index int
err error
}

func NewInstallerModel(providers []*terraform.Provider) installer {
return installer{
spinner: DefaultSpinner,
providers: providers,
index: 0,
}
}

func RunInstaller(providers []*terraform.Provider) (err error) {
if _, err = tea.NewProgram(NewInstallerModel(providers)).Run(); err != nil {
return
}
return nil
}

func (i installer) Init() tea.Cmd {
return tea.Batch(
installProvider(i.providers[i.index]),
i.spinner.Tick,
)
}

func (i installer) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {

case tea.KeyMsg:
switch msg.String() {
case "ctrl+c":
return i, tea.Quit
}

case spinner.TickMsg:
var cmd tea.Cmd
i.spinner, cmd = i.spinner.Update(msg)
return i, cmd

case providerMsg:
if i.index >= len(i.providers)-1 {
return i, tea.Sequence(
tea.Printf("%s %s", CheckMark, i.providers[i.index]),
tea.Quit,
)
}
i.index++
return i, tea.Batch(
tea.Printf("%s %s", CheckMark, i.providers[i.index-1]),
installProvider(i.providers[i.index]),
)

case errMsg:
i.err = msg
if i.index >= len(i.providers)-1 {
return i, tea.Sequence(
tea.Printf("%s %s Reason: %s", CrossMark, i.providers[i.index], i.err),
tea.Quit,
)
}
i.index++
return i, tea.Batch(
tea.Printf("%s %s Reason: %s", CrossMark, i.providers[i.index-1], i.err),
installProvider(i.providers[i.index]),
)
}

return i, nil
}

func (i installer) View() string {
return fmt.Sprintf("%s Installing %s", i.spinner.View(), i.providers[i.index])
}

func installProvider(provider *terraform.Provider) tea.Cmd {
return func() tea.Msg {
err := tpm.Install(provider, viper.GetBool("force"))
if err != nil {
return errMsg{err}
}
return providerMsg(provider.String())
}
}
18 changes: 18 additions & 0 deletions cmd/tui/tui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tui

import (
"github.com/charmbracelet/bubbles/spinner"
"github.com/charmbracelet/lipgloss"
)

var (
DefaultSpinner = spinner.New(spinner.WithSpinner(spinner.MiniDot))
CheckMark = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓")
CrossMark = lipgloss.NewStyle().Foreground(lipgloss.Color("160")).SetString("⨯")
)

type providerMsg string

type errMsg struct{ err error }

func (e errMsg) Error() string { return e.err.Error() }
98 changes: 98 additions & 0 deletions cmd/tui/uninstaller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package tui

import (
"fmt"

"github.com/Madh93/tpm/internal/terraform"
"github.com/Madh93/tpm/internal/tpm"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
)

type uninstaller struct {
spinner spinner.Model
providers []*terraform.Provider
index int
err error
}

func NewUninstallerModel(providers []*terraform.Provider) uninstaller {
return uninstaller{
spinner: DefaultSpinner,
providers: providers,
index: 0,
}
}

func RunUninstaller(providers []*terraform.Provider) (err error) {
if _, err = tea.NewProgram(NewUninstallerModel(providers)).Run(); err != nil {
return
}
return nil
}

func (u uninstaller) Init() tea.Cmd {
return tea.Batch(
uninstallProvider(u.providers[u.index]),
u.spinner.Tick,
)
}

func (u uninstaller) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {

case tea.KeyMsg:
switch msg.String() {
case "ctrl+c":
return u, tea.Quit
}

case spinner.TickMsg:
var cmd tea.Cmd
u.spinner, cmd = u.spinner.Update(msg)
return u, cmd

case providerMsg:
if u.index >= len(u.providers)-1 {
return u, tea.Sequence(
tea.Printf("%s %s", CheckMark, u.providers[u.index]),
tea.Quit,
)
}
u.index++
return u, tea.Batch(
tea.Printf("%s %s", CheckMark, u.providers[u.index-1]),
uninstallProvider(u.providers[u.index]),
)

case errMsg:
u.err = msg
if u.index >= len(u.providers)-1 {
return u, tea.Sequence(
tea.Printf("%s %s Reason: %s", CrossMark, u.providers[u.index], u.err),
tea.Quit,
)
}
u.index++
return u, tea.Batch(
tea.Printf("%s %s Reason: %s", CrossMark, u.providers[u.index-1], u.err),
uninstallProvider(u.providers[u.index]),
)
}

return u, nil
}

func (u uninstaller) View() string {
return fmt.Sprintf("%s Unistalling %s", u.spinner.View(), u.providers[u.index])
}

func uninstallProvider(provider *terraform.Provider) tea.Cmd {
return func() tea.Msg {
err := tpm.Uninstall(provider)
if err != nil {
return errMsg{err}
}
return providerMsg(provider.String())
}
}
10 changes: 4 additions & 6 deletions cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"log"
"runtime"

"github.com/Madh93/tpm/cmd/tui"
"github.com/Madh93/tpm/internal/terraform"
"github.com/Madh93/tpm/internal/tpm"
"github.com/spf13/cobra"
)

Expand All @@ -29,11 +29,9 @@ var uninstallCmd = &cobra.Command{
}

// Uninstall providers
for _, provider := range providers {
err := tpm.Uninstall(provider)
if err != nil {
log.Fatal("Error: ", err)
}
err := tui.RunUninstaller(providers)
if err != nil {
log.Fatal("Error: ", err)
}
},
}
Expand Down
16 changes: 15 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ go 1.20

require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/charmbracelet/bubbles v0.15.0
github.com/charmbracelet/bubbletea v0.24.0
github.com/charmbracelet/lipgloss v0.7.1
github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
Expand All @@ -13,21 +16,32 @@ require (
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
Loading

0 comments on commit 066858c

Please sign in to comment.