pkg/grept_plan.go (100 lines of code) (raw):

package pkg import ( "fmt" "github.com/Azure/golden" "github.com/ahmetb/go-linq/v3" "strings" "sync" ) func RunGreptPlan(c *GreptConfig) (*GreptPlan, error) { err := c.RunPlan() if err != nil { return nil, err } plan := newPlan(c) for _, rb := range golden.Blocks[Rule](c) { checkErr := rb.CheckError() if checkErr == nil { continue } plan.addRule(&FailedRule{ Rule: rb, CheckError: checkErr, }) for _, fb := range golden.Blocks[Fix](c) { if linq.From(fb.GetRuleIds()).Contains(rb.Id()) { plan.addFix(fb) } } } return plan, nil } var _ golden.Plan = &GreptPlan{} type GreptPlan struct { FailedRules []*FailedRule Fixes map[string]Fix c *GreptConfig mu sync.Mutex } func newPlan(c *GreptConfig) *GreptPlan { return &GreptPlan{ c: c, Fixes: make(map[string]Fix), } } func (p *GreptPlan) String() string { sb := strings.Builder{} for _, r := range p.FailedRules { sb.WriteString(r.String()) sb.WriteString("\n---\n") } for _, f := range p.Fixes { sb.WriteString(fmt.Sprintf("%s would be apply:\n %s\n", f.Address(), golden.BlockToString(f))) sb.WriteString("\n---\n") } return sb.String() } func (p *GreptPlan) Apply() error { addresses := make(map[string]struct{}) for _, fix := range p.Fixes { addresses[fix.Address()] = struct{}{} } if err := golden.Traverse[Fix](p.c.BaseConfig, func(fix Fix) error { if _, ok := p.Fixes[fix.Id()]; !ok { return nil } if decodeErr := golden.Decode(fix); decodeErr != nil { return fmt.Errorf("rule.%s.%s(%s) decode error: %+v", fix.Type(), fix.Name(), fix.HclBlock().Range().String(), decodeErr) } return nil }); err != nil { return err } if err := golden.Traverse[Fix](p.c.BaseConfig, func(fix Fix) error { if _, ok := p.Fixes[fix.Id()]; !ok { return nil } return fix.Apply() }); err != nil { return err } return nil } func (p *GreptPlan) addRule(fr *FailedRule) { p.mu.Lock() p.FailedRules = append(p.FailedRules, fr) p.mu.Unlock() } func (p *GreptPlan) addFix(f Fix) { p.mu.Lock() p.Fixes[f.Id()] = f p.mu.Unlock() } type FailedRule struct { Rule CheckError error } func (fr *FailedRule) String() string { address := fr.Address() return fmt.Sprintf("%s check return failure: %s", address, fr.CheckError.Error()) }