feat(help): Add target-syntax help topic (#13)

diff --git a/cmd/aspect/BUILD.bazel b/cmd/aspect/BUILD.bazel
index 4e8b33d..cfb7f47 100644
--- a/cmd/aspect/BUILD.bazel
+++ b/cmd/aspect/BUILD.bazel
@@ -10,6 +10,7 @@
     visibility = ["//visibility:private"],
     deps = [
         "//cmd/aspect/version",
+        "//docs/help/topics",
         "//pkg/ioutils",
         "@com_github_fatih_color//:color",
         "@com_github_mattn_go_isatty//:go-isatty",
diff --git a/cmd/aspect/root.go b/cmd/aspect/root.go
index 8bfa033..140d452 100644
--- a/cmd/aspect/root.go
+++ b/cmd/aspect/root.go
@@ -17,6 +17,7 @@
 	"github.com/spf13/viper"
 
 	"aspect.build/cli/cmd/aspect/version"
+	"aspect.build/cli/docs/help/topics"
 	"aspect.build/cli/pkg/ioutils"
 )
 
@@ -59,5 +60,13 @@
 	// ### Child commands
 	cmd.AddCommand(version.NewDefaultVersionCmd())
 
+	// ### "Additional help topic commands" which are not runnable
+	// https://pkg.go.dev/github.com/spf13/cobra#Command.IsAdditionalHelpTopicCommand
+	cmd.AddCommand(&cobra.Command{
+		Use:   "target-syntax",
+		Short: "Documentation on Bazel's syntax for targets",
+		Long:  topics.Read("target-syntax"),
+	})
+
 	return cmd
 }
diff --git a/docs/help/topics/BUILD.bazel b/docs/help/topics/BUILD.bazel
new file mode 100644
index 0000000..51797f1
--- /dev/null
+++ b/docs/help/topics/BUILD.bazel
@@ -0,0 +1,10 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "topics",
+    srcs = ["main.go"],
+    data = ["target-syntax"],
+    importpath = "aspect.build/cli/docs/help/topics",
+    visibility = ["//visibility:public"],
+    deps = ["@io_bazel_rules_go//go/tools/bazel:go_default_library"],
+)
diff --git a/docs/help/topics/main.go b/docs/help/topics/main.go
new file mode 100644
index 0000000..d667533
--- /dev/null
+++ b/docs/help/topics/main.go
@@ -0,0 +1,20 @@
+package topics
+
+import (
+	"fmt"
+	"github.com/bazelbuild/rules_go/go/tools/bazel"
+	"os"
+)
+
+func Read(topic string) string {
+	rpath := "docs/help/topics/" + topic
+	r, err := bazel.Runfile(rpath)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Unable to locate %s in runfiles: %v\n", rpath, err)
+	}
+	c, err := os.ReadFile(r)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Failed to read %s: %v\n", r, err)
+	}
+	return string(c)
+}
diff --git a/docs/help/topics/target-syntax b/docs/help/topics/target-syntax
new file mode 100644
index 0000000..bc69f6f
--- /dev/null
+++ b/docs/help/topics/target-syntax
@@ -0,0 +1,83 @@
+Target pattern syntax
+=====================
+
+The BUILD file label syntax is used to specify a single target. Target
+patterns generalize this syntax to sets of targets, and also support
+working-directory-relative forms, recursion, subtraction and filtering.
+Examples:
+
+Specifying a single target:
+
+  //foo/bar:wiz     The single target '//foo/bar:wiz'.
+  foo/bar/wiz       Equivalent to:
+                      '//foo/bar/wiz:wiz' if foo/bar/wiz is a package,
+                      '//foo/bar:wiz' if foo/bar is a package,
+                      '//foo:bar/wiz' otherwise.
+  //foo/bar         Equivalent to '//foo/bar:bar'.
+
+Specifying all rules in a package:
+
+  //foo/bar:all       Matches all rules in package 'foo/bar'.
+
+Specifying all rules recursively beneath a package:
+
+  //foo/...:all     Matches all rules in all packages beneath directory 'foo'.
+  //foo/...           (ditto)
+
+  By default, directory symlinks are followed when performing this recursive traversal, except
+  those that point to under the output base (for example, the convenience symlinks that are created
+  in the root directory of the workspace) But we understand that your workspace may intentionally
+  contain directories with weird symlink structures that you don't want consumed. As such, if a
+  directory has a file named
+  'DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN'
+  then symlinks in that directory won't be followed when evaluating recursive
+  target patterns.
+
+Working-directory relative forms:  (assume cwd = 'workspace/foo')
+
+  Target patterns which do not begin with '//' are taken relative to
+  the working directory.  Patterns which begin with '//' are always
+  absolute.
+
+  ...:all           Equivalent to  '//foo/...:all'.
+  ...                 (ditto)
+
+  bar/...:all       Equivalent to  '//foo/bar/...:all'.
+  bar/...             (ditto)
+
+  bar:wiz           Equivalent to '//foo/bar:wiz'.
+  :foo              Equivalent to '//foo:foo'.
+
+  bar               Equivalent to '//foo/bar:bar'.
+  foo/bar           Equivalent to '//foo/foo/bar:bar'.
+
+  bar:all           Equivalent to '//foo/bar:all'.
+  :all              Equivalent to '//foo:all'.
+
+Summary of target wildcards:
+
+  :all,             Match all rules in the specified packages.
+  :*, :all-targets  Match all targets (rules and files) in the specified
+                      packages, including .par and _deploy.jar files.
+
+Subtractive patterns:
+
+  Target patterns may be preceded by '-', meaning they should be
+  subtracted from the set of targets accumulated by preceding
+  patterns. (Note that this means order matters.) For example:
+
+    % bazel build -- foo/... -foo/contrib/...
+
+  builds everything in 'foo', except 'contrib'.  In case a target not
+  under 'contrib' depends on something under 'contrib' though, in order to
+  build the former bazel has to build the latter too. As usual, the '--' is
+  required to prevent '-f' from being interpreted as an option.
+
+  When running the test command, test suite expansion is applied to each target
+  pattern in sequence as the set of targets is evaluated. This means that
+  individual tests from a test suite can be excluded by a later target pattern.
+  It also means that an exclusion target pattern which matches a test suite will
+  exclude all tests which that test suite references. (Targets that would be
+  matched by the list of target patterns without any test suite expansion are
+  also built unless --build_tests_only is set.)
+  
\ No newline at end of file
diff --git a/integration_tests/BUILD.bazel b/integration_tests/BUILD.bazel
index 4302246..dd53bc8 100644
--- a/integration_tests/BUILD.bazel
+++ b/integration_tests/BUILD.bazel
@@ -1,4 +1,10 @@
 sh_test(
+    name = "help_test",
+    srcs = ["help_test.sh"],
+    data = ["//cmd/aspect"],
+)
+
+sh_test(
     name = "version_test",
     srcs = ["version_test.sh"],
     data = ["//cmd/aspect"],
diff --git a/integration_tests/help_test.sh b/integration_tests/help_test.sh
new file mode 100755
index 0000000..693cbbe
--- /dev/null
+++ b/integration_tests/help_test.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+set -o pipefail -o errexit -o nounset
+HOME="$TEST_TMPDIR"
+ASPECT="$TEST_SRCDIR/build_aspect_cli/cmd/aspect/aspect_/aspect"
+export HOME
+set -x
+
+# Only capture stdout, just like `bazel help` prints to stdout
+help=$($ASPECT help 2>/dev/null) || true
+
+[[ "$help" =~ "Available Commands:" ]] || {
+    echo >&2 "Expected 'aspect help' stdout to contain 'Available Commands:', but was"
+    echo "$help"
+    exit 1
+}
+
+# Should include additional help topics
+help=$($ASPECT help target-syntax 2>/dev/null) || true
+[[ "$help" =~ "Target pattern syntax" ]] || {
+    echo >&2 "Expected 'aspect help target-syntax' stdout to contain 'Target pattern syntax' , but was"
+    echo "$help"
+    exit 1
+}