Skip to content

Commit 7badd6f

Browse files
committed
Exec bazel instead of subprocessing
1 parent 1f9a1ac commit 7badd6f

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

core/core.go

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,6 @@ func RunBazeliskWithArgsFunc(argsFunc ArgsFunc, repos *Repositories) (int, error
9090
// RunBazeliskWithArgsFuncAndConfig runs the main Bazelisk logic for the given ArgsFunc and Bazel
9191
// repositories and config.
9292
func RunBazeliskWithArgsFuncAndConfig(argsFunc ArgsFunc, repos *Repositories, config config.Config) (int, error) {
93-
return RunBazeliskWithArgsFuncAndConfigAndOut(argsFunc, repos, config, nil)
94-
}
95-
96-
// RunBazeliskWithArgsFuncAndConfigAndOut runs the main Bazelisk logic for the given ArgsFunc and Bazel
97-
// repositories and config, writing its stdout to the passed writer.
98-
func RunBazeliskWithArgsFuncAndConfigAndOut(argsFunc ArgsFunc, repos *Repositories, config config.Config, out io.Writer) (int, error) {
9993
httputil.UserAgent = getUserAgent(config)
10094

10195
bazelInstallation, err := GetBazelInstallation(repos, config)
@@ -108,8 +102,8 @@ func RunBazeliskWithArgsFuncAndConfigAndOut(argsFunc ArgsFunc, repos *Repositori
108102
// --print_env must be the first argument.
109103
if len(args) > 0 && args[0] == "--print_env" {
110104
// print environment variables for sub-processes
111-
cmd := makeBazelCmd(bazelInstallation.Path, args, nil, config)
112-
for _, val := range cmd.Env {
105+
_, _, env := makeBazelCmd(bazelInstallation.Path, args, config)
106+
for _, val := range env {
113107
fmt.Println(val)
114108
}
115109
return 0, nil
@@ -161,7 +155,7 @@ func RunBazeliskWithArgsFuncAndConfigAndOut(argsFunc ArgsFunc, repos *Repositori
161155
}
162156
}
163157

164-
exitCode, err := runBazel(bazelInstallation.Path, args, out, config)
158+
exitCode, err := execBazel(bazelInstallation.Path, args, config)
165159
if err != nil {
166160
return -1, fmt.Errorf("could not run Bazel: %v", err)
167161
}
@@ -636,50 +630,68 @@ func maybeDelegateToWrapper(bazel string, config config.Config) string {
636630
return maybeDelegateToWrapperFromDir(bazel, wd, config)
637631
}
638632

639-
func prependDirToPathList(cmd *exec.Cmd, dir string) {
633+
func prependDirToPathList(env []string, dir string) {
640634
found := false
641-
for idx, val := range cmd.Env {
635+
for idx, val := range env {
642636
splits := strings.Split(val, "=")
643637
if len(splits) != 2 {
644638
continue
645639
}
646640
if strings.EqualFold(splits[0], "PATH") {
647641
found = true
648-
cmd.Env[idx] = fmt.Sprintf("PATH=%s%s%s", dir, string(os.PathListSeparator), splits[1])
642+
env[idx] = fmt.Sprintf("PATH=%s%s%s", dir, string(os.PathListSeparator), splits[1])
649643
break
650644
}
651645
}
652646

653647
if !found {
654-
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", dir))
648+
env = append(env, fmt.Sprintf("PATH=%s", dir))
655649
}
656650
}
657651

658-
func makeBazelCmd(bazel string, args []string, out io.Writer, config config.Config) *exec.Cmd {
652+
func makeBazelCmd(bazel string, args []string, config config.Config) (string, []string, []string) {
659653
execPath := maybeDelegateToWrapper(bazel, config)
660654

661-
cmd := exec.Command(execPath, args...)
662-
cmd.Env = append(os.Environ(), skipWrapperEnv+"=true")
655+
env := append(os.Environ(), skipWrapperEnv+"=true")
663656
if execPath != bazel {
664-
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", bazelReal, bazel))
657+
env = append(env, fmt.Sprintf("%s=%s", bazelReal, bazel))
665658
}
666659
selfPath, err := os.Executable()
667660
if err != nil {
668-
cmd.Env = append(cmd.Env, bazeliskEnv+"="+selfPath)
661+
env = append(env, bazeliskEnv+"="+selfPath)
662+
}
663+
prependDirToPathList(env, filepath.Dir(execPath))
664+
665+
commandLine := []string{execPath}
666+
commandLine = append(commandLine, args...)
667+
return execPath, commandLine, env
668+
}
669+
670+
func execBazel(bazel string, args []string, config config.Config) (int, error) {
671+
if runtime.GOOS == "windows" {
672+
// syscall.Exec is not supported on windows
673+
return runBazel(bazel, args, nil, config)
669674
}
670-
prependDirToPathList(cmd, filepath.Dir(execPath))
675+
676+
execPath, args, env := makeBazelCmd(bazel, args, config)
677+
678+
err := syscall.Exec(execPath, args, env)
679+
return 1, fmt.Errorf("could not start Bazel: %v", err)
680+
}
681+
682+
func runBazel(bazel string, args []string, out io.Writer, config config.Config) (int, error) {
683+
execPath, commandLine, env := makeBazelCmd(bazel, args, config)
684+
685+
cmd := exec.Command(execPath, commandLine[1:]...)
686+
cmd.Env = env
671687
cmd.Stdin = os.Stdin
672688
if out == nil {
673689
cmd.Stdout = os.Stdout
674690
} else {
675691
cmd.Stdout = out
676692
}
677693
cmd.Stderr = os.Stderr
678-
return cmd
679-
}
680694

681-
func runBazel(bazel string, args []string, out io.Writer, config config.Config) (int, error) {
682-
cmd := makeBazelCmd(bazel, args, out, config)
683695
err := cmd.Start()
684696
if err != nil {
685697
return 1, fmt.Errorf("could not start Bazel: %v", err)

0 commit comments

Comments
 (0)