package engine import ( "context" "fmt" "strings" "github.com/darroyo/nasctl/internal/db" "github.com/darroyo/nasctl/internal/modules" ) type ModuleResult struct { Module string `json:"module"` Applied bool `json:"applied"` Error string `json:"error,omitempty"` } type ApplyResult struct { Results []ModuleResult `json:"results"` } type Engine struct { modules []modules.Module } func New(mods ...modules.Module) *Engine { return &Engine{modules: mods} } func (e *Engine) DirtyList(ctx context.Context, database *db.DB) ([]db.DirtyModule, error) { return database.ListDirty() } func (e *Engine) ApplyAll(ctx context.Context, database *db.DB) (ApplyResult, error) { result := ApplyResult{Results: make([]ModuleResult, 0)} var errors []string for _, mod := range e.modules { dirty, err := mod.IsDirty(ctx, database) if err != nil { errors = append(errors, fmt.Sprintf("%s: check dirty: %v", mod.Name(), err)) result.Results = append(result.Results, ModuleResult{ Module: mod.Name(), Error: err.Error(), }) continue } if !dirty { continue } if err := mod.Apply(ctx, database); err != nil { msg := err.Error() errors = append(errors, fmt.Sprintf("%s: %s", mod.Name(), msg)) _ = database.AppendApplyLog(mod.Name(), msg, false) result.Results = append(result.Results, ModuleResult{ Module: mod.Name(), Error: msg, }) continue } result.Results = append(result.Results, ModuleResult{ Module: mod.Name(), Applied: true, }) } if len(errors) > 0 { return result, fmt.Errorf("%s", strings.Join(errors, "; ")) } return result, nil }