From 70cc3e556ad3c4153c732373c3e1d8e2e859a94a Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:44:07 -0700 Subject: [PATCH 1/2] feat: allow envs and workspace root into bazelisk Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- pkg/aspect/aquery/aquery.go | 2 +- pkg/aspect/aquery/aquery_test.go | 10 ++-- pkg/aspect/build/build.go | 2 +- pkg/aspect/build/build_test.go | 6 +- pkg/aspect/clean/clean.go | 2 +- pkg/aspect/clean/clean_test.go | 34 ++++++------ pkg/aspect/cquery/cquery.go | 2 +- pkg/aspect/cquery/cquery_test.go | 10 ++-- pkg/aspect/info/info.go | 2 +- pkg/aspect/query/query.go | 2 +- pkg/aspect/query/query_test.go | 10 ++-- pkg/aspect/query/shared/query.go | 4 +- pkg/aspect/run/run.go | 2 +- pkg/aspect/run/run_test.go | 6 +- pkg/aspect/test/test.go | 2 +- pkg/aspect/test/test_test.go | 5 +- pkg/aspect/version/version.go | 2 +- pkg/bazel/bazel.go | 42 +++++++++++--- pkg/bazel/bazel_test.go | 84 +++++++++++++++++++++++++++- pkg/bazel/bazelisk.go | 94 +++++++++++++++++--------------- 20 files changed, 217 insertions(+), 106 deletions(-) diff --git a/pkg/aspect/aquery/aquery.go b/pkg/aspect/aquery/aquery.go index 0f68a2d17..fbad4c3c4 100644 --- a/pkg/aspect/aquery/aquery.go +++ b/pkg/aspect/aquery/aquery.go @@ -68,5 +68,5 @@ func (q *AQuery) Run(cmd *cobra.Command, args []string) error { } } - return shared.RunQuery(q.Bzl, presetVerb, query) + return shared.RunQuery(q.Bzl, presetVerb, query, q.Streams) } diff --git a/pkg/aspect/aquery/aquery_test.go b/pkg/aspect/aquery/aquery_test.go index 647e0b74f..f74ed0de6 100644 --- a/pkg/aspect/aquery/aquery_test.go +++ b/pkg/aspect/aquery/aquery_test.go @@ -30,14 +30,14 @@ func TestQuery(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} q := aquery.New(streams, spawner, true) q.Presets = []*shared.PresetQuery{ { @@ -63,7 +63,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -159,7 +159,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) diff --git a/pkg/aspect/build/build.go b/pkg/aspect/build/build.go index 02c641ca1..f39867eb0 100644 --- a/pkg/aspect/build/build.go +++ b/pkg/aspect/build/build.go @@ -38,7 +38,7 @@ func New( // Event Protocol backend used by Aspect plugins to subscribe to build events. func (b *Build) Run(args []string, besBackend bep.BESBackend) (exitErr error) { besBackendFlag := fmt.Sprintf("--bes_backend=%s", besBackend.Addr()) - exitCode, bazelErr := b.bzl.Spawn(append([]string{"build", besBackendFlag}, args...)) + exitCode, bazelErr := b.bzl.Spawn(append([]string{"build", besBackendFlag}, args...), b.Streams) // Process the subscribers errors before the Bazel one. subscriberErrors := besBackend.Errors() diff --git a/pkg/aspect/build/build_test.go b/pkg/aspect/build/build_test.go index f50dbc0cd..8fe9fb04a 100644 --- a/pkg/aspect/build/build_test.go +++ b/pkg/aspect/build/build_test.go @@ -37,7 +37,7 @@ func TestBuild(t *testing.T) { } bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(expectErr.ExitCode, expectErr.Err) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -66,7 +66,7 @@ func TestBuild(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -99,7 +99,7 @@ func TestBuild(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. diff --git a/pkg/aspect/clean/clean.go b/pkg/aspect/clean/clean.go index 6411f04da..65faaaf7c 100644 --- a/pkg/aspect/clean/clean.go +++ b/pkg/aspect/clean/clean.go @@ -180,7 +180,7 @@ func (c *Clean) Run(_ *cobra.Command, _ []string) error { if c.ExpungeAsync { cmd = append(cmd, "--expunge_async") } - if exitCode, err := c.bzl.Spawn(cmd); exitCode != 0 { + if exitCode, err := c.bzl.Spawn(cmd, c.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/clean/clean_test.go b/pkg/aspect/clean/clean_test.go index b52f687ca..bc528e382 100644 --- a/pkg/aspect/clean/clean_test.go +++ b/pkg/aspect/clean/clean_test.go @@ -67,13 +67,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + streams := ioutils.Streams{} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}). + Spawn([]string{"clean"}, streams). Return(0, nil) - b := clean.New(ioutils.Streams{}, bzl, false) + b := clean.New(streams, bzl, false) g.Expect(b.Run(nil, []string{})).Should(Succeed()) }) @@ -82,13 +83,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + streams := ioutils.Streams{} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean", "--expunge"}). + Spawn([]string{"clean", "--expunge"}, streams). Return(0, nil) - b := clean.New(ioutils.Streams{}, bzl, false) + b := clean.New(streams, bzl, false) b.Expunge = true g.Expect(b.Run(nil, []string{})).Should(Succeed()) }) @@ -98,13 +100,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + streams := ioutils.Streams{} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean", "--expunge_async"}). + Spawn([]string{"clean", "--expunge_async"}, streams). Return(0, nil) - b := clean.New(ioutils.Streams{}, bzl, false) + b := clean.New(streams, bzl, false) b.ExpungeAsync = true g.Expect(b.Run(nil, []string{})).Should(Succeed()) }) @@ -114,14 +117,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}). + Spawn([]string{"clean"}, streams). Return(0, nil) - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} b := clean.New(streams, bzl, true) b.Behavior = chooseReclaim{} @@ -136,14 +139,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}). + Spawn([]string{"clean"}, streams). Return(0, nil).AnyTimes() - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} b := clean.New(streams, bzl, true) viper := *viper.New() @@ -195,15 +198,14 @@ func TestClean(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}). + Spawn([]string{"clean"}, streams). Return(0, nil) - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} - c := clean.New(streams, bzl, true) c.Behavior = chooseWorkaround{} c.Workaround = confirm{} diff --git a/pkg/aspect/cquery/cquery.go b/pkg/aspect/cquery/cquery.go index 5f2a8a7f7..89bad01aa 100644 --- a/pkg/aspect/cquery/cquery.go +++ b/pkg/aspect/cquery/cquery.go @@ -68,5 +68,5 @@ func (q *CQuery) Run(cmd *cobra.Command, args []string) error { } } - return shared.RunQuery(q.Bzl, presetVerb, query) + return shared.RunQuery(q.Bzl, presetVerb, query, q.Streams) } diff --git a/pkg/aspect/cquery/cquery_test.go b/pkg/aspect/cquery/cquery_test.go index 9c6e305d5..ff4233e16 100644 --- a/pkg/aspect/cquery/cquery_test.go +++ b/pkg/aspect/cquery/cquery_test.go @@ -30,14 +30,14 @@ func TestQuery(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} q := cquery.New(streams, spawner, true) q.Presets = []*shared.PresetQuery{ { @@ -63,7 +63,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -159,7 +159,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) diff --git a/pkg/aspect/info/info.go b/pkg/aspect/info/info.go index 788053c26..aed46270c 100644 --- a/pkg/aspect/info/info.go +++ b/pkg/aspect/info/info.go @@ -39,7 +39,7 @@ func (v *Info) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd = append(bazelCmd, args...) bzl := bazel.New() - if exitCode, err := bzl.Spawn(bazelCmd); exitCode != 0 { + if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/query/query.go b/pkg/aspect/query/query.go index c87261254..66ca9349c 100644 --- a/pkg/aspect/query/query.go +++ b/pkg/aspect/query/query.go @@ -108,7 +108,7 @@ func (q *Query) Run(cmd *cobra.Command, args []string) error { } } - return shared.RunQuery(q.Bzl, presetVerb, query) + return shared.RunQuery(q.Bzl, presetVerb, query, q.Streams) } func (q *Query) checkConfig(baseUseKey string, baseInquiredKey string, question string) error { diff --git a/pkg/aspect/query/query_test.go b/pkg/aspect/query/query_test.go index 4c007a9e6..f76f3d8fb 100644 --- a/pkg/aspect/query/query_test.go +++ b/pkg/aspect/query/query_test.go @@ -32,14 +32,14 @@ func TestQuery(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} q := query.New(streams, spawner, true) q.Presets = []*shared.PresetQuery{ { @@ -72,7 +72,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -217,7 +217,7 @@ func TestQuery(t *testing.T) { spawner := bazel_mock.NewMockBazel(ctrl) spawner. EXPECT(). - Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}). + Spawn([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) diff --git a/pkg/aspect/query/shared/query.go b/pkg/aspect/query/shared/query.go index 1ad88fadb..1266cd3b8 100644 --- a/pkg/aspect/query/shared/query.go +++ b/pkg/aspect/query/shared/query.go @@ -156,13 +156,13 @@ func ProcessQueries(presets []*PresetQuery) (map[string]*PresetQuery, []string, return processedPresets, presetNames, nil } -func RunQuery(bzl bazel.Bazel, verb string, query string) error { +func RunQuery(bzl bazel.Bazel, verb string, query string, streams ioutils.Streams) error { bazelCmd := []string{ verb, query, } - if exitCode, err := bzl.Spawn(bazelCmd); exitCode != 0 { + if exitCode, err := bzl.Spawn(bazelCmd, streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/run/run.go b/pkg/aspect/run/run.go index 4f0d37cc1..b6909030f 100644 --- a/pkg/aspect/run/run.go +++ b/pkg/aspect/run/run.go @@ -38,7 +38,7 @@ func New( // Event Protocol backend used by Aspect plugins to subscribe to build events. func (cmd *Run) Run(args []string, besBackend bep.BESBackend) (exitErr error) { besBackendFlag := fmt.Sprintf("--bes_backend=%s", besBackend.Addr()) - exitCode, bazelErr := cmd.bzl.Spawn(append([]string{"run", besBackendFlag}, args...)) + exitCode, bazelErr := cmd.bzl.Spawn(append([]string{"run", besBackendFlag}, args...), cmd.Streams) // Process the subscribers errors before the Bazel one. subscriberErrors := besBackend.Errors() diff --git a/pkg/aspect/run/run_test.go b/pkg/aspect/run/run_test.go index 353e95ee9..c6d5cce1e 100644 --- a/pkg/aspect/run/run_test.go +++ b/pkg/aspect/run/run_test.go @@ -37,7 +37,7 @@ func TestRun(t *testing.T) { } bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(expectErr.ExitCode, expectErr.Err) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -66,7 +66,7 @@ func TestRun(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -99,7 +99,7 @@ func TestRun(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}). + Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. diff --git a/pkg/aspect/test/test.go b/pkg/aspect/test/test.go index 6d6945850..0d8944fbe 100644 --- a/pkg/aspect/test/test.go +++ b/pkg/aspect/test/test.go @@ -34,7 +34,7 @@ func (t *Test) Run(args []string, besBackend bep.BESBackend) (exitErr error) { bazelCmd := []string{"test", besBackendFlag} bazelCmd = append(bazelCmd, args...) - exitCode, bazelErr := t.bzl.Spawn(bazelCmd) + exitCode, bazelErr := t.bzl.Spawn(bazelCmd, t.Streams) // Process the subscribers errors before the Bazel one. subscriberErrors := besBackend.Errors() diff --git a/pkg/aspect/test/test_test.go b/pkg/aspect/test/test_test.go index da5c99b1e..6146fb5d0 100644 --- a/pkg/aspect/test/test_test.go +++ b/pkg/aspect/test/test_test.go @@ -27,10 +27,11 @@ func TestTest(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + streams := ioutils.Streams{} bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"test", "--bes_backend=grpc://127.0.0.1:12345"}). + Spawn([]string{"test", "--bes_backend=grpc://127.0.0.1:12345"}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) @@ -44,7 +45,7 @@ func TestTest(t *testing.T) { Errors(). Times(1) - b := test.New(ioutils.Streams{}, bzl) + b := test.New(streams, bzl) g.Expect(b.Run([]string{}, besBackend)).Should(Succeed()) }) } diff --git a/pkg/aspect/version/version.go b/pkg/aspect/version/version.go index 639819ea5..e5cefc3f6 100644 --- a/pkg/aspect/version/version.go +++ b/pkg/aspect/version/version.go @@ -51,7 +51,7 @@ func (v *Version) Run(bzl bazel.Bazel) error { } else { fmt.Fprintf(v.Stdout, "Aspect version: %s\n", version) } - bzl.Spawn(bazelCmd) + bzl.Spawn(bazelCmd, v.Streams) return nil } diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index 10ebf7e38..d0ad4e59f 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -41,7 +41,7 @@ var startupFlags []string type Bazel interface { AQuery(expr string) (*analysis.ActionGraphContainer, error) - Spawn(command []string) (int, error) + Spawn(command []string, streams ioutils.Streams) (int, error) RunCommand(command []string, streams ioutils.Streams) (int, error) Flags() (map[string]*flags.FlagInfo, error) AvailableStartupFlags() []string @@ -50,6 +50,9 @@ type Bazel interface { type bazel struct { workspaceFinder workspace.Finder + + overrideWorkspaceRoot string + env []string } func New() Bazel { @@ -58,6 +61,23 @@ func New() Bazel { } } +// WithOverrideWorkspaceRoot returns a new instance of Bazel, overriding the +// value for the workspace root. +func (b *bazel) WithOverrideWorkspaceRoot(workspaceRoot string) Bazel { + newBazel := *b + newBazel.workspaceFinder = nil + newBazel.overrideWorkspaceRoot = workspaceRoot + return &newBazel +} + +// WithEnv returns a new instance of Bazel, setting the provided environment +// variables. +func (b *bazel) WithEnv(env []string) Bazel { + newBazel := *b + newBazel.env = env + return &newBazel +} + // AvailableStartupFlags will return the full list of startup flags available for // the current version of bazel. This is NOT the list of startup flags that have been // set for the current run via SetStartupFlags. @@ -84,24 +104,28 @@ func (*bazel) createRepositories() *core.Repositories { // Spawn is similar to the main() function of bazelisk // see https://github.com/bazelbuild/bazelisk/blob/7c3d9d5/bazelisk.go -func (b *bazel) Spawn(command []string) (int, error) { - return b.RunCommand(command, ioutils.DefaultStreams) +func (b *bazel) Spawn(command []string, streams ioutils.Streams) (int, error) { + return b.RunCommand(command, streams) } func (b *bazel) RunCommand(command []string, streams ioutils.Streams) (int, error) { - // Prepend startup flags command = append(startupFlags, command...) repos := b.createRepositories() - workspaceRoot, err := b.workspaceFinder.Find() - if err != nil { - return 1, err + var bazelisk *Bazelisk + if b.overrideWorkspaceRoot != "" { + bazelisk = NewBazelisk(b.overrideWorkspaceRoot) + } else { + workspaceRoot, err := b.workspaceFinder.Find() + if err != nil { + return 1, err + } + bazelisk = NewBazelisk(workspaceRoot) } - bazelisk := NewBazelisk(workspaceRoot) - exitCode, err := bazelisk.Run(command, repos, streams) + exitCode, err := bazelisk.Run(command, repos, streams, b.env) return exitCode, err } diff --git a/pkg/bazel/bazel_test.go b/pkg/bazel/bazel_test.go index b0ae1358f..54f779b84 100644 --- a/pkg/bazel/bazel_test.go +++ b/pkg/bazel/bazel_test.go @@ -8,16 +8,48 @@ package bazel import ( "fmt" + "os" + "path/filepath" + "strings" "testing" "github.com/golang/mock/gomock" . "github.com/onsi/gomega" workspace_mock "aspect.build/cli/pkg/bazel/workspace/mock" + "aspect.build/cli/pkg/ioutils" ) +var testTmpdir = os.Getenv("TEST_TMPDIR") +var workspaceDir = filepath.Join(testTmpdir, "project") +var workspaceFile = filepath.Join(workspaceDir, "WORKSPACE") +var workspaceOverrideDir = filepath.Join(testTmpdir, "project", "foo", "bar") +var wrapperOverridePath = filepath.Join(workspaceOverrideDir, wrapperPath) +var wrapperContents = []byte("#!/usr/bin/env bash\nprintf 'wrapper called'") + +func init() { + if err := os.Setenv("BAZELISK_HOME", testTmpdir); err != nil { + panic(err) + } + if err := os.MkdirAll(workspaceDir, os.ModePerm); err != nil { + panic(err) + } + if err := os.WriteFile(workspaceFile, []byte{}, 0644); err != nil { + panic(err) + } + if err := os.MkdirAll(filepath.Dir(wrapperOverridePath), os.ModePerm); err != nil { + panic(err) + } + if err := os.WriteFile(wrapperOverridePath, wrapperContents, 0777); err != nil { + panic(err) + } + if err := os.Chdir(workspaceDir); err != nil { + panic(err) + } +} + func TestBazel(t *testing.T) { - t.Run("when the workspace finder fails, the interceptor fails", func(t *testing.T) { + t.Run("when the workspace finder fails, Spawn fails", func(t *testing.T) { g := NewGomegaWithT(t) ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -34,7 +66,55 @@ func TestBazel(t *testing.T) { workspaceFinder: workspaceFinder, } - _, err := bzl.Spawn([]string{"help"}) + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} + _, err := bzl.Spawn([]string{"--print_env"}, streams) g.Expect(err).To(MatchError(expectedErr)) }) + + t.Run("when a custom environment is passed, it should be used by bazelisk", func(t *testing.T) { + g := NewGomegaWithT(t) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + workspaceFinder := workspace_mock.NewMockFinder(ctrl) + workspaceFinder.EXPECT(). + Find(). + Return("", nil). + Times(1) + + bzl := &bazel{ + workspaceFinder: workspaceFinder, + } + + env := []string{fmt.Sprintf("FOO=%s", "BAR")} + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} + _, err := bzl.WithEnv(env).Spawn([]string{"--print_env"}, streams) + g.Expect(err).To(Not(HaveOccurred())) + g.Expect(stdout.String()).To(ContainSubstring("FOO=BAR")) + }) + + t.Run("when the workspace override directory is set, it should be used by bazelisk", func(t *testing.T) { + g := NewGomegaWithT(t) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + workspaceFinder := workspace_mock.NewMockFinder(ctrl) + workspaceFinder.EXPECT(). + Find(). + Times(0) + + bzl := &bazel{ + workspaceFinder: workspaceFinder, + } + + var out strings.Builder + streams := ioutils.Streams{Stdout: &out, Stderr: &out} + // workspaceOverrideDir is an unconventional location that has a tools/bazel to be used. + // It must run the tools/bazel we placed under that location. + _, err := bzl.WithOverrideWorkspaceRoot(workspaceOverrideDir).Spawn([]string{"build"}, streams) + g.Expect(err).To(Not(HaveOccurred())) + g.Expect(out.String()).To(Equal("wrapper called")) + }) } diff --git a/pkg/bazel/bazelisk.go b/pkg/bazel/bazelisk.go index c681f0e9e..5d81ab160 100644 --- a/pkg/bazel/bazelisk.go +++ b/pkg/bazel/bazelisk.go @@ -57,7 +57,7 @@ func NewBazelisk(workspaceRoot string) *Bazelisk { } // Run runs the main Bazelisk logic for the given arguments and Bazel repositories. -func (bazelisk *Bazelisk) Run(args []string, repos *core.Repositories, streams ioutils.Streams) (int, error) { +func (bazelisk *Bazelisk) Run(args []string, repos *core.Repositories, streams ioutils.Streams, env []string) (int, error) { httputil.UserAgent = bazelisk.getUserAgent() bazeliskHome := bazelisk.GetEnvOrConfig("BAZELISK_HOME") @@ -124,9 +124,9 @@ func (bazelisk *Bazelisk) Run(args []string, repos *core.Repositories, streams i // --print_env must be the first argument. if len(args) > 0 && args[0] == "--print_env" { // print environment variables for sub-processes - cmd := bazelisk.makeBazelCmd(bazelPath, args, ioutils.DefaultStreams) + cmd := bazelisk.makeBazelCmd(bazelPath, args, streams, env) for _, val := range cmd.Env { - fmt.Println(val) + fmt.Fprintln(streams.Stdout, val) } return 0, nil } @@ -143,7 +143,7 @@ func (bazelisk *Bazelisk) Run(args []string, repos *core.Repositories, streams i } if args[0] == "--migrate" { - bazelisk.migrate(bazelPath, args[1:], newFlags) + bazelisk.migrate(streams, bazelPath, args[1:], newFlags) } else { // When --strict is present, it expands to the list of --incompatible_ flags // that should be enabled for the given Bazel version. @@ -165,13 +165,13 @@ func (bazelisk *Bazelisk) Run(args []string, repos *core.Repositories, streams i } if gnuFormat { - fmt.Printf("Bazelisk %s\n", BazeliskVersion) + fmt.Fprintf(streams.Stdout, "Bazelisk %s\n", BazeliskVersion) } else { - fmt.Printf("Bazelisk version: %s\n", BazeliskVersion) + fmt.Fprintf(streams.Stdout, "Bazelisk version: %s\n", BazeliskVersion) } } - exitCode, err := bazelisk.runBazel(bazelPath, args, streams) + exitCode, err := bazelisk.runBazel(bazelPath, args, streams, env) if err != nil { return -1, fmt.Errorf("could not run Bazel: %v", err) } @@ -375,11 +375,15 @@ func (bazelisk *Bazelisk) prependDirToPathList(cmd *exec.Cmd, dir string) { } } -func (bazelisk *Bazelisk) makeBazelCmd(bazel string, args []string, streams ioutils.Streams) *exec.Cmd { +func (bazelisk *Bazelisk) makeBazelCmd(bazel string, args []string, streams ioutils.Streams, env []string) *exec.Cmd { execPath := bazelisk.maybeDelegateToWrapper(bazel) cmd := exec.Command(execPath, args...) - cmd.Env = append(os.Environ(), skipWrapperEnv+"=true") + cmd.Env = os.Environ() + if env != nil { + cmd.Env = append(cmd.Env, env...) + } + cmd.Env = append(cmd.Env, skipWrapperEnv+"=true") if execPath != bazel { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", bazelReal, bazel)) } @@ -390,8 +394,8 @@ func (bazelisk *Bazelisk) makeBazelCmd(bazel string, args []string, streams iout return cmd } -func (bazelisk *Bazelisk) runBazel(bazel string, args []string, streams ioutils.Streams) (int, error) { - cmd := bazelisk.makeBazelCmd(bazel, args, streams) +func (bazelisk *Bazelisk) runBazel(bazel string, args []string, streams ioutils.Streams, env []string) (int, error) { + cmd := bazelisk.makeBazelCmd(bazel, args, streams, env) err := cmd.Start() if err != nil { return 1, fmt.Errorf("could not start Bazel: %v", err) @@ -427,7 +431,7 @@ func (bazelisk *Bazelisk) getIncompatibleFlags(bazelPath, cmd string) ([]string, Stdout: &out, Stderr: nil, } - if _, err := bazelisk.runBazel(bazelPath, []string{"help", cmd, "--short"}, streams); err != nil { + if _, err := bazelisk.runBazel(bazelPath, []string{"help", cmd, "--short"}, streams, nil); err != nil { return nil, fmt.Errorf("unable to determine incompatible flags with binary %s: %v", bazelPath, err) } @@ -460,71 +464,71 @@ func (bazelisk *Bazelisk) insertArgs(baseArgs []string, newArgs []string) []stri return result } -func (bazelisk *Bazelisk) shutdownIfNeeded(bazelPath string) { +func (bazelisk *Bazelisk) shutdownIfNeeded(streams ioutils.Streams, bazelPath string) { bazeliskClean := bazelisk.GetEnvOrConfig("BAZELISK_SHUTDOWN") if len(bazeliskClean) == 0 { return } - fmt.Printf("bazel shutdown\n") - exitCode, err := bazelisk.runBazel(bazelPath, []string{"shutdown"}, ioutils.DefaultStreams) - fmt.Printf("\n") + fmt.Fprintf(streams.Stdout, "bazel shutdown\n") + exitCode, err := bazelisk.runBazel(bazelPath, []string{"shutdown"}, streams, nil) + fmt.Fprintf(streams.Stdout, "\n") if err != nil { log.Fatalf("failed to run bazel shutdown: %v", err) } if exitCode != 0 { - fmt.Printf("Failure: shutdown command failed.\n") + fmt.Fprintf(streams.Stderr, "Failure: shutdown command failed.\n") os.Exit(exitCode) } } -func (bazelisk *Bazelisk) cleanIfNeeded(bazelPath string) { +func (bazelisk *Bazelisk) cleanIfNeeded(streams ioutils.Streams, bazelPath string) { bazeliskClean := bazelisk.GetEnvOrConfig("BAZELISK_CLEAN") if len(bazeliskClean) == 0 { return } - fmt.Printf("bazel clean --expunge\n") - exitCode, err := bazelisk.runBazel(bazelPath, []string{"clean", "--expunge"}, ioutils.DefaultStreams) - fmt.Printf("\n") + fmt.Fprintf(streams.Stdout, "bazel clean --expunge\n") + exitCode, err := bazelisk.runBazel(bazelPath, []string{"clean", "--expunge"}, streams, nil) + fmt.Fprintf(streams.Stdout, "\n") if err != nil { log.Fatalf("failed to run clean: %v", err) } if exitCode != 0 { - fmt.Printf("Failure: clean command failed.\n") + fmt.Fprintf(streams.Stdout, "Failure: clean command failed.\n") os.Exit(exitCode) } } // migrate will run Bazel with each flag separately and report which ones are failing. -func (bazelisk *Bazelisk) migrate(bazelPath string, baseArgs []string, flags []string) { +func (bazelisk *Bazelisk) migrate(streams ioutils.Streams, bazelPath string, baseArgs []string, flags []string) { // 1. Try with all the flags. args := bazelisk.insertArgs(baseArgs, flags) - fmt.Printf("\n\n--- Running Bazel with all incompatible flags\n\n") - bazelisk.shutdownIfNeeded(bazelPath) - bazelisk.cleanIfNeeded(bazelPath) - fmt.Printf("bazel %s\n", strings.Join(args, " ")) - exitCode, err := bazelisk.runBazel(bazelPath, args, ioutils.DefaultStreams) + fmt.Fprintf(streams.Stdout, "\n\n--- Running Bazel with all incompatible flags\n\n") + bazelisk.shutdownIfNeeded(streams, bazelPath) + bazelisk.cleanIfNeeded(streams, bazelPath) + fmt.Fprintf(streams.Stdout, "bazel %s\n", strings.Join(args, " ")) + exitCode, err := bazelisk.runBazel(bazelPath, args, streams, nil) if err != nil { log.Fatalf("could not run Bazel: %v", err) } if exitCode == 0 { - fmt.Printf("Success: No migration needed.\n") + fmt.Fprintf(streams.Stdout, "Success: No migration needed.\n") os.Exit(0) } // 2. Try with no flags, as a sanity check. args = baseArgs - fmt.Printf("\n\n--- Running Bazel with no incompatible flags\n\n") - bazelisk.shutdownIfNeeded(bazelPath) - bazelisk.cleanIfNeeded(bazelPath) - fmt.Printf("bazel %s\n", strings.Join(args, " ")) - exitCode, err = bazelisk.runBazel(bazelPath, args, ioutils.DefaultStreams) + fmt.Fprintf(streams.Stdout, "\n\n--- Running Bazel with no incompatible flags\n\n") + bazelisk.shutdownIfNeeded(streams, bazelPath) + bazelisk.cleanIfNeeded(streams, bazelPath) + fmt.Fprintf(streams.Stdout, "bazel %s\n", strings.Join(args, " ")) + exitCode, err = bazelisk.runBazel(bazelPath, args, streams, nil) if err != nil { log.Fatalf("could not run Bazel: %v", err) } if exitCode != 0 { - fmt.Printf("Failure: Command failed, even without incompatible flags.\n") + fmt.Fprintf(streams.Stdout, "Failure: Command failed, even without incompatible flags.\n") os.Exit(exitCode) } @@ -533,11 +537,11 @@ func (bazelisk *Bazelisk) migrate(bazelPath string, baseArgs []string, flags []s var failList []string for _, arg := range flags { args = bazelisk.insertArgs(baseArgs, []string{arg}) - fmt.Printf("\n\n--- Running Bazel with %s\n\n", arg) - bazelisk.shutdownIfNeeded(bazelPath) - bazelisk.cleanIfNeeded(bazelPath) - fmt.Printf("bazel %s\n", strings.Join(args, " ")) - exitCode, err = bazelisk.runBazel(bazelPath, args, ioutils.DefaultStreams) + fmt.Fprintf(streams.Stdout, "\n\n--- Running Bazel with %s\n\n", arg) + bazelisk.shutdownIfNeeded(streams, bazelPath) + bazelisk.cleanIfNeeded(streams, bazelPath) + fmt.Fprintf(streams.Stdout, "bazel %s\n", strings.Join(args, " ")) + exitCode, err = bazelisk.runBazel(bazelPath, args, streams, nil) if err != nil { log.Fatalf("could not run Bazel: %v", err) } @@ -550,16 +554,16 @@ func (bazelisk *Bazelisk) migrate(bazelPath string, baseArgs []string, flags []s print := func(l []string) { for _, arg := range l { - fmt.Printf(" %s\n", arg) + fmt.Fprintf(streams.Stdout, " %s\n", arg) } } // 4. Print report - fmt.Printf("\n\n+++ Result\n\n") - fmt.Printf("Command was successful with the following flags:\n") + fmt.Fprintf(streams.Stdout, "\n\n+++ Result\n\n") + fmt.Fprintf(streams.Stdout, "Command was successful with the following flags:\n") print(passList) - fmt.Printf("\n") - fmt.Printf("Migration is needed for the following flags:\n") + fmt.Fprintf(streams.Stdout, "\n") + fmt.Fprintf(streams.Stdout, "Migration is needed for the following flags:\n") print(failList) os.Exit(1) From f9f7400ed429265f6beaa5f3e8d2ae7e92c8c560 Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Tue, 12 Jul 2022 10:39:35 -0700 Subject: [PATCH 2/2] fix: run gazelle Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- pkg/bazel/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/bazel/BUILD.bazel b/pkg/bazel/BUILD.bazel index 579e60f08..38071e9f6 100644 --- a/pkg/bazel/BUILD.bazel +++ b/pkg/bazel/BUILD.bazel @@ -29,6 +29,7 @@ go_test( embed = [":bazel"], deps = [ "//pkg/bazel/workspace/mock", + "//pkg/ioutils", "@com_github_golang_mock//gomock", "@com_github_onsi_gomega//:gomega", ],