(ctx context.Context, logger slog.Logger, cfg *devConfig)
| 713 | } |
| 714 | |
| 715 | func preflight(ctx context.Context, logger slog.Logger, cfg *devConfig) error { |
| 716 | // Source lib.sh to run its dependency checks (bash 4+, GNU |
| 717 | // getopt, make 4+) and then check command dependencies, |
| 718 | // matching the original develop.sh. Prints helpful install |
| 719 | // instructions on failure and exits non-zero. |
| 720 | libSh := filepath.Join(cfg.projectRoot, "scripts", "lib.sh") |
| 721 | libCheck := exec.CommandContext(ctx, "bash", "-c", //nolint:gosec // libSh is a project-relative path, not user input |
| 722 | "source "+libSh+" && dependencies curl git go jq make pnpm") |
| 723 | libCheck.Stdout = os.Stderr |
| 724 | libCheck.Stderr = os.Stderr |
| 725 | if err := libCheck.Run(); err != nil { |
| 726 | return xerrors.New("dependency check failed, see above") |
| 727 | } |
| 728 | apiAddr := fmt.Sprintf("http://127.0.0.1:%d", cfg.apiPort) |
| 729 | if isCoderRunning(ctx, apiAddr) { |
| 730 | logger.Info(ctx, "coder is already running on this port", |
| 731 | slog.F("port", cfg.apiPort)) |
| 732 | return nil |
| 733 | } |
| 734 | if isPortBusy(ctx, cfg.apiPort) { |
| 735 | return xerrors.Errorf("port %d is already in use", cfg.apiPort) |
| 736 | } |
| 737 | if isPortBusy(ctx, cfg.webPort) { |
| 738 | return xerrors.Errorf("port %d is already in use (frontend)", cfg.webPort) |
| 739 | } |
| 740 | if cfg.useProxy && isPortBusy(ctx, cfg.proxyPort) { |
| 741 | return xerrors.Errorf("port %d is already in use (proxy)", cfg.proxyPort) |
| 742 | } |
| 743 | if cfg.coderMetricsPort != 0 && isPortBusy(ctx, cfg.coderMetricsPort) { |
| 744 | return xerrors.Errorf("port %d is already in use (prometheus)", cfg.coderMetricsPort) |
| 745 | } |
| 746 | return nil |
| 747 | } |
| 748 | |
| 749 | // buildBinary uses os.Environ() directly (not cfg.cmd()) because |
| 750 | // the build needs the full unfiltered parent environment. |
no test coverage detected