tweag / rules_haskell

Haskell rules for Bazel.
https://haskell.build
Apache License 2.0
266 stars 80 forks source link

Generating API documentation using aspect doesn't appear to work #1603

Closed brendanhay closed 3 years ago

brendanhay commented 3 years ago

(or, alternative title - ... doesn't appear to work as documented/understood)

The use case Generating API documentation section states:

The haskell_doc rule can be used to build API documentation for a given library (using Haddock). Building a target called //my/pkg:mylib_docs would make the documentation available at bazel-bin/my/pkg/mylib_docs/index/index.html.

Alternatively, you can use the @rules_haskell//haskell:defs.bzl%haskell_doc_aspect aspect to ask Bazel from the command-line to build documentation for any given target (or indeed all targets), like in the following:

Which I, perhaps naively, assume to mean I can generate the Haddock documentation of a haskell_library target without having to also define a corresponding (or top-level) haskell_doc target for the library as follows:

> git clone https://github.com/tweag/rules_haskell
> cd rules_haskell/examples
> nix-shell
> bazel build --config nixpkgs //cat_hs/lib/args --aspects @rules_haskell//haskell:defs.bzl%haskell_doc_aspect
ERROR: /.../rules_haskell/examples/cat_hs/lib/args/BUILD.bazel:7:16: in @rules_haskell//haskell:haddock.bzl%haskell_doc_aspect aspect on _haskell_library rule //cat_hs/lib/args:args:
Traceback (most recent call last):
    File "/.../.cache/bazel/_bazel_bren/af35c6839a3be93e48ea226293f1be1c/external/rules_haskell/haskell/haddock.bzl", line 139, column 15, in _haskell_doc_aspect_impl
        target[HaskellCcLibrariesInfo],
Error: <target //cat_hs/lib/args:args> (rule '_haskell_library') doesn't contain declared provider 'HaskellCcLibrariesInfo'
ERROR: Analysis of aspect '@rules_haskell//haskell:defs.bzl%haskell_doc_aspect of //cat_hs/lib/args:args' failed; build aborted: Analysis of target '//cat_hs/lib/args:args' failed
INFO: Elapsed time: 0.099s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured)

If I comment out the use of HaskellCcLibrariesInfo in haskell/haddock.bzl and replace it with an empty list, for testing:

> bazel build --config nixpkgs //cat_hs/lib/args --aspects @rules_haskell//haskell:defs.bzl%haskell_doc_aspect
INFO: Analyzed target //cat_hs/lib/args:args (6 packages loaded, 465 targets configured).
INFO: Found 1 target...
Aspect @rules_haskell//haskell:haddock.bzl%haskell_doc_aspect of //cat_hs/lib/args:args up-to-date:
  bazel-bin/external/stackage/colour-2.3.5/_install/colour-2.3.5_haddock_html
  bazel-bin/external/stackage/ansi-terminal-0.11/_install/ansi-terminal-0.11_haddock_html
  bazel-bin/external/stackage/ansi-wl-pprint-0.6.9/_install/ansi-wl-pprint-0.6.9_haddock_html
  bazel-bin/external/stackage/transformers-compat-0.6.6/_install/transformers-compat-0.6.6_haddock_html
  bazel-bin/external/stackage/optparse-applicative-0.16.1.0/_install/optparse-applicative-0.16.1.0_haddock_html
  bazel-bin/cat_hs/lib/args/doc-catZUhsZSlibZSargsZSargs

Everything appears to work -

aherrmann commented 3 years ago

Thanks for raising this and the detailed description.

This is a consequence of https://github.com/bazelbuild/bazel/issues/11736. //haskell:private/cc_libraries.bzl%haskell_cc_libraries_aspect is used to obtain HaskellCcLibrariesInfo and most other parts of rules_haskell depend on it. Unfortunately, aspect on aspect dependency cannot currently be expressed for aspects invoked from the command-line.

brendanhay commented 3 years ago

Makes sense - I'd seen the Bazel issue but the contributor responses aren't reassuring. Do you have any suggestions for how one might programmatically create a haskell_doc target for hundreds of haskell_library targets, instead? I'm currently running bazel query 'kind("haskell_library", //... -test/...)') and the copy-pasta-ing the results into a haskell_doc target which isn't ideal. I've seen various commentary around haskell_repl's custom support for //... wildcards in certain attributes - could haskell_doc be extended in such a way or is this just too much of a hack? Writing a custom gazelle tool is also an option if I'm the only one encountering this.

aherrmann commented 3 years ago

Yes, BUILD file generation seems like a reasonable approach. A query is a simple way to obtain all library targets, on the generation side buildozer could make it easy to create/update the haskell_doc target in the BUILD file automatically. A custom Gazelle extension is of course also a possibility, though it may be overkill if all you want is a single haskell_doc target for the entire repo.

The way haskell_repl's wildcards work unfortunately doesn't solve the root issue here. Also haskell_repl needs to be told about relevant targets in its deps attribute. The wildcard mechanism is only about automatically including transitive dependencies of its deps, but, it cannot discover all targets in the repo automatically by itself. Bazel simply doesn't allow this.

brendanhay commented 3 years ago

It didn't even occur to me to use buildozer. 🙄 Thanks!

brendanhay commented 2 years ago

For posterity:

# BUILD.bazel
haskell_doc(
    name = "docs",
    deps = []
)
bazel run --run_under "cd $PWD &&" @com_github_bazelbuild_buildtools//buildozer -- \
  "set deps $(bazel query 'kind("haskell_library", //...)')" //:docs