70 lines
1.5 KiB
Go
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
|