Files
2dph/internal/cmdbin/exec.go
T
eSliderandGitHub 20b78a9a20
Tests / Test (push) Failing after 5s
Tests / Release (semver) (push) Skipped
feat: brain/index.go shebang; mail import is not a brain write (D14). (#12)
Commands live at bin/brain/{index,get,stats,eval,watch}.go and
bin/mail/import.go, bin/markdown/import.go, bin/postgres/query.go.
Python remains the Ladybug write worker. index_mail is a deprecation
shim that rebuilds via --with-mail.
2026-08-13 17:46:25 +01:00

55 lines
1.1 KiB
Go

package cmdbin
import (
"errors"
"os"
"os/exec"
"path/filepath"
"strings"
)
// Root is the 2dph checkout (KB_ROOT, or walk up for .git / var).
func Root() string {
if v := os.Getenv("KB_ROOT"); v != "" {
return v
}
wd, err := os.Getwd()
if err != nil {
return "."
}
for i := 0; i < 10; i++ {
if _, err := os.Stat(filepath.Join(wd, ".git")); err == nil {
return wd
}
if _, err := os.Stat(filepath.Join(wd, "var")); err == nil {
return wd
}
parent := filepath.Dir(wd)
if parent == wd {
break
}
wd = parent
}
return "."
}
// ExecFile runs repo-relative path (python/bash shebang scripts) with stdio.
func ExecFile(rel string, args []string) int {
path := filepath.Join(Root(), filepath.FromSlash(rel))
cmd := exec.Command(path, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = Root()
if err := cmd.Run(); err != nil {
if ee, ok := err.(*exec.ExitError); ok {
return ee.ExitCode()
}
if errors.Is(err, os.ErrNotExist) || strings.Contains(err.Error(), "no such file") {
return 127
}
return 1
}
return 0
}