diff --git a/git/git.go b/git/git.go index 80d8c88c384c856d866477026d31a90d53aa6d92..7293c0694eafd737714283b44d9f29c369f3bd6b 100644 --- a/git/git.go +++ b/git/git.go @@ -11,9 +11,15 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" ) +type Repo struct { + Name string + Repository *git.Repository + Readme string + LastUpdated *time.Time +} + type RepoCommit struct { Name string - Repo *git.Repository Commit *object.Commit } @@ -28,22 +34,22 @@ func (cl CommitLog) Less(i, j int) bool { type RepoSource struct { mtx sync.Mutex path string - repos []*git.Repository + repos []*Repo commits CommitLog } -func NewRepoSource(repoPath string) *RepoSource { +func NewRepoSource(repoPath string, poll time.Duration) *RepoSource { rs := &RepoSource{path: repoPath} go func() { for { rs.loadRepos() - time.Sleep(time.Second * 10) + time.Sleep(poll) } }() return rs } -func (rs *RepoSource) AllRepos() []*git.Repository { +func (rs *RepoSource) AllRepos() []*Repo { rs.mtx.Lock() defer rs.mtx.Unlock() return rs.repos @@ -65,19 +71,25 @@ func (rs *RepoSource) loadRepos() { if err != nil { return } - rs.repos = make([]*git.Repository, 0) + rs.repos = make([]*Repo, 0) rs.commits = make([]RepoCommit, 0) - for _, rd := range rd { - r, err := git.PlainOpen(rs.path + string(os.PathSeparator) + rd.Name()) + for _, de := range rd { + rn := de.Name() + r := &Repo{Name: rn} + rg, err := git.PlainOpen(rs.path + string(os.PathSeparator) + rn) if err != nil { log.Fatal(err) } - l, err := r.Log(&git.LogOptions{All: true}) + r.Repository = rg + l, err := rg.Log(&git.LogOptions{All: true}) if err != nil { log.Fatal(err) } l.ForEach(func(c *object.Commit) error { - rs.commits = append(rs.commits, RepoCommit{Name: rd.Name(), Repo: r, Commit: c}) + if r.LastUpdated == nil { + r.LastUpdated = &c.Author.When + } + rs.commits = append(rs.commits, RepoCommit{Name: rn, Commit: c}) return nil }) sort.Sort(rs.commits) diff --git a/tui/bubble.go b/tui/bubble.go index 2f5b45bb343330cd47185912a8d5acbb8f085319..538fc1ac1c4448a462012f3a65c61f67662d5bd2 100644 --- a/tui/bubble.go +++ b/tui/bubble.go @@ -4,6 +4,7 @@ import ( "fmt" "smoothie/git" "smoothie/tui/bubbles/commits" + "time" tea "github.com/charmbracelet/bubbletea" "github.com/gliderlabs/ssh" @@ -19,28 +20,6 @@ const ( quitState ) -type stateMsg struct{ state sessionState } -type infoMsg struct{ text string } -type errMsg struct{ err error } - -func (e errMsg) Error() string { - return e.err.Error() -} - -func SessionHandler(reposPath string) func(ssh.Session) (tea.Model, []tea.ProgramOption) { - rs := git.NewRepoSource(reposPath) - 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), []tea.ProgramOption{tea.WithAltScreen()} - } - return nil, nil - } -} - type Model struct { state sessionState error string @@ -64,7 +43,7 @@ func NewModel(width int, height int, windowChanges <-chan ssh.Window, repoSource } func (m *Model) Init() tea.Cmd { - return tea.Batch(m.windowChangesCmd, m.getCommitsCmd) + return tea.Batch(m.windowChangesCmd, m.loadGitCmd) } func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -114,3 +93,17 @@ func (m *Model) View() string { content = h + "\n" + s + "\n" + f return appBoxStyle.Render(content) } + +func SessionHandler(reposPath string) func(ssh.Session) (tea.Model, []tea.ProgramOption) { + rs := git.NewRepoSource(reposPath, time.Second*10) + 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), []tea.ProgramOption{tea.WithAltScreen()} + } + return nil, nil + } +} diff --git a/tui/commands.go b/tui/commands.go index 7189ed70236ee73eb15805add4e10373f535169f..e26b9564acd3f358abdb8553210811b13543d572 100644 --- a/tui/commands.go +++ b/tui/commands.go @@ -6,7 +6,14 @@ import ( tea "github.com/charmbracelet/bubbletea" ) +type stateMsg struct{ state sessionState } +type infoMsg struct{ text string } type windowMsg struct{} +type errMsg struct{ err error } + +func (e errMsg) Error() string { + return e.err.Error() +} func (m *Model) windowChangesCmd() tea.Msg { w := <-m.windowChanges @@ -15,7 +22,7 @@ func (m *Model) windowChangesCmd() tea.Msg { return windowMsg{} } -func (m *Model) getCommitsCmd() tea.Msg { +func (m *Model) loadGitCmd() tea.Msg { m.commitTimeline = commits.NewBubble(m.height, 2, 80, m.repoSource.GetCommits(200)) m.state = loadedState return nil