From bcbb569536597d35e24007acf2fd5e945c65611d Mon Sep 17 00:00:00 2001 From: Toby Padilla Date: Tue, 10 Aug 2021 17:14:49 -0500 Subject: [PATCH] Allow for README templates --- git/git.go | 17 ++--- tui/bubble.go | 53 +++++---------- tui/bubbles/repo/bubble.go | 85 ++++++++++++++++++++++-- tui/{ => bubbles/repo}/viewport_patch.go | 2 +- tui/commands.go | 20 +++--- tui/defaults.go | 3 +- 6 files changed, 113 insertions(+), 67 deletions(-) rename tui/{ => bubbles/repo}/viewport_patch.go (97%) diff --git a/git/git.go b/git/git.go index 5858e9c30e10d333cb4cd20489e7274d2c5794b5..6de0807075ea653b9b89c033788e4d14fcf9d105 100644 --- a/git/git.go +++ b/git/git.go @@ -28,8 +28,6 @@ type RepoCommit struct { type CommitLog []RepoCommit -type ReadmeTransform func(string) string - 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 { @@ -37,19 +35,18 @@ func (cl CommitLog) Less(i, j int) bool { } type RepoSource struct { - Path string - mtx sync.Mutex - repos []*Repo - commits CommitLog - readmeTransform ReadmeTransform + Path string + mtx sync.Mutex + repos []*Repo + commits CommitLog } -func NewRepoSource(repoPath string, rf ReadmeTransform) *RepoSource { +func NewRepoSource(repoPath string) *RepoSource { err := os.MkdirAll(repoPath, os.ModeDir|os.FileMode(0700)) if err != nil { log.Fatal(err) } - rs := &RepoSource{Path: repoPath, readmeTransform: rf} + rs := &RepoSource{Path: repoPath} return rs } @@ -129,7 +126,7 @@ func (rs *RepoSource) loadRepo(name string, rg *git.Repository) (*Repo, error) { if err == nil { rmd, err := rf.Contents() if err == nil { - r.Readme = rs.readmeTransform(rmd) + r.Readme = rmd } } } diff --git a/tui/bubble.go b/tui/bubble.go index f6f1c021ea4c0c9a5d5cbc78ac2abc8eaa5a7d62..51109f08b1f5b99a14298d08cff1df132ecafd42 100644 --- a/tui/bubble.go +++ b/tui/bubble.go @@ -9,9 +9,7 @@ import ( "smoothie/tui/bubbles/selection" "time" - "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour" "github.com/charmbracelet/lipgloss" "github.com/gliderlabs/ssh" ) @@ -28,6 +26,7 @@ const ( type MenuEntry struct { Name string `json:"name"` + Note string `json:"note"` Repo string `json:"repo"` } @@ -45,20 +44,19 @@ type SessionConfig struct { } type Bubble struct { - config *Config - state sessionState - error string - width int - height int - windowChanges <-chan ssh.Window - repoSource *git.RepoSource - repoMenu []MenuEntry - repos []*git.Repo - boxes []tea.Model - activeBox int - repoSelect *selection.Bubble - commitsLog *commits.Bubble - readmeViewport *ViewportBubble + config *Config + state sessionState + error string + width int + height int + windowChanges <-chan ssh.Window + repoSource *git.RepoSource + repoMenu []MenuEntry + repos []*git.Repo + boxes []tea.Model + activeBox int + repoSelect *selection.Bubble + commitsLog *commits.Bubble } func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble { @@ -69,12 +67,6 @@ func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble { windowChanges: sCfg.WindowChanges, repoSource: cfg.RepoSource, boxes: make([]tea.Model, 2), - readmeViewport: &ViewportBubble{ - Viewport: &viewport.Model{ - Width: boxRightWidth - horizontalPadding - 2, - Height: sCfg.Height - verticalPadding - viewportHeightConstant, - }, - }, } b.state = startState return b @@ -149,21 +141,6 @@ func (b *Bubble) View() string { return appBoxStyle.Render(content) } -func glamourReadme(md string) string { - tr, err := glamour.NewTermRenderer( - glamour.WithAutoStyle(), - glamour.WithWordWrap(boxRightWidth-2), - ) - if err != nil { - log.Fatal(err) - } - mdt, err := tr.Render(md) - if err != nil { - return md - } - return mdt -} - func loadConfig(rs *git.RepoSource) (*Config, error) { cfg := &Config{} cfg.RepoSource = rs @@ -183,7 +160,7 @@ func loadConfig(rs *git.RepoSource) (*Config, error) { } func SessionHandler(reposPath string, repoPoll time.Duration) func(ssh.Session) (tea.Model, []tea.ProgramOption) { - rs := git.NewRepoSource(reposPath, glamourReadme) + rs := git.NewRepoSource(reposPath) err := createDefaultConfigRepo(rs) if err != nil { if err != nil { diff --git a/tui/bubbles/repo/bubble.go b/tui/bubbles/repo/bubble.go index 3d1f22da4d48b41eaa832b5e738084d9f0c87d3a..417ffc9b4b44dea31f59c7c84cd3a09ddb0ff8b1 100644 --- a/tui/bubbles/repo/bubble.go +++ b/tui/bubbles/repo/bubble.go @@ -1,22 +1,95 @@ package repo import ( + "bytes" + "smoothie/git" + "text/template" + + "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/go-git/go-git/v5" + "github.com/charmbracelet/glamour" ) +type ErrMsg struct { + Error error +} + type Bubble struct { - repo *git.Repository + templateObject interface{} + repoSource *git.RepoSource + name string + repo *git.Repo + readmeViewport *ViewportBubble +} + +func NewBubble(rs *git.RepoSource, name string, width int, height int, tmp interface{}) *Bubble { + return &Bubble{ + templateObject: tmp, + repoSource: rs, + name: name, + readmeViewport: &ViewportBubble{ + Viewport: &viewport.Model{ + Width: width, + Height: height, + }, + }, + } } func (b *Bubble) Init() tea.Cmd { - return nil + return b.setupCmd } -func (b *Bubble) Update(tea.Msg) (tea.Model, tea.Cmd) { - return nil, nil +func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + return b.readmeViewport.Update(msg) } func (b *Bubble) View() string { - return "repo" + return b.readmeViewport.View() +} + +func (b *Bubble) setupCmd() tea.Msg { + r, err := b.repoSource.GetRepo(b.name) + if err != nil { + return ErrMsg{err} + } + md := r.Readme + if b.templateObject != nil { + t, err := template.New("readme").Parse(md) + if err != nil { + return ErrMsg{err} + } + buf := &bytes.Buffer{} + err = t.Execute(buf, b.templateObject) + if err != nil { + return ErrMsg{err} + } + md = buf.String() + } + md, err = b.glamourize(md) + if err != nil { + return ErrMsg{err} + } + b.readmeViewport.Viewport.GotoTop() + b.readmeViewport.Viewport.SetContent(md) + return nil +} + +func (b *Bubble) templatize(t string) (string, error) { + return "", nil +} + +func (b *Bubble) glamourize(md string) (string, error) { + tr, err := glamour.NewTermRenderer( + glamour.WithAutoStyle(), + glamour.WithWordWrap(b.readmeViewport.Viewport.Width), + ) + if err != nil { + return "", err + } + mdt, err := tr.Render(md) + if err != nil { + return "", err + } + return mdt, nil } diff --git a/tui/viewport_patch.go b/tui/bubbles/repo/viewport_patch.go similarity index 97% rename from tui/viewport_patch.go rename to tui/bubbles/repo/viewport_patch.go index b924145a069d6c7765a15540d7c06b55e990084e..df176ebebe429decac912802b7e98c21476a8d64 100644 --- a/tui/viewport_patch.go +++ b/tui/bubbles/repo/viewport_patch.go @@ -1,4 +1,4 @@ -package tui +package repo import ( "github.com/charmbracelet/bubbles/viewport" diff --git a/tui/commands.go b/tui/commands.go index 0018e2b49b102348ff9fe287fc44cf4ab4d894cf..e82f2a0cb7082ac3aa86afe10c3c525b7774984f 100644 --- a/tui/commands.go +++ b/tui/commands.go @@ -2,6 +2,7 @@ package tui import ( "smoothie/tui/bubbles/commits" + "smoothie/tui/bubbles/repo" "smoothie/tui/bubbles/selection" tea "github.com/charmbracelet/bubbletea" @@ -57,16 +58,13 @@ func (b *Bubble) loadGitCmd() tea.Msg { } func (b *Bubble) getRepoCmd(name string) tea.Cmd { - return func() tea.Msg { - r, err := b.repoSource.GetRepo(name) - if err != nil { - return errMsg{err} - } - b.readmeViewport.Viewport.GotoTop() - b.readmeViewport.Viewport.Height = b.height - verticalPadding - viewportHeightConstant - b.readmeViewport.Viewport.Width = boxLeftWidth - 2 - b.readmeViewport.Viewport.SetContent(r.Readme) - b.boxes[1] = b.readmeViewport - return nil + var tmplConfig *Config + if name == "config" { + tmplConfig = b.config } + h := b.height - verticalPadding - viewportHeightConstant + w := boxRightWidth - 2 + rb := repo.NewBubble(b.repoSource, name, w, h, tmplConfig) + b.boxes[1] = rb + return rb.Init() } diff --git a/tui/defaults.go b/tui/defaults.go index b69c4bb99d1b96835abed8a20c7c017ea6ccf767..4d31c6c5157f4578bee167bfe94802f76493c521 100644 --- a/tui/defaults.go +++ b/tui/defaults.go @@ -17,7 +17,8 @@ const defaultConfig = `{ "menu": [ { "name": "Home", - "repo": "config" + "repo": "config", + "note": "Configuration and content repo" } ] }`