Skip to content

Commit

Permalink
Stardoc generates extend.md (#1128)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeagle committed Nov 2, 2021
1 parent 425d85d commit 64908c5
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 199 deletions.
2 changes: 1 addition & 1 deletion BUILD.bazel
Expand Up @@ -32,7 +32,7 @@ nogo(
visibility = ["//visibility:public"],
)

exports_files(["WORKSPACE", "repository.md"])
exports_files(["WORKSPACE", "extend.md", "repository.md"])

filegroup(
name = "all_files",
Expand Down
10 changes: 5 additions & 5 deletions README.rst
Expand Up @@ -3,17 +3,17 @@ Gazelle build file generator

.. All external links are here
.. _Architecture of Gazelle: Design.rst
.. _Repository rules: repository.rst
.. _go_repository: repository.rst#go_repository
.. _Repository rules: repository.md
.. _go_repository: repository.md#go_repository
.. _fix: #fix-and-update
.. _update: #fix-and-update
.. _Avoiding conflicts with proto rules: https://github.com/bazelbuild/rules_go/blob/master/proto/core.rst#avoiding-conflicts
.. _gazelle rule: #bazel-rule
.. _doublestar.Match: https://github.com/bmatcuk/doublestar#match
.. _Extending Gazelle: extend.rst
.. _Supported languages: extend.rst#supported-languages
.. _Extending Gazelle: extend.md
.. _Supported languages: extend.md#supported-languages
.. _extended: `Extending Gazelle`_
.. _gazelle_binary: extend.rst#gazelle_binary
.. _gazelle_binary: extend.md#gazelle_binary
.. _import_prefix: https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library.import_prefix
.. _strip_import_prefix: https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library.strip_import_prefix
.. _buildozer: https://github.com/bazelbuild/buildtools/tree/master/buildozer
Expand Down
9 changes: 6 additions & 3 deletions WORKSPACE
Expand Up @@ -15,10 +15,13 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_go",
sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
sha256 = "e0c127187c63f96158a7fd609300e216f70b44912806f62f0d17c7d3a3872bc1",
strip_prefix = "rules_go-027d78bed3952d73c6fb7099b3247f903aa7318d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
# Need a prerelease version of rules_go to pick up bzl_library fixes
# https://github.com/bazelbuild/rules_go/pull/2942
# Can go back to release artifact after 0.30 release
"https://github.com/bazelbuild/rules_go/archive/027d78bed3952d73c6fb7099b3247f903aa7318d.zip",
],
)

Expand Down
1 change: 1 addition & 0 deletions docs/BUILD.bazel
Expand Up @@ -10,6 +10,7 @@ load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")

_DOC_SRCS = {
"//internal:repository_docs": "repository.md",
"//internal:extend_docs": "extend.md",
}

[
Expand Down
155 changes: 155 additions & 0 deletions extend.md
@@ -0,0 +1,155 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->


Extending Gazelle
=================

Gazelle started out as a build file generator for Go projects, but it can be
extended to support other languages and custom sets of rules.

To extend Gazelle, you must do three things:

* Write a [go_library] with a function named `NewLanguage` that provides an
implementation of the [Language] interface. This interface provides hooks for
generating rules, parsing configuration directives, and resolving imports
to Bazel labels. By convention, the library's package name should match
the language (for example, `proto` or `bzl`).
* Write a [gazelle_binary](#gazelle_binary) rule. Include your library in the `languages`
list.
* Write a [gazelle] rule that points to your `gazelle_binary`. When you run
`bazel run //:gazelle`, your binary will be built and executed instead of
the default binary.

Supported languages
-------------------

Some extensions have been published by the community.

* [bazel-skylib] has an extension for generating `bzl_library` rules.
See [@bazel_skylib//gazelle/bzl].
* [rules_python] has an extension for generating `py_library`, `py_binary`, and
`py_test` rules (currently pending in PR [#514]).
* [rules_sass] has an extension for generating `sass_library` and
`sass_binary` rules (currently pending in PR [#75]).
* [rules_r] has an extension for generating rules for R package builds and
tests.
* Ecosia's [bazel_rules_nodejs_contrib] has an extension for generating
`js_library`, `jest_node_test`, `js_import`, and `ts_library` rules.
* Tweag's [rules_haskell] has an extension, [gazelle_cabal], for generating rules from Cabal files

If you have an extension you'd like linked here, please open a PR!

Example
-------

**TODO:** Add a self-contained, concise, realistic example.

Gazelle itself is built using the model described above, so it may serve as
an example.

[//language/proto:go_default_library] and [//language/go:go_default_library]
both implement the [Language]
interface. There is also [//internal/gazellebinarytest:go_default_library],
a stub implementation used for testing.

`//cmd/gazelle` is a `gazelle_binary` rule that includes both of these
libraries through the `DEFAULT_LANGUAGES` list (you may want to use
`DEFAULT_LANGUAGES` in your own rule).

```starlark
load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle_binary")

gazelle_binary(
name = "gazelle",
languages = DEFAULT_LANGUAGES,
visibility = ["//visibility:public"],
)
```

This binary can be invoked using a `gazelle` rule like this:

```starlark
load("@bazel_gazelle//:def.bzl", "gazelle")

# gazelle:prefix example.com/project
gazelle(
name = "gazelle",
gazelle = "//:my_gazelle_binary",
)
```

You can run this with `bazel run //:gazelle`.

Interacting with protos
-----------------------

The proto extension ([//language/proto:go_default_library]) gathers metadata
from .proto files and generates `proto_library` rules based on that metadata.
Extensions that generate language-specific proto rules (e.g.,
`go_proto_library`) may use this metadata.

For API reference, see the [proto godoc].

To get proto configuration information, call [proto.GetProtoConfig]. This is
mainly useful for discovering the current proto mode.

To get information about `proto_library` rules, examine the `OtherGen`
list of rules passed to `language.GenerateRules`. This is a list of rules
generated by other language extensions, and it will include `proto_library`
rules in each directory, if there were any. For each of these rules, you can
call `r.PrivateAttr(proto.PackageKey)` to get a [proto.Package] record. This
includes the proto package name, as well as source names, imports, and options.

[Language]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language#Language
[//internal/gazellebinarytest:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/internal/gazellebinarytest
[//language/go:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/go
[//language/proto:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/proto
[gazelle]: https://github.com/bazelbuild/bazel-gazelle#bazel-rule
[go_binary]: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-binary
[go_library]: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-library
[proto godoc]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto
[proto.GetProtoConfig]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#GetProtoConfig
[proto.Package]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#Package
[rules_python]: https://github.com/bazelbuild/rules_python
[rules_r]: https://github.com/grailbio/rules_r
[rules_sass]: https://github.com/bazelbuild/rules_sass
[rules_haskell]: https://github.com/tweag/rules_haskell
[bazel_rules_nodejs_contrib]: https://github.com/ecosia/bazel_rules_nodejs_contrib#build-file-generation
[bazel-skylib]: https://github.com/bazelbuild/bazel-skylib
[@bazel_skylib//gazelle/bzl]: https://github.com/bazelbuild/bazel-skylib/tree/master/gazelle/bzl
[gazelle_cabal]: https://github.com/tweag/gazelle_cabal
[#75]: https://github.com/bazelbuild/rules_sass/pull/75
[#514]: https://github.com/bazelbuild/rules_python/pull/514
[#803]: https://github.com/bazelbuild/bazel-gazelle/issues/803


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

## gazelle_binary

<pre>
gazelle_binary(<a href="#gazelle_binary-name">name</a>, <a href="#gazelle_binary-languages">languages</a>)
</pre>

The `gazelle_binary` rule builds a Go binary that incorporates a list of
language extensions. This requires generating a small amount of code that
must be compiled into Gazelle's main package, so the normal [go_binary]
rule is not used.

When the binary runs, each language extension is run sequentially. This affects
the order that rules appear in generated build files. Metadata may be produced
by an earlier extension and consumed by a later extension. For example, the
proto extension stores metadata in hidden attributes of generated
`proto_library` rules. The Go extension uses this metadata to generate
`go_proto_library` rules.


**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="gazelle_binary-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="gazelle_binary-languages"></a>languages | A list of language extensions the Gazelle binary will use.<br><br> Each extension must be a [go_library] or something compatible. Each extension must export a function named <code>NewLanguage</code> with no parameters that returns a value assignable to [Language]. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | required | |


0 comments on commit 64908c5

Please sign in to comment.