Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 08f61b7

Browse files
committed
Revert "SG start bazel enhancements (#59718)"
This reverts commit 00185f9.
1 parent ffb890b commit 08f61b7

21 files changed

+983
-1405
lines changed

.bazel_fix_commands.json

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1 @@
1-
[
2-
{
3-
"regex": "^Check that imports in Go sources match importpath attributes in deps.$",
4-
"command": "./dev/bazel_configure_accept_changes.sh",
5-
"args": []
6-
},
7-
{
8-
"regex": "missing input file",
9-
"command": "./dev/bazel_configure_accept_changes.sh",
10-
"args": []
11-
},
12-
{
13-
"regex": ": undefined:",
14-
"command": "./dev/bazel_configure_accept_changes.sh",
15-
"args": []
16-
}
17-
]
1+
[]

deps.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4201,8 +4201,8 @@ def go_dependencies():
42014201
name = "com_github_nxadm_tail",
42024202
build_file_proto_mode = "disable_global",
42034203
importpath = "github.com/nxadm/tail",
4204-
sum = "h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=",
4205-
version = "v1.4.11",
4204+
sum = "h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=",
4205+
version = "v1.4.8",
42064206
)
42074207
go_repository(
42084208
name = "com_github_nytimes_gziphandler",

dev/bazel_configure_accept_changes.sh

Lines changed: 0 additions & 19 deletions
This file was deleted.

dev/sg/internal/run/BUILD.bazel

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
load("@io_bazel_rules_go//go:def.bzl", "go_library")
21
load("//dev:go_defs.bzl", "go_test")
2+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
33

44
go_library(
55
name = "run",
66
srcs = [
7+
"bazel_build.go",
78
"bazel_command.go",
89
"command.go",
910
"helpers.go",
1011
"ibazel.go",
11-
"installer.go",
1212
"logger.go",
1313
"pid.go",
1414
"prefix_suffix_saver.go",
1515
"run.go",
16-
"sgconfig_command.go",
16+
"run_bazel.go",
1717
],
1818
importpath = "github.com/sourcegraph/sourcegraph/dev/sg/internal/run",
1919
visibility = ["//dev/sg:__subpackages__"],
@@ -28,9 +28,9 @@ go_library(
2828
"//lib/output",
2929
"//lib/process",
3030
"@com_github_grafana_regexp//:regexp",
31-
"@com_github_nxadm_tail//:tail",
3231
"@com_github_rjeczalik_notify//:notify",
3332
"@com_github_sourcegraph_conc//pool",
33+
"@org_golang_x_sync//semaphore",
3434
],
3535
)
3636

dev/sg/internal/run/bazel_build.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package run
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"os/exec"
8+
9+
"github.com/sourcegraph/sourcegraph/dev/sg/internal/std"
10+
"github.com/sourcegraph/sourcegraph/dev/sg/root"
11+
"github.com/sourcegraph/sourcegraph/lib/output"
12+
"github.com/sourcegraph/sourcegraph/lib/process"
13+
)
14+
15+
// BazelBuild peforms a bazel build command with all the given targets and blocks until an
16+
// error is returned or the build is completed.
17+
func BazelBuild(ctx context.Context, cmds ...BazelCommand) error {
18+
if len(cmds) == 0 {
19+
// no Bazel commands so we return
20+
return nil
21+
}
22+
std.Out.WriteLine(output.Styled(output.StylePending, fmt.Sprintf("Detected %d bazel targets, running bazel build before anything else", len(cmds))))
23+
24+
repoRoot, err := root.RepositoryRoot()
25+
if err != nil {
26+
return err
27+
}
28+
29+
targets := make([]string, 0, len(cmds))
30+
for _, cmd := range cmds {
31+
targets = append(targets, cmd.Target)
32+
}
33+
34+
var cancel func()
35+
ctx, cancel = context.WithCancel(ctx)
36+
37+
args := append([]string{"build"}, targets...)
38+
cmd := exec.CommandContext(ctx, "bazel", args...)
39+
40+
sc := &startedCmd{
41+
stdoutBuf: &prefixSuffixSaver{N: 32 << 10},
42+
stderrBuf: &prefixSuffixSaver{N: 32 << 10},
43+
}
44+
45+
sc.cancel = cancel
46+
sc.Cmd = cmd
47+
sc.Cmd.Dir = repoRoot
48+
49+
var stdoutWriter, stderrWriter io.Writer
50+
logger := newCmdLogger(ctx, "bazel", std.Out.Output)
51+
stdoutWriter = io.MultiWriter(logger, sc.stdoutBuf)
52+
stderrWriter = io.MultiWriter(logger, sc.stderrBuf)
53+
eg, err := process.PipeOutputUnbuffered(ctx, sc.Cmd, stdoutWriter, stderrWriter)
54+
if err != nil {
55+
return err
56+
}
57+
sc.outEg = eg
58+
59+
// Bazel out directory should exist here before returning
60+
if err := sc.Start(); err != nil {
61+
return err
62+
}
63+
return sc.Wait()
64+
}

dev/sg/internal/run/bazel_command.go

Lines changed: 105 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,123 +3,150 @@ package run
33
import (
44
"context"
55
"fmt"
6+
"io"
67
"os/exec"
7-
"strings"
88

99
"github.com/rjeczalik/notify"
10-
1110
"github.com/sourcegraph/sourcegraph/dev/sg/internal/secrets"
11+
"github.com/sourcegraph/sourcegraph/dev/sg/internal/std"
12+
"github.com/sourcegraph/sourcegraph/lib/errors"
13+
"github.com/sourcegraph/sourcegraph/lib/output"
14+
"github.com/sourcegraph/sourcegraph/lib/process"
1215
)
1316

1417
// A BazelCommand is a command definition for sg run/start that uses
1518
// bazel under the hood. It will handle restarting itself autonomously,
1619
// as long as iBazel is running and watch that specific target.
1720
type BazelCommand struct {
18-
Name string
19-
Description string `yaml:"description"`
20-
Target string `yaml:"target"`
21-
Args string `yaml:"args"`
22-
PreCmd string `yaml:"precmd"`
23-
Env map[string]string `yaml:"env"`
24-
IgnoreStdout bool `yaml:"ignoreStdout"`
25-
IgnoreStderr bool `yaml:"ignoreStderr"`
26-
ContinueWatchOnExit bool `yaml:"continueWatchOnExit"`
27-
// Preamble is a short and visible message, displayed when the command is launched.
28-
Preamble string `yaml:"preamble"`
21+
Name string
22+
Description string `yaml:"description"`
23+
Target string `yaml:"target"`
24+
Args string `yaml:"args"`
25+
PreCmd string `yaml:"precmd"`
26+
Env map[string]string `yaml:"env"`
27+
IgnoreStdout bool `yaml:"ignoreStdout"`
28+
IgnoreStderr bool `yaml:"ignoreStderr"`
2929
ExternalSecrets map[string]secrets.ExternalSecret `yaml:"external_secrets"`
30-
31-
// RunTarget specifies a target that should be run via `bazel run $RunTarget` instead of directly executing the binary.
32-
RunTarget string `yaml:"runTarget"`
3330
}
3431

35-
func (bc BazelCommand) GetName() string {
36-
return bc.Name
32+
func (bc *BazelCommand) BinLocation() (string, error) {
33+
return binLocation(bc.Target)
3734
}
3835

39-
func (bc BazelCommand) GetContinueWatchOnExit() bool {
40-
return bc.ContinueWatchOnExit
41-
}
36+
func (bc *BazelCommand) watch(ctx context.Context) (<-chan struct{}, error) {
37+
// Grab the location of the binary in bazel-out.
38+
binLocation, err := bc.BinLocation()
39+
if err != nil {
40+
return nil, err
41+
}
4242

43-
func (bc BazelCommand) GetEnv() map[string]string {
44-
return bc.Env
45-
}
43+
// Set up the watcher.
44+
restart := make(chan struct{})
45+
events := make(chan notify.EventInfo, 1)
46+
if err := notify.Watch(binLocation, events, notify.All); err != nil {
47+
return nil, err
48+
}
4649

47-
func (bc BazelCommand) GetIgnoreStdout() bool {
48-
return bc.IgnoreStdout
49-
}
50+
// Start watching for a freshly compiled version of the binary.
51+
go func() {
52+
defer close(events)
53+
defer notify.Stop(events)
54+
55+
for {
56+
select {
57+
case <-ctx.Done():
58+
return
59+
case e := <-events:
60+
if e.Event() != notify.Remove {
61+
restart <- struct{}{}
62+
}
63+
}
5064

51-
func (bc BazelCommand) GetIgnoreStderr() bool {
52-
return bc.IgnoreStderr
53-
}
65+
}
66+
}()
5467

55-
func (bc BazelCommand) GetPreamble() string {
56-
return bc.Preamble
68+
return restart, nil
5769
}
5870

59-
func (bc BazelCommand) GetBinaryLocation() (string, error) {
60-
baseOutput, err := outputPath()
71+
func (bc *BazelCommand) Start(ctx context.Context, dir string, parentEnv map[string]string) error {
72+
std.Out.WriteLine(output.Styledf(output.StylePending, "Running %s...", bc.Name))
73+
74+
// Run the binary for the first time.
75+
cancel, err := bc.start(ctx, dir, parentEnv)
6176
if err != nil {
62-
return "", err
77+
return errors.Wrapf(err, "failed to start Bazel command %q", bc.Name)
6378
}
64-
// Trim "bazel-out" because the next bazel query will include it.
65-
outputPath := strings.TrimSuffix(strings.TrimSpace(string(baseOutput)), "bazel-out")
6679

67-
// Get the binary from the specific target.
68-
cmd := exec.Command("bazel", "cquery", bc.Target, "--output=files")
69-
baseOutput, err = cmd.Output()
80+
// Restart when the binary change.
81+
wantRestart, err := bc.watch(ctx)
7082
if err != nil {
71-
return "", err
83+
return err
7284
}
73-
binPath := strings.TrimSpace(string(baseOutput))
7485

75-
return fmt.Sprintf("%s%s", outputPath, binPath), nil
86+
// Wait forever until we're asked to stop or that restarting returns an error.
87+
for {
88+
select {
89+
case <-ctx.Done():
90+
return ctx.Err()
91+
case <-wantRestart:
92+
std.Out.WriteLine(output.Styledf(output.StylePending, "Restarting %s...", bc.Name))
93+
cancel()
94+
cancel, err = bc.start(ctx, dir, parentEnv)
95+
if err != nil {
96+
return err
97+
}
98+
}
99+
}
76100
}
77101

78-
func (bc BazelCommand) GetExternalSecrets() map[string]secrets.ExternalSecret {
79-
return bc.ExternalSecrets
80-
}
102+
func (bc *BazelCommand) start(ctx context.Context, dir string, parentEnv map[string]string) (func(), error) {
103+
binLocation, err := bc.BinLocation()
104+
if err != nil {
105+
return nil, err
106+
}
81107

82-
func (bc BazelCommand) watchPaths() ([]string, error) {
83-
// If no target is defined, there is nothing to be built and watched
84-
if bc.Target == "" {
85-
return nil, nil
108+
sc := &startedCmd{
109+
stdoutBuf: &prefixSuffixSaver{N: 32 << 10},
110+
stderrBuf: &prefixSuffixSaver{N: 32 << 10},
86111
}
87-
// Grab the location of the binary in bazel-out.
88-
binLocation, err := bc.GetBinaryLocation()
112+
113+
commandCtx, cancel := context.WithCancel(ctx)
114+
sc.cancel = cancel
115+
sc.Cmd = exec.CommandContext(commandCtx, "bash", "-c", fmt.Sprintf("%s\n%s", bc.PreCmd, binLocation))
116+
sc.Cmd.Dir = dir
117+
118+
secretsEnv, err := getSecrets(ctx, bc.Name, bc.ExternalSecrets)
89119
if err != nil {
90-
return nil, err
120+
std.Out.WriteLine(output.Styledf(output.StyleWarning, "[%s] %s %s",
121+
bc.Name, output.EmojiFailure, err.Error()))
91122
}
92-
return []string{binLocation}, nil
93123

94-
}
124+
sc.Cmd.Env = makeEnv(parentEnv, secretsEnv, bc.Env)
95125

96-
func (bc BazelCommand) StartWatch(ctx context.Context) (<-chan struct{}, error) {
97-
if watchPaths, err := bc.watchPaths(); err != nil {
98-
return nil, err
126+
var stdoutWriter, stderrWriter io.Writer
127+
logger := newCmdLogger(commandCtx, bc.Name, std.Out.Output)
128+
if bc.IgnoreStdout {
129+
std.Out.WriteLine(output.Styledf(output.StyleSuggestion, "Ignoring stdout of %s", bc.Name))
130+
stdoutWriter = sc.stdoutBuf
99131
} else {
100-
// skip remove events as we don't care about files being removed, we only
101-
// want to know when the binary has been rebuilt
102-
return WatchPaths(ctx, watchPaths, notify.Remove)
132+
stdoutWriter = io.MultiWriter(logger, sc.stdoutBuf)
103133
}
104-
}
105-
106-
func (bc BazelCommand) GetExecCmd(ctx context.Context) (*exec.Cmd, error) {
107-
var cmd string
108-
var err error
109-
if bc.RunTarget != "" {
110-
cmd = "bazel run " + bc.RunTarget
134+
if bc.IgnoreStderr {
135+
std.Out.WriteLine(output.Styledf(output.StyleSuggestion, "Ignoring stderr of %s", bc.Name))
136+
stderrWriter = sc.stderrBuf
111137
} else {
112-
if cmd, err = bc.GetBinaryLocation(); err != nil {
113-
return nil, err
114-
}
138+
stderrWriter = io.MultiWriter(logger, sc.stderrBuf)
115139
}
116140

117-
return exec.CommandContext(ctx, "bash", "-c", fmt.Sprintf("%s\n%s", bc.PreCmd, cmd)), nil
118-
}
141+
eg, err := process.PipeOutputUnbuffered(ctx, sc.Cmd, stdoutWriter, stderrWriter)
142+
if err != nil {
143+
return nil, err
144+
}
145+
sc.outEg = eg
146+
147+
if err := sc.Start(); err != nil {
148+
return nil, err
149+
}
119150

120-
func outputPath() ([]byte, error) {
121-
// Get the output directory from Bazel, which varies depending on which OS
122-
// we're running against.
123-
cmd := exec.Command("bazel", "info", "output_path")
124-
return cmd.Output()
151+
return cancel, nil
125152
}

0 commit comments

Comments
 (0)