From 279adb157e86b044be9c28fe40a3d60b3e2b3d00 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Tue, 17 Feb 2026 11:11:54 +0100 Subject: [PATCH] refactor for better maintainability and readabilty --- cmd/survey/cmd.go | 47 ++++++++++++++------------------- cmd/survey/init.go | 4 +-- cmd/survey/intro.go | 22 +++++++-------- cmd/survey/main.go | 3 +-- cmd/survey/runner.go | 28 ++++++++++---------- cmd/survey/tasks/createIssue.go | 4 +-- pkg/task/task.go | 33 ++++++++++++----------- 7 files changed, 68 insertions(+), 73 deletions(-) diff --git a/cmd/survey/cmd.go b/cmd/survey/cmd.go index 5d0b6fb..280bab9 100644 --- a/cmd/survey/cmd.go +++ b/cmd/survey/cmd.go @@ -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) } diff --git a/cmd/survey/init.go b/cmd/survey/init.go index 533976b..4f563ea 100644 --- a/cmd/survey/init.go +++ b/cmd/survey/init.go @@ -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), } } diff --git a/cmd/survey/intro.go b/cmd/survey/intro.go index a734d20..840d631 100644 --- a/cmd/survey/intro.go +++ b/cmd/survey/intro.go @@ -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 } diff --git a/cmd/survey/main.go b/cmd/survey/main.go index 2456cb0..5ff186a 100644 --- a/cmd/survey/main.go +++ b/cmd/survey/main.go @@ -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 } } diff --git a/cmd/survey/runner.go b/cmd/survey/runner.go index a64190a..def5759 100644 --- a/cmd/survey/runner.go +++ b/cmd/survey/runner.go @@ -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) +} diff --git a/cmd/survey/tasks/createIssue.go b/cmd/survey/tasks/createIssue.go index 9a9a2d4..a2827c3 100644 --- a/cmd/survey/tasks/createIssue.go +++ b/cmd/survey/tasks/createIssue.go @@ -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) diff --git a/pkg/task/task.go b/pkg/task/task.go index f995446..4358e56 100644 --- a/pkg/task/task.go +++ b/pkg/task/task.go @@ -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) -}