70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package executil
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"strings"
|
|
|
|
"zlh-agent/scripts"
|
|
)
|
|
|
|
// RunEmbeddedScript executes an embedded script via bash by piping its contents to stdin.
|
|
// If the script is a devcontainer installer, this automatically prepends the shared common.sh
|
|
// so that tiny per-runtime installers can call install_runtime in the same shell session.
|
|
func RunEmbeddedScript(scriptPath string, extraEnv ...string) error {
|
|
normalized := normalizeEmbeddedPath(scriptPath)
|
|
|
|
payload, err := loadEmbeddedPayload(normalized)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd := exec.Command("bash")
|
|
cmd.Stdin = bytes.NewReader(payload)
|
|
|
|
// Inherit current env and overlay any provided vars (e.g., RUNTIME_VERSION=24).
|
|
if len(extraEnv) > 0 {
|
|
cmd.Env = append(os.Environ(), extraEnv...)
|
|
}
|
|
|
|
// Match RunScript behavior (executil.go)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
return cmd.Run()
|
|
}
|
|
|
|
func loadEmbeddedPayload(normalized string) ([]byte, error) {
|
|
// If this is a devcontainer installer, prepend the shared library.
|
|
if strings.HasPrefix(normalized, "devcontainer/") {
|
|
commonPath := "devcontainer/lib/common.sh"
|
|
common, err := scripts.FS.ReadFile(commonPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("embedded script missing: %s: %w", commonPath, err)
|
|
}
|
|
|
|
body, err := scripts.FS.ReadFile(normalized)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("embedded script missing: %s: %w", normalized, err)
|
|
}
|
|
|
|
// Ensure bash sees common first, then runtime installer.
|
|
return append(append(common, '\n'), body...), nil
|
|
}
|
|
|
|
data, err := scripts.FS.ReadFile(normalized)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("embedded script missing: %s: %w", normalized, err)
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
func normalizeEmbeddedPath(p string) string {
|
|
p = strings.TrimPrefix(p, "scripts/")
|
|
p = path.Clean(p)
|
|
return strings.TrimPrefix(p, "/")
|
|
}
|