package main import ( "encoding/json" "errors" "flag" "io" "io/fs" "log" "net" "os" "path/filepath" "strings" ) func main() { var instance_path string var target string var arguments string var program string var workdir string var exit_code int = 0 fallback_instance_path, ins_err := get_instance_path() flag.StringVar(&instance_path, "i", fallback_instance_path, "The path to the used instance") flag.StringVar(&target, "t", "run", "The target to run") cwd, cwd_err := os.Getwd() flag.StringVar(&workdir, "w", cwd, "The working directory") flag.Parse() if flag.NArg() == 0 { log.Fatal("a package is required") } else if flag.NArg() == 1 { program = flag.Arg(0) arguments = "" } else if flag.NArg() > 1 { program = flag.Arg(0) arguments = strings.Join(flag.Args()[1:], " ") } if ins_err != nil && instance_path == "" { log.Fatal(ins_err) } if cwd_err != nil && cwd == "" { log.Fatal(cwd_err) } ln, err := net.Dial("unix", instance_path+"/boundaries.sock") if err != nil { log.Fatal(err) } cmdMap := make(map[string]string) cmdMap["command"] = "run" cmdMap["target"] = target cmdMap["workdir"] = workdir cmdMap["arguments"] = arguments cmdMap["package"] = program cmd, err := json.Marshal(cmdMap) if err != nil { log.Fatal(err) } ln.Write(cmd) go func() { for { buffer := make([]byte, 1024) n, err := os.Stdin.Read(buffer) if err == io.EOF { break } else if err != nil { log.Fatal(err) } ln.Write(buffer[:n]) } }() func() { for { buffer := make([]byte, 1024) n, err := ln.Read(buffer) objmap := make(map[string]interface{}) if err == io.EOF { break } else if err != nil { log.Fatal(err) } err = json.Unmarshal(buffer[:n], &objmap) if err != nil { os.Stdout.Write(buffer[:n]) } else { command, has := objmap["command"] if has && command == "end-command-pipe" { status_code, has := objmap["status_code"] if has { exit_code = int(status_code.(float64)) break } else { os.Stdout.Write(buffer[:n]) } } else { os.Stdout.Write(buffer[:n]) } } } }() os.Exit(exit_code) } func path_exists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if errors.Is(err, fs.ErrNotExist) { return false, nil } return false, err } func get_instance_path() (string, error) { // When bnd-run has been started by boundaries, this can be used to get the instance it used app_dir, has := os.LookupEnv("APP_DIR") if has { return filepath.Abs(filepath.Join(app_dir, "..", "..")) } // Fallback to the user-path home, err := os.UserHomeDir() if err != nil { return "", err } home_instance_path, err := filepath.Abs(filepath.Join(home, "boundaries")) if exists, err := path_exists(home_instance_path); exists && err == nil { return home_instance_path, nil } return "", errors.New("no suitable instance path found") }