refactor for better maintainability and readabilty

This commit is contained in:
Robin Olsen
2026-02-17 11:11:54 +01:00
parent a38e32aa78
commit 279adb157e
7 changed files with 68 additions and 73 deletions

View File

@@ -1,48 +1,41 @@
package main
import (
"errors"
"log"
"os"
"github.com/LazyBachelor/LazyPM/pkg/task"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "survey",
Short: "Run the user survey",
Short: "This application exists to gather metrics and feedback on task management interfaces.",
}
var startCmd = &cobra.Command{
Use: "start",
Short: "Start the user survey",
Run: func(cmd *cobra.Command, args []string) {
if err := newIntroModel().Run(); err != nil {
if errors.Is(err, ErrUserQuit) {
os.Exit(0)
}
log.Fatalf("Failed to run intro screen: %v\n", err)
}
RunE: runStartCmd,
}
svc, close, err := initializeServices(cmd.Context())
if err != nil {
log.Fatalf("Failed to initialize services: %v\n", err)
}
defer close()
func runStartCmd(cmd *cobra.Command, args []string) error {
if err := newIntroModel().Run(); err != nil {
return returnIfUserQuit(err, "failed to run intro")
}
surveyTasks := initTasks()
interfaces := initInterfaces()
svc, cleanup, err := initializeServices(cmd.Context())
if err != nil {
return returnIfUserQuit(err, "failed to initialize services")
}
defer cleanup()
if err := taskLoop(cmd.Context(), svc, surveyTasks, interfaces); err != nil {
if errors.Is(err, task.ErrUserQuit) {
os.Exit(0)
}
log.Fatalf("Task loop failed: %v\n", err)
}
},
surveyTasks := initTasks(svc)
interfaces := initInterfaces()
if err := taskLoop(cmd.Context(), surveyTasks, interfaces); err != nil {
return returnIfUserQuit(err, "task loop failed")
}
return nil
}
func init() {
rootCmd.CompletionOptions.DisableDefaultCmd = true
rootCmd.AddCommand(startCmd)
}

View File

@@ -21,9 +21,9 @@ func initializeServices(ctx context.Context) (*service.Services, func(), error)
return service.NewServices(ctx, config)
}
func initTasks() []*task.Task {
func initTasks(svc *service.Services) []*task.Task {
return []*task.Task{
tasks.NewCreateIssueTask(),
tasks.NewCreateIssueTask(svc),
}
}

View File

@@ -34,6 +34,17 @@ func newIntroModel() introModel {
}
}
func (m introModel) Run() error {
model, err := tea.NewProgram(m, tea.WithAltScreen()).Run()
if err != nil {
return err
}
if m, ok := model.(introModel); ok && m.userQuit {
return ErrUserQuit
}
return nil
}
func (m introModel) Init() tea.Cmd {
return nil
}
@@ -68,17 +79,6 @@ func (m introModel) View() string {
return ""
}
func (m introModel) Run() error {
model, err := tea.NewProgram(m, tea.WithAltScreen()).Run()
if err != nil {
return err
}
if m, ok := model.(introModel); ok && m.userQuit {
return ErrUserQuit
}
return nil
}
func (m *introModel) SetSize(width, height int) {
m.width, m.height = width, height
}

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"log"
"github.com/charmbracelet/fang"
)
@@ -12,6 +11,6 @@ func main() {
if err := fang.Execute(ctx, rootCmd,
fang.WithColorSchemeFunc(fang.AnsiColorScheme)); err != nil {
log.Fatalf("Failed to execute command: %v\n", err)
return
}
}

View File

@@ -6,45 +6,38 @@ import (
"fmt"
"math/rand"
"github.com/LazyBachelor/LazyPM/internal/service"
"github.com/LazyBachelor/LazyPM/pkg/task"
)
func taskLoop(ctx context.Context, svc *service.Services, surveyTasks []*task.Task, interfaces []task.Interface) error {
func taskLoop(ctx context.Context, surveyTasks []*task.Task, interfaces []task.Interface) error {
interfaceIndex := rand.Int() % len(interfaces)
for _, t := range surveyTasks {
t.SetInterface(interfaces[interfaceIndex])
if err := t.Initialize(ctx, svc); err != nil {
if err := t.Initialize(ctx); err != nil {
return fmt.Errorf("failed to initialize task: %w", err)
}
if err := t.IntroduceTask(); err != nil {
if errors.Is(err, task.ErrUserQuit) {
return task.ErrUserQuit
}
return fmt.Errorf("failed to display task introduction screen: %w", err)
return returnIfUserQuit(err, "failed to display task introduction screen")
}
if err := t.StartInterface(ctx, t.Config); err != nil {
return fmt.Errorf("failed to start task interface: %w", err)
return returnIfUserQuit(err, "failed to start task interface")
}
ok, err := t.Validate(ctx, svc)
ok, err := t.Validate(ctx)
if err != nil {
return fmt.Errorf("validation error: %w", err)
return returnIfUserQuit(err, "validation error")
}
if !ok {
return fmt.Errorf("task validation failed: task did not meet requirements")
}
if err := t.StartQuestionnaire(); err != nil {
if errors.Is(err, task.ErrUserQuit) {
return task.ErrUserQuit
}
return fmt.Errorf("failed to start questionnaire: %w", err)
return returnIfUserQuit(err, "failed to start questionnaire")
}
interfaceIndex++
@@ -54,3 +47,10 @@ func taskLoop(ctx context.Context, svc *service.Services, surveyTasks []*task.Ta
}
return nil
}
func returnIfUserQuit(err error, msg string) error {
if errors.Is(err, ErrUserQuit) {
return nil
}
return fmt.Errorf("%s: %w", msg, err)
}

View File

@@ -11,11 +11,11 @@ import (
"github.com/charmbracelet/huh"
)
func NewCreateIssueTask() *task.Task {
func NewCreateIssueTask(svc *service.Services) *task.Task {
aboutScreen := ui.NewTaskModel(createIssueDetails())
questionnaire := ui.NewQuestionnaireModel(createIssueQuestionnaire())
task := task.NewTask(aboutScreen, questionnaire)
task := task.NewTask(svc, aboutScreen, questionnaire)
task.SetConfigFunc(createIssueConfig)
task.SetDbStateFunc(createIssueDbState)
task.SetValidateFunc(createIssueValidate)

View File

@@ -16,12 +16,15 @@ type Task struct {
validateFunc ValidateFunc
dbStateFunc DbStateFunc
svc *service.Services
}
func NewTask(aboutScreen tea.Model, questionnaire tea.Model) *Task {
func NewTask(svc *service.Services, aboutScreen tea.Model, questionnaire tea.Model) *Task {
return &Task{
aboutScreen: aboutScreen,
questionnaire: questionnaire,
svc: svc,
}
}
@@ -47,6 +50,20 @@ func (t *Task) StartInterface(ctx context.Context, cfg TaskConfig) error {
return t.interfaceType.Run(ctx, cfg)
}
func (t *Task) Initialize(ctx context.Context) error {
if t.dbStateFunc == nil {
return fmt.Errorf("dbStateFunc is not set")
}
return t.dbStateFunc(ctx, t.svc)
}
func (t *Task) Validate(ctx context.Context) (bool, error) {
if t.validateFunc == nil {
return false, fmt.Errorf("validateFunc is not set")
}
return t.validateFunc(ctx, t.svc)
}
func (t *Task) StartQuestionnaire() error {
if t.questionnaire == nil {
return fmt.Errorf("questionnaire is not set")
@@ -76,17 +93,3 @@ func (t *Task) SetDbStateFunc(fn DbStateFunc) {
func (t *Task) SetValidateFunc(fn ValidateFunc) {
t.validateFunc = fn
}
func (t *Task) Initialize(ctx context.Context, svc *service.Services) error {
if t.dbStateFunc == nil {
return fmt.Errorf("dbStateFunc is not set")
}
return t.dbStateFunc(ctx, svc)
}
func (t *Task) Validate(ctx context.Context, svc *service.Services) (bool, error) {
if t.validateFunc == nil {
return false, fmt.Errorf("validateFunc is not set")
}
return t.validateFunc(ctx, svc)
}