From 269e53ed74ec883855af807333442f2ec947aaf2 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Wed, 31 Jan 2024 08:57:28 -0800 Subject: [PATCH] Add model list subcommand --- internal/cmd/model/list.go | 130 +++++++++++++++++++++++++++++++++++++ internal/cmd/model/root.go | 1 + 2 files changed, 131 insertions(+) create mode 100644 internal/cmd/model/list.go diff --git a/internal/cmd/model/list.go b/internal/cmd/model/list.go new file mode 100644 index 0000000..7f534f5 --- /dev/null +++ b/internal/cmd/model/list.go @@ -0,0 +1,130 @@ +package model + +import ( + "encoding/json" + "fmt" + "os/exec" + + "github.com/replicate/cli/internal/client" + "github.com/replicate/cli/internal/util" + "github.com/spf13/cobra" + + "github.com/charmbracelet/bubbles/table" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +var baseStyle = lipgloss.NewStyle(). + BorderStyle(lipgloss.NormalBorder()). + BorderForeground(lipgloss.Color("240")) + +type model struct { + table table.Model +} + +func (m model) Init() tea.Cmd { return nil } + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "esc": + if m.table.Focused() { + m.table.Blur() + } else { + m.table.Focus() + } + case "q", "ctrl+c": + return m, tea.Quit + case "enter": + selected := m.table.SelectedRow() + if len(selected) == 0 { + return m, nil + } + url := fmt.Sprintf("https://replicate.com/%s", selected[0]) + return m, tea.ExecProcess(exec.Command("open", url), nil) + } + } + m.table, cmd = m.table.Update(msg) + return m, cmd +} + +func (m model) View() string { + return baseStyle.Render(m.table.View()) + "\n" +} + +var listCmd = &cobra.Command{ + Use: "list", + Short: "List models", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + r8, err := client.NewClient() + if err != nil { + return err + } + + models, err := r8.ListModels(ctx) + if err != nil { + return fmt.Errorf("failed to get predictions: %w", err) + } + + if cmd.Flags().Changed("json") || !util.IsTTY() { + bytes, err := json.MarshalIndent(models, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal predictions: %w", err) + } + fmt.Println(string(bytes)) + return nil + } + + columns := []table.Column{ + {Title: "Name", Width: 20}, + {Title: "Description", Width: 60}, + } + + rows := []table.Row{} + + for _, model := range models.Results { + rows = append(rows, table.Row{ + model.Owner + "/" + model.Name, + model.Description, + }) + } + + t := table.New( + table.WithColumns(columns), + table.WithRows(rows), + table.WithFocused(true), + table.WithHeight(30), + ) + + s := table.DefaultStyles() + s.Header = s.Header. + BorderStyle(lipgloss.NormalBorder()). + BorderForeground(lipgloss.Color("240")). + BorderBottom(true). + Bold(false) + s.Selected = s.Selected. + Foreground(lipgloss.Color("229")). + Background(lipgloss.Color("57")). + Bold(false) + t.SetStyles(s) + + m := model{t} + if _, err := tea.NewProgram(m).Run(); err != nil { + return err + } + + return nil + }, +} + +func init() { + addListFlags(listCmd) +} + +func addListFlags(cmd *cobra.Command) { + cmd.Flags().Bool("json", false, "Emit JSON") +} diff --git a/internal/cmd/model/root.go b/internal/cmd/model/root.go index c945365..d19b9c8 100644 --- a/internal/cmd/model/root.go +++ b/internal/cmd/model/root.go @@ -16,6 +16,7 @@ func init() { Title: "Subcommands:", }) for _, cmd := range []*cobra.Command{ + listCmd, showCmd, schemaCmd, createCmd,