From 6a670c96ac614e24536e7ad978c81447cc0aa379 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 01:39:48 -0600 Subject: [PATCH 01/14] Tests are green --- cmd/aspect/aquery/aquery.go | 8 +- cmd/aspect/build/build.go | 8 +- cmd/aspect/clean/clean.go | 8 +- cmd/aspect/cquery/cquery.go | 8 +- cmd/aspect/query/query.go | 8 +- cmd/aspect/run/run.go | 8 +- cmd/aspect/test/test.go | 8 +- cmd/aspect/version/version.go | 8 +- pkg/aspect/analyzeprofile/analyzeprofile.go | 7 +- pkg/aspect/aquery/aquery_test.go | 6 +- pkg/aspect/build/build.go | 2 +- pkg/aspect/build/build_test.go | 6 +- .../canonicalizeflags/canonicalizeflags.go | 7 +- pkg/aspect/clean/clean.go | 2 +- pkg/aspect/clean/clean_test.go | 12 +-- pkg/aspect/cquery/cquery_test.go | 6 +- pkg/aspect/dump/dump.go | 7 +- pkg/aspect/fetch/fetch.go | 7 +- pkg/aspect/info/info.go | 7 +- pkg/aspect/mobileinstall/mobileinstall.go | 7 +- pkg/aspect/modquery/modquery.go | 7 +- pkg/aspect/printaction/printaction.go | 7 +- pkg/aspect/query/query_test.go | 6 +- pkg/aspect/query/shared/query.go | 2 +- pkg/aspect/root/flags/bazel_flags.go | 5 +- pkg/aspect/root/flags/interceptor.go | 5 +- pkg/aspect/run/run.go | 2 +- pkg/aspect/run/run_test.go | 6 +- pkg/aspect/shutdown/shutdown.go | 7 +- pkg/aspect/sync/sync.go | 7 +- pkg/aspect/test/test.go | 2 +- pkg/aspect/test/test_test.go | 2 +- pkg/aspect/version/version.go | 2 +- pkg/aspect/version/version_test.go | 25 ++++- pkg/bazel/bazel.go | 79 +++++++------- pkg/bazel/bazel_test.go | 101 +++++++++--------- pkg/bazel/workspace/finder.go | 29 ++--- pkg/bazel/workspace/finder_test.go | 62 ++++------- pkg/plugin/client/client.go | 23 +++- pkg/plugin/sdk/v1alpha2/plugin/interface.go | 6 +- pkg/plugin/sdk/v1alpha3/plugin/interface.go | 5 +- 41 files changed, 309 insertions(+), 221 deletions(-) diff --git a/cmd/aspect/aquery/aquery.go b/cmd/aspect/aquery/aquery.go index ba9b84aac..3e90d3793 100644 --- a/cmd/aspect/aquery/aquery.go +++ b/cmd/aspect/aquery/aquery.go @@ -29,10 +29,10 @@ import ( ) func NewDefaultAQueryCmd() *cobra.Command { - return NewAQueryCommand(ioutils.DefaultStreams, bazel.New()) + return NewAQueryCommand(ioutils.DefaultStreams, bazel.FindFromWd) } -func NewAQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { +func NewAQueryCommand(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *cobra.Command { cmd := &cobra.Command{ Use: "aquery", Short: "Executes an aquery.", @@ -42,6 +42,10 @@ func NewAQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { flags.FlagsInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } q := aquery.New(streams, bzl, true) return q.Run(cmd, args) }, diff --git a/cmd/aspect/build/build.go b/cmd/aspect/build/build.go index 7adf4c029..00e9f324a 100644 --- a/cmd/aspect/build/build.go +++ b/cmd/aspect/build/build.go @@ -36,7 +36,7 @@ func NewDefaultBuildCmd(pluginSystem system.PluginSystem) *cobra.Command { return NewBuildCmd( ioutils.DefaultStreams, pluginSystem, - bazel.New(), + bazel.FindFromWd, ) } @@ -44,7 +44,7 @@ func NewDefaultBuildCmd(pluginSystem system.PluginSystem) *cobra.Command { func NewBuildCmd( streams ioutils.Streams, pluginSystem system.PluginSystem, - bzl bazel.Bazel, + bzlProvider bazel.BazelProvider, ) *cobra.Command { return &cobra.Command{ Use: "build", @@ -58,6 +58,10 @@ func NewBuildCmd( pluginSystem.BuildHooksInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } b := build.New(streams, bzl) besBackend := bep.BESBackendFromContext(ctx) return b.Run(args, besBackend) diff --git a/cmd/aspect/clean/clean.go b/cmd/aspect/clean/clean.go index 0761c1a31..decaafe36 100644 --- a/cmd/aspect/clean/clean.go +++ b/cmd/aspect/clean/clean.go @@ -32,11 +32,11 @@ import ( // NewDefaultCleanCmd creates a new default clean cobra command. func NewDefaultCleanCmd() *cobra.Command { - return NewCleanCmd(ioutils.DefaultStreams, bazel.New()) + return NewCleanCmd(ioutils.DefaultStreams, bazel.FindFromWd) } // NewCleanCmd creates a new clean cobra command. -func NewCleanCmd(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { +func NewCleanCmd(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *cobra.Command { var expunge bool var expungeAsync bool @@ -79,6 +79,10 @@ Workaround inconistent state: }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { isInteractive := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) + bzl, err := bzlProvider() + if err != nil { + return err + } c := clean.NewDefault(streams, bzl, isInteractive) c.Expunge = expunge c.ExpungeAsync = expungeAsync diff --git a/cmd/aspect/cquery/cquery.go b/cmd/aspect/cquery/cquery.go index 6236f28b1..dcbf9b3f7 100644 --- a/cmd/aspect/cquery/cquery.go +++ b/cmd/aspect/cquery/cquery.go @@ -29,10 +29,10 @@ import ( ) func NewDefaultCQueryCmd() *cobra.Command { - return NewCQueryCommand(ioutils.DefaultStreams, bazel.New()) + return NewCQueryCommand(ioutils.DefaultStreams, bazel.FindFromWd) } -func NewCQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { +func NewCQueryCommand(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *cobra.Command { cmd := &cobra.Command{ Use: "cquery", Short: "Executes a cquery.", @@ -42,6 +42,10 @@ func NewCQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { flags.FlagsInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } q := cquery.New(streams, bzl, true) return q.Run(cmd, args) }, diff --git a/cmd/aspect/query/query.go b/cmd/aspect/query/query.go index 7495c7076..7560c5237 100644 --- a/cmd/aspect/query/query.go +++ b/cmd/aspect/query/query.go @@ -29,10 +29,10 @@ import ( ) func NewDefaultQueryCmd() *cobra.Command { - return NewQueryCommand(ioutils.DefaultStreams, bazel.New()) + return NewQueryCommand(ioutils.DefaultStreams, bazel.FindFromWd) } -func NewQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { +func NewQueryCommand(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *cobra.Command { cmd := &cobra.Command{ Use: "query", Short: "Executes a dependency graph query.", @@ -42,6 +42,10 @@ func NewQueryCommand(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { flags.FlagsInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } q := query.New(streams, bzl, true) return q.Run(cmd, args) }, diff --git a/cmd/aspect/run/run.go b/cmd/aspect/run/run.go index 5c6740834..dfb31b550 100644 --- a/cmd/aspect/run/run.go +++ b/cmd/aspect/run/run.go @@ -36,14 +36,14 @@ func NewDefaultRunCmd(pluginSystem system.PluginSystem) *cobra.Command { return NewRunCmd( ioutils.DefaultStreams, pluginSystem, - bazel.New(), + bazel.FindFromWd, ) } func NewRunCmd( streams ioutils.Streams, pluginSystem system.PluginSystem, - bzl bazel.Bazel, + bzlProvider bazel.BazelProvider, ) *cobra.Command { return &cobra.Command{ Use: "run", @@ -63,6 +63,10 @@ use 'bazel run --script_path' to write a script and then execute it. pluginSystem.RunHooksInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } r := run.New(streams, bzl) besBackend := bep.BESBackendFromContext(ctx) return r.Run(args, besBackend) diff --git a/cmd/aspect/test/test.go b/cmd/aspect/test/test.go index 97b9ec982..58b10624b 100644 --- a/cmd/aspect/test/test.go +++ b/cmd/aspect/test/test.go @@ -36,14 +36,14 @@ func NewDefaultTestCmd(pluginSystem system.PluginSystem) *cobra.Command { return NewTestCmd( ioutils.DefaultStreams, pluginSystem, - bazel.New(), + bazel.FindFromWd, ) } func NewTestCmd( streams ioutils.Streams, pluginSystem system.PluginSystem, - bzl bazel.Bazel, + bzlProvider bazel.BazelProvider, ) *cobra.Command { return &cobra.Command{ Use: "test", @@ -66,6 +66,10 @@ specify targets. pluginSystem.TestHooksInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } t := test.New(streams, bzl) besBackend := bep.BESBackendFromContext(ctx) return t.Run(args, besBackend) diff --git a/cmd/aspect/version/version.go b/cmd/aspect/version/version.go index c0eb7391f..32997e507 100644 --- a/cmd/aspect/version/version.go +++ b/cmd/aspect/version/version.go @@ -30,10 +30,10 @@ import ( ) func NewDefaultVersionCmd() *cobra.Command { - return NewVersionCmd(ioutils.DefaultStreams, bazel.New()) + return NewVersionCmd(ioutils.DefaultStreams, bazel.FindFromWd) } -func NewVersionCmd(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { +func NewVersionCmd(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *cobra.Command { v := version.New(streams) v.BuildInfo = *buildinfo.Current() @@ -46,6 +46,10 @@ func NewVersionCmd(streams ioutils.Streams, bzl bazel.Bazel) *cobra.Command { flags.FlagsInterceptor(streams), }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { + bzl, err := bzlProvider() + if err != nil { + return err + } return v.Run(bzl) }, ), diff --git a/pkg/aspect/analyzeprofile/analyzeprofile.go b/pkg/aspect/analyzeprofile/analyzeprofile.go index 5d9de3895..27f9c96fb 100644 --- a/pkg/aspect/analyzeprofile/analyzeprofile.go +++ b/pkg/aspect/analyzeprofile/analyzeprofile.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *AnalyzeProfile { func (v *AnalyzeProfile) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"analyze-profile"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/aquery/aquery_test.go b/pkg/aspect/aquery/aquery_test.go index 8f7019cab..8a6862620 100644 --- a/pkg/aspect/aquery/aquery_test.go +++ b/pkg/aspect/aquery/aquery_test.go @@ -43,7 +43,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)"}, streams). + RunCommand([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) q := aquery.New(streams, spawner, true) @@ -71,7 +71,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)"}, streams). + RunCommand([]string{"aquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -167,7 +167,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)"}, streams). + RunCommand([]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 74aaaba03..9b790c911 100644 --- a/pkg/aspect/build/build.go +++ b/pkg/aspect/build/build.go @@ -46,7 +46,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...), b.Streams) + exitCode, bazelErr := b.bzl.RunCommand(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 a7e552f5e..6410dfac5 100644 --- a/pkg/aspect/build/build_test.go +++ b/pkg/aspect/build/build_test.go @@ -45,7 +45,7 @@ func TestBuild(t *testing.T) { } bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(expectErr.ExitCode, expectErr.Err) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -74,7 +74,7 @@ func TestBuild(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -107,7 +107,7 @@ func TestBuild(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"build", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]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/canonicalizeflags/canonicalizeflags.go b/pkg/aspect/canonicalizeflags/canonicalizeflags.go index 12247eafd..b85c99832 100644 --- a/pkg/aspect/canonicalizeflags/canonicalizeflags.go +++ b/pkg/aspect/canonicalizeflags/canonicalizeflags.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *CanonicalizeFlags { func (v *CanonicalizeFlags) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"canonicalize-flags"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/clean/clean.go b/pkg/aspect/clean/clean.go index 234882f7c..17172f6c9 100644 --- a/pkg/aspect/clean/clean.go +++ b/pkg/aspect/clean/clean.go @@ -193,7 +193,7 @@ func (c *Clean) Run(_ *cobra.Command, _ []string) error { if c.ExpungeAsync { cmd = append(cmd, "--expunge_async") } - if exitCode, err := c.bzl.Spawn(cmd, c.Streams); exitCode != 0 { + if exitCode, err := c.bzl.RunCommand(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 e693ce5c7..8a326ebe6 100644 --- a/pkg/aspect/clean/clean_test.go +++ b/pkg/aspect/clean/clean_test.go @@ -79,7 +79,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}, streams). + RunCommand([]string{"clean"}, streams). Return(0, nil) b := clean.New(streams, bzl, false) @@ -95,7 +95,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean", "--expunge"}, streams). + RunCommand([]string{"clean", "--expunge"}, streams). Return(0, nil) b := clean.New(streams, bzl, false) @@ -112,7 +112,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean", "--expunge_async"}, streams). + RunCommand([]string{"clean", "--expunge_async"}, streams). Return(0, nil) b := clean.New(streams, bzl, false) @@ -130,7 +130,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}, streams). + RunCommand([]string{"clean"}, streams). Return(0, nil) b := clean.New(streams, bzl, true) @@ -152,7 +152,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}, streams). + RunCommand([]string{"clean"}, streams). Return(0, nil).AnyTimes() b := clean.New(streams, bzl, true) @@ -211,7 +211,7 @@ func TestClean(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"clean"}, streams). + RunCommand([]string{"clean"}, streams). Return(0, nil) c := clean.New(streams, bzl, true) diff --git a/pkg/aspect/cquery/cquery_test.go b/pkg/aspect/cquery/cquery_test.go index e05dcd509..87870de6c 100644 --- a/pkg/aspect/cquery/cquery_test.go +++ b/pkg/aspect/cquery/cquery_test.go @@ -43,7 +43,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)"}, streams). + RunCommand([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) q := cquery.New(streams, spawner, true) @@ -71,7 +71,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)"}, streams). + RunCommand([]string{"cquery", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -167,7 +167,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)"}, streams). + RunCommand([]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/dump/dump.go b/pkg/aspect/dump/dump.go index f6f315726..b8455ea26 100644 --- a/pkg/aspect/dump/dump.go +++ b/pkg/aspect/dump/dump.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *Dump { func (v *Dump) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"dump"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/fetch/fetch.go b/pkg/aspect/fetch/fetch.go index 6f300f15e..bf40964f4 100644 --- a/pkg/aspect/fetch/fetch.go +++ b/pkg/aspect/fetch/fetch.go @@ -38,9 +38,12 @@ func New(streams ioutils.Streams) *Fetch { func (v *Fetch) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"fetch"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/info/info.go b/pkg/aspect/info/info.go index d3cbac91a..ddb69ff19 100644 --- a/pkg/aspect/info/info.go +++ b/pkg/aspect/info/info.go @@ -45,9 +45,12 @@ func (v *Info) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd = append(bazelCmd, "--show_make_env") } bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/mobileinstall/mobileinstall.go b/pkg/aspect/mobileinstall/mobileinstall.go index 503b15d62..08bf1e467 100644 --- a/pkg/aspect/mobileinstall/mobileinstall.go +++ b/pkg/aspect/mobileinstall/mobileinstall.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *MobileInstall { func (v *MobileInstall) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"mobile-install"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/modquery/modquery.go b/pkg/aspect/modquery/modquery.go index c9e8457cd..85cb2bdc1 100644 --- a/pkg/aspect/modquery/modquery.go +++ b/pkg/aspect/modquery/modquery.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *ModQuery { func (v *ModQuery) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"modquery"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/printaction/printaction.go b/pkg/aspect/printaction/printaction.go index 601fe60e9..bc6031c81 100644 --- a/pkg/aspect/printaction/printaction.go +++ b/pkg/aspect/printaction/printaction.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *PrintAction { func (v *PrintAction) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"print_action"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/query/query_test.go b/pkg/aspect/query/query_test.go index 62f1e3a92..bed4bf8dc 100644 --- a/pkg/aspect/query/query_test.go +++ b/pkg/aspect/query/query_test.go @@ -45,7 +45,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)"}, streams). + RunCommand([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) q := query.New(streams, spawner, true) @@ -80,7 +80,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)"}, streams). + RunCommand([]string{"query", "somepath(//cmd/aspect/query:query, @com_github_bazelbuild_bazelisk//core:go_default_library)"}, streams). Return(0, nil) promptRunner := query_mock.NewMockPromptRunner(ctrl) @@ -225,7 +225,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)"}, streams). + RunCommand([]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 b40ce1fc2..d517c1fce 100644 --- a/pkg/aspect/query/shared/query.go +++ b/pkg/aspect/query/shared/query.go @@ -170,7 +170,7 @@ func RunQuery(bzl bazel.Bazel, verb string, query string, streams ioutils.Stream query, } - if exitCode, err := bzl.Spawn(bazelCmd, streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/root/flags/bazel_flags.go b/pkg/aspect/root/flags/bazel_flags.go index 54e3a0e4f..1fb5971bf 100644 --- a/pkg/aspect/root/flags/bazel_flags.go +++ b/pkg/aspect/root/flags/bazel_flags.go @@ -72,7 +72,10 @@ func AddBazelFlags(cmd *cobra.Command) error { subCommands[command.Use] = command } - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } bzlFlags, err := bzl.Flags() if err != nil { return fmt.Errorf("unable to determine available bazel flags: %w", err) diff --git a/pkg/aspect/root/flags/interceptor.go b/pkg/aspect/root/flags/interceptor.go index b2df9f8f8..5807eab4a 100644 --- a/pkg/aspect/root/flags/interceptor.go +++ b/pkg/aspect/root/flags/interceptor.go @@ -55,7 +55,10 @@ func FlagsInterceptor(streams ioutils.Streams) interceptors.Interceptor { } } - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } availableStartupFlags := bzl.AvailableStartupFlags() startupFlags := []string{} argsWithoutStartupFlags := []string{} diff --git a/pkg/aspect/run/run.go b/pkg/aspect/run/run.go index cb78f7bcb..4541efec6 100644 --- a/pkg/aspect/run/run.go +++ b/pkg/aspect/run/run.go @@ -46,7 +46,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...), cmd.Streams) + exitCode, bazelErr := cmd.bzl.RunCommand(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 576fee8e2..6f8be65fc 100644 --- a/pkg/aspect/run/run_test.go +++ b/pkg/aspect/run/run_test.go @@ -45,7 +45,7 @@ func TestRun(t *testing.T) { } bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(expectErr.ExitCode, expectErr.Err) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -74,7 +74,7 @@ func TestRun(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) besBackend. @@ -107,7 +107,7 @@ func TestRun(t *testing.T) { bzl := bazel_mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"run", "--bes_backend=grpc://127.0.0.1:12345", "//..."}, streams). + RunCommand([]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/shutdown/shutdown.go b/pkg/aspect/shutdown/shutdown.go index 2cbda0936..ab6faf1dc 100644 --- a/pkg/aspect/shutdown/shutdown.go +++ b/pkg/aspect/shutdown/shutdown.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *Shutdown { func (v *Shutdown) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"shutdown"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/sync/sync.go b/pkg/aspect/sync/sync.go index 9b38910ea..dae0500b5 100644 --- a/pkg/aspect/sync/sync.go +++ b/pkg/aspect/sync/sync.go @@ -39,9 +39,12 @@ func New(streams ioutils.Streams) *Sync { func (v *Sync) Run(ctx context.Context, _ *cobra.Command, args []string) error { bazelCmd := []string{"sync"} bazelCmd = append(bazelCmd, args...) - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } - if exitCode, err := bzl.Spawn(bazelCmd, v.Streams); exitCode != 0 { + if exitCode, err := bzl.RunCommand(bazelCmd, v.Streams); exitCode != 0 { err = &aspecterrors.ExitError{ Err: err, ExitCode: exitCode, diff --git a/pkg/aspect/test/test.go b/pkg/aspect/test/test.go index 302293334..db8e3b123 100644 --- a/pkg/aspect/test/test.go +++ b/pkg/aspect/test/test.go @@ -42,7 +42,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, t.Streams) + exitCode, bazelErr := t.bzl.RunCommand(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 64a1b886e..11d1e41f0 100644 --- a/pkg/aspect/test/test_test.go +++ b/pkg/aspect/test/test_test.go @@ -39,7 +39,7 @@ func TestTest(t *testing.T) { bzl := mock.NewMockBazel(ctrl) bzl. EXPECT(). - Spawn([]string{"test", "--bes_backend=grpc://127.0.0.1:12345"}, streams). + RunCommand([]string{"test", "--bes_backend=grpc://127.0.0.1:12345"}, streams). Return(0, nil) besBackend := bep_mock.NewMockBESBackend(ctrl) diff --git a/pkg/aspect/version/version.go b/pkg/aspect/version/version.go index e547c8571..23edd861d 100644 --- a/pkg/aspect/version/version.go +++ b/pkg/aspect/version/version.go @@ -55,7 +55,7 @@ func (v *Version) Run(bzl bazel.Bazel) error { // Propagate the flag bazelCmd = append(bazelCmd, "--gnu_format") } - bzl.Spawn(bazelCmd, v.Streams) + bzl.RunCommand(bazelCmd, v.Streams) return nil } diff --git a/pkg/aspect/version/version_test.go b/pkg/aspect/version/version_test.go index 1cb2bb92c..bd5af9efb 100644 --- a/pkg/aspect/version/version_test.go +++ b/pkg/aspect/version/version_test.go @@ -17,6 +17,9 @@ package version_test import ( + "io" + "os" + "path/filepath" "strings" "testing" @@ -36,8 +39,28 @@ const ( release = "1.2.3" ) +func createWorkspace() (string, error) { + wr, err := os.MkdirTemp("", "wksp_root") + if err != nil { + return "", err + } + wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) + if err != nil { + return "", err + } + defer wksp.Close() + if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { + return "", err + } + return wr, nil +} + func TestVersion(t *testing.T) { - bzl := bazel.New() + g := NewGomegaWithT(t) + wr, err := createWorkspace() + g.Expect(err).ToNot(HaveOccurred()) + bzl := bazel.New(wr) + t.Run("without release build info", func(t *testing.T) { g := NewGomegaWithT(t) var stdout strings.Builder diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index a8cc64197..008b27edc 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -28,7 +28,6 @@ import ( "aspect.build/cli/bazel/flags" "aspect.build/cli/pkg/bazel/workspace" "aspect.build/cli/pkg/ioutils" - "github.com/bazelbuild/bazelisk/core" "github.com/bazelbuild/bazelisk/repositories" "google.golang.org/protobuf/proto" @@ -47,9 +46,11 @@ var availableStartupFlags []string // cli execution. var startupFlags []string +type BazelProvider func() (Bazel, error) + type Bazel interface { + WithEnv(env []string) Bazel AQuery(expr string) (*analysis.ActionGraphContainer, 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 @@ -57,35 +58,55 @@ type Bazel interface { } type bazel struct { - workspaceFinder workspace.Finder - - overrideWorkspaceRoot string - env []string + workspaceRoot string + env []string } -func New() Bazel { +func New(workspaceRoot string) Bazel { return &bazel{ - workspaceFinder: workspace.DefaultFinder, + workspaceRoot: workspaceRoot, } } -// 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 +func Find(startDir string) (Bazel, error) { + finder := workspace.DefaultFinder + wr, err := finder.Find(startDir) + if err != nil { + return nil, err + } + return New(wr), nil +} + +func FindFromWd() (Bazel, error) { + wd, err := os.Getwd() + if err != nil { + return nil, err + } + return Find(wd) } -// 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 + b.env = env + return b } +// // 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. @@ -110,29 +131,13 @@ func (*bazel) createRepositories() *core.Repositories { return core.CreateRepositories(gcs, gcs, gitHub, gcs, gcs, true) } -// 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, 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() - 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(b.workspaceRoot) 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 c0a449b29..e4d4d15b7 100644 --- a/pkg/bazel/bazel_test.go +++ b/pkg/bazel/bazel_test.go @@ -29,10 +29,8 @@ import ( "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" ) @@ -59,77 +57,84 @@ func init() { if err := os.WriteFile(wrapperOverridePath, wrapperContents, 0777); err != nil { panic(err) } - if err := os.Chdir(workspaceDir); err != nil { - panic(err) - } + // if err := os.Chdir(workspaceDir); err != nil { + // panic(err) + // } } +// func createWorkspace() (string, error) { +// wr, err := os.MkdirTemp("", "wksp_root") +// if err != nil { +// return "", err +// } +// wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) +// if err != nil { +// return "", err +// } +// defer wksp.Close() +// if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { +// return "", err +// } +// return wr, nil +// } + func TestBazel(t *testing.T) { - t.Run("when the workspace finder fails, Spawn fails", func(t *testing.T) { + 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() - - expectedErr := fmt.Errorf("failed to find yada yada yada") - - workspaceFinder := workspace_mock.NewMockFinder(ctrl) - workspaceFinder.EXPECT(). - Find(). - Return("", expectedErr). - Times(1) - - bzl := &bazel{ - workspaceFinder: workspaceFinder, - } + // ctrl := gomock.NewController(t) + // defer ctrl.Finish() - var stdout strings.Builder - streams := ioutils.Streams{Stdout: &stdout} - _, err := bzl.Spawn([]string{"--print_env"}, streams) - g.Expect(err).To(MatchError(expectedErr)) - }) + // workspaceFinder := workspace_mock.NewMockFinder(ctrl) + // workspaceFinder.EXPECT(). + // Find(). + // Return("", nil). + // Times(1) - 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() + // bzl := &bazel{ + // workspaceFinder: workspaceFinder, + // } - workspaceFinder := workspace_mock.NewMockFinder(ctrl) - workspaceFinder.EXPECT(). - Find(). - Return("", nil). - Times(1) + // wr, err := createWorkspace() + // g.Expect(err).ToNot(HaveOccurred()) + // defer os.RemoveAll(wr) + // bzl := bazel.New(wr) - bzl := &bazel{ - workspaceFinder: workspaceFinder, - } + bzl := New(workspaceDir) 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) + _, err := bzl.WithEnv(env).RunCommand([]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() + // ctrl := gomock.NewController(t) + // defer ctrl.Finish() + + // workspaceFinder := workspace_mock.NewMockFinder(ctrl) + // workspaceFinder.EXPECT(). + // Find(). + // Times(0) + + // bzl := &bazel{ + // workspaceFinder: workspaceFinder, + // } - workspaceFinder := workspace_mock.NewMockFinder(ctrl) - workspaceFinder.EXPECT(). - Find(). - Times(0) + // wr, err := createWorkspace() + // g.Expect(err).ToNot(HaveOccurred()) + // defer os.RemoveAll(wr) + // bzl := bazel.New(wr) - bzl := &bazel{ - workspaceFinder: workspaceFinder, - } + bzl := New(workspaceOverrideDir) 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) + _, err := bzl.RunCommand([]string{"build"}, streams) g.Expect(err).To(Not(HaveOccurred())) g.Expect(out.String()).To(Equal("wrapper called")) }) diff --git a/pkg/bazel/workspace/finder.go b/pkg/bazel/workspace/finder.go index b329148bc..e8bda8481 100644 --- a/pkg/bazel/workspace/finder.go +++ b/pkg/bazel/workspace/finder.go @@ -30,34 +30,21 @@ var workspaceFilenames = []string{"WORKSPACE", "WORKSPACE.bazel"} // Finder wraps the Find method that performs the finding of the WORKSPACE file // in the user's Bazel project. type Finder interface { - Find() (string, error) + Find(string) (string, error) } type finder struct { - osGetwd func() (dir string, err error) - osStat func(string) (fs.FileInfo, error) - - workspaceRoot string + osStat func(string) (fs.FileInfo, error) } // DefaultFinder is the Finder with default dependencies. var DefaultFinder = &finder{ - osGetwd: os.Getwd, - osStat: os.Stat, + osStat: os.Stat, } // Find tries to find the root of a Bazel workspace. -func (f *finder) Find() (string, error) { - if f.workspaceRoot != "" { - return f.workspaceRoot, nil - } - - wd, err := f.osGetwd() - if err != nil { - return "", fmt.Errorf("failed to find bazel workspace: %w", err) - } - - for current := wd; current != "." && current != filepath.Dir(current); current = filepath.Dir(current) { +func (f *finder) Find(startDir string) (string, error) { + for current := startDir; current != "." && current != filepath.Dir(current); current = filepath.Dir(current) { for _, workspaceFilename := range workspaceFilenames { workspacePath := path.Join(current, workspaceFilename) fileInfo, err := f.osStat(workspacePath) @@ -70,10 +57,10 @@ func (f *finder) Find() (string, error) { if fileInfo.IsDir() { continue } - f.workspaceRoot = path.Dir(workspacePath) - return f.workspaceRoot, nil + workspaceRoot := path.Dir(workspacePath) + return workspaceRoot, nil } } - return "", fmt.Errorf("failed to find bazel workspace: the current working directory %q is not a Bazel workspace", wd) + return "", fmt.Errorf("failed to find bazel workspace: the current working directory %q is not a Bazel workspace", startDir) } diff --git a/pkg/bazel/workspace/finder_test.go b/pkg/bazel/workspace/finder_test.go index c7f4f8279..2f59c2be0 100644 --- a/pkg/bazel/workspace/finder_test.go +++ b/pkg/bazel/workspace/finder_test.go @@ -28,23 +28,23 @@ import ( stdlib_mock "aspect.build/cli/pkg/stdlib/mock" ) +const ( + startDir = "fake_working_directory/foo/bar" +) + func TestWorkspaceFinder(t *testing.T) { - t.Run("when os.Getwd fails, Find fails", func(t *testing.T) { - g := NewGomegaWithT(t) - ctrl := gomock.NewController(t) - defer ctrl.Finish() + // t.Run("when os.Getwd fails, Find fails", func(t *testing.T) { + // g := NewGomegaWithT(t) + // ctrl := gomock.NewController(t) + // defer ctrl.Finish() - expectedErr := fmt.Errorf("os.Getwd failed") + // expectedErr := fmt.Errorf("os.Getwd failed") - finder := &finder{ - osGetwd: func() (string, error) { - return "", expectedErr - }, - } - workspacePath, err := finder.Find() - g.Expect(workspacePath).To(BeEmpty()) - g.Expect(err).To(MatchError(expectedErr)) - }) + // finder := &finder{} + // workspacePath, err := finder.Find() + // g.Expect(workspacePath).To(BeEmpty()) + // g.Expect(err).To(MatchError(expectedErr)) + // }) t.Run("when os.Stat fails, Find fails", func(t *testing.T) { g := NewGomegaWithT(t) @@ -54,14 +54,11 @@ func TestWorkspaceFinder(t *testing.T) { expectedErr := fmt.Errorf("os.Stat failed") finder := &finder{ - osGetwd: func() (string, error) { - return "fake_working_directory/foo/bar", nil - }, osStat: func(s string) (fs.FileInfo, error) { return nil, expectedErr }, } - workspacePath, err := finder.Find() + workspacePath, err := finder.Find(startDir) g.Expect(workspacePath).To(BeEmpty()) g.Expect(err).To(MatchError(expectedErr)) }) @@ -86,14 +83,11 @@ func TestWorkspaceFinder(t *testing.T) { for _, wd := range wds { expectedErr := fmt.Errorf("failed to find bazel workspace: the current working directory \"%s\" is not a Bazel workspace", wd) finder := &finder{ - osGetwd: func() (string, error) { - return wd, nil - }, osStat: func(s string) (fs.FileInfo, error) { return nil, os.ErrNotExist }, } - workspacePath, err := finder.Find() + workspacePath, err := finder.Find(wd) g.Expect(workspacePath).To(BeEmpty()) g.Expect(err).To(MatchError(expectedErr)) } @@ -112,15 +106,12 @@ func TestWorkspaceFinder(t *testing.T) { Times(1) finder := &finder{ - osGetwd: func() (string, error) { - return "fake_working_directory/foo/bar", nil - }, osStat: func(s string) (fs.FileInfo, error) { return fsFileInfo, nil }, } - workspacePath, err := finder.Find() - g.Expect(workspacePath).To(Equal("fake_working_directory/foo/bar")) + workspacePath, err := finder.Find(startDir) + g.Expect(workspacePath).To(Equal(startDir)) g.Expect(err).To(BeNil()) }) t.Run("case 2", func(t *testing.T) { @@ -141,15 +132,12 @@ func TestWorkspaceFinder(t *testing.T) { ) finder := &finder{ - osGetwd: func() (string, error) { - return "fake_working_directory/foo/bar", nil - }, osStat: func(s string) (fs.FileInfo, error) { return fsFileInfo, nil }, } - workspacePath, err := finder.Find() - g.Expect(workspacePath).To(Equal("fake_working_directory/foo/bar")) + workspacePath, err := finder.Find(startDir) + g.Expect(workspacePath).To(Equal(startDir)) g.Expect(err).To(BeNil()) }) t.Run("case 3", func(t *testing.T) { @@ -174,14 +162,11 @@ func TestWorkspaceFinder(t *testing.T) { ) finder := &finder{ - osGetwd: func() (string, error) { - return "fake_working_directory/foo/bar", nil - }, osStat: func(s string) (fs.FileInfo, error) { return fsFileInfo, nil }, } - workspacePath, err := finder.Find() + workspacePath, err := finder.Find(startDir) g.Expect(workspacePath).To(Equal("fake_working_directory/foo")) g.Expect(err).To(BeNil()) }) @@ -211,14 +196,11 @@ func TestWorkspaceFinder(t *testing.T) { ) finder := &finder{ - osGetwd: func() (string, error) { - return "fake_working_directory/foo/bar", nil - }, osStat: func(s string) (fs.FileInfo, error) { return fsFileInfo, nil }, } - workspacePath, err := finder.Find() + workspacePath, err := finder.Find(startDir) g.Expect(workspacePath).To(Equal("fake_working_directory/foo")) g.Expect(err).To(BeNil()) }) diff --git a/pkg/plugin/client/client.go b/pkg/plugin/client/client.go index 29a8615d7..7f1328582 100644 --- a/pkg/plugin/client/client.go +++ b/pkg/plugin/client/client.go @@ -39,9 +39,7 @@ type Factory interface { } func NewFactory() Factory { - return &clientFactory{ - bzl: bazel.New(), - } + return &clientFactory{} } // CustomCommandExecutor requires the Plugin implementations to provide the @@ -55,9 +53,24 @@ type clientFactory struct { bzl bazel.Bazel } +func (c *clientFactory) bazel() (bazel.Bazel, error) { + if c.bzl == nil { + var err error + c.bzl, err = bazel.FindFromWd() + if err != nil { + return nil, err + } + } + return c.bzl, nil +} + // buildPlugin asks bazel to build the target and returns the path to the resulting binary. func (c *clientFactory) buildPlugin(target string) (string, error) { - queryOutput, err := c.bzl.AQuery(target) + bzl, err := c.bazel() + if err != nil { + return "", err + } + queryOutput, err := bzl.AQuery(target) if err != nil { return "", err } @@ -87,7 +100,7 @@ func (c *clientFactory) buildPlugin(target string) (string, error) { // build the developer or CI would be performing. // This is important only in the setup we don't recommend, where normal users // are building the plugin from source instead of a pre-built binary. - if _, err := c.bzl.RunCommand([]string{"build", target}, streams); err != nil { + if _, err := bzl.RunCommand([]string{"build", target}, streams); err != nil { return "", fmt.Errorf("failed to build plugin %q with Bazel: %w", target, err) } diff --git a/pkg/plugin/sdk/v1alpha2/plugin/interface.go b/pkg/plugin/sdk/v1alpha2/plugin/interface.go index 08915fcc2..e1ddd0214 100644 --- a/pkg/plugin/sdk/v1alpha2/plugin/interface.go +++ b/pkg/plugin/sdk/v1alpha2/plugin/interface.go @@ -137,8 +137,10 @@ func (cm *PluginCommandManager) Save(commands []*Command) error { // Execute satisfies CommandManager. func (cm *PluginCommandManager) Execute(command string, ctx context.Context, args []string) error { - bzl := bazel.New() - + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } return cm.commands[command](ctx, args, bzl) } diff --git a/pkg/plugin/sdk/v1alpha3/plugin/interface.go b/pkg/plugin/sdk/v1alpha3/plugin/interface.go index aa6bef6d6..6c18782f7 100644 --- a/pkg/plugin/sdk/v1alpha3/plugin/interface.go +++ b/pkg/plugin/sdk/v1alpha3/plugin/interface.go @@ -168,7 +168,10 @@ func (cm *PluginCommandManager) Save(commands []*Command) error { // Execute satisfies CommandManager. func (cm *PluginCommandManager) Execute(command string, ctx context.Context, args []string) error { - bzl := bazel.New() + bzl, err := bazel.FindFromWd() + if err != nil { + return err + } return cm.commands[command](ctx, args, bzl) } From 3d28dcb2f2b1ee0bd7eab8b736379a0735f3bdba Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 09:36:10 -0600 Subject: [PATCH 02/14] Clean up --- pkg/bazel/bazel_test.go | 52 ----------------------------------------- 1 file changed, 52 deletions(-) diff --git a/pkg/bazel/bazel_test.go b/pkg/bazel/bazel_test.go index e4d4d15b7..d0bf9c38b 100644 --- a/pkg/bazel/bazel_test.go +++ b/pkg/bazel/bazel_test.go @@ -57,47 +57,11 @@ func init() { if err := os.WriteFile(wrapperOverridePath, wrapperContents, 0777); err != nil { panic(err) } - // if err := os.Chdir(workspaceDir); err != nil { - // panic(err) - // } } -// func createWorkspace() (string, error) { -// wr, err := os.MkdirTemp("", "wksp_root") -// if err != nil { -// return "", err -// } -// wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) -// if err != nil { -// return "", err -// } -// defer wksp.Close() -// if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { -// return "", err -// } -// return wr, nil -// } - func TestBazel(t *testing.T) { 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, - // } - - // wr, err := createWorkspace() - // g.Expect(err).ToNot(HaveOccurred()) - // defer os.RemoveAll(wr) - // bzl := bazel.New(wr) bzl := New(workspaceDir) @@ -111,22 +75,6 @@ func TestBazel(t *testing.T) { 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, - // } - - // wr, err := createWorkspace() - // g.Expect(err).ToNot(HaveOccurred()) - // defer os.RemoveAll(wr) - // bzl := bazel.New(wr) bzl := New(workspaceOverrideDir) From c12ae61db074973a1aa1d9be648160ed5741248b Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 09:39:39 -0600 Subject: [PATCH 03/14] Clean up --- pkg/bazel/bazel.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index 008b27edc..87bec9406 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -90,23 +90,6 @@ func (b *bazel) WithEnv(env []string) Bazel { return b } -// // 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. From 660c1ff5f5e5fcac067ca58118ea85e2a6a9ea43 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 09:41:40 -0600 Subject: [PATCH 04/14] Clean up --- pkg/bazel/workspace/finder_test.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pkg/bazel/workspace/finder_test.go b/pkg/bazel/workspace/finder_test.go index 2f59c2be0..68e8785b9 100644 --- a/pkg/bazel/workspace/finder_test.go +++ b/pkg/bazel/workspace/finder_test.go @@ -33,19 +33,6 @@ const ( ) func TestWorkspaceFinder(t *testing.T) { - // t.Run("when os.Getwd fails, Find fails", func(t *testing.T) { - // g := NewGomegaWithT(t) - // ctrl := gomock.NewController(t) - // defer ctrl.Finish() - - // expectedErr := fmt.Errorf("os.Getwd failed") - - // finder := &finder{} - // workspacePath, err := finder.Find() - // g.Expect(workspacePath).To(BeEmpty()) - // g.Expect(err).To(MatchError(expectedErr)) - // }) - t.Run("when os.Stat fails, Find fails", func(t *testing.T) { g := NewGomegaWithT(t) ctrl := gomock.NewController(t) From 70dc2ec0d7d6cf89c3d9ea665854937f6f34ccdd Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 10:09:11 -0600 Subject: [PATCH 05/14] Add change --- pkg/bazel/bazel.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index 87bec9406..e999bc2a2 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -46,6 +46,8 @@ var availableStartupFlags []string // cli execution. var startupFlags []string +// TODO(chuck): REMOVE ME + type BazelProvider func() (Bazel, error) type Bazel interface { From 417db4c34cd2160c08e80a325304f98b0620c0fd Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 10:09:23 -0600 Subject: [PATCH 06/14] Remove change --- pkg/bazel/bazel.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index e999bc2a2..87bec9406 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -46,8 +46,6 @@ var availableStartupFlags []string // cli execution. var startupFlags []string -// TODO(chuck): REMOVE ME - type BazelProvider func() (Bazel, error) type Bazel interface { From 740ea6b474492580a80cdcffcae350c0937da346 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 10:13:50 -0600 Subject: [PATCH 07/14] Gazelle cleanup --- pkg/bazel/BUILD.bazel | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/bazel/BUILD.bazel b/pkg/bazel/BUILD.bazel index d63e9ca31..17bcbc2bd 100644 --- a/pkg/bazel/BUILD.bazel +++ b/pkg/bazel/BUILD.bazel @@ -28,9 +28,7 @@ go_test( srcs = ["bazel_test.go"], embed = [":bazel"], deps = [ - "//pkg/bazel/workspace/mock", "//pkg/ioutils", - "@com_github_golang_mock//gomock", "@com_github_onsi_gomega//:gomega", ], ) From 73516b036333ceb8e3be7c464107eaf777b55e2e Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 13:59:15 -0600 Subject: [PATCH 08/14] Update the test to reflect the original intent. --- pkg/aspect/version/BUILD.bazel | 3 +- pkg/aspect/version/version.go | 6 ++ pkg/aspect/version/version_test.go | 90 ++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/pkg/aspect/version/BUILD.bazel b/pkg/aspect/version/BUILD.bazel index ac0bfa7f4..f6d912b4a 100644 --- a/pkg/aspect/version/BUILD.bazel +++ b/pkg/aspect/version/BUILD.bazel @@ -18,8 +18,9 @@ go_test( deps = [ ":version", "//buildinfo", - "//pkg/bazel", + "//pkg/bazel/mock", "//pkg/ioutils", + "@com_github_golang_mock//gomock", "@com_github_onsi_gomega//:gomega", ], ) diff --git a/pkg/aspect/version/version.go b/pkg/aspect/version/version.go index 23edd861d..de2517b3e 100644 --- a/pkg/aspect/version/version.go +++ b/pkg/aspect/version/version.go @@ -48,6 +48,12 @@ func (v *Version) Run(bzl bazel.Bazel) error { return err } + // If we do not have a Bazel workspace, do not bother trying to get additional version + // information. + if bzl == nil { + return nil + } + // Check if the --gnu_format flag is set, if that is the case, // the version is printed differently bazelCmd := []string{"version"} diff --git a/pkg/aspect/version/version_test.go b/pkg/aspect/version/version_test.go index bd5af9efb..84909b62b 100644 --- a/pkg/aspect/version/version_test.go +++ b/pkg/aspect/version/version_test.go @@ -17,17 +17,15 @@ package version_test import ( - "io" - "os" - "path/filepath" "strings" "testing" + "github.com/golang/mock/gomock" . "github.com/onsi/gomega" "aspect.build/cli/buildinfo" "aspect.build/cli/pkg/aspect/version" - "aspect.build/cli/pkg/bazel" + bazel_mock "aspect.build/cli/pkg/bazel/mock" "aspect.build/cli/pkg/ioutils" ) @@ -39,39 +37,71 @@ const ( release = "1.2.3" ) -func createWorkspace() (string, error) { - wr, err := os.MkdirTemp("", "wksp_root") - if err != nil { - return "", err - } - wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) - if err != nil { - return "", err - } - defer wksp.Close() - if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { - return "", err - } - return wr, nil -} +// func createWorkspace() (string, error) { +// wr, err := os.MkdirTemp("", "wksp_root") +// if err != nil { +// return "", err +// } +// wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) +// if err != nil { +// return "", err +// } +// defer wksp.Close() +// if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { +// return "", err +// } +// return wr, nil +// } func TestVersion(t *testing.T) { - g := NewGomegaWithT(t) - wr, err := createWorkspace() - g.Expect(err).ToNot(HaveOccurred()) - bzl := bazel.New(wr) + t.Run("with a Bazel instance", func(t *testing.T) { + g := NewWithT(t) + ctrl := gomock.NewController(t) + defer ctrl.Finish() - t.Run("without release build info", func(t *testing.T) { - g := NewGomegaWithT(t) var stdout strings.Builder streams := ioutils.Streams{Stdout: &stdout} + bzl := bazel_mock.NewMockBazel(ctrl) + bzl. + EXPECT(). + RunCommand([]string{"version"}, streams). + Return(0, nil) + v := version.New(streams) err := v.Run(bzl) g.Expect(err).To(BeNil()) + }) + + t.Run("with a Bazel instance, with --gnu_format", func(t *testing.T) { + g := NewWithT(t) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} + bzl := bazel_mock.NewMockBazel(ctrl) + bzl. + EXPECT(). + RunCommand([]string{"version", "--gnu_format"}, streams). + Return(0, nil) + + v := version.New(streams) + v.GNUFormat = true + err := v.Run(bzl) + g.Expect(err).To(BeNil()) + }) + + t.Run("no Bazel instance, without release build info", func(t *testing.T) { + g := NewGomegaWithT(t) + var stdout strings.Builder + streams := ioutils.Streams{Stdout: &stdout} + v := version.New(streams) + err := v.Run(nil) + g.Expect(err).To(BeNil()) g.Expect(stdout.String()).To(Equal("Aspect version: unknown [not built with --stamp]\n")) }) - t.Run("with release build info", func(t *testing.T) { + t.Run("no Bazel instance, with release build info", func(t *testing.T) { t.Run("git is clean", func(t *testing.T) { g := NewGomegaWithT(t) var stdout strings.Builder @@ -84,7 +114,7 @@ func TestVersion(t *testing.T) { buildinfo.CleanGitStatus, release, ) - err := v.Run(bzl) + err := v.Run(nil) g.Expect(err).To(BeNil()) g.Expect(stdout.String()).To(Equal("Aspect version: 1.2.3\n")) }) @@ -101,13 +131,13 @@ func TestVersion(t *testing.T) { dirtyGitStatus, release, ) - err := v.Run(bzl) + err := v.Run(nil) g.Expect(err).To(BeNil()) g.Expect(stdout.String()).To(Equal("Aspect version: 1.2.3 (with local changes)\n")) }) }) - t.Run("with --gnu_format", func(t *testing.T) { + t.Run("no Bazel instance, with --gnu_format", func(t *testing.T) { g := NewGomegaWithT(t) var stdout strings.Builder streams := ioutils.Streams{Stdout: &stdout} @@ -120,7 +150,7 @@ func TestVersion(t *testing.T) { buildinfo.CleanGitStatus, release, ) - err := v.Run(bzl) + err := v.Run(nil) g.Expect(err).To(BeNil()) g.Expect(stdout.String()).To(Equal("Aspect 1.2.3\n")) }) From 708d3dedba0f2bcd8e0d7760f4e6d27ba8edf702 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 14:17:37 -0600 Subject: [PATCH 09/14] Clean up --- pkg/aspect/version/version_test.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pkg/aspect/version/version_test.go b/pkg/aspect/version/version_test.go index 84909b62b..9699de198 100644 --- a/pkg/aspect/version/version_test.go +++ b/pkg/aspect/version/version_test.go @@ -37,22 +37,6 @@ const ( release = "1.2.3" ) -// func createWorkspace() (string, error) { -// wr, err := os.MkdirTemp("", "wksp_root") -// if err != nil { -// return "", err -// } -// wksp, err := os.Create(filepath.Join(wr, "WORKSPACE")) -// if err != nil { -// return "", err -// } -// defer wksp.Close() -// if _, err := io.WriteString(wksp, `workspace(name = "test_workspace")`); err != nil { -// return "", err -// } -// return wr, nil -// } - func TestVersion(t *testing.T) { t.Run("with a Bazel instance", func(t *testing.T) { g := NewWithT(t) From 7e68714ceae9ce8f408a6d9e0533279acaa288e5 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 14:30:51 -0600 Subject: [PATCH 10/14] Add bazel.NotFoundError --- pkg/bazel/workspace/finder.go | 11 ++++++++++- pkg/bazel/workspace/finder_test.go | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/bazel/workspace/finder.go b/pkg/bazel/workspace/finder.go index e8bda8481..1512c450f 100644 --- a/pkg/bazel/workspace/finder.go +++ b/pkg/bazel/workspace/finder.go @@ -27,6 +27,14 @@ import ( // https://github.com/bazelbuild/bazel/blob/8346ea4c/src/main/cpp/workspace_layout.cc#L37 var workspaceFilenames = []string{"WORKSPACE", "WORKSPACE.bazel"} +type NotFoundError struct { + startDir string +} + +func (nfe *NotFoundError) Error() string { + return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.startDir) +} + // Finder wraps the Find method that performs the finding of the WORKSPACE file // in the user's Bazel project. type Finder interface { @@ -52,7 +60,8 @@ func (f *finder) Find(startDir string) (string, error) { if os.IsNotExist(err) { continue } - return "", fmt.Errorf("failed to find bazel workspace: %w", err) + // return "", fmt.Errorf("failed to find bazel workspace: %w", err) + return "", &NotFoundError{startDir: startDir} } if fileInfo.IsDir() { continue diff --git a/pkg/bazel/workspace/finder_test.go b/pkg/bazel/workspace/finder_test.go index 68e8785b9..fec36a237 100644 --- a/pkg/bazel/workspace/finder_test.go +++ b/pkg/bazel/workspace/finder_test.go @@ -38,7 +38,7 @@ func TestWorkspaceFinder(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - expectedErr := fmt.Errorf("os.Stat failed") + expectedErr := &NotFoundError{startDir: startDir} finder := &finder{ osStat: func(s string) (fs.FileInfo, error) { From b85a068517712b6802d7fe74608a0f6e469553bb Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 14:43:44 -0600 Subject: [PATCH 11/14] Add NotFoundError --- cmd/aspect/version/BUILD.bazel | 1 + cmd/aspect/version/version.go | 3 ++- pkg/bazel/workspace/BUILD.bazel | 5 +++- pkg/bazel/workspace/finder.go | 9 ------- pkg/bazel/workspace/not_found_error.go | 37 ++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 pkg/bazel/workspace/not_found_error.go diff --git a/cmd/aspect/version/BUILD.bazel b/cmd/aspect/version/BUILD.bazel index 4e4122065..7ebee5766 100644 --- a/cmd/aspect/version/BUILD.bazel +++ b/cmd/aspect/version/BUILD.bazel @@ -10,6 +10,7 @@ go_library( "//pkg/aspect/root/flags", "//pkg/aspect/version", "//pkg/bazel", + "//pkg/bazel/workspace", "//pkg/interceptors", "//pkg/ioutils", "@com_github_spf13_cobra//:cobra", diff --git a/cmd/aspect/version/version.go b/cmd/aspect/version/version.go index 32997e507..45b5a426b 100644 --- a/cmd/aspect/version/version.go +++ b/cmd/aspect/version/version.go @@ -25,6 +25,7 @@ import ( "aspect.build/cli/pkg/aspect/root/flags" "aspect.build/cli/pkg/aspect/version" "aspect.build/cli/pkg/bazel" + "aspect.build/cli/pkg/bazel/workspace" "aspect.build/cli/pkg/interceptors" "aspect.build/cli/pkg/ioutils" ) @@ -47,7 +48,7 @@ func NewVersionCmd(streams ioutils.Streams, bzlProvider bazel.BazelProvider) *co }, func(ctx context.Context, cmd *cobra.Command, args []string) (exitErr error) { bzl, err := bzlProvider() - if err != nil { + if err != nil && !workspace.IsNotFoundError(err) { return err } return v.Run(bzl) diff --git a/pkg/bazel/workspace/BUILD.bazel b/pkg/bazel/workspace/BUILD.bazel index be05539b8..14cde07bf 100644 --- a/pkg/bazel/workspace/BUILD.bazel +++ b/pkg/bazel/workspace/BUILD.bazel @@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "workspace", - srcs = ["finder.go"], + srcs = [ + "finder.go", + "not_found_error.go", + ], importpath = "aspect.build/cli/pkg/bazel/workspace", visibility = ["//visibility:public"], ) diff --git a/pkg/bazel/workspace/finder.go b/pkg/bazel/workspace/finder.go index 1512c450f..84c8deff0 100644 --- a/pkg/bazel/workspace/finder.go +++ b/pkg/bazel/workspace/finder.go @@ -27,14 +27,6 @@ import ( // https://github.com/bazelbuild/bazel/blob/8346ea4c/src/main/cpp/workspace_layout.cc#L37 var workspaceFilenames = []string{"WORKSPACE", "WORKSPACE.bazel"} -type NotFoundError struct { - startDir string -} - -func (nfe *NotFoundError) Error() string { - return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.startDir) -} - // Finder wraps the Find method that performs the finding of the WORKSPACE file // in the user's Bazel project. type Finder interface { @@ -60,7 +52,6 @@ func (f *finder) Find(startDir string) (string, error) { if os.IsNotExist(err) { continue } - // return "", fmt.Errorf("failed to find bazel workspace: %w", err) return "", &NotFoundError{startDir: startDir} } if fileInfo.IsDir() { diff --git a/pkg/bazel/workspace/not_found_error.go b/pkg/bazel/workspace/not_found_error.go new file mode 100644 index 000000000..cd17b3a7c --- /dev/null +++ b/pkg/bazel/workspace/not_found_error.go @@ -0,0 +1,37 @@ +/* + * Copyright 2022 Aspect Build Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package workspace + +import ( + "fmt" +) + +type NotFoundError struct { + startDir string +} + +func (nfe *NotFoundError) Error() string { + return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.startDir) +} + +func IsNotFoundError(err error) bool { + if err == nil { + return false + } + _, ok := err.(*NotFoundError) + return ok +} From cc7279b27ead6124190121a82dc9a535c9983fcd Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 14:57:21 -0600 Subject: [PATCH 12/14] Move NotFoundError to its own file --- pkg/bazel/workspace/BUILD.bazel | 5 ++- pkg/bazel/workspace/finder.go | 2 +- pkg/bazel/workspace/finder_test.go | 2 +- pkg/bazel/workspace/not_found_error.go | 4 +-- pkg/bazel/workspace/not_found_error_test.go | 38 +++++++++++++++++++++ 5 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 pkg/bazel/workspace/not_found_error_test.go diff --git a/pkg/bazel/workspace/BUILD.bazel b/pkg/bazel/workspace/BUILD.bazel index 14cde07bf..f7c86a02d 100644 --- a/pkg/bazel/workspace/BUILD.bazel +++ b/pkg/bazel/workspace/BUILD.bazel @@ -12,7 +12,10 @@ go_library( go_test( name = "workspace_test", - srcs = ["finder_test.go"], + srcs = [ + "finder_test.go", + "not_found_error_test.go", + ], embed = [":workspace"], deps = [ "//pkg/stdlib/mock", diff --git a/pkg/bazel/workspace/finder.go b/pkg/bazel/workspace/finder.go index 84c8deff0..c5d92c5a5 100644 --- a/pkg/bazel/workspace/finder.go +++ b/pkg/bazel/workspace/finder.go @@ -52,7 +52,7 @@ func (f *finder) Find(startDir string) (string, error) { if os.IsNotExist(err) { continue } - return "", &NotFoundError{startDir: startDir} + return "", &NotFoundError{StartDir: startDir} } if fileInfo.IsDir() { continue diff --git a/pkg/bazel/workspace/finder_test.go b/pkg/bazel/workspace/finder_test.go index fec36a237..b7a0273da 100644 --- a/pkg/bazel/workspace/finder_test.go +++ b/pkg/bazel/workspace/finder_test.go @@ -38,7 +38,7 @@ func TestWorkspaceFinder(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - expectedErr := &NotFoundError{startDir: startDir} + expectedErr := &NotFoundError{StartDir: startDir} finder := &finder{ osStat: func(s string) (fs.FileInfo, error) { diff --git a/pkg/bazel/workspace/not_found_error.go b/pkg/bazel/workspace/not_found_error.go index cd17b3a7c..27cd7a85b 100644 --- a/pkg/bazel/workspace/not_found_error.go +++ b/pkg/bazel/workspace/not_found_error.go @@ -21,11 +21,11 @@ import ( ) type NotFoundError struct { - startDir string + StartDir string } func (nfe *NotFoundError) Error() string { - return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.startDir) + return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.StartDir) } func IsNotFoundError(err error) bool { diff --git a/pkg/bazel/workspace/not_found_error_test.go b/pkg/bazel/workspace/not_found_error_test.go new file mode 100644 index 000000000..ab05371b3 --- /dev/null +++ b/pkg/bazel/workspace/not_found_error_test.go @@ -0,0 +1,38 @@ +/* + * Copyright 2022 Aspect Build Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package workspace_test + +import ( + "errors" + "testing" + + "aspect.build/cli/pkg/bazel/workspace" + . "github.com/onsi/gomega" +) + +func TestIsNotFoundError(t *testing.T) { + t.Run("when it is a NotFoundError", func(t *testing.T) { + g := NewWithT(t) + err := &workspace.NotFoundError{StartDir: "path"} + g.Expect(workspace.IsNotFoundError(err)).To(BeTrue()) + }) + t.Run("when it is not a NotFoundError", func(t *testing.T) { + g := NewWithT(t) + err := errors.New("not a NotFoundError") + g.Expect(workspace.IsNotFoundError(err)).To(BeFalse()) + }) +} From 0740832702625a42ddb022bb3281e1b7d4fbd8e7 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 16:41:20 -0600 Subject: [PATCH 13/14] Separate first-party imports --- pkg/bazel/bazel.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/bazel/bazel.go b/pkg/bazel/bazel.go index 87bec9406..211bb2de3 100644 --- a/pkg/bazel/bazel.go +++ b/pkg/bazel/bazel.go @@ -28,6 +28,7 @@ import ( "aspect.build/cli/bazel/flags" "aspect.build/cli/pkg/bazel/workspace" "aspect.build/cli/pkg/ioutils" + "github.com/bazelbuild/bazelisk/core" "github.com/bazelbuild/bazelisk/repositories" "google.golang.org/protobuf/proto" From cc8fbd15bf4a8158dbe2e70b07b8fce275eb6662 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Wed, 21 Sep 2022 16:44:39 -0600 Subject: [PATCH 14/14] Add doc comments --- pkg/bazel/workspace/not_found_error.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/bazel/workspace/not_found_error.go b/pkg/bazel/workspace/not_found_error.go index 27cd7a85b..db02d5532 100644 --- a/pkg/bazel/workspace/not_found_error.go +++ b/pkg/bazel/workspace/not_found_error.go @@ -20,6 +20,7 @@ import ( "fmt" ) +// Represents a failure to find a Bazel workspace. type NotFoundError struct { StartDir string } @@ -28,6 +29,7 @@ func (nfe *NotFoundError) Error() string { return fmt.Sprintf("failed to find a Bazel workspace starting at %s", nfe.StartDir) } +// Determines whether the provided error is a NotFoundError. func IsNotFoundError(err error) bool { if err == nil { return false