// Package hello is a toy module that writes a marker file. It exists to // validate the engine end-to-end before real modules arrive in Plan 3. package hello import ( "context" "fmt" "os" "path/filepath" "gitlab.hive-brain.de/MDietermann/Archduino/internal/module" ) const defaultRelPath = ".cache/archduino/hello.ok" const markerContent = "archduino-hello\n" // Module is the exported module value. Path is overridable for tests. type Module struct { Path string // absolute path; if empty, ~/.cache/archduino/hello.ok is used } func (m Module) resolve() (string, error) { if m.Path != "" { return m.Path, nil } home, err := os.UserHomeDir() if err != nil { return "", err } return filepath.Join(home, defaultRelPath), nil } func (Module) Meta() module.Meta { return module.Meta{ ID: "hello", Name: "Hello", Description: "Toy module that writes a marker file (engine smoke test).", } } type state struct{ Present bool } func (m Module) Detect(ctx context.Context) (module.State, error) { path, err := m.resolve() if err != nil { return nil, err } data, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { return state{Present: false}, nil } return nil, err } return state{Present: string(data) == markerContent}, nil } func (m Module) Plan(ctx context.Context, cur module.State) (module.Plan, error) { s, _ := cur.(state) if s.Present { return module.Plan{}, nil } path, err := m.resolve() if err != nil { return module.Plan{}, err } return module.Plan{Actions: []module.Action{{ Description: "write marker " + path, Kind: module.ActionFileWrite, Exec: func(ctx context.Context) error { if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err } return os.WriteFile(path, []byte(markerContent), 0o644) }, }}}, 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 !st.(state).Present { return fmt.Errorf("hello: marker not present after apply") } return nil }