// Package shellconfig writes marker-delimited blocks into rc files. package shellconfig import ( "context" "fmt" "os" "path/filepath" "gitlab.hive-brain.de/MDietermann/Archduino/internal/config" "gitlab.hive-brain.de/MDietermann/Archduino/internal/module" "gitlab.hive-brain.de/MDietermann/Archduino/internal/platform" ) type Module struct{ cfg config.ShellConfigSection } func New(cfg config.ShellConfigSection) Module { return Module{cfg: cfg} } type state struct{ Missing []config.ShellConfigBlock } func (Module) Meta() module.Meta { return module.Meta{ID: "shellconfig", Name: "Shell config blocks", Description: "Write archduino blocks into rc files."} } func resolveFile(name string) (string, error) { h, err := os.UserHomeDir() if err != nil { return "", err } return filepath.Join(h, name), nil } func (m Module) Detect(ctx context.Context) (module.State, error) { var missing []config.ShellConfigBlock for _, b := range m.cfg.Blocks { p, err := resolveFile(b.File) if err != nil { return nil, err } has, err := platform.HasBlock(p, b.Name) if err != nil { return nil, err } if !has { missing = append(missing, b) } } return state{Missing: missing}, nil } func (m Module) Plan(ctx context.Context, cur module.State) (module.Plan, error) { s, _ := cur.(state) var actions []module.Action for _, b := range s.Missing { b := b actions = append(actions, module.Action{ Description: fmt.Sprintf("write block %s into %s", b.Name, b.File), Kind: module.ActionFileWrite, Exec: func(ctx context.Context) error { p, err := resolveFile(b.File) if err != nil { return err } return platform.EnsureBlock(p, b.Name, b.Content) }, }) } return module.Plan{Actions: actions}, nil } func (m Module) Apply(ctx context.Context, p module.Plan, r module.Reporter) error { for i, a := range p.Actions { r.Progress(m.Meta().ID, i+1, len(p.Actions), a.Description) if err := a.Exec(ctx); err != nil { return err } } return nil } func (m Module) Verify(ctx context.Context) error { st, err := m.Detect(ctx) if err != nil { return err } if miss := st.(state).Missing; len(miss) > 0 { return fmt.Errorf("shell blocks still missing: %d", len(miss)) } return nil }