Files
orca/internal/jobspec/spec.go
T

70 lines
1.5 KiB
Go

package jobspec
import (
"fmt"
"os"
"strings"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsimple"
)
type Spec struct {
Job JobSpec `hcl:"job,block"`
Tasks []TaskSpec `hcl:"task,block"`
}
type JobSpec struct {
Name string `hcl:"name,label"`
Type string `hcl:"type,optional"`
}
type TaskSpec struct {
Name string `hcl:"name,label"`
Command string `hcl:"command"`
Args []string `hcl:"args,optional"`
Env []string `hcl:"env,optional"`
}
func ParseFile(path string) (*Spec, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read spec file: %w", err)
}
return Parse(data, path)
}
func Parse(data []byte, filename string) (*Spec, error) {
var spec Spec
err := hclsimple.Decode(filename, data, nil, &spec)
if err != nil {
return nil, fmt.Errorf("decode hcl: %w", err)
}
if spec.Job.Name == "" {
return nil, fmt.Errorf("spec missing job name")
}
if len(spec.Tasks) == 0 {
return nil, fmt.Errorf("spec must have at least one task")
}
for i, t := range spec.Tasks {
if t.Command == "" {
return nil, fmt.Errorf("task[%d] (%s) missing command", i, t.Name)
}
}
return &spec, nil
}
func (s *Spec) Validate() error {
if strings.TrimSpace(s.Job.Name) == "" {
return fmt.Errorf("job name is required")
}
if len(s.Tasks) == 0 {
return fmt.Errorf("at least one task is required")
}
return nil
}
var _ = hcl.Diagnostics{}
var _ = gohcl.DecodeBody