Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,6 @@ tasks:
- "-//tests/legacy/test_chdir:go_default_test"
- "-//tests/legacy/test_rundir:go_default_test"
- "-//tests/legacy/transitive_data:go_default_test"
# Stardoc produces different line-endings on windows,
# so the documentation it generates doesn't match the checked in files

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, one more thing. Can you add a comment here identifying the issue tracking this so we can recover it when that's resolved

- "-//docs:all"
16 changes: 16 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,19 @@ local_repository(
name = "runfiles_remote_test",
path = "tests/core/runfiles/runfiles_remote_test",
)

# For API doc generation
# This is a dev dependency, users should not need to install it
# so we declare it in the WORKSPACE
http_archive(
name = "io_bazel_stardoc",
sha256 = "c9794dcc8026a30ff67cf7cf91ebe245ca294b20b071845d12c192afe243ad72",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz",
"https://github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz",
],
)

load("@io_bazel_stardoc//:setup.bzl", "stardoc_repositories")

stardoc_repositories()
88 changes: 88 additions & 0 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")

_NAV_HEADER = """# Extra rules

This is a collection of helper rules. These are not core to building a go binary, but are supplied
to make life a little easier.

Contents
- [gazelle](#gazelle)
- [gomock](#gomock)
- [go_embed_data](#go_embed_data)

------------------------------------------------------------------------
"""

_NAV_FOOTER = """

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of these in .rst files is to make it possible to conveniently link many times to the same place, sort of like a reusable consts. While these values defined like this are kind of nice to have, it seems to me that since none of them are used more than once, we should probably just inline the link in the .bzl that is being used to generate.

I think that would give us all the content we need on the page and simplify the BUILD file a great deal since we wouldn't need to generate a template at all.

What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, after a bit of finagling I was able to get it to work without the template and by transferring over the consts to docstring comments.

[gazelle rule]: https://github.com/bazelbuild/bazel-gazelle#bazel-rule
[golang/mock]: https://github.com/golang/mock
[gomock_rule]: https://github.com/jmhodges/bazel_gomock
[core go rules]: core.rst
"""

# Workaround https://github.com/bazelbuild/stardoc/issues/25

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm... looking at the linked issue, it's possible that it is actually resolved and the workaround isn't necessary. See alexeagle/stardoc@586650b.

If you are 100% sure that this is necessary, what would you think about writing the template.vm file out in the //docs directory itself and just referring to it rather than generating? I don't see anything in here that's only knowable at build time, so I would like to understand the advantages you see in generating the file instead of checking it in.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are totally right about this, thank you for pointing it out!

write_file(
name = "gen_header",
out = "header.vm",
content = [
_NAV_HEADER,
"${moduleDocstring}",
_NAV_FOOTER,
],
)

_DOC_SRCS = {
"extras:embed_data": "//go:extras.rst",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the //go:extras.rst supposed to be? I thought this was generating extras.md?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, updating this.

}

[
stardoc(
name = file.replace(":", "_") + "_doc",
out = file.replace(":", "_") + ".md_",
header_template = ":header.vm",
input = "//%s.bzl" % file,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the // to the dictionary above. I was staring at that for quite a while trying to figure out if it was a target or if this was some additional syntax that I needed to learn.

deps = ["//" + file],
)
for file in _DOC_SRCS.keys()
]

[
diff_test(
name = "check_" + k.replace(":", "/"),
failure_message = "Please run \"bazel run //docs:update\"",
# Source file
file1 = v.replace(".rst", ".md"),
# Output from stardoc rule above
file2 = k.replace(":", "_") + ".md_",
)
for [
k,
v,
] in _DOC_SRCS.items()
]

write_file(
name = "gen_update",
out = "update.sh",
content = [
"#!/bin/sh",
"cd $BUILD_WORKSPACE_DIRECTORY",
] + [
"cp -fv bazel-bin/docs/{0} {1}".format(
k.replace(":", "_") + ".md_",
v[2:].replace(":", "/").replace(".rst", ".md"),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and above. This feels like a lot of work to avoid writing .md in the _DOC_SRCS dict. I think you should just write the file that you want to compare against instead of doing some translation at the comparison point.

)
for [
k,
v,
] in _DOC_SRCS.items()
],
)

sh_binary(
name = "update",
srcs = ["update.sh"],
data = [k.replace(":", "_") + ".md_" for k in _DOC_SRCS.keys()],
)
3 changes: 3 additions & 0 deletions extras/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")

# TODO do we really need exports_files
exports_files(["embed_data.bzl"])

filegroup(
name = "all_rules",
srcs = glob(["*.bzl"]) + ["//go/private:all_rules"],
Expand Down
65 changes: 57 additions & 8 deletions extras/embed_data.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,40 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""embed_data.bzl provides the go_embed_data rule for embedding data in go files"""
"""
gazelle
-------

This rule has moved. See [gazelle rule] in the Gazelle repository.

gomock
------

This rule allows you to generate mock interfaces with mockgen (from [golang/mock]) which can be useful for certain testing scenarios. See [gomock_rule] in the gomock repository.

"""

load(
"@io_bazel_rules_go//go/private:context.bzl", #TODO: This ought to be def
"go_context",
)

_DOC = """`go_embed_data` generates a .go file that contains data from a file or a
list of files. It should be consumed in the srcs list of one of the
[core go rules].

Before using `go_embed_data`, you must add the following snippet to your
WORKSPACE:

``` bzl
load("@io_bazel_rules_go//extras:embed_data_deps.bzl", "go_embed_data_dependencies")

go_embed_data_dependencies()
```

`go_embed_data` accepts the attributes listed below.
"""

def _go_embed_data_impl(ctx):
go = go_context(ctx)
if ctx.attr.src and ctx.attr.srcs:
Expand Down Expand Up @@ -80,14 +107,36 @@ def _go_embed_data_impl(ctx):

go_embed_data = rule(
implementation = _go_embed_data_impl,
doc = _DOC,
attrs = {
"package": attr.string(),
"var": attr.string(default = "Data"),
"src": attr.label(allow_single_file = True),
"srcs": attr.label_list(allow_files = True),
"flatten": attr.bool(),
"unpack": attr.bool(),
"string": attr.bool(),
"package": attr.string(
doc = "Go package name for the generated .go file.",
),
"var": attr.string(
default = "Data",
doc = "Name of the variable that will contain the embedded data.",
),
"src": attr.label(
allow_single_file = True,
doc = """A single file to embed. This cannot be used at the same time as `srcs`.
The generated file will have a variable of type `[]byte` or `string` with the contents of this file.""",
),
"srcs": attr.label_list(
allow_files = True,
doc = """A list of files to embed. This cannot be used at the same time as `src`.
The generated file will have a variable of type `map[string][]byte` or `map[string]string` with the contents
of each file. The map keys are relative paths of the files from the repository root. Keys for files in external
repositories will be prefixed with `"external/repo/"` where "repo" is the name of the external repository.""",
),
"flatten": attr.bool(
doc = "If `True` and `srcs` is used, map keys are file base names instead of relative paths.",
),
"unpack": attr.bool(
doc = "If `True`, sources are treated as archives and their contents will be stored. Supported formats are `.zip` and `.tar`",
),
"string": attr.bool(
doc = "If `True`, the embedded data will be stored as `string` instead of `[]byte`.",
),
"_embed": attr.label(
default = "@io_bazel_rules_go//go/tools/builders:embed",
executable = True,
Expand Down
5 changes: 5 additions & 0 deletions go/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")

exports_files([
"extras.rst",
"extras.md",
])

filegroup(
name = "all_files",
testonly = True,
Expand Down
69 changes: 69 additions & 0 deletions go/extras.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Extra rules

This is a collection of helper rules. These are not core to building a go binary, but are supplied
to make life a little easier.

Contents
- [gazelle](#gazelle)
- [gomock](#gomock)
- [go_embed_data](#go_embed_data)

------------------------------------------------------------------------


gazelle
-------

This rule has moved. See [gazelle rule] in the Gazelle repository.

gomock
------

This rule allows you to generate mock interfaces with mockgen (from [golang/mock]) which can be useful for certain testing scenarios. See [gomock_rule] in the gomock repository.



[gazelle rule]: https://github.com/bazelbuild/bazel-gazelle#bazel-rule
[golang/mock]: https://github.com/golang/mock
[gomock_rule]: https://github.com/jmhodges/bazel_gomock
[core go rules]: core.rst

<a id="#go_embed_data"></a>

## go_embed_data

<pre>
go_embed_data(<a href="#go_embed_data-name">name</a>, <a href="#go_embed_data-flatten">flatten</a>, <a href="#go_embed_data-package">package</a>, <a href="#go_embed_data-src">src</a>, <a href="#go_embed_data-srcs">srcs</a>, <a href="#go_embed_data-string">string</a>, <a href="#go_embed_data-unpack">unpack</a>, <a href="#go_embed_data-var">var</a>)
</pre>

`go_embed_data` generates a .go file that contains data from a file or a
list of files. It should be consumed in the srcs list of one of the
[core go rules].

Before using `go_embed_data`, you must add the following snippet to your
WORKSPACE:

``` bzl
load("@io_bazel_rules_go//extras:embed_data_deps.bzl", "go_embed_data_dependencies")

go_embed_data_dependencies()
```

`go_embed_data` accepts the attributes listed below.


**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="go_embed_data-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="go_embed_data-flatten"></a>flatten | If <code>True</code> and <code>srcs</code> is used, map keys are file base names instead of relative paths. | Boolean | optional | False |
| <a id="go_embed_data-package"></a>package | Go package name for the generated .go file. | String | optional | "" |
| <a id="go_embed_data-src"></a>src | A single file to embed. This cannot be used at the same time as <code>srcs</code>. The generated file will have a variable of type <code>[]byte</code> or <code>string</code> with the contents of this file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="go_embed_data-srcs"></a>srcs | A list of files to embed. This cannot be used at the same time as <code>src</code>. The generated file will have a variable of type <code>map[string][]byte</code> or <code>map[string]string</code> with the contents of each file. The map keys are relative paths of the files from the repository root. Keys for files in external repositories will be prefixed with <code>"external/repo/"</code> where "repo" is the name of the external repository. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="go_embed_data-string"></a>string | If <code>True</code>, the embedded data will be stored as <code>string</code> instead of <code>[]byte</code>. | Boolean | optional | False |
| <a id="go_embed_data-unpack"></a>unpack | If <code>True</code>, sources are treated as archives and their contents will be stored. Supported formats are <code>.zip</code> and <code>.tar</code> | Boolean | optional | False |
| <a id="go_embed_data-var"></a>var | Name of the variable that will contain the embedded data. | String | optional | "Data" |


2 changes: 1 addition & 1 deletion go/extras.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ WORKSPACE:
| A list of files to embed. This cannot be used at the same time as :param:`src`. |
| The generated file will have a variable of type :type:`map[string][]byte` or |
| :type:`map[string]string` with the contents of each file. |
| The map keys are relative paths the files from the repository root. |
Comment thread
cvarier marked this conversation as resolved.
| The map keys are relative paths of the files from the repository root. |
| Keys for files in external repositories will be prefixed with :value:`"external/repo/"` where |
| "repo" is the name of the external repository. |
+----------------------------+-----------------------------+---------------------------------------+
Expand Down