Checkpoint commit

Have got a basic table select model working.  Now will try to setup modal models to support prompts and confirmations
This commit is contained in:
Leon Mika 2022-03-27 08:48:34 +11:00
parent 33115c7c13
commit 6ac22aad1f
8 changed files with 205 additions and 27 deletions

View file

@ -24,7 +24,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18
- name: Configure
run: |
git config --global url."https://${{ secrets.GO_MODULES_TOKEN }}:x-oauth-basic@github.com/lmika".insteadOf "https://github.com/lmika"

View file

@ -4,8 +4,6 @@ import (
"context"
"flag"
"fmt"
"os"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
tea "github.com/charmbracelet/bubbletea"
@ -17,6 +15,8 @@ import (
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
"github.com/lmika/awstools/internal/dynamo-browse/ui"
"github.com/lmika/gopkgs/cli"
"log"
"os"
)
func main() {
@ -58,6 +58,18 @@ func main() {
p := tea.NewProgram(uiModel, tea.WithAltScreen())
loopback.program = p
// TEMP -- profiling
//cf, err := os.Create("trace.out")
//if err != nil {
// log.Fatal("could not create CPU profile: ", err)
//}
//defer cf.Close() // error handling omitted for example
//if err := trace.Start(cf); err != nil {
// log.Fatal("could not start CPU profile: ", err)
//}
//defer trace.Stop()
// END TEMP
f, err := tea.LogToFile("debug.log", "debug")
if err != nil {
fmt.Println("fatal:", err)
@ -65,6 +77,7 @@ func main() {
}
defer f.Close()
log.Println("launching")
if err := p.Start(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
os.Exit(1)

6
docker-compose.yml Normal file
View file

@ -0,0 +1,6 @@
version: '3'
services:
dynamo:
image: amazon/dynamodb-local:latest
ports:
- 8000:8000

13
go.mod
View file

@ -1,27 +1,30 @@
module github.com/lmika/awstools
go 1.17
go 1.18
require (
github.com/alecthomas/participle/v2 v2.0.0-alpha7
github.com/asdine/storm v2.1.2+incompatible
github.com/aws/aws-sdk-go-v2 v1.15.0
github.com/aws/aws-sdk-go-v2/config v1.13.1
github.com/aws/aws-sdk-go-v2/credentials v1.8.0
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.8.0
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.0
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0
github.com/brianvoe/gofakeit/v6 v6.15.0
github.com/calyptia/go-bubble-table v0.1.0
github.com/charmbracelet/bubbles v0.10.3
github.com/charmbracelet/bubbletea v0.20.0
github.com/charmbracelet/lipgloss v0.5.0
github.com/google/uuid v1.3.0
github.com/lmika/events v0.0.0-20200906102219-a2269cd4394e
github.com/lmika/gopkgs v0.0.0-20211210041137-0dc91e939890
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.1
)
require (
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
github.com/asdine/storm v2.1.2+incompatible // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.10.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 // indirect
@ -34,13 +37,10 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 // indirect
github.com/aws/smithy-go v1.11.1 // indirect
github.com/brianvoe/gofakeit/v6 v6.15.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lunixbochs/vtclean v1.0.0 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
@ -50,6 +50,7 @@ require (
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sahilm/fuzzy v0.1.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect

1
go.sum
View file

@ -116,6 +116,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=

View file

@ -34,10 +34,12 @@ type uiModel struct {
table table.Model
viewport viewport.Model
// TEMP
tableSelect tea.Model
tableWidth, tableHeight int
ready bool
//resultSet *models.ResultSet
ready bool
state controllers.State
message string
@ -62,6 +64,11 @@ func NewModel(dispatcher *dispatcher.Dispatcher, commandController *commandctrl.
message: "Press s to scan",
textInput: textInput,
// TEMP
tableSelect: newSizeWaitModel(func(w, h int) tea.Model {
return newTableSelectModel(w, h)
}),
dispatcher: dispatcher,
commandController: commandController,
tableReadController: tableReadController,
@ -72,7 +79,7 @@ func NewModel(dispatcher *dispatcher.Dispatcher, commandController *commandctrl.
}
func (m uiModel) Init() tea.Cmd {
m.invokeOperation(context.Background(), m.tableReadController.Scan())
//m.invokeOperation(context.Background(), m.tableReadController.Scan())
return nil
}
@ -215,11 +222,13 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
updatedTable, tableMsgs := m.table.Update(msg)
updatedViewport, viewportMsgs := m.viewport.Update(msg)
updatedTableSelectModel, tableSelectMsgs := m.tableSelect.Update(msg)
m.table = updatedTable
m.viewport = updatedViewport
m.tableSelect = updatedTableSelectModel
return m, tea.Batch(textInputCommands, tableMsgs, viewportMsgs)
return m, tea.Batch(textInputCommands, tableMsgs, viewportMsgs, tableSelectMsgs)
}
func (m uiModel) invokeOperation(ctx context.Context, op uimodels.Operation) {
@ -233,27 +242,32 @@ func (m uiModel) invokeOperation(ctx context.Context, op uimodels.Operation) {
}
func (m uiModel) View() string {
if !m.ready {
return "Initializing"
}
// TEMP
return m.tableSelect.View()
/*
if !m.ready {
return "Initializing"
}
if m.pendingInput != nil {
return lipgloss.JoinVertical(lipgloss.Top,
m.headerView(),
m.table.View(),
m.splitterView(),
m.viewport.View(),
m.textInput.View(),
)
}
if m.pendingInput != nil {
return lipgloss.JoinVertical(lipgloss.Top,
m.headerView(),
m.table.View(),
m.splitterView(),
m.viewport.View(),
m.textInput.View(),
m.footerView(),
)
}
return lipgloss.JoinVertical(lipgloss.Top,
m.headerView(),
m.table.View(),
m.splitterView(),
m.viewport.View(),
m.footerView(),
)
*/
}
func (m uiModel) headerView() string {

View file

@ -0,0 +1,48 @@
package ui
import (
tea "github.com/charmbracelet/bubbletea"
"log"
)
// sizeWaitModel is a model which waits until the first screen size message comes through. It then creates the
// submodel and delegates calls to that model
type sizeWaitModel struct {
constr func(width, height int) tea.Model
model tea.Model
}
func newSizeWaitModel(constr func(width, height int) tea.Model) tea.Model {
return sizeWaitModel{constr: constr}
}
func (s sizeWaitModel) Init() tea.Cmd {
return nil
}
func (s sizeWaitModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch m := msg.(type) {
case tea.WindowSizeMsg:
log.Println("got window size message")
if s.model == nil {
log.Println("creating model")
s.model = s.constr(m.Width, m.Height)
s.model.Init()
}
}
var submodelCmds tea.Cmd
if s.model != nil {
log.Println("starting update")
s.model, submodelCmds = s.model.Update(msg)
log.Println("ending update")
}
return s, submodelCmds
}
func (s sizeWaitModel) View() string {
if s.model == nil {
return ""
}
return s.model.View()
}

View file

@ -0,0 +1,95 @@
package ui
import (
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var (
titleStyle = lipgloss.NewStyle().MarginLeft(2)
itemStyle = lipgloss.NewStyle().PaddingLeft(4)
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
helpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1)
quitTextStyle = lipgloss.NewStyle().Margin(1, 0, 2, 4)
)
type tableSelectModel struct {
list list.Model
}
func (t tableSelectModel) Init() tea.Cmd {
return nil
}
func (t tableSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
t.list.SetHeight(msg.Height)
t.list.SetWidth(msg.Width)
return t, nil
case tea.KeyMsg:
switch keypress := msg.String(); keypress {
case "ctrl+c":
return t, tea.Quit
case "enter":
//i, ok := m.list.SelectedItem().(item)
//if ok {
// m.choice = string(i)
//}
return t, tea.Quit
}
}
var cmd tea.Cmd
t.list, cmd = t.list.Update(msg)
return t, cmd
}
func (t tableSelectModel) View() string {
return t.list.View()
}
func newTableSelectModel(w, h int) tableSelectModel {
tableItems := []tableItem{
{name: "alpha"},
{name: "beta"},
{name: "gamma"},
}
items := toListItems(tableItems)
delegate := list.NewDefaultDelegate()
delegate.ShowDescription = false
return tableSelectModel{
list: list.New(items, delegate, w, h),
}
}
type tableItem struct {
name string
}
func (ti tableItem) FilterValue() string {
return ""
}
func (ti tableItem) Title() string {
return ti.name
}
func (ti tableItem) Description() string {
return "abc"
}
func toListItems[T list.Item](xs []T) []list.Item {
ls := make([]list.Item, len(xs))
for i, x := range xs {
ls[i] = x
}
return ls
}