feat: add test command (#38)
Currently it's just a simple pass-through to bazel
diff --git a/cmd/aspect/clean/BUILD.bazel b/cmd/aspect/clean/BUILD.bazel
index 80e22c2..d33eca3 100644
--- a/cmd/aspect/clean/BUILD.bazel
+++ b/cmd/aspect/clean/BUILD.bazel
@@ -7,8 +7,6 @@
visibility = ["//visibility:public"],
deps = [
"//pkg/aspect/clean",
- "//pkg/bazel",
- "//pkg/ioutils",
"@com_github_mattn_go_isatty//:go-isatty",
"@com_github_spf13_cobra//:cobra",
],
diff --git a/cmd/aspect/main.go b/cmd/aspect/main.go
index b7c645c..264275d 100644
--- a/cmd/aspect/main.go
+++ b/cmd/aspect/main.go
@@ -28,6 +28,12 @@
// ask the user if they want to install for all users of the workspace, if so
// - tools/bazel file and put our bootstrap code in there
//
+
+ // Convenience for local development: under `bazel run //:aspect` respect the
+ // users working directory, don't run in the execroot
+ if wd, exists := os.LookupEnv("BUILD_WORKING_DIRECTORY"); exists {
+ _ = os.Chdir(wd)
+ }
cmd := root.NewDefaultRootCmd()
if err := cmd.ExecuteContext(context.Background()); err != nil {
var exitErr *aspecterrors.ExitError
diff --git a/cmd/aspect/root/BUILD.bazel b/cmd/aspect/root/BUILD.bazel
index d186a75..cea46cb 100644
--- a/cmd/aspect/root/BUILD.bazel
+++ b/cmd/aspect/root/BUILD.bazel
@@ -13,6 +13,7 @@
"//cmd/aspect/clean",
"//cmd/aspect/docs",
"//cmd/aspect/info",
+ "//cmd/aspect/test",
"//cmd/aspect/version",
"//docs/help/topics",
"//pkg/ioutils",
diff --git a/cmd/aspect/root/root.go b/cmd/aspect/root/root.go
index 608513e..55686fd 100644
--- a/cmd/aspect/root/root.go
+++ b/cmd/aspect/root/root.go
@@ -19,6 +19,7 @@
"aspect.build/cli/cmd/aspect/clean"
"aspect.build/cli/cmd/aspect/docs"
"aspect.build/cli/cmd/aspect/info"
+ "aspect.build/cli/cmd/aspect/test"
"aspect.build/cli/cmd/aspect/version"
"aspect.build/cli/docs/help/topics"
"aspect.build/cli/pkg/ioutils"
@@ -74,6 +75,7 @@
cmd.AddCommand(version.NewDefaultVersionCmd())
cmd.AddCommand(docs.NewDefaultDocsCmd())
cmd.AddCommand(info.NewDefaultInfoCmd())
+ cmd.AddCommand(test.NewDefaultTestCmd())
// ### "Additional help topic commands" which are not runnable
// https://pkg.go.dev/github.com/spf13/cobra#Command.IsAdditionalHelpTopicCommand
diff --git a/cmd/aspect/test/BUILD.bazel b/cmd/aspect/test/BUILD.bazel
new file mode 100644
index 0000000..2fbf5c4
--- /dev/null
+++ b/cmd/aspect/test/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "test",
+ srcs = ["test.go"],
+ importpath = "aspect.build/cli/cmd/aspect/test",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//pkg/aspect/test",
+ "//pkg/bazel",
+ "//pkg/ioutils",
+ "@com_github_spf13_cobra//:cobra",
+ ],
+)
diff --git a/cmd/aspect/test/test.go b/cmd/aspect/test/test.go
new file mode 100644
index 0000000..7037eb9
--- /dev/null
+++ b/cmd/aspect/test/test.go
@@ -0,0 +1,42 @@
+/*
+Copyright © 2021 Aspect Build Systems
+
+Not licensed for re-use
+*/
+
+package test
+
+import (
+ "github.com/spf13/cobra"
+
+ "aspect.build/cli/pkg/aspect/test"
+ "aspect.build/cli/pkg/bazel"
+ "aspect.build/cli/pkg/ioutils"
+)
+
+func NewDefaultTestCmd() *cobra.Command {
+ return NewTestCmd(ioutils.DefaultStreams, bazel.New())
+}
+
+func NewTestCmd(streams ioutils.Streams, bzl bazel.Spawner) *cobra.Command {
+ v := test.New(streams, bzl)
+
+ cmd := &cobra.Command{
+ Use: "test",
+ Short: "Builds the specified targets and runs all test targets among them.",
+ Long: `Builds the specified targets and runs all test targets among them (test targets
+might also need to satisfy provided tag, size or language filters) using
+the specified options.
+
+This command accepts all valid options to 'build', and inherits
+defaults for 'build' from your .bazelrc. If you don't use .bazelrc,
+don't forget to pass all your 'build' options to 'test' too.
+
+See 'bazel help target-syntax' for details and examples on how to
+specify targets.
+`,
+ RunE: v.Run,
+ }
+
+ return cmd
+}
diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel
index 95a8cc4..15f106d 100644
--- a/docs/BUILD.bazel
+++ b/docs/BUILD.bazel
@@ -2,12 +2,14 @@
load("@bazel_skylib//rules:write_file.bzl", "write_file")
# This list must be updated when we add a new command
+# buildifier: keep sorted
_DOCS = [
"aspect.md",
"aspect_build.md",
"aspect_clean.md",
"aspect_docs.md",
"aspect_info.md",
+ "aspect_test.md",
"aspect_version.md",
]
diff --git a/docs/aspect.md b/docs/aspect.md
index f40087b..3fbd99b 100644
--- a/docs/aspect.md
+++ b/docs/aspect.md
@@ -20,6 +20,7 @@
* [aspect clean](aspect_clean.md) - Removes the output tree.
* [aspect docs](aspect_docs.md) - Open documentation in the browser.
* [aspect info](aspect_info.md) - Displays runtime info about the bazel server.
+* [aspect test](aspect_test.md) - Builds the specified targets and runs all test targets among them.
* [aspect version](aspect_version.md) - Print the version of aspect CLI as well as tools it invokes.
###### Auto generated by spf13/cobra
diff --git a/docs/aspect_test.md b/docs/aspect_test.md
new file mode 100644
index 0000000..20de475
--- /dev/null
+++ b/docs/aspect_test.md
@@ -0,0 +1,40 @@
+## aspect test
+
+Builds the specified targets and runs all test targets among them.
+
+### Synopsis
+
+Builds the specified targets and runs all test targets among them (test targets
+might also need to satisfy provided tag, size or language filters) using
+the specified options.
+
+This command accepts all valid options to 'build', and inherits
+defaults for 'build' from your .bazelrc. If you don't use .bazelrc,
+don't forget to pass all your 'build' options to 'test' too.
+
+See 'bazel help target-syntax' for details and examples on how to
+specify targets.
+
+
+```
+aspect test [flags]
+```
+
+### Options
+
+```
+ -h, --help help for test
+```
+
+### Options inherited from parent commands
+
+```
+ --config string config file (default is $HOME/.aspect.yaml)
+ --interactive Interactive mode (e.g. prompts for user input)
+```
+
+### SEE ALSO
+
+* [aspect](aspect.md) - Aspect.build bazel wrapper
+
+###### Auto generated by spf13/cobra
diff --git a/pkg/aspect/test/BUILD.bazel b/pkg/aspect/test/BUILD.bazel
new file mode 100644
index 0000000..592c2b1
--- /dev/null
+++ b/pkg/aspect/test/BUILD.bazel
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+ name = "test",
+ srcs = ["test.go"],
+ importpath = "aspect.build/cli/pkg/aspect/test",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//pkg/aspecterrors",
+ "//pkg/bazel",
+ "//pkg/ioutils",
+ "@com_github_spf13_cobra//:cobra",
+ ],
+)
+
+go_test(
+ name = "test_test",
+ srcs = ["test_test.go"],
+ deps = [
+ ":test",
+ "//pkg/bazel/mock",
+ "//pkg/ioutils",
+ "@com_github_golang_mock//gomock",
+ "@com_github_onsi_gomega//:gomega",
+ ],
+)
diff --git a/pkg/aspect/test/test.go b/pkg/aspect/test/test.go
new file mode 100644
index 0000000..701706b
--- /dev/null
+++ b/pkg/aspect/test/test.go
@@ -0,0 +1,42 @@
+/*
+Copyright © 2021 Aspect Build Systems Inc
+
+Not licensed for re-use.
+*/
+
+package test
+
+import (
+ "aspect.build/cli/pkg/bazel"
+ "aspect.build/cli/pkg/ioutils"
+ "github.com/spf13/cobra"
+
+ "aspect.build/cli/pkg/aspecterrors"
+)
+
+type Test struct {
+ ioutils.Streams
+ bzl bazel.Spawner
+}
+
+func New(streams ioutils.Streams, bzl bazel.Spawner) *Test {
+ return &Test{
+ Streams: streams,
+ bzl: bzl,
+ }
+}
+
+func (v *Test) Run(_ *cobra.Command, args []string) error {
+ bazelCmd := []string{"test"}
+ bazelCmd = append(bazelCmd, args...)
+
+ if exitCode, err := v.bzl.Spawn(bazelCmd); exitCode != 0 {
+ err = &aspecterrors.ExitError{
+ Err: err,
+ ExitCode: exitCode,
+ }
+ return err
+ }
+
+ return nil
+}
diff --git a/pkg/aspect/test/test_test.go b/pkg/aspect/test/test_test.go
new file mode 100644
index 0000000..1a8d7c0
--- /dev/null
+++ b/pkg/aspect/test/test_test.go
@@ -0,0 +1,30 @@
+package test_test
+
+import (
+ "testing"
+
+ "aspect.build/cli/pkg/aspect/test"
+ "aspect.build/cli/pkg/bazel/mock"
+ "aspect.build/cli/pkg/ioutils"
+ "github.com/golang/mock/gomock"
+ . "github.com/onsi/gomega"
+)
+
+// Embrace the stutter :)
+func TestTest(t *testing.T) {
+
+ t.Run("test calls bazel test", func(t *testing.T) {
+ g := NewGomegaWithT(t)
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ spawner := mock.NewMockSpawner(ctrl)
+ spawner.
+ EXPECT().
+ Spawn([]string{"test"}).
+ Return(0, nil)
+
+ b := test.New(ioutils.Streams{}, spawner)
+ g.Expect(b.Run(nil, []string{})).Should(Succeed())
+ })
+}