package task import ( "fmt" "os" "time" "github.com/google/uuid" "gopkg.in/yaml.v3" ) // ParseFile reads a YAML file and returns tasks. Supports both single-task // and batch (tasks: [...]) formats. func ParseFile(path string) ([]Task, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading task file: %w", err) } return Parse(data) } // Parse parses YAML bytes into tasks. func Parse(data []byte) ([]Task, error) { // Try batch format first. var batch BatchFile if err := yaml.Unmarshal(data, &batch); err == nil && len(batch.Tasks) > 0 { return initTasks(batch.Tasks), nil } // Try single task. var t Task if err := yaml.Unmarshal(data, &t); err != nil { return nil, fmt.Errorf("parsing task YAML: %w", err) } if t.Name == "" { return nil, fmt.Errorf("task must have a name") } return initTasks([]Task{t}), nil } func initTasks(tasks []Task) []Task { now := time.Now() for i := range tasks { if tasks[i].ID == "" { tasks[i].ID = uuid.New().String() } if tasks[i].Priority == "" { tasks[i].Priority = PriorityNormal } if tasks[i].Retry.MaxAttempts == 0 { tasks[i].Retry.MaxAttempts = 1 } if tasks[i].Retry.Backoff == "" { tasks[i].Retry.Backoff = "exponential" } tasks[i].State = StatePending tasks[i].CreatedAt = now tasks[i].UpdatedAt = now } return tasks }