refactor for better maintainability and readabilty
This commit is contained in:
@@ -1,48 +1,41 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/task"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "survey",
|
Use: "survey",
|
||||||
Short: "Run the user survey",
|
Short: "This application exists to gather metrics and feedback on task management interfaces.",
|
||||||
}
|
}
|
||||||
|
|
||||||
var startCmd = &cobra.Command{
|
var startCmd = &cobra.Command{
|
||||||
Use: "start",
|
Use: "start",
|
||||||
Short: "Start the user survey",
|
Short: "Start the user survey",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: runStartCmd,
|
||||||
if err := newIntroModel().Run(); err != nil {
|
}
|
||||||
if errors.Is(err, ErrUserQuit) {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
log.Fatalf("Failed to run intro screen: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
svc, close, err := initializeServices(cmd.Context())
|
func runStartCmd(cmd *cobra.Command, args []string) error {
|
||||||
if err != nil {
|
if err := newIntroModel().Run(); err != nil {
|
||||||
log.Fatalf("Failed to initialize services: %v\n", err)
|
return returnIfUserQuit(err, "failed to run intro")
|
||||||
}
|
}
|
||||||
defer close()
|
|
||||||
|
|
||||||
surveyTasks := initTasks()
|
svc, cleanup, err := initializeServices(cmd.Context())
|
||||||
interfaces := initInterfaces()
|
if err != nil {
|
||||||
|
return returnIfUserQuit(err, "failed to initialize services")
|
||||||
|
}
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
if err := taskLoop(cmd.Context(), svc, surveyTasks, interfaces); err != nil {
|
surveyTasks := initTasks(svc)
|
||||||
if errors.Is(err, task.ErrUserQuit) {
|
interfaces := initInterfaces()
|
||||||
os.Exit(0)
|
|
||||||
}
|
if err := taskLoop(cmd.Context(), surveyTasks, interfaces); err != nil {
|
||||||
log.Fatalf("Task loop failed: %v\n", err)
|
return returnIfUserQuit(err, "task loop failed")
|
||||||
}
|
}
|
||||||
},
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
rootCmd.CompletionOptions.DisableDefaultCmd = true
|
||||||
rootCmd.AddCommand(startCmd)
|
rootCmd.AddCommand(startCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ func initializeServices(ctx context.Context) (*service.Services, func(), error)
|
|||||||
return service.NewServices(ctx, config)
|
return service.NewServices(ctx, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initTasks() []*task.Task {
|
func initTasks(svc *service.Services) []*task.Task {
|
||||||
return []*task.Task{
|
return []*task.Task{
|
||||||
tasks.NewCreateIssueTask(),
|
tasks.NewCreateIssueTask(svc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
func (m introModel) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -68,17 +79,6 @@ func (m introModel) View() string {
|
|||||||
return ""
|
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) {
|
func (m *introModel) SetSize(width, height int) {
|
||||||
m.width, m.height = width, height
|
m.width, m.height = width, height
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/fang"
|
"github.com/charmbracelet/fang"
|
||||||
)
|
)
|
||||||
@@ -12,6 +11,6 @@ func main() {
|
|||||||
|
|
||||||
if err := fang.Execute(ctx, rootCmd,
|
if err := fang.Execute(ctx, rootCmd,
|
||||||
fang.WithColorSchemeFunc(fang.AnsiColorScheme)); err != nil {
|
fang.WithColorSchemeFunc(fang.AnsiColorScheme)); err != nil {
|
||||||
log.Fatalf("Failed to execute command: %v\n", err)
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,45 +6,38 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/LazyBachelor/LazyPM/internal/service"
|
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/task"
|
"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)
|
interfaceIndex := rand.Int() % len(interfaces)
|
||||||
|
|
||||||
for _, t := range surveyTasks {
|
for _, t := range surveyTasks {
|
||||||
|
|
||||||
t.SetInterface(interfaces[interfaceIndex])
|
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)
|
return fmt.Errorf("failed to initialize task: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.IntroduceTask(); err != nil {
|
if err := t.IntroduceTask(); err != nil {
|
||||||
if errors.Is(err, task.ErrUserQuit) {
|
return returnIfUserQuit(err, "failed to display task introduction screen")
|
||||||
return task.ErrUserQuit
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to display task introduction screen: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.StartInterface(ctx, t.Config); err != nil {
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("validation error: %w", err)
|
return returnIfUserQuit(err, "validation error")
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("task validation failed: task did not meet requirements")
|
return fmt.Errorf("task validation failed: task did not meet requirements")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.StartQuestionnaire(); err != nil {
|
if err := t.StartQuestionnaire(); err != nil {
|
||||||
if errors.Is(err, task.ErrUserQuit) {
|
return returnIfUserQuit(err, "failed to start questionnaire")
|
||||||
return task.ErrUserQuit
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to start questionnaire: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaceIndex++
|
interfaceIndex++
|
||||||
@@ -54,3 +47,10 @@ func taskLoop(ctx context.Context, svc *service.Services, surveyTasks []*task.Ta
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func returnIfUserQuit(err error, msg string) error {
|
||||||
|
if errors.Is(err, ErrUserQuit) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%s: %w", msg, err)
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import (
|
|||||||
"github.com/charmbracelet/huh"
|
"github.com/charmbracelet/huh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCreateIssueTask() *task.Task {
|
func NewCreateIssueTask(svc *service.Services) *task.Task {
|
||||||
aboutScreen := ui.NewTaskModel(createIssueDetails())
|
aboutScreen := ui.NewTaskModel(createIssueDetails())
|
||||||
questionnaire := ui.NewQuestionnaireModel(createIssueQuestionnaire())
|
questionnaire := ui.NewQuestionnaireModel(createIssueQuestionnaire())
|
||||||
|
|
||||||
task := task.NewTask(aboutScreen, questionnaire)
|
task := task.NewTask(svc, aboutScreen, questionnaire)
|
||||||
task.SetConfigFunc(createIssueConfig)
|
task.SetConfigFunc(createIssueConfig)
|
||||||
task.SetDbStateFunc(createIssueDbState)
|
task.SetDbStateFunc(createIssueDbState)
|
||||||
task.SetValidateFunc(createIssueValidate)
|
task.SetValidateFunc(createIssueValidate)
|
||||||
|
|||||||
@@ -16,12 +16,15 @@ type Task struct {
|
|||||||
|
|
||||||
validateFunc ValidateFunc
|
validateFunc ValidateFunc
|
||||||
dbStateFunc DbStateFunc
|
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{
|
return &Task{
|
||||||
aboutScreen: aboutScreen,
|
aboutScreen: aboutScreen,
|
||||||
questionnaire: questionnaire,
|
questionnaire: questionnaire,
|
||||||
|
svc: svc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +50,20 @@ func (t *Task) StartInterface(ctx context.Context, cfg TaskConfig) error {
|
|||||||
return t.interfaceType.Run(ctx, cfg)
|
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 {
|
func (t *Task) StartQuestionnaire() error {
|
||||||
if t.questionnaire == nil {
|
if t.questionnaire == nil {
|
||||||
return fmt.Errorf("questionnaire is not set")
|
return fmt.Errorf("questionnaire is not set")
|
||||||
@@ -76,17 +93,3 @@ func (t *Task) SetDbStateFunc(fn DbStateFunc) {
|
|||||||
func (t *Task) SetValidateFunc(fn ValidateFunc) {
|
func (t *Task) SetValidateFunc(fn ValidateFunc) {
|
||||||
t.validateFunc = fn
|
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)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user