Skip to content

Commit

Permalink
Upgrade termkit/skeleton to v0.2.0 and add GetRepositoryBranches func…
Browse files Browse the repository at this point in the history
…tionality with associated types and UI updates for branch selection.
  • Loading branch information
canack committed Jan 5, 2025
1 parent 0e11431 commit ac225e2
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 10 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/charmbracelet/lipgloss v1.0.0
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/termkit/skeleton v0.1.3
github.com/termkit/skeleton v0.2.0
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/termkit/skeleton v0.1.3 h1:XiCqLDQXhtU4LhrgDKYHaPFRumngLPs9ssebL8WXHVI=
github.com/termkit/skeleton v0.1.3/go.mod h1:KjHXehkpVm8i3pli9PTG+Lat2PrUBsw6QQe5kbgYXHs=
github.com/termkit/skeleton v0.2.0 h1:Nbs7i5+vsouK25Gl4+vuMB1/7jokZ77HN2wV1IYgpBQ=
github.com/termkit/skeleton v0.2.0/go.mod h1:KjHXehkpVm8i3pli9PTG+Lat2PrUBsw6QQe5kbgYXHs=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4=
Expand Down
1 change: 1 addition & 0 deletions internal/github/usecase/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
type UseCase interface {
GetAuthUser(ctx context.Context) (*GetAuthUserOutput, error)
ListRepositories(ctx context.Context, input ListRepositoriesInput) (*ListRepositoriesOutput, error)
GetRepositoryBranches(ctx context.Context, input GetRepositoryBranchesInput) (*GetRepositoryBranchesOutput, error)
GetWorkflowHistory(ctx context.Context, input GetWorkflowHistoryInput) (*GetWorkflowHistoryOutput, error)
GetTriggerableWorkflows(ctx context.Context, input GetTriggerableWorkflowsInput) (*GetTriggerableWorkflowsOutput, error)
InspectWorkflow(ctx context.Context, input InspectWorkflowInput) (*InspectWorkflowOutput, error)
Expand Down
17 changes: 17 additions & 0 deletions internal/github/usecase/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ type ListRepositoriesOutput struct {
Repositories []GithubRepository
}

// ------------------------------------------------------------

type GetRepositoryBranchesInput struct {
Repository string
}

type GetRepositoryBranchesOutput struct {
Branches []GithubBranch
}

type GithubBranch struct {
Name string
IsDefault bool
}

// ------------------------------------------------------------

type GithubRepository struct {
Name string
Private bool
Expand Down
36 changes: 36 additions & 0 deletions internal/github/usecase/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,42 @@ func (u useCase) ListRepositories(ctx context.Context, input ListRepositoriesInp
}, errors.Join(resultErrs...)
}

func (u useCase) GetRepositoryBranches(ctx context.Context, input GetRepositoryBranchesInput) (*GetRepositoryBranchesOutput, error) {
// Get Repository to get the default branch
repository, err := u.githubRepository.GetRepository(ctx, input.Repository)
if err != nil {
return nil, err
}

var mainBranch = repository.DefaultBranch

branches, err := u.githubRepository.ListBranches(ctx, input.Repository)
if err != nil {
return nil, err
}

if len(branches) == 0 {
return &GetRepositoryBranchesOutput{}, nil
}

var result = []GithubBranch{
{
Name: mainBranch,
IsDefault: true,
},
}

for _, branch := range branches {
result = append(result, GithubBranch{
Name: branch.Name,
})
}

return &GetRepositoryBranchesOutput{
Branches: result,
}, nil
}

func (u useCase) workerListRepositories(ctx context.Context, repository gr.GithubRepository, results chan<- GithubRepository, errs chan<- error) {
getWorkflows, err := u.githubRepository.GetWorkflows(ctx, repository.FullName)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions internal/terminal/handler/ghrepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,18 @@ func (m *ModelGithubRepository) handleTableInputs(_ context.Context) {
if len(selectedRow) > 0 && selectedRow[0] != "" {
m.selectedRepository.RepositoryName = selectedRow[0]
m.selectedRepository.BranchName = selectedRow[1]

workflowCount := selectedRow[3]
if workflowCount != "" {
count, _ := strconv.Atoi(workflowCount)
if count == 0 {
m.skeleton.LockTab("workflow")
m.skeleton.LockTab("trigger")
} else {
m.skeleton.UnlockTab("workflow")
m.skeleton.UnlockTab("trigger")
}
}
}
}

Expand Down
116 changes: 108 additions & 8 deletions internal/terminal/handler/ghworkflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import (
"context"
"errors"
"fmt"
"github.com/termkit/skeleton"
"sort"
"strings"

"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/table"
"github.com/charmbracelet/bubbles/textinput"
"github.com/termkit/gama/internal/terminal/handler/status"
hdltypes "github.com/termkit/gama/internal/terminal/handler/types"
"github.com/termkit/skeleton"
"sort"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
Expand All @@ -25,6 +25,7 @@ type ModelGithubWorkflow struct {
cancelSyncTriggerableWorkflows context.CancelFunc
tableReady bool
lastRepository string
mainBranch string

// shared properties
selectedRepository *hdltypes.SelectedRepository
Expand All @@ -39,6 +40,7 @@ type ModelGithubWorkflow struct {
help help.Model
tableTriggerableWorkflow table.Model
status *status.ModelStatus
textInput textinput.Model
}

func SetupModelGithubWorkflow(sk *skeleton.Skeleton, githubUseCase gu.UseCase) *ModelGithubWorkflow {
Expand All @@ -63,6 +65,21 @@ func SetupModelGithubWorkflow(sk *skeleton.Skeleton, githubUseCase gu.UseCase) *
Bold(false)
tableTriggerableWorkflow.SetStyles(s)

tableTriggerableWorkflow.KeyMap = table.KeyMap{
LineUp: key.NewBinding(
key.WithKeys("up"),
),
LineDown: key.NewBinding(
key.WithKeys("down"),
),
}

ti := textinput.New()
ti.Focus()
ti.CharLimit = 128
ti.Placeholder = "Type to switch branch"
ti.ShowSuggestions = true

modelStatus := status.SetupModelStatus(sk)

return &ModelGithubWorkflow{
Expand All @@ -75,6 +92,7 @@ func SetupModelGithubWorkflow(sk *skeleton.Skeleton, githubUseCase gu.UseCase) *
selectedRepository: hdltypes.NewSelectedRepository(),
syncTriggerableWorkflowsContext: context.Background(),
cancelSyncTriggerableWorkflows: func() {},
textInput: ti,
}
}

Expand All @@ -92,10 +110,38 @@ func (m *ModelGithubWorkflow) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.syncTriggerableWorkflowsContext, m.cancelSyncTriggerableWorkflows = context.WithCancel(context.Background())

m.lastRepository = m.selectedRepository.RepositoryName
m.mainBranch = m.selectedRepository.BranchName

go m.syncTriggerableWorkflows(m.syncTriggerableWorkflowsContext)
go m.syncBranches(m.syncTriggerableWorkflowsContext)
}

var selectedBranch = m.textInput.Value()
if selectedBranch != "" {
var isBranchExist bool
for _, branch := range m.textInput.AvailableSuggestions() {
if branch == selectedBranch {
isBranchExist = true
m.selectedRepository.BranchName = selectedBranch
break
}
}

if !isBranchExist {
m.status.SetErrorMessage(fmt.Sprintf("Branch %s is not exist", selectedBranch))
m.skeleton.LockTabsToTheRight()
} else {
m.skeleton.UnlockTabs()
}
}
if selectedBranch == "" {
m.selectedRepository.BranchName = m.mainBranch
m.skeleton.UnlockTabs()
}

m.textInput, cmd = m.textInput.Update(msg)
cmds = append(cmds, cmd)

m.tableTriggerableWorkflow, cmd = m.tableTriggerableWorkflow.Update(msg)
cmds = append(cmds, cmd)

Expand Down Expand Up @@ -127,11 +173,28 @@ func (m *ModelGithubWorkflow) View() string {
m.tableTriggerableWorkflow.SetHeight(termHeight - 17)
}

doc := strings.Builder{}
doc.WriteString(style.Render(m.tableTriggerableWorkflow.View()))
doc.WriteString("\n\n\n")
return lipgloss.JoinVertical(lipgloss.Top,
style.Render(m.tableTriggerableWorkflow.View()),
m.viewSearchBar(),
m.status.View(),
helpWindowStyle.Render(m.ViewHelp()),
)
}

func (m *ModelGithubWorkflow) viewSearchBar() string {
// Define window style
windowStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("#3b698f")).
Padding(0, 1).
Width(m.skeleton.GetTerminalWidth() - 6).MarginLeft(1)

if len(m.textInput.AvailableSuggestions()) > 0 && m.textInput.Value() == "" {
var mainBranch = m.mainBranch
m.textInput.Placeholder = "Type to switch branch (default: " + mainBranch + ")"
}

return lipgloss.JoinVertical(lipgloss.Top, doc.String(), m.status.View(), helpWindowStyle.Render(m.ViewHelp()))
return windowStyle.Render(m.textInput.View())
}

func (m *ModelGithubWorkflow) syncTriggerableWorkflows(ctx context.Context) {
Expand Down Expand Up @@ -175,10 +238,47 @@ func (m *ModelGithubWorkflow) syncTriggerableWorkflows(ctx context.Context) {

m.tableTriggerableWorkflow.SetRows(tableRowsTriggerableWorkflow)

if len(tableRowsTriggerableWorkflow) > 0 {
m.tableTriggerableWorkflow.SetCursor(0)
}

m.tableReady = true
m.status.SetSuccessMessage(fmt.Sprintf("[%s@%s] Triggerable workflows fetched.", m.selectedRepository.RepositoryName, m.selectedRepository.BranchName))
}

func (m *ModelGithubWorkflow) syncBranches(ctx context.Context) {
defer m.skeleton.TriggerUpdate()

m.status.Reset()
m.status.SetProgressMessage(fmt.Sprintf("[%s] Fetching branches...", m.selectedRepository.RepositoryName))

branches, err := m.github.GetRepositoryBranches(ctx, gu.GetRepositoryBranchesInput{
Repository: m.selectedRepository.RepositoryName,
})
if errors.Is(err, context.Canceled) {
return
} else if err != nil {
m.status.SetError(err)
m.status.SetErrorMessage("Branches cannot be listed")
return
}

if branches == nil || len(branches.Branches) == 0 {
m.selectedRepository.BranchName = ""
m.status.SetDefaultMessage(fmt.Sprintf("[%s] No branches found.", m.selectedRepository.RepositoryName))
return
}

var bs = make([]string, len(branches.Branches))
for i, branch := range branches.Branches {
bs[i] = branch.Name
}

m.textInput.SetSuggestions(bs)

m.status.SetSuccessMessage(fmt.Sprintf("[%s] Branches fetched.", m.selectedRepository.RepositoryName))
}

func (m *ModelGithubWorkflow) handleTableInputs(_ context.Context) {
if !m.tableReady {
return
Expand Down
2 changes: 1 addition & 1 deletion internal/terminal/handler/ghworkflowhistory.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ func (m *ModelGithubWorkflowHistory) syncWorkflowHistory(ctx context.Context) {

if len(workflowHistory.Workflows) == 0 {
m.modelTabOptions.SetStatus(taboptions.OptionNone)
m.status.SetDefaultMessage(fmt.Sprintf("[%s@%s] No workflows found.", m.selectedRepository.RepositoryName, m.selectedRepository.BranchName))
m.status.SetDefaultMessage(fmt.Sprintf("[%s@%s] No workflow history found.", m.selectedRepository.RepositoryName, m.selectedRepository.BranchName))
return
}

Expand Down

0 comments on commit ac225e2

Please sign in to comment.