Skip to content

Commit

Permalink
Add missing 📁
Browse files Browse the repository at this point in the history
  • Loading branch information
adam committed Dec 21, 2022
1 parent 98ef4a2 commit db3556e
Show file tree
Hide file tree
Showing 17 changed files with 517 additions and 0 deletions.
5 changes: 5 additions & 0 deletions messages/authenticationErrorMsg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package messages

type AuthenticationErrorMsg struct {
Err error
}
7 changes: 7 additions & 0 deletions messages/authenticationMsg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package messages

import "github.com/admcpr/hub-bub/structs"

type AuthenticationMsg struct {
User structs.User
}
3 changes: 3 additions & 0 deletions messages/errMsg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package messages

type ErrMsg struct{ Err error }
7 changes: 7 additions & 0 deletions messages/orgListMsg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package messages

import "github.com/admcpr/hub-bub/structs"

type OrgListMsg struct {
Organisations []structs.Organisation
}
7 changes: 7 additions & 0 deletions messages/repositoryListMsg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package messages

import "github.com/admcpr/hub-bub/queries"

type RepositoryListMsg struct {
OrganizationQuery queries.OrganizationQuery
}
16 changes: 16 additions & 0 deletions models/mainModel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package models

import tea "github.com/charmbracelet/bubbletea"

/*
Model management
Need to replace this with the a MainModel, see nested models youtube
*/
type modelName int

var MainModel []tea.Model

const (
UserModelName modelName = iota
OrganisationModelName
)
160 changes: 160 additions & 0 deletions models/organisationModel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package models

import (
"log"

"github.com/admcpr/hub-bub/messages"
"github.com/admcpr/hub-bub/queries"
"github.com/admcpr/hub-bub/structs"
"github.com/admcpr/hub-bub/utils"
"github.com/charmbracelet/bubbles/table"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/cli/go-gh"
graphql "github.com/cli/shurcooL-graphql"
)

/* Repository model */
type OrganisationModel struct {
Title string
Url string
RepositoryTable table.Model
}

func (m OrganisationModel) Init() tea.Cmd {
return nil
}

func (m OrganisationModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

switch msg := msg.(type) {

case messages.RepositoryListMsg:
// m.RepositoryTable = buildRepositoryTable(msg.Repositories)
m.RepositoryTable = buildRepositoryTable(msg.OrganizationQuery)
return m, nil

case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "enter", " ":
return m, tea.Batch(
tea.Printf("Let's go to %s!", m.RepositoryTable.SelectedRow()[1]),
)
case "esc":
return MainModel[UserModelName], nil
}
}

m.RepositoryTable, cmd = m.RepositoryTable.Update(msg)

return m, cmd
}

// View implements tea.Model
func (m OrganisationModel) View() string {
return utils.BaseStyle.Render(m.RepositoryTable.View()) + "\n"
}

func (m OrganisationModel) GetRepositories() tea.Msg {
client, err := gh.GQLClient(nil)
if err != nil {
return messages.AuthenticationErrorMsg{Err: err}
}

var organizationQuery = queries.OrganizationQuery{}

variables := map[string]interface{}{
"login": graphql.String(m.Title),
"first": graphql.Int(30),
}
err = client.Query("OrganizationRepositories", &organizationQuery, variables)
if err != nil {
log.Fatal(err)
}

return messages.RepositoryListMsg{OrganizationQuery: organizationQuery}
}

func buildOrganisationTable(organisations []structs.Organisation) table.Model {
columns := []table.Column{
{Title: "Login", Width: 20},
{Title: "Url", Width: 80},
}

rows := make([]table.Row, len(organisations))
for i, org := range organisations {
rows[i] = table.Row{org.Login, org.Url}
}

t := table.New(
table.WithColumns(columns),
table.WithRows(rows),
table.WithFocused(true),
table.WithHeight(len(organisations)),
)

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)

return t
}

func buildRepositoryTable(organizationQuery queries.OrganizationQuery) table.Model {
columns := []table.Column{
{Title: "Name", Width: 20},
{Title: "Issues", Width: 10},
{Title: "Wiki", Width: 10},
{Title: "Projects", Width: 10},
{Title: "Rebase Merge", Width: 10},
{Title: "Auto Merge", Width: 10},
{Title: "Delete Branch On Merge", Width: 10},
}

edges := organizationQuery.Organization.Repositories.Edges

rows := make([]table.Row, len(edges))
for i, repo := range edges {
rows[i] = table.Row{
repo.Node.Name,
utils.YesNo(repo.Node.HasIssuesEnabled),
utils.YesNo(repo.Node.HasWikiEnabled),
utils.YesNo(repo.Node.HasProjectsEnabled),
utils.YesNo(repo.Node.RebaseMergeAllowed),
utils.YesNo(repo.Node.AutoMergeAllowed),
utils.YesNo(repo.Node.DeleteBranchOnMerge),
}
}

t := table.New(
table.WithColumns(columns),
table.WithRows(rows),
table.WithFocused(true),
table.WithHeight(len(edges)),
)

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)

return t
}
35 changes: 35 additions & 0 deletions models/organisationModel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package models

import (
"reflect"
"testing"

tea "github.com/charmbracelet/bubbletea"
)

func TestOrganisationModel_Update(t *testing.T) {
type args struct {
msg tea.Msg
}
tests := []struct {
name string
m OrganisationModel
args args
wantModel tea.Model
wantCmd tea.Cmd
}{
// TODO: Add more test cases.
{"Quit KeyMsg", OrganisationModel{}, args{tea.KeyMsg{Type: tea.KeyCtrlC}}, OrganisationModel{}, tea.Quit},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotModel, gotCmd := tt.m.Update(tt.args.msg)
if !reflect.DeepEqual(gotModel, tt.wantModel) {
t.Errorf("OrganisationModel.Update() gotModel = %v, want %v", gotModel, tt.wantModel)
}
if reflect.ValueOf(gotCmd) != reflect.ValueOf(tt.wantCmd) {
t.Errorf("OrganisationModel.Update() gotCmd = %v, want %v", gotCmd, tt.wantCmd)
}
})
}
}
110 changes: 110 additions & 0 deletions models/userModel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package models

import (
"fmt"

"github.com/admcpr/hub-bub/messages"
"github.com/admcpr/hub-bub/structs"
"github.com/admcpr/hub-bub/utils"
"github.com/cli/go-gh"

"github.com/charmbracelet/bubbles/table"
tea "github.com/charmbracelet/bubbletea"
)

type UserModel struct {
Authenticated bool
User structs.User
SelectedOrgUrl string
OrganisationTable table.Model
}

func (m UserModel) Init() tea.Cmd {
return checkLoginStatus
}

func (m UserModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

switch msg := msg.(type) {

case messages.AuthenticationMsg:
m.Authenticated = true
m.User = msg.User
return m, getOrganisations

case messages.AuthenticationErrorMsg:
m.Authenticated = false
return m, nil

case messages.OrgListMsg:
m.OrganisationTable = buildOrganisationTable(msg.Organisations)
return m, nil

case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "enter", " ":
MainModel[UserModelName] = m
orgModel := &OrganisationModel{
Title: m.OrganisationTable.SelectedRow()[0],
Url: m.OrganisationTable.SelectedRow()[1],
}

MainModel[OrganisationModelName] = orgModel

return orgModel, orgModel.GetRepositories
}
}

m.OrganisationTable, cmd = m.OrganisationTable.Update(msg)

return m, cmd
}

func (m UserModel) View() string {
s := fmt.Sprintln("Press q to quit.")

if !m.Authenticated {
return fmt.Sprintln("You are not authenticated try running `gh auth login`")
}

s += fmt.Sprintf("Hello %s, press Enter to select an organisation.\n", m.User.Name)
s += utils.BaseStyle.Render(m.OrganisationTable.View()) + "\n"

return s
}

func checkLoginStatus() tea.Msg {
// Use an API helper to grab repository tags
client, err := gh.RESTClient(nil)
if err != nil {
return messages.AuthenticationErrorMsg{Err: err}
}
response := structs.User{}

err = client.Get("user", &response)
if err != nil {
fmt.Println(err)
return messages.AuthenticationErrorMsg{Err: err}
}

return messages.AuthenticationMsg{User: response}
}

func getOrganisations() tea.Msg {
client, err := gh.RESTClient(nil)
if err != nil {
return messages.AuthenticationErrorMsg{Err: err}
}
response := []structs.Organisation{}

err = client.Get("user/orgs", &response)
if err != nil {
fmt.Println(err)
return messages.ErrMsg{Err: err}
}

return messages.OrgListMsg{Organisations: response}
}
39 changes: 39 additions & 0 deletions models/userModel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package models

import (
"reflect"
"testing"

messages "github.com/admcpr/hub-bub/messages"
structs "github.com/admcpr/hub-bub/structs"
tea "github.com/charmbracelet/bubbletea"
)

func TestUserModel_Update(t *testing.T) {
testUser := structs.User{Login: "test"}
type args struct {
msg tea.Msg
}
tests := []struct {
name string
m UserModel
args args
wantModel tea.Model
wantCmd tea.Cmd
}{
// TODO: Add test cases.
{"Authentication Success", UserModel{}, args{messages.AuthenticationMsg{User: testUser}}, UserModel{Authenticated: true, User: testUser}, getOrganisations},
{"Authentication Failure", UserModel{}, args{messages.AuthenticationErrorMsg{}}, UserModel{Authenticated: false}, nil},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotModel, gotCmd := tt.m.Update(tt.args.msg)
if !reflect.DeepEqual(gotModel, tt.wantModel) {
t.Errorf("UserModel.Update() gotModel = %v, want %v", gotModel, tt.wantModel)
}
if reflect.ValueOf(gotCmd) != reflect.ValueOf(tt.wantCmd) {
t.Errorf("UserModel.Update() gotCmd = %v, want %v", gotCmd, tt.wantCmd)
}
})
}
}
Loading

0 comments on commit db3556e

Please sign in to comment.