Diff
1diff --git a/git/git.go b/git/git.go
2index 80d8c88c384c856d866477026d31a90d53aa6d92..7293c0694eafd737714283b44d9f29c369f3bd6b 100644
3--- a/git/git.go
4+++ b/git/git.go
5@@ -11,9 +11,15 @@ import (
6 "github.com/go-git/go-git/v5/plumbing/object"
7 )
8
9+type Repo struct {
10+ Name string
11+ Repository *git.Repository
12+ Readme string
13+ LastUpdated *time.Time
14+}
15+
16 type RepoCommit struct {
17 Name string
18- Repo *git.Repository
19 Commit *object.Commit
20 }
21
22@@ -28,22 +34,22 @@ func (cl CommitLog) Less(i, j int) bool {
23 type RepoSource struct {
24 mtx sync.Mutex
25 path string
26- repos []*git.Repository
27+ repos []*Repo
28 commits CommitLog
29 }
30
31-func NewRepoSource(repoPath string) *RepoSource {
32+func NewRepoSource(repoPath string, poll time.Duration) *RepoSource {
33 rs := &RepoSource{path: repoPath}
34 go func() {
35 for {
36 rs.loadRepos()
37- time.Sleep(time.Second * 10)
38+ time.Sleep(poll)
39 }
40 }()
41 return rs
42 }
43
44-func (rs *RepoSource) AllRepos() []*git.Repository {
45+func (rs *RepoSource) AllRepos() []*Repo {
46 rs.mtx.Lock()
47 defer rs.mtx.Unlock()
48 return rs.repos
49@@ -65,19 +71,25 @@ func (rs *RepoSource) loadRepos() {
50 if err != nil {
51 return
52 }
53- rs.repos = make([]*git.Repository, 0)
54+ rs.repos = make([]*Repo, 0)
55 rs.commits = make([]RepoCommit, 0)
56- for _, rd := range rd {
57- r, err := git.PlainOpen(rs.path + string(os.PathSeparator) + rd.Name())
58+ for _, de := range rd {
59+ rn := de.Name()
60+ r := &Repo{Name: rn}
61+ rg, err := git.PlainOpen(rs.path + string(os.PathSeparator) + rn)
62 if err != nil {
63 log.Fatal(err)
64 }
65- l, err := r.Log(&git.LogOptions{All: true})
66+ r.Repository = rg
67+ l, err := rg.Log(&git.LogOptions{All: true})
68 if err != nil {
69 log.Fatal(err)
70 }
71 l.ForEach(func(c *object.Commit) error {
72- rs.commits = append(rs.commits, RepoCommit{Name: rd.Name(), Repo: r, Commit: c})
73+ if r.LastUpdated == nil {
74+ r.LastUpdated = &c.Author.When
75+ }
76+ rs.commits = append(rs.commits, RepoCommit{Name: rn, Commit: c})
77 return nil
78 })
79 sort.Sort(rs.commits)
80diff --git a/tui/bubble.go b/tui/bubble.go
81index 2f5b45bb343330cd47185912a8d5acbb8f085319..538fc1ac1c4448a462012f3a65c61f67662d5bd2 100644
82--- a/tui/bubble.go
83+++ b/tui/bubble.go
84@@ -4,6 +4,7 @@ import (
85 "fmt"
86 "smoothie/git"
87 "smoothie/tui/bubbles/commits"
88+ "time"
89
90 tea "github.com/charmbracelet/bubbletea"
91 "github.com/gliderlabs/ssh"
92@@ -19,28 +20,6 @@ const (
93 quitState
94 )
95
96-type stateMsg struct{ state sessionState }
97-type infoMsg struct{ text string }
98-type errMsg struct{ err error }
99-
100-func (e errMsg) Error() string {
101- return e.err.Error()
102-}
103-
104-func SessionHandler(reposPath string) func(ssh.Session) (tea.Model, []tea.ProgramOption) {
105- rs := git.NewRepoSource(reposPath)
106- return func(s ssh.Session) (tea.Model, []tea.ProgramOption) {
107- if len(s.Command()) == 0 {
108- pty, changes, active := s.Pty()
109- if !active {
110- return nil, nil
111- }
112- return NewModel(pty.Window.Width, pty.Window.Height, changes, rs), []tea.ProgramOption{tea.WithAltScreen()}
113- }
114- return nil, nil
115- }
116-}
117-
118 type Model struct {
119 state sessionState
120 error string
121@@ -64,7 +43,7 @@ func NewModel(width int, height int, windowChanges <-chan ssh.Window, repoSource
122 }
123
124 func (m *Model) Init() tea.Cmd {
125- return tea.Batch(m.windowChangesCmd, m.getCommitsCmd)
126+ return tea.Batch(m.windowChangesCmd, m.loadGitCmd)
127 }
128
129 func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
130@@ -114,3 +93,17 @@ func (m *Model) View() string {
131 content = h + "\n" + s + "\n" + f
132 return appBoxStyle.Render(content)
133 }
134+
135+func SessionHandler(reposPath string) func(ssh.Session) (tea.Model, []tea.ProgramOption) {
136+ rs := git.NewRepoSource(reposPath, time.Second*10)
137+ return func(s ssh.Session) (tea.Model, []tea.ProgramOption) {
138+ if len(s.Command()) == 0 {
139+ pty, changes, active := s.Pty()
140+ if !active {
141+ return nil, nil
142+ }
143+ return NewModel(pty.Window.Width, pty.Window.Height, changes, rs), []tea.ProgramOption{tea.WithAltScreen()}
144+ }
145+ return nil, nil
146+ }
147+}
148diff --git a/tui/commands.go b/tui/commands.go
149index 7189ed70236ee73eb15805add4e10373f535169f..e26b9564acd3f358abdb8553210811b13543d572 100644
150--- a/tui/commands.go
151+++ b/tui/commands.go
152@@ -6,7 +6,14 @@ import (
153 tea "github.com/charmbracelet/bubbletea"
154 )
155
156+type stateMsg struct{ state sessionState }
157+type infoMsg struct{ text string }
158 type windowMsg struct{}
159+type errMsg struct{ err error }
160+
161+func (e errMsg) Error() string {
162+ return e.err.Error()
163+}
164
165 func (m *Model) windowChangesCmd() tea.Msg {
166 w := <-m.windowChanges
167@@ -15,7 +22,7 @@ func (m *Model) windowChangesCmd() tea.Msg {
168 return windowMsg{}
169 }
170
171-func (m *Model) getCommitsCmd() tea.Msg {
172+func (m *Model) loadGitCmd() tea.Msg {
173 m.commitTimeline = commits.NewBubble(m.height, 2, 80, m.repoSource.GetCommits(200))
174 m.state = loadedState
175 return nil