feat(arduinocli): implement PlanForce

This commit is contained in:
MDietermann
2026-04-14 22:16:18 +02:00
parent 25b4eefecd
commit 48d50efe19
2 changed files with 113 additions and 24 deletions

View File

@@ -4,7 +4,6 @@ package arduinocli
import (
"bytes"
"context"
"errors"
"fmt"
"os"
"path/filepath"
@@ -61,6 +60,30 @@ func (m Module) Detect(ctx context.Context) (module.State, error) {
return s, nil
}
// downloadBinary fetches, extracts, and installs arduino-cli to bp.
func (m Module) downloadBinary(ctx context.Context, bp string) error {
tmpDir, err := os.MkdirTemp("", "arduinocli-")
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
archive := filepath.Join(tmpDir, "arduino-cli.tar.gz")
if err := platform.Download(ctx, m.cfg.URL, archive, 0o644); err != nil {
return err
}
if err := platform.ExtractTarGz(ctx, archive, tmpDir); err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(bp), 0o755); err != nil {
return err
}
data, err := os.ReadFile(filepath.Join(tmpDir, "arduino-cli"))
if err != nil {
return err
}
return os.WriteFile(bp, data, 0o755)
}
func (m Module) Plan(ctx context.Context, cur module.State) (module.Plan, error) {
s, _ := cur.(state)
var actions []module.Action
@@ -69,28 +92,7 @@ func (m Module) Plan(ctx context.Context, cur module.State) (module.Plan, error)
actions = append(actions, module.Action{
Description: "download + install arduino-cli " + m.cfg.Version,
Kind: module.ActionFileWrite,
Exec: func(ctx context.Context) error {
tmpDir, err := os.MkdirTemp("", "arduinocli-")
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
archive := filepath.Join(tmpDir, "arduino-cli.tar.gz")
if err := platform.Download(ctx, m.cfg.URL, archive, 0o644); err != nil {
return err
}
if err := platform.ExtractTarGz(ctx, archive, tmpDir); err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(bp), 0o755); err != nil {
return err
}
data, err := os.ReadFile(filepath.Join(tmpDir, "arduino-cli"))
if err != nil {
return err
}
return os.WriteFile(bp, data, 0o755)
},
Exec: func(ctx context.Context) error { return m.downloadBinary(ctx, bp) },
})
}
for _, core := range s.MissingCores {
@@ -138,6 +140,33 @@ func (m Module) Verify(ctx context.Context) error {
return nil
}
// PlanForce redownloads the arduino-cli binary, refreshes the core index,
// and reinstalls every configured core unconditionally. arduino-cli's
// `core install` is idempotent, so reissuing it is safe.
func (m Module) PlanForce(ctx context.Context) (module.Plan, error) {
return module.Plan{}, errors.New("PlanForce not implemented")
bp, err := binaryPath()
if err != nil {
return module.Plan{}, err
}
actions := []module.Action{
{
Description: "redownload + reinstall arduino-cli " + m.cfg.Version + " (force)",
Kind: module.ActionFileWrite,
Exec: func(ctx context.Context) error { return m.downloadBinary(ctx, bp) },
},
{
Description: "arduino-cli core update-index (force)",
Kind: module.ActionCommand,
Exec: func(ctx context.Context) error { return m.runner.Run(ctx, bp, "core", "update-index") },
},
}
for _, core := range m.cfg.Cores {
core := core
actions = append(actions, module.Action{
Description: "arduino-cli core install " + core + " (force)",
Kind: module.ActionCommand,
Exec: func(ctx context.Context) error { return m.runner.Run(ctx, bp, "core", "install", core) },
})
}
return module.Plan{Actions: actions}, nil
}