Skip to content

Commit

Permalink
List latest commits in bubble
Browse files Browse the repository at this point in the history
  • Loading branch information
Toby Padilla committed Jul 30, 2021
1 parent e938b1c commit e0eb757
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 14 deletions.
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
s, err := server.NewServer(
cfg.Port,
cfg.KeyPath,
bm.Middleware(tui.SessionHandler),
bm.Middleware(tui.SessionHandler(cfg.RepoPath)),
gm.Middleware(cfg.RepoPath, cfg.RepoAuthPath),
lm.Middleware(),
)
Expand Down
6 changes: 6 additions & 0 deletions tui/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ func (m *Model) windowChangesCmd() tea.Msg {
m.height = w.Height
return windowMsg{}
}

func (m *Model) getCommitsCmd() tea.Msg {
m.commits = m.repos.getCommits(20)
m.state = commitsLoadedState
return nil
}
77 changes: 77 additions & 0 deletions tui/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package tui

import (
"log"
"os"
"sort"
"sync"
"time"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)

type commitLog []*object.Commit

func (cl commitLog) Len() int { return len(cl) }
func (cl commitLog) Swap(i, j int) { cl[i], cl[j] = cl[j], cl[i] }
func (cl commitLog) Less(i, j int) bool { return cl[i].Author.When.After(cl[j].Author.When) }

type repoSource struct {
mtx sync.Mutex
path string
repos []*git.Repository
commits commitLog
}

func newRepoSource(repoPath string) *repoSource {
rs := &repoSource{path: repoPath}
go func() {
for {
rs.loadRepos()
time.Sleep(time.Second * 10)
}
}()
return rs
}

func (rs *repoSource) allRepos() []*git.Repository {
rs.mtx.Lock()
defer rs.mtx.Unlock()
return rs.repos
}

func (rs *repoSource) getCommits(limit int) []*object.Commit {
rs.mtx.Lock()
defer rs.mtx.Unlock()
if limit > len(rs.commits) {
limit = len(rs.commits)
}
return rs.commits[:limit]
}

func (rs *repoSource) loadRepos() {
rs.mtx.Lock()
defer rs.mtx.Unlock()
rd, err := os.ReadDir(rs.path)
if err != nil {
return
}
rs.repos = make([]*git.Repository, 0)
for _, rd := range rd {
r, err := git.PlainOpen(rs.path + string(os.PathSeparator) + rd.Name())
if err != nil {
log.Fatal(err)
}
l, err := r.Log(&git.LogOptions{All: true})
if err != nil {
log.Fatal(err)
}
l.ForEach(func(c *object.Commit) error {
rs.commits = append(rs.commits, c)
return nil
})
sort.Sort(rs.commits)
rs.repos = append(rs.repos, r)
}
}
36 changes: 26 additions & 10 deletions tui/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (

tea "github.com/charmbracelet/bubbletea"
"github.com/gliderlabs/ssh"
"github.com/go-git/go-git/v5/plumbing/object"
)

type sessionState int

const (
startState sessionState = iota
errorState
commitsLoadedState
quittingState
quitState
)
Expand All @@ -24,15 +26,18 @@ func (e errMsg) Error() string {
return e.err.Error()
}

func SessionHandler(s ssh.Session) (tea.Model, []tea.ProgramOption) {
if len(s.Command()) == 0 {
pty, changes, active := s.Pty()
if !active {
return nil, nil
func SessionHandler(repoPath string) func(ssh.Session) (tea.Model, []tea.ProgramOption) {
rs := newRepoSource(repoPath)
return func(s ssh.Session) (tea.Model, []tea.ProgramOption) {
if len(s.Command()) == 0 {
pty, changes, active := s.Pty()
if !active {
return nil, nil
}
return NewModel(pty.Window.Width, pty.Window.Height, changes, rs), nil
}
return NewModel(pty.Window.Width, pty.Window.Height, changes), []tea.ProgramOption{tea.WithAltScreen()}
return nil, nil
}
return nil, nil
}

type Model struct {
Expand All @@ -42,20 +47,24 @@ type Model struct {
width int
height int
windowChanges <-chan ssh.Window
repos *repoSource
commits []*object.Commit
}

func NewModel(width int, height int, windowChanges <-chan ssh.Window) *Model {
func NewModel(width int, height int, windowChanges <-chan ssh.Window, repos *repoSource) *Model {
m := &Model{
width: width,
height: height,
windowChanges: windowChanges,
repos: repos,
commits: make([]*object.Commit, 0),
}
m.state = startState
return m
}

func (m *Model) Init() tea.Cmd {
return tea.Batch(m.windowChangesCmd, tea.HideCursor)
return tea.Batch(m.windowChangesCmd, tea.HideCursor, m.getCommitsCmd)
}

func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
Expand Down Expand Up @@ -86,11 +95,18 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

func (m *Model) View() string {
pad := 6
h := headerStyle.Width(m.width - pad).Render("Smoothie")
h := headerStyle.Width(m.width - pad).Render("Charm Beta")
f := footerStyle.Render(m.info)
s := ""
content := ""
switch m.state {
case startState:
s += normalStyle.Render("Loading")
case commitsLoadedState:
for _, c := range m.commits {
msg := fmt.Sprintf("%s %s %s %s", c.Author.When, c.Author.Name, c.Author.Email, c.Message)
s += normalStyle.Render(msg) + "\n"
}
case errorState:
s += errorStyle.Render(fmt.Sprintf("Bummer: %s", m.error))
default:
Expand Down
3 changes: 0 additions & 3 deletions tui/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ var normalStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FFFFFF"))

var footerStyle = lipgloss.NewStyle().
BorderStyle(lipgloss.Border{Left: ">"}).
BorderForeground(lipgloss.Color("#6D6D6D")).
BorderLeft(true).
Foreground(lipgloss.Color("#373737")).
PaddingLeft(1).
MarginLeft(1).
Bold(true)

var errorStyle = lipgloss.NewStyle().
Expand Down

0 comments on commit e0eb757

Please sign in to comment.