Skip to content

Commit

Permalink
Break out loader from project
Browse files Browse the repository at this point in the history
  • Loading branch information
sourishkrout committed Sep 20, 2023
1 parent d2c04e0 commit 93f3fcc
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 214 deletions.
212 changes: 4 additions & 208 deletions internal/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import (
"bytes"
"context"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/stateful/runme/internal/document"
Expand Down Expand Up @@ -57,6 +54,10 @@ func getProject() (proj project.Project, err error) {
return
}

func getLoader(cmd *cobra.Command) project.ProjectLoader {
return project.NewLoader(cmd.OutOrStdout(), cmd.InOrStdin(), isTerminal(os.Stdout.Fd()))
}

func getCodeBlocks() (document.CodeBlocks, error) {
return project.GetCodeBlocks(
filepath.Join(fChdir, fFileName),
Expand Down Expand Up @@ -315,208 +316,3 @@ func replaceVarValue(ev CommandExportExtractMatch, newValue string) string {
replacedText := fmt.Sprintf("%s=%q", parts[0], newValue)
return replacedText
}

type loadTasksModel struct {
spinner spinner.Model

status string
filename string

clear bool

err error

tasks project.CodeBlocks
files []string

nextTaskMsg tea.Cmd
}

type loadTaskFinished struct{}

func newLoadTasksModel(nextTaskMsg tea.Cmd) loadTasksModel {
return loadTasksModel{
spinner: spinner.New(spinner.WithSpinner(spinner.MiniDot)),
nextTaskMsg: nextTaskMsg,
status: "Initializing...",
tasks: make(project.CodeBlocks, 0),
}
}

func loadFiles(proj project.Project, w io.Writer, r io.Reader) ([]string, error) {
m, err := runTasksModel(proj, true, w, r)
if err != nil {
return nil, err
}

return m.files, nil
}

func loadTasks(proj project.Project, w io.Writer, r io.Reader, filter bool) (project.CodeBlocks, error) {
m, err := runTasksModel(proj, false, w, r)
if err != nil {
return nil, err
}

tasks := m.tasks

if filter {
tasks = project.FilterCodeBlocks[project.CodeBlock](m.tasks, fAllowUnknown, fAllowUnnamed)

if len(tasks) == 0 {
// try again without filtering unnamed
tasks = project.FilterCodeBlocks[project.CodeBlock](m.tasks, fAllowUnknown, true)
}
}

return tasks, nil
}

func runTasksModel(proj project.Project, filesOnly bool, w io.Writer, r io.Reader) (*loadTasksModel, error) {
channel := make(chan interface{})
go proj.LoadTasks(filesOnly, channel)

nextTaskMsg := func() tea.Msg {
msg, ok := <-channel

if !ok {
return loadTaskFinished{}
}

return msg
}

m := newLoadTasksModel(nextTaskMsg)

resultModel := m

if isTerminal(os.Stdout.Fd()) {
p := tea.NewProgram(m, tea.WithOutput(w), tea.WithInput(r))
result, err := p.Run()
if err != nil {
return nil, err
}

resultModel = result.(loadTasksModel)
} else {
if strings.ToLower(os.Getenv("RUNME_VERBOSE")) != "true" {
w = io.Discard
}

_, _ = fmt.Fprintln(w, "Initializing...")

outer:
for {
if resultModel.err != nil {
break
}

switch msg := nextTaskMsg().(type) {
case loadTaskFinished:
_, _ = fmt.Fprintln(w, "")
break outer
case project.LoadTaskStatusSearchingFiles:
_, _ = fmt.Fprintln(w, "Searching for files...")
case project.LoadTaskStatusParsingFiles:
_, _ = fmt.Fprintln(w, "Parsing files...")
default:
if newModel, ok := resultModel.TaskUpdate(msg).(loadTasksModel); ok {
resultModel = newModel
}
}
}
}

if resultModel.err != nil {
return nil, resultModel.err
}

return &resultModel, nil
}

func (m loadTasksModel) Init() tea.Cmd {
return tea.Batch(
func() tea.Msg {
return m.spinner.Tick()
},
m.nextTaskMsg,
)
}

func (m loadTasksModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.err != nil {
return m, tea.Quit
}

switch msg := msg.(type) {
case spinner.TickMsg:
var cmd tea.Cmd
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
case loadTaskFinished:
m.clear = true
return m, tea.Quit
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "crtl+d":
m.err = errors.New("aborted")
return m, tea.Quit
}
}

if m, ok := m.TaskUpdate(msg).(loadTasksModel); ok {
return m, m.nextTaskMsg
}

return m, nil
}

func (m loadTasksModel) TaskUpdate(msg tea.Msg) tea.Model {
switch msg := msg.(type) {

case project.LoadTaskError:
m.err = msg.Err

// status
case project.LoadTaskStatusSearchingFiles:
m.filename = ""
m.status = "Searching for files..."
case project.LoadTaskStatusParsingFiles:
m.filename = ""
m.status = "Parsing files..."

// filename
case project.LoadTaskSearchingFolder:
m.filename = msg.Folder
case project.LoadTaskParsingFile:
m.filename = msg.Filename

// results
case project.LoadTaskFoundFile:
m.files = append(m.files, msg.Filename)
case project.LoadTaskFoundTask:
m.tasks = append(m.tasks, msg.Task)

default:
return nil
}

return m
}

func (m loadTasksModel) View() (s string) {
if m.clear {
return
}

s += m.spinner.View()
s += " "

s += m.status

if m.filename != "" {
s += fmt.Sprintf(" (%s)", m.filename)
}

return
}
3 changes: 2 additions & 1 deletion internal/cmd/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func fmtCmd() *cobra.Command {
files := args

if len(files) == 0 {
projectFiles, err := loadFiles(proj, cmd.OutOrStdout(), cmd.InOrStdin())
loader := getLoader(cmd)
projectFiles, err := loader.LoadFiles(proj)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ func listCmd() *cobra.Command {
return err
}

allBlocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
loader := getLoader(cmd)
allBlocks, err := loader.LoadTasks(proj, fAllowUnknown, fAllowUnnamed, true)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ func printCmd() *cobra.Command {
}

generateBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
loader := getLoader(cmd)
blocks, err := loader.LoadTasks(proj, fAllowUnknown, fAllowUnnamed, true)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ func runCmd() *cobra.Command {

{
searchBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
loader := getLoader(cmd)
blocks, err := loader.LoadTasks(proj, fAllowUnknown, fAllowUnnamed, true)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ func tasksCmd() *cobra.Command {
}

generateBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
loader := getLoader(cmd)
blocks, err := loader.LoadTasks(proj, fAllowUnknown, fAllowUnnamed, true)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func tuiCmd() *cobra.Command {
return err
}

blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), false)
loader := getLoader(cmd)
blocks, err := loader.LoadTasks(proj, fAllowUnknown, fAllowUnnamed, false)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 93f3fcc

Please sign in to comment.