Fix docs for `sh_test` and `sh_binary` (#40)

These rules incorrectly shared rule and attr-level docs.

Work towards https://github.com/bazelbuild/bazel/issues/24473
diff --git a/shell/private/sh_binary.bzl b/shell/private/sh_binary.bzl
index eec109a..7a3c791 100644
--- a/shell/private/sh_binary.bzl
+++ b/shell/private/sh_binary.bzl
@@ -19,4 +19,27 @@
 # For doc generation only.
 visibility("public")
 
-sh_binary = make_sh_executable_rule(executable = True)
+sh_binary = make_sh_executable_rule(
+    doc = """
+<p>
+  The <code>sh_binary</code> rule is used to declare executable shell scripts.
+  (<code>sh_binary</code> is a misnomer: its outputs aren't necessarily binaries.) This rule ensures
+  that all dependencies are built, and appear in the <code>runfiles</code> area at execution time.
+  We recommend that you name your <code>sh_binary()</code> rules after the name of the script minus
+  the extension (e.g. <code>.sh</code>); the rule name and the file name must be distinct.
+  <code>sh_binary</code> respects shebangs, so any available interpreter may be used (eg.
+  <code>#!/bin/zsh</code>)
+</p>
+<h4 id="sh_binary_examples">Example</h4>
+<p>For a simple shell script with no dependencies and some data files:
+</p>
+<pre class="code">
+sh_binary(
+    name = "foo",
+    srcs = ["foo.sh"],
+    data = glob(["datafiles/*.txt"]),
+)
+</pre>
+""",
+    executable = True,
+)
diff --git a/shell/private/sh_executable.bzl b/shell/private/sh_executable.bzl
index a04dff8..105484e 100644
--- a/shell/private/sh_executable.bzl
+++ b/shell/private/sh_executable.bzl
@@ -169,39 +169,20 @@
 
     return _create_windows_exe_launcher(ctx, sh_toolchain, primary_output)
 
-def make_sh_executable_rule(extra_attrs = {}, **kwargs):
+def make_sh_executable_rule(doc, extra_attrs = {}, **kwargs):
     return rule(
         _sh_executable_impl,
-        doc = """
-<p>
-  The <code>sh_binary</code> rule is used to declare executable shell scripts.
-  (<code>sh_binary</code> is a misnomer: its outputs aren't necessarily binaries.) This rule ensures
-  that all dependencies are built, and appear in the <code>runfiles</code> area at execution time.
-  We recommend that you name your <code>sh_binary()</code> rules after the name of the script minus
-  the extension (e.g. <code>.sh</code>); the rule name and the file name must be distinct.
-  <code>sh_binary</code> respects shebangs, so any available interpreter may be used (eg.
-  <code>#!/bin/zsh</code>)
-</p>
-<h4 id="sh_binary_examples">Example</h4>
-<p>For a simple shell script with no dependencies and some data files:
-</p>
-<pre class="code">
-sh_binary(
-    name = "foo",
-    srcs = ["foo.sh"],
-    data = glob(["datafiles/*.txt"]),
-)
-</pre>
-""",
+        doc = doc,
         attrs = {
             "srcs": attr.label_list(
                 allow_files = True,
                 doc = """
-The list of input files.
+The file containing the shell script.
 <p>
-  This attribute should be used to list shell script source files that belong to
-  this library. Scripts can load other scripts using the shell's <code>source</code>
-  or <code>.</code> command.
+  This attribute must be a singleton list, whose element is the shell script.
+  This script must be executable, and may be a source file or a generated file.
+  All other files required at runtime (whether scripts or data) belong in the
+  <code>data</code> attribute.
 </p>
 """,
             ),
diff --git a/shell/private/sh_test.bzl b/shell/private/sh_test.bzl
index 5a9ba9e..eaffd9e 100644
--- a/shell/private/sh_test.bzl
+++ b/shell/private/sh_test.bzl
@@ -20,6 +20,24 @@
 visibility("public")
 
 sh_test = make_sh_executable_rule(
+    doc = """
+<p>A <code>sh_test()</code> rule creates a test written as a Bourne shell script.</p>
+
+<p>See the <a href="${link common-definitions#common-attributes-tests}">
+attributes common to all test rules (*_test)</a>.</p>
+
+<h4 id="sh_test_examples">Examples</h4>
+
+<pre class="code">
+sh_test(
+    name = "foo_integration_test",
+    size = "small",
+    srcs = ["foo_integration_test.sh"],
+    deps = [":foo_sh_lib"],
+    data = glob(["testdata/*.txt"]),
+)
+</pre>
+""",
     test = True,
     fragments = ["coverage"],
     extra_attrs = {