| 454 | } |
| 455 | |
| 456 | func (a *Handler) Start() error { |
| 457 | name := a.name |
| 458 | if name == "" { |
| 459 | return fmt.Errorf("invalid app name: %q", name) |
| 460 | } |
| 461 | var binPath string |
| 462 | var err error |
| 463 | if e := os.Getenv("CAMLI_APP_BINDIR"); e != "" { |
| 464 | binPath, err = exec.LookPath(filepath.Join(e, name)) |
| 465 | if err != nil { |
| 466 | log.Printf("%q executable not found in %q", name, e) |
| 467 | } |
| 468 | } |
| 469 | if binPath == "" || err != nil { |
| 470 | binPath, err = exec.LookPath(name) |
| 471 | if err != nil { |
| 472 | return fmt.Errorf("%q executable not found in PATH", name) |
| 473 | } |
| 474 | } |
| 475 | |
| 476 | cmd := exec.Command(binPath) |
| 477 | cmd.Stdout = os.Stdout |
| 478 | cmd.Stderr = os.Stderr |
| 479 | // TODO(mpl): extract Env methods from dev/devcam/env.go to a util pkg and use them here. |
| 480 | newVars := make(map[string]string, len(a.envVars)) |
| 481 | for k, v := range a.envVars { |
| 482 | newVars[k+"="] = v |
| 483 | } |
| 484 | env := os.Environ() |
| 485 | for pos, oldkv := range env { |
| 486 | for k, newVal := range newVars { |
| 487 | if strings.HasPrefix(oldkv, k) { |
| 488 | env[pos] = k + newVal |
| 489 | delete(newVars, k) |
| 490 | break |
| 491 | } |
| 492 | } |
| 493 | } |
| 494 | for k, v := range newVars { |
| 495 | env = append(env, k+v) |
| 496 | } |
| 497 | cmd.Env = env |
| 498 | if err := cmd.Start(); err != nil { |
| 499 | return fmt.Errorf("could not start app %v: %v", name, err) |
| 500 | } |
| 501 | a.process = cmd.Process |
| 502 | return nil |
| 503 | } |
| 504 | |
| 505 | // ProgramName returns the name of the app's binary. It may be a file name in |
| 506 | // CAMLI_APP_BINDIR or PATH, or an absolute path. |